From fd6e55ccbb5ed4c50bfa2e765752f57eaa0dfd0e Mon Sep 17 00:00:00 2001 From: Truptimayee Dash Date: Mon, 4 Aug 2025 12:57:45 +0530 Subject: [PATCH] my 2nd commit --- .vscode/settings.json | 3 + __manifest__.py | 12 +- __pycache__/__init__.cpython-310.pyc | Bin 202 -> 202 bytes models/__init__.py | 6 + models/__pycache__/__init__.cpython-310.pyc | Bin 830 -> 985 bytes .../__pycache__/application.cpython-310.pyc | Bin 3053 -> 3429 bytes models/__pycache__/enrollment.cpython-310.pyc | Bin 2160 -> 2315 bytes .../enrollment_fee_summary.cpython-310.pyc | Bin 1000 -> 1054 bytes .../enrollment_subject.cpython-310.pyc | Bin 920 -> 1108 bytes .../__pycache__/fee_element.cpython-310.pyc | Bin 0 -> 538 bytes .../__pycache__/fee_structure.cpython-310.pyc | Bin 0 -> 2402 bytes models/__pycache__/schedule.cpython-310.pyc | Bin 2057 -> 2299 bytes .../__pycache__/school_class.cpython-310.pyc | Bin 1311 -> 2123 bytes .../__pycache__/school_course.cpython-310.pyc | Bin 1718 -> 1280 bytes .../school_course_attendance.cpython-310.pyc | Bin 1336 -> 841 bytes .../school_course_schedule.cpython-310.pyc | Bin 1584 -> 1638 bytes .../school_course_student.cpython-310.pyc | Bin 613 -> 781 bytes .../school_fee_structure_line.cpython-310.pyc | Bin 0 -> 649 bytes .../school_student.cpython-310.pyc | Bin 0 -> 2127 bytes .../school_subject.cpython-310.pyc | Bin 1449 -> 3012 bytes ...chool_subject_teacher_info.cpython-310.pyc | Bin 1786 -> 1635 bytes .../teacher_attendance.cpython-310.pyc | Bin 1327 -> 1297 bytes models/application.py | 59 +++++++--- models/enrollment.py | 45 +++++--- models/enrollment_fee_summary.py | 1 + models/enrollment_subject.py | 16 ++- models/fee_element.py | 8 ++ models/fee_structure.py | 66 +++++++++++ models/schedule.py | 17 ++- models/school_class.py | 57 +++++++--- models/school_course.py | 17 +-- models/school_course_attendance.py | 20 +--- models/school_course_schedule.py | 1 + models/school_course_student.py | 4 +- models/school_fee_structure_line.py | 10 ++ models/school_student.py | 52 +++++++++ models/school_subject.py | 88 ++++++++++++--- models/school_subject_teacher_info.py | 36 +++--- models/teacher_attendance.py | 2 +- security/ir.model.access.csv | 7 +- views/application.xml | 40 +++++-- views/class.xml | 13 ++- views/course.xml | 9 +- views/course_attendance.xml | 9 +- views/enrollment.xml | 12 +- views/fee_element_views.xml | 33 ++++++ views/fee_structure_views.xml | 56 ++++++++++ views/lesson_views.xml | 5 - views/menu.xml | 33 ++++-- views/schedule.xml | 29 ++++- views/school_student_views.xml | 105 ++++++++++++++++++ views/school_subject_teacher_views.xml | 5 - views/subject.xml | 88 +++++++++------ views/teacher_attendance_view.xml | 12 ++ 54 files changed, 762 insertions(+), 214 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 models/__pycache__/fee_element.cpython-310.pyc create mode 100644 models/__pycache__/fee_structure.cpython-310.pyc create mode 100644 models/__pycache__/school_fee_structure_line.cpython-310.pyc create mode 100644 models/__pycache__/school_student.cpython-310.pyc create mode 100644 models/fee_element.py create mode 100644 models/fee_structure.py create mode 100644 models/school_fee_structure_line.py create mode 100644 models/school_student.py create mode 100644 views/fee_element_views.xml create mode 100644 views/fee_structure_views.xml create mode 100644 views/school_student_views.xml diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3b66410 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "git.ignoreLimitWarning": true +} \ No newline at end of file diff --git a/__manifest__.py b/__manifest__.py index 4082d64..2ffdbff 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -1,10 +1,10 @@ { 'name': 'School_Management', 'version': '1.0', - 'depends': ['base', 'web', 'mail'], + 'depends': ['base', 'web', 'mail','product'], 'license': 'LGPL-3', 'data': [ - 'security/security.xml', + 'security/security.xml', 'security/ir.model.access.csv', 'views/schedule.xml', 'views/class.xml', @@ -19,9 +19,11 @@ 'views/timeoff_views.xml', 'views/teacher_attendance_view.xml', 'views/school_misc_views.xml', - 'views/school_reporting_views.xml', - 'views/menu.xml', - + 'views/school_reporting_views.xml', + 'views/school_student_views.xml', + 'views/fee_structure_views.xml', + 'views/fee_element_views.xml', + 'views/menu.xml', ], 'installable': True, 'application': True, diff --git a/__pycache__/__init__.cpython-310.pyc b/__pycache__/__init__.cpython-310.pyc index 6741cf076a7d4aabb9a01c9b10206fb393741db4..08b7bb9a20ff10a757472cdec01eefa9d77e3278 100644 GIT binary patch delta 19 ZcmX@bc#4rbpO=@50SIJy`zCVl2LLLz1V{h? delta 19 ZcmX@bc#4rbpO=@50SInBXq?Es9{@86145S$s}rUaFs_*yKW{aM>bZpd*V!K!hlW5Cak`8Hyx8 bY>CMincUg5fJ`2S$qLLelMR@;m;@LBlb<=q delta 69 zcmcb~zK@MJpO=@50SG>A>CCX4$SccqfnlP~c~+rd22J7328?-(%zm0elRq$pbFO44 X5&+CgFg`| diff --git a/models/__pycache__/application.cpython-310.pyc b/models/__pycache__/application.cpython-310.pyc index 0528151e4a54d34f9120c0e8aa84b886ae742da7..e53371b17f4ea1710fc1645afa7fad3b169aa4d4 100644 GIT binary patch delta 1599 zcmZvbO-$TI6vsWbS$jYE3XniZ_y$8**aeahHB!<=sVYTWXjRowWm$d$>(#DJ#|FxZ zb`Qz1k&1k+DyY;$&rz>E^w3K#m3s5N$DVphPkr;)MOD>Z&G`3!@Bha0It^!xASzO13L5_sJ6k)Miw$)fcaXrbELA6d(G@Tah|w< zT!aF;is&k#>W30#29O626zKn+!2pe-*+W!0NcrJzehBl!7*XvT7#V@i4N8xab%c1V zYaK=F7+G&p_9kU-A&MwBu4JQU3}#ojAUVo{CA0`J0zw^ z%n(l#&l1lN&k@fO&lArf_rn75JaQ2hi5JMTM7&6Gi+G9R%fuGNSBRJSV>zR%f)#%6 zVioRPGFXN3E9E7#%diIPuM~R?GwV>nOcgdLQ-RGr#o9{F)nWE`@`JiIoo~5*vmDn2 zccDE@!u4YR*pE-kE&mHYNPbsWSuSB(wPO`5HD#5yQER$UG*ywR+EZ1jHhOA9s?DC- zlxnM|wxqh>Q}?BM&{Gejde~DBrP}VP54KUNmG!pSeg8V?%C(jgQY+PKUA6nj*)Bfy zT;MI=oBEWy;>{y%kZsQ3RhIs}nwah3M`8|9Ok#(nZWMD%LyvLD1Mq_bJL%|KZ2rwp zx?q!w(kZ_QH0Tj;?xz{Sy->i9idao{GSAt^$$94e4nvEHt%faH!tPADP%agw00R{? z(9e_x!=_$n(09oiOnyz@8hA|RZhOQRWqBN75Xq-=;s+3(w2cpUrfRN$RNoIpOUU8d z%aKiqz!hokLW;7lgr<&mV785HtqFANwk?hOz4Z~Lp zaiV&7f@9KbUSJ{`!p>x>sxtZ4SpoaZyY_r?ZjN{UWll@(;bGJFT)7`Of+x4O_frux zY_!b_2xrQU@>%IicE%ctD8}?`s4rQ-0NK$#S3$u|R(FLw6iXM6@sVm#EW|dFor~fl z;7@}X-(;z@B)L4VyDqeJm*se2>+mS%4i%8Uj@c-KovDr|jxjd+Kb~Eyn*3}&pG{52 z59(a_v5@mm^;+E(S7*}4<@YESliBRde0GmFIbDS`=gIHS3EUR9i*EO7JE!t$zsP>Y zK3S8KdruB#0GD?+5>I64>O`(do{BKAlPv=5Ohw22mw%I$)B>JF30sco#mrxY{$ws+ Y(~2dQH1ZqFO1{fa4*Yk-QUCw| delta 1255 zcma))&rcIU6vubA+h5DJP)dK$QYeK2El?29#GAM#9t09oy)>F;-5J{A(j~jqM1qtk zR}#ryJs>x(;$NT#Z~g&$H1X((KS19+S|F&2yV>u4=DqLCyxF%uQa=-6GZc~qxW4V} z)z#2p__Hj*=ng#g$3r*WX8w%;m8h5c4#Y|jM}8VOAQc%oh};9LP#Ii3;0nPgOcl)Z zqAP^l2OOyhG<-~GFGR#jKSZLm53>X4j3CE4&i>;zp;5HPF+G6k1aOkZkOz_D$f?e> z1Z5F#m>hAoF65}-rq&md=zhmnVoN03K2w<}p3WHB*{Jc^tH4$~a+7_dUe zkjK$8j-1DM9(e-e6UdVopG2Oz;xDk`(KMaCC=RnWeL|1n&}^ zqx0~dqc_SzVZn`*^}1;q%UfGUL)Tgjv$^ej5$Bu%&kPAV%bo>)#j6^cZJ*wjB4jBB zjV*|-SXQlg7av&(K&uY~yqeu&1rK=qTdYYN&6?}%dT)~C=_jv6GHLGgf}Du1WHV#k z^;t|eEqWqYIY;%cko(R%|6S+EC$;&Hq{4HS0@)Gn2~PvBNlTz)his5IobC;w0vtkI z+fJ8Zuk0$bZLP+#IvnLWquF)S%I578(el9pR)EV0m)wPn0l864=jX24uts(Be2rB> zP=qr+FF?XX`sD? diff --git a/models/__pycache__/enrollment.cpython-310.pyc b/models/__pycache__/enrollment.cpython-310.pyc index 9ac326e45214616d8a84a1f5131e8d1db68ef19b..f73d4b5760dfd833e5a125f8313e6a713ded3423 100644 GIT binary patch literal 2315 zcmZuzOOG2x5T2fw$ItaX^4KJsm?R_^h>16EgrbC9f;ePZWH``TG@4AccgLEC(>;#x zD4de(O8f!@-1ti^apJ_88$yEW_SkEbjMY8$RdrWa*K3?Ln>7QU-@p3t=%=b-{Gq_| zVF~9`t(4_X~2H4=dHo#$Ixdh$iqf@X zlQt2x4h>lUmB2=+bwz791*eY*ZEO0BrdKt6R?};m-qiFu(n`lU)NvjzXe%~K-WKvM z!X?c+g}l?y(R$cPRd^S!;Tnsc)A%~#_cT6_*o7{fg7?wV4~}hm zL32J__@l{VwiUWHN4FHZJx8|{x-&<26uLV{cNMxfNB0!EKS%c! zdN4;15Sjg(g;ySbQ{(;uD|^iT_5yE9N3W#rPB!6!;Vou<8!#a-Q;O!}FaVZBVdq;G z@S^pEG0_?1d=lmp&bn3?Yk3?*K<#~;QF~<^@H`6QqP0IG;%TQ8xsy~cb-&T?qFyQs z@`>P=mGe-Ybah){(tWJj3qwv-#YDLrXmw{!BHsp{jcH{U=P{;jtF#%-(;Ba!#$x3p zIXb&Rt}T`h@L-rzXIH)O26#X^jCjI8;sGV84-V3h#j)luNVn8~UFqK}t7|D+#pKzD zg*kSlML}YMQExEgi(>1|JwwKNVv-~QpK7;s1|?{gYeO9#tg1k$fRyRV*U$!DQHJQE zRlZLdm#w8@$Fu)eysCCA9J+X~A@S1KHNI>8KwgrO!JD~$kIYvjC4jVVJvYI?(l+;` z(Y5&v+#xOO8PbeE)|M*Ba(eVJida{Jsd(MmuH?M_P@o|H;VTyWx3bw zNYD4vAYr~QYrc=oVG=94;rq`gL0n24y#$%SM98DD>T+D&QhHCZi*0A<6=gZC&isi^ zk@n6}z$9jk4~dwSifjgDsrXYY z723j>3hXdtsnB|fRc_K&xe4V8OIzh8U0KQ)K!)ngTI_w9vTbaUQ`#=G%a5a!;VlH+ zK)rsMJ11OBX;sg-f~)@psu7M^3POisDLks3avdWFDK*4HoIJxOHfdWMq>aB8sS&&B z{?%A%5cNZ3yZ_W2H8-3YYCCPRhHE{uMYz(l*R4ofwRo;FP6uOViswh^5#v!Vou}%L ZhF<+Pld$Q}!u?QvY;^8y7#=xo{RexSouvQ( literal 2160 zcma(S$!_FC)aAC_PVZSJ>m=jMOaQa=ArcZo2+fcTT$m84nFFOD%lK7y9K7^Yxkq$s zxR6})6WsDkb>+mF8$yCtWoIEXk;YNKdP~*Y-%H+ZHw^sFMyJP)YZ!kh;^t=|@dSTj z7XcVR5+fy)q$V|qqRph1TGS%OHwM(eIy1mxfoLe zI)``z<}}{acthhYjW;#k)_6kxFOK?x~ z7Lm6E%lgf|O1^^fRan#VW#p~EI&8pwyi=pAn%+cuOVeveJMaLS;K4RLJh$k&<~+ja zw&Agg4tC(ZGlOox`|tst_rZq`@!W)uFuNbi-XJ>8^W<5^^CU@GR?Oyw=JeSWi#BeE z7bb%hBtXU}wi;3V(^u{-}Q?d?h7*3Kxsh3U| z74a)3ou~Rl&RmqIV-*w7xxGsi`4;eeOzZmy#|&njDh6~{TWF(&S@$}b-hNo<2&4@> z92V5xR|iIf2C`wyQw9mlzxGD``eO3a35yEazOHG233CS} zU(7b&d^2PW-=%5Dr#emEpd#AU-KeTl6beN62jn_>@tf2|{UZR{IAy1$YFH^ysnLY9qF@*7Su_N;j@+ZeD6yyw^; z;fQ$=_TkSAykXA09dTiDrAb;@n6e8jiD1c4I-Es0hYN#mq44id+2=<&qW zzT2JE%dn$k29tyZihhL}KDqMCzsoNy$N%3P_*>Eq0#(u=kc}X~@+h5wYz4u~Ntjd; zTVFvYFcI;1tg6LpDm(7;Fq`h?8KVtRE-Rb>>3kJu*x=HRQ!Ko+_Krg?n`jRh(GC|470ht+Bdrns7D2WLhExc17`Bptu_7 rGVxtS_t`HI)722=blT6=e{=olZ9Yl&i?YIBsx2YZc=e1HSvLOzM3--C diff --git a/models/__pycache__/enrollment_fee_summary.cpython-310.pyc b/models/__pycache__/enrollment_fee_summary.cpython-310.pyc index d39457a062f369105e71b82b78b981e268d9baf4..3a99eb4bf0f661fe14d852dcff893500fe458d23 100644 GIT binary patch delta 242 zcmaFCK97SppO=@50SGETb!G%l!n0gW0@5HeU)4n9UDl3#2oo08LHd1Bx(334&GfgJp$M1cDhf1t%La z7E16HCuij6=jauel%}NSmE2+vhA<{CWSq+=JlUQpoHvRaDj8ptnl^bFQxTg8(Ah;I mllhnf_+)@g4h9xR7DhfMKE}ye%s~PWS+EiiAv*aCvkU-PB|8NG delta 211 zcmbQo@q(QM!ifrf`ATd_XpTIztNgBE}RRpa@fx09Yk2SXMBFFPK4-f3iJe;pCHya~Opt zr!j?3KE+hTCJb~zk?>?E<^UckAd`cEg^`7kk7@D(<{%x299RK}5CIamIBatBQ%ZAE S?HGZ)Vm2Tl!ob5Q#smP95-hC% diff --git a/models/__pycache__/enrollment_subject.cpython-310.pyc b/models/__pycache__/enrollment_subject.cpython-310.pyc index 1edcf72d20f8bcdfafe6f9cd89601cb6b1ff9ad6..7c82cbc7ee21ebcb83055bd9b1347afff9e77dd9 100644 GIT binary patch delta 361 zcmbQieuaZCpO=@50SMOdcV}?2Oypb0STu2igE@CPLkia-#uV-pjug&b<|v+2)-28x zo)p$z#wcDOn>&R!g)f~cg+E0gMGz>@mm(C*pea0Ao^fiuCXXi5Ek?sCcITYL;$j6u z5YGt4GXn99VLW3H&jiLZ0r5;>JW~+Q48}79@yua7a}du0#X31m_z~-ooh4C_ecQV;>i1aB5C!a!F=>-sDau83DH9lEjkI;*|_V z8o)3r(wKaJ$wxu~$mC#PVPs+CV-jHGVdP?D;br^G!#`Pp*+&4P4y+hNXilzSmH`0D CRa=<= delta 171 zcmcb@F@v2ipO=@50SHuOnlt7zP2^k1m^E>OgFa^pR|;z{V-$BPYZhk;H<-->Wb>x* zr0}LQrSPTjrwH^iNAaZy1~X_1O;%@|Iyr~QosoO;7N)+*zRc3noWZF%smUdo`FXe4 zic1npN{d%A6v+T>Dw3I8!R#XfVsbFBFtRZ6F$pm8fZ^mj%sv7THDHAxLUytRiwpqo CFD5Vm diff --git a/models/__pycache__/fee_element.cpython-310.pyc b/models/__pycache__/fee_element.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..750b47d208760d349bd664c4d426b20092b7d442 GIT binary patch literal 538 zcmYjOJx{|h5VajA4JoY(12Yp+B^ZQx_N=+ut=u!MCJW3(7u#;oS~FDkkSZPq&D7`a<+)mRmH6+288w5!Z9K= z?~UU^bIa3wfDd!s+~9nWqGMQ<`#HvwNP$vOwyd^Vgv{bRzOQse_47qWmR!l|PM3v! zH9M=cKj#xpIc>8xt?+*6YHqs~%+9H<AM>cJGiq_6wSm Bj8y;t literal 0 HcmV?d00001 diff --git a/models/__pycache__/fee_structure.cpython-310.pyc b/models/__pycache__/fee_structure.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c8ed105ce9d9244bd0f551f66da5e01d6042e690 GIT binary patch literal 2402 zcmaJ@&2Jk;6rY)0+Z$)?B#zrO{fhfVV}zn6{Ynu+se(!mU=Hb_S_Q3EeiLUad)J*^ zgJPxP&azh^(Ryd2nT zte$(0{aM}8`A!V7o#^~VDBF-|E9izzYCCx4k*wg8e2+#lj|1}raL)qa*)n%84;I*v zgZyL5D5T~WtbSuQ${`klQ0Dp^h`gt zy-7K>Q-SI(ha+(G5qrqJY2%rJV=%jG!ErcYyjAobG5t=$DdRZ`r*Y47y0X^XjN|q# zDc4ffYoklrC3acmg1bYak- zb4eO2S$FF~^TmE)wH+i$ZIRg0kS!6rJY<)NT^X_~#I6q6RbtnM>>9D_Lw23m@{lbP zyD?-pkcq`heP{6cONK9wIITx4E{*t-&Y7Ndp$Zsk?I?M_7b*#R?wwwkhH+FwVUjvG z&3jWfp%W$vxmPy>)so3x`DPULg7%R2$L_=_QXHi#Bhgaw`Kb6y>XUMDB%{=GM}hD| z=$9!LtHZ|Rz}f>c)D`2pYN_n0by`TdH0 zEg}wLoBRB}0EUTTHTuWso%=!Gh*d3M;g%igkl zb3KMQUhiy~pDe@tP7nnx*})C2XNPVb74Sz}UFdEpI%ucyNeDRNIJf`q*Z!Tf3nL|I z4SGDyVnd4RQZS6kfSP#tO%tF0mS+K9XymD6@^l>|5AV9bXBY}5x>FhQt$|FUp-Anz ztuEk?B7xOKGd4331Aed z5IwP|gbYvti%{kp!vd6{ac~Ey1myvuQj@h(!O74xR0jwP&Hz!d$y#Tz;AH5;6Bk8e zm{Xr@^BsdiwksZpZLz}vi_osvW`4#_513`z<_64$S_{YdIXH#)8JtVN*(YMdGW;BJ z>i|EG+|GE*GNUkSP3B%`gr7|_7Ou>47Cu9T>Q)vP6Cnyt*quRByN&HIi|7j<(OnEl z$Ua8&9;SA<^C_a0IYjecBD!)0(Rbe>n#Zt(%ReGIi4%rD{ETQ4XAN&ZL-YrJgTkL) zAo>NfDZD!&Slw0h{Ziv(@cV_Qj!c;h#ZFC(=ue zIgHmB+y$OVuRJOrrV!|S(209ds*X|byWN%{+$= zDFkVt^B)E6o=jdzXI=H<2v1kklKy@jn#ZBZB{W5=$Pc^ozvm~)Ji8q+$>}csW&hc~ zc-Toe5?nyoO* zcw*ONTQ*ITscpGi?KntZIoFCdrJWBVxrC)`OTB?q(H{_90NIrhB&L3u^R1oXk`+~! z1Dat9F=gri#gP`05ObK#Z9XZA+%DyRb0=Kxq9PUHpvSd~+_B4C(TGMpuWc%;ipsm$ eNw$dG`}9x7^f~Nx+IcHe=xxfHgw|bUN5wz?0$0rd literal 0 HcmV?d00001 diff --git a/models/__pycache__/schedule.cpython-310.pyc b/models/__pycache__/schedule.cpython-310.pyc index 8c22f01895ce12888709d0a1730f8249cff2dd45..7e16979d2e163436670b646f7295ec2c6554fa65 100644 GIT binary patch delta 896 zcmZ{iPj3=I6u@_uo!#X>l>VVW3s#Ilu`SR-t5!*C)JqSBgN6%I-UhazYyz}VE*$K| zXb)sQf!_4$7x3n1ki^8BAHbs*-@J6ugHEzvqx@PO7<>->=d9Q1Pqbc-G9uRL`FjGB@&Cr8=6k^iJ=ch`rVzSV?LjHKBb z+GqCg<@$;J!tS+X=f4L>sp2zOo4m`8%{KOZ&%gi;_=TtLwfM0PCU`Gc-AC*r_7nSw z1IR%L5Qm6^#9`zJgovZWVd6PtxlaW5iNYMjaGx0FbeJDg!922Cm?H71rP?zSF?7_$9B2&+OSa z7s#noRu~xv-R5ABDM%~2R+Lt9tt4&BwJmAeu5C*zyH=J~ajhb4$F&`4yRJRnMO6!% zBlB|qP4dFb<$=^fapuJ-r^=~OJ3TtKTEiUc8~9(vhWdfUKYdkOj1|S6cF69CH`)`H z7vHqZ#x1PqZ^%%bg%Z*w`O(mVAxhX)X&5h-KlQLva$>n8U7rCNS>rGFQ|M5RSc%0F^z>(AJc;R z&p=r8jS4fxN8|bfvtjo-R^J{@`Jn?=mlpo3 z9P=Epk8{j4HsMPYUMD9LF5f%L7DCGji=90)Q#_@G~TPr%h5 fyv==akf4hB>c28(UiU09Q#}O}BuR>v50%U>&M1+i diff --git a/models/__pycache__/school_class.cpython-310.pyc b/models/__pycache__/school_class.cpython-310.pyc index 5e4594c918e857db00981ceee6013cbd427892f2..81cf391541a84a1a95bbba3579a15b52dc363f2b 100644 GIT binary patch literal 2123 zcmaJ?OK;mo5ayB;NlDbhw&EsD3-q0`54Uk2Zi^xa8lXAFIXEZ606}xt5)D3-S*nEu z`;?%k_SQoWJ=nSRC-kpuk3Hqwo_y-eQnDq(Ce*a+_9D?dQN4bCznXCceY(9EsSV#Y&*o7{SCa7(Zw`itjhAR|1eS90 zl8a0#=P(r+m&%IAX+m?$PXobyeC1Clgb^}sgeGU9#m&$bjU$I!+~y7L{9=VJVsB`0 z_XXn~Z}JxEny71`4Oy6B8JerGZt>}O^o0b)!s`+Wtlz5Vku|7)L<(iq#9az-kmGu;?3jPxMD|iRiR`6G_zJkAo zjT(FN^Lz?}RmEMnv8vdHO;pTU^@3dt@=0I<)sON(Je{N<_^b^=ZY5s>I^0f zZ59uW>3x8&^iUidN5&DujI-UqRF)`yQ109Trp}fkJN(0d*U<8OM|`ti^0M5|r~0o> zf0V~XJQTSos{Oj!_U9A&b8L;L%KJ8p^8+5=yGgs6C_G~}s86TE*;*JZB67Jnj3-&8 zyvO4zEsHptH7T@-6d-4vItNcgoQwo0o4)u;l+-u$0d52h;JT@GBZEsG-$bFzw0P+dqQ=DUsg> zKZ>4C;*1&@QKRN?Kf(wSNHqh1MW^;27h)R;XBuvR$l^-y#i4bcntLL{n*a%;PGa*B znreI4*2^_63xRpm7m9Mf!#hUAg=(iVD(74ib~JTGRZTEJbfUaPzF-I8QaUMHKsg1v zNa>jJRTQ3KWA6H9i`gCLpKfo!eAZ>2*=5>pH*geoYFPsDp^mQJr}2ocY;AMhCP=1r P*6vZYNIKfU*fjqGuS^=5 literal 1311 zcma)6OK%e~5VkkFn@zGw`l3Z}AO|?)k^@2@RR{qEaiQUma#;mg+Z{LAbRVs~K_n^{ zT5;ot^e_3!i8D7YF!rV;RIP-g9naWf&-cxYlQ)}ng5z-Ybo{kK$aifl4;zi=_{nV) zK!7GBr2$Q?z@pl=l1gd^w$Uqz6F6@O*x;NIa5$Z~rzCxKkz*1TFOmx;E7c3 zLCh17U8-vDB^R%S$VETWPRrvme1@x>1QbYM0Szi(1vYmkE>v{5Z&px6%L5mx;GtDB zdo|Q)P)EH1b));JH=zN(@oGU6T4y9^LmO6bUV&9u!+90f5%Pv=45D$KCp$?f<=mIX z=tbI6PPte&Q>P!Md{2{;g^06}@&rGg#)8AVwKyfG`x71&${Uml5*JnEq}(!w^4=X4 zah`?Aye7EpO))2O-Yl=*<6$)BBBD#Fu~669*}?DU9TX?z75U(OrUe%1gih!tIi+7P zU&zGj&+iU+2Ay3lWjNxUD2by(4xNKsbRNiaOX!=Fogs~LOWBeq2g(&Z$_1Pgv4)$! zp78Bq4tYLIXJ#sSu{6x^!jxyluq^Cwv0>8GJDREWFw(@BL;x%;0kkz}7llV#)c!rc zS0=%*?Oo%4BXi;7C7R#X+kDjN=fzcSqKOVd$1^lav5ux{FXANmh-G+CFN#|zFjs%e zeu3t~>pzgZK)xU2Vs<6VHzT=y!5E7S(}Xi^>l?N%A>F?Q5+?dz_kMRxd5q~QGN$T` zVMX+HO!jq?}#-mt)Q@#WWC1CwNcG SL_O2*OL{0)h)+GbY5f6(AXl9L diff --git a/models/__pycache__/school_course.cpython-310.pyc b/models/__pycache__/school_course.cpython-310.pyc index 01c5d1fbc18eb1d61e20925cd06177cd246d93c7..33b0f0d466d9b4ad279a1be6eb2297aa119870fc 100644 GIT binary patch delta 661 zcmZ8fzi-qq6t-jMlDkXN^zM3X;fg3jr7V?TL*kcIiAqSlrCWwpQJ&FVm5VDoH-M0e z1S>*SRu)DUM*ac*3lH5GU}a(C*}b9QCtKh5zVE%~ME(}P?Ikjfdj!{y<;U4Cewj>8 z_K*PqT9F0K>B7rBN)8Elz}^#Jf}XK=Ea$+FN#_5wrI}|s3kjmqrt@+xD$u1(-&{VD zXSns%<>#FX=zL&#ApEls0`QS}c^6p+Lg+#dSRK5={tcJSlx zv~TF%WT4BLl+}K5eqPPXqM6Iu1jo%1MBTJs={V{i$feTa?zC8l_B*}*aCpOdI*0ul zh1b!l#Mv@t0wt=V5ugJ6YsS}&RHFS&uh=x(ZvXJ7&%>jle)T}s!X*FpGyGsyD8p^r zJS?k1Yn)<&Mik{tC===H%bi+7d*XlUej#cXr>Ncb1$%s6fDW|EIP#Y-WwQZ#y literal 1718 zcma)7OK;mo5av>pM7=0KWyNtD0<90a=-^Wj6h#fiEeh1iK@JKKE(n6Nmg(@}>{3NV zq?bC^{t*A69`@Qp(Q|LTv@=UeaSa713C_;9vyXXwQr7FW4SbG2ySx6QZWzB4c=%Wd zzQRwQpa26{Y$VKMiRqb)uo>49%d?pAjR7^V-Wyu;!V!((80CNQrCrf2c`O@r=&`md(fL}Wt) znqVVpY1D$YMr}kL=%CKLuGYI+@1gEMPwRcux4_Z*HtIXjhb`DfT=RA{-a)*p@!m%J z9@_V{eP7!Lhz~R#z!09iH@pKlgr_(T;Rrs#@d8LXc#fk#MBin!R2^?d6ueq!GrLc zi=sWt1CeuZU!{e8mV)~-$a&#hWO)#~li)T8qkLI(UZ+v+PVj;#FNUitv~S}e&v^<# z8gkVt-Ss2z+NbO3V*kGzWWE5N=Ee3|DzZ4nyJzK$EC!EOqKmMIdC~u#^EdI*ovkJw z`ygdBPZK=V>zuB28L|g`WTH+DJi+g;Llp0fm&OnF&n(AAe#dUuz_??-U~^$P%xUp- zhEciaT*_e1-7t>AH|XhACfs9rZwfj|St-`x-c*+4@s(-_9%cgW4Y7m9zn}9Lml?-7ez| z8$KGl=;A39;lX#=+?{6mW7l=Ly3ZxXfsHuK+Pn^yD6gM7`c^^e_w8@>-vj5@A zDMtJwcG{yvf83SfD&(poe8T#KwNJ;Je8ObwmRhf$jt-UW`&3EaS8dp%#HRQo(gmnT`ul^qiEkO``pmsC?0QA@QY5zYtF zZ7Q(Vn%|~5pL5|kIWf-`k^MEvR|eA1p8>IoDbx~tE9KbD@yql z$@J{@I_Nk`xt?;+xr#A_#U5pCK;nSJhq`NxiZAGAm_GSA3fr)l#T?VYZtPa?7F)fx zWm{cK@0gC7%A)=k#J@6OeZph@Q^<7|Wl5&`IsGT-O`Gml_7`Pkz9dphqQaKZWrNzk D8R_ID diff --git a/models/__pycache__/school_course_attendance.cpython-310.pyc b/models/__pycache__/school_course_attendance.cpython-310.pyc index 459330377d9ff1e32e3728385b6ae1ef06658e83..e41a523adea2f6e45541f2728e9fd9f7f7946849 100644 GIT binary patch literal 841 zcmY*Xy>8nu5GM6w$&TzQ4iFUWlBs|e58YY>MOqJ?Via&E!Kgs!uCW41bVzxy*LDs1 z3?2JQTs!p@I`t^JutR`Hes{;a?~W(O;}N6vQ~y}M@fiDU!RZPJ+|bsqNB{#~vxeuq z@p6x|j|@EUzccWW-}~SEJb+-yvhWZ2vdlAsMgrE_48B%agD$Q5bcFtE-fp1@{6e#6uuXK=lFIdLCRIL>kn5*(TG;uVM8UZ+-R*1hC|}x-_15V zWoOs+R;MIl7Vv`0;$o+WR^!5U z-3Qqh;KTUJi8D7Y@SL=)o3;r{e)jYG?6CB?ko*tc42>D@{I;0#E|{fTy@V`(=Pz!Rn2!>FI0-0_zycanzzS^c9J}T&aKJsU1l5ACf(Ny8EAWu3 zK^^xrs27qI@C(TbG+_0N1U@uj4c7*&!v?Oau!(VQ>DC}R5+dn|iBx<)&v^!67V+7R zD$cu6A?SvelJ!!zy`8);8uSP!1_*^1<(?Dm^=265vB(&v2rMmwX_^FF zBpzL*_Mh34!HvLlZ!o>JAks&FChhIFV$|-7{Cdi=feO-GU1V31O=NX*eorDsEJH(c zDDNSeJ-$1zg~5LWwU1T!9Ou((INTo8&La8fh{Gh|%<#s;_P^+!-W?sHa@DfmX=;x# z136>5&KSaHJTvVx_GuC(bBR-^;304o$#`t=llXNI?Hz>KbXR0t*XCfypzEq^Xomah zOMGBF%z}EX*tl$L?M0@QQ7pGi>@7ozEKHYO14EjR!L)`lx*oBqP1med>SL#PmS_8R zq0#SDwQZVGnnzIv*ED>We~EYzu_`;duhDn!?t?kiwSAn8nu2 z9L1i(9?YQ0F)>L+sfs%{F*8T6B%>%bF{Mfv%t=fx$t=q(snpBOtjNsU*!G5rQFd}M z^BhLS$pS318C55*Vfn(yI(Z?hJ|oBEi>&IL9PycX8L35?C6m9i>ho{_9U{QM!^puX G#smO4fGYg} delta 103 zcmaFHvw?>O>NB!W{>`dBS%*!Jiw$U|00R%B G7!v>^1{kFP diff --git a/models/__pycache__/school_course_student.cpython-310.pyc b/models/__pycache__/school_course_student.cpython-310.pyc index d1694f45972025eb9597d88cbaa21d6a8b39488d..3b051313f4e8b8b58428d70b4b0d0c731a47efba 100644 GIT binary patch delta 341 zcmY+8%}T>i5QTHoG)?no>JL;`;zEdEz$b9gl?WBBt8O%81`~<7b#m(>Pv9m<$W!7I(@Xl)@75byZrt0L)Qf1d8w*C-rGKh-!0W0^1ygyYg?8yOP9t(sH z*e?YqoQ7_D$<8MJe}Eh&d`TrLmbA<6!Id^9X-v}novhBhYBW|4(ztzN7b9OuOEZ|k X0zF_p+irLC!=MYSQ>(Vyp6h$xNTO%< delta 196 zcmeBWd&Ve#P3+L+>Sc=JNZ|@*(Bz(Y-+pocqoUC*w&Iea z%)Inl9Qk=EsX3`7sa4!Xsl|E)iA5!OsYSQggG)+NQu9hQ8H?C~#`$S-PQJ+KDbJal zUs_b08lRbRi>nx-0?1y;P$UFYR3tPxmdPJ%KL-N~BMYMdlhEY7Oln#XNw5kKAq*sL YaoFVMri_@% diff --git a/models/__pycache__/school_fee_structure_line.cpython-310.pyc b/models/__pycache__/school_fee_structure_line.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e13022d7c3dccceac197a5462b3138b5d23958c GIT binary patch literal 649 zcmZuvKX2496t`n1%^kT4p@W$<3^y=V2!V>q)GoJKCs|gW+e;POhm#D~6}E~G!WUxj z%EVV-;@K%_2c8t?z4!b1{k2=ImIUP|yWejqA-|&WR5%(R@ax~;0R(7A3>DO5A~Q@d zNjKB-wKj04^Ep}1~!2Yq1b&^8f!Dsz@I^lBm~5Rm~D z3^KuWep>(o4*B;?oS;=gfjSin)R%CQ^k-0F)=5X{m#*20J6&@ww zl+)9!qR(kUuIeK27~N+vZzTG-#*kmeg(uEqNt5<6;^n((Fz@lXkv?8olULba=*_eu literal 0 HcmV?d00001 diff --git a/models/__pycache__/school_student.cpython-310.pyc b/models/__pycache__/school_student.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e84bf7a648ce3e7dad964895e7802f697d3c1c0e GIT binary patch literal 2127 zcmaJ?OOM<{5bm};9?$H|>}FqikidikU_hhn=8YgqvH`>)t4I?LSc@z()wAoBACqoR z!dT&y+)(}j2jG_f!Y}A6CvHgGA|$A4+sST-@TlAUbyd5ozxui+@Atb5pO0?;c<^VN zvEKftYwYHx|`x%_Ef;D4(%UIXpES!7Ff(^0x^GSI77Y^^h z@F{!3gHv!GNqJZI$CHCRPsYU@L{^joW#C9vShpL)YHf&Svm~BGMVx1P>DDW7-?y}@ z3K?hn+LPkJJeC5=ZoPc?)g8SSPV#g%FGN^>JdDA&Wd}Lc?b@VUs>r1%*N<$2ZlgGj z_C?vhC-Z5Xh~d41yvQ+?Z7Gtd5MVwc`}n1D?X{Izl!~&~gt1F#NeVTh4Wn$K-Rk@k zj*FXz#?*GODG$5H?2sLDR4OtRlt_Jm=a`BAGsCaveQiTo<40<&ful>B77! z+QKx-@B}GRyjRI@uQt?NjAje%eVRn+cM#oJrhP5!JXUU2@znqY69-}%&6A>B z{ydX;lF$yrJIIO8jf3CAfcaM0-bo^*hFgTT8?;U6VuLOcy40Xcgf2JeGNCICxDAj`FnH@Frg*Ha?U#64w~S}mzcq?k)4inGPi}5hwuN*=dF}ujXndG7u1S#?7!CjD=Dt+u^u~in%I#_o9WN>%Nfb zfAWuIsLKCY8~_Kax#OgTslCtXj{oGMCOW(2Ml44ZU7jg=hmYb6@<*ljg%HDW63@zW zRklasWs*iyAx3JRrjcBfok9xn@idpIUTQ9f6w?>{Gt}8!N=&NnYNuGtgmy^Lx`P@H zjgoZdVJse*v34O(qd3!U5y^c~U{$kXkgIqCBhISZK&a1F;fDJn6B6YT&MGoOh2g%B z9%_J{Wm%klJ#6la^26g={J&4=!SQ=|j9-$rjm_Mz_i*r--C^Gje&CP!A(Q>WybrA> zJmY}l(0*V6L#C}=&3s2*#ueJeS|cygsM|1x<;0R}#wf+)wG+!FG;Cp0E_R-EhCBb1 z=Z_!g4Fzh~KdrqmB+kQ7cSGWNp3t}#h7aaZQd?Ta1t&qMiHv8Y1xaVr-d(H`+d0x~ z;&yfpA}Ozt#l0P8n0?)!Rb?%lQCZWy<~&uRE9GDj)DGQiz5Gf;A<#r;ED~YFr@Irn zX(-=9!dYQx($M^jxu~5;gE`(Bg&dw63!r-?aV(Mk`={ literal 0 HcmV?d00001 diff --git a/models/__pycache__/school_subject.cpython-310.pyc b/models/__pycache__/school_subject.cpython-310.pyc index 108693ceb6dd2c1a67c417ef2755be80e54c5e73..2dffe324c54fa6531e15d831c4bcadccb23f5192 100644 GIT binary patch literal 3012 zcma(TU2oJz(7X2ed>1E|kOWepiYuxRrtKBNHwDU91V|7fg}zuI%Xl{zNB+3%Iwg0y zyp%|7A5hzO9unU8OMb0XsZ!tCr#wJs*1qHps8pXkH#0k5J3F)EbbP$7!E>_v%jzEu zP5T{*;l}{t2E6hD0H!e#X)$q0OkEo5u1=6gBO|W36{6kMn9huCjTxM*nJ;v=$|}p6 zWBv)cnxp4toH8EC+*}EH#AL4fozNk9?K{cEf)J?)P;mIE0C59e`6~dfxrAvhWyIAP zbq!uwGuze|Y}^Xc#FA{oHs25U56(Zx0d?$G+HWlzDI7Ef^qE zWx{_RChfd>r$8L25wtQ;>e*;*pn+kTun*L*1Yh3>1!s=!(7o#I$d|HtMtlWjdqB^N z)(Cx8d_6*+6Q@V$^Ww}1eL>8R&= z9x^3+N8eM(3PY_hSxI|#X|{PEsJtFvLcIjy2?zu*cyvI<;k^y76ae5pAg>8Psvz7A z#SH<_P=IQGW z)8H1c7ac>?z_%DffZ>SG0XUWSxu^D*%=ed0;F4NDiK^9)uFsANePCpIU|%RB*84_| zjI0Y~4t1PiNtgnfm_mR?#3u+2Bx~X*GCoD1_IwO6wQ(hW97){0Qgl8pu7s4hQalj1 zRl}$*QLUl+K{bJ@d{yqM##LdfVpauQ6fOO-=@_}OmWD~Lw|OSMfjDw|P=9dSW-x>d z$)gpwG2q62r-Kcw3m&}D#7$7yyUedVNm-gciM#5rs8cWY6Ti)4o@7soLH49vC~dVm z-F(U`?7kAvBS7dt?10_baNnyhAo zkr(6#sN5Y2Q&C6miryx>WCup`F8LYcc8pzZr-Cb3%Uk3}ZH2H3GqE*FQRP6#eu+B%)#4&fHn3*L|gEZ#0XkX(o-^|>xVwiXxm_fPq&`-Ma zX#(F#<;cjbM+u*Y{_MIlLy}$;CLHFDbZ1LJ4`<6hTVUD2)aM|B(Dkb@k+VZ+qE&)!orCMA#bY)%*4PsP|PPd%Z5f_2=F5lY1T^pDb8h_>DZp ztsfx)0yHBzWi)q~LoIePH}{xV^KRxd{}%!t_#X-Qf}RHFF6)3hC8OXo+LMuEf?R^g zvB4d?i4gT5f*$k{yR2X10pgV!4`3D6J`%P9>#%|6Dr~|Qo@=m; zY3!KZG&zwno6ZhTMN(FMUBj_%u<2Y1qLvv>;#}<8#C56C;@E^ryq%>=KozyNNfv8u z{9SvDsOn&<)$$9WwJe6eWpPn0DWS(RtdcgJeGw-oLRFjJUOdifeba3N;VJrG@S&?) zR}9L=(Ks!RWEHh;hrc39C`NF(9AxYe?Bf3WCX)B$8F?N4K}#Hl_wM6IFlpP$5| z0|`v2-1vfvs+;CU0mstr3p64E~P{;lpz z7uz?!#^Sr#s|elL9JgP{SMyUnR8Rv;Y$^>|N6rk|dop><3pCucVoR#q*T!?H z_djC!8FT(UE$3Hi{ry;WE_22)f>|cG#n!`(FG2lyZBSV7Zw)4+brW)KyUDrfa*my` z4!Maqe>;n_R^rzx_z{FoRC;Ecq+DAUZ}%its&CnFFD~ZyWg%EtzXu#(cnAn~4t&V=W#&F#ewX b^Q&#IyV``0n-V^;FHna_R!Brcy5;-_d_0JB diff --git a/models/__pycache__/school_subject_teacher_info.cpython-310.pyc b/models/__pycache__/school_subject_teacher_info.cpython-310.pyc index e3725f48d67b9c15c0a3020a4ca6f49c2544456a..1ae5d3bc116babc7bdbbcad4030c15f8c1a156f2 100644 GIT binary patch literal 1635 zcmZ`(OK;mo5a#kB(u!!yir(ShQAB~{%1f$^ z1m~0->;KRmd+7fu_S#eLJ++t4E+xe|WCgCiZ)Rs_cjhBS7`81MfBf*v@XwZI{iVsx z;S%|Vp6WB2zyg+A1&di>$9Cbw4zs?szy{~71rD;2`^JeqaL=s1_cyJ#`i^Q90x+*s zYmi|Mm2#4CmTKS4L7AH@{}4bcW?;oOu-E}RcF`NPzyTLLXn}w2#=fxxutJvhwG#)# zSKt|2p)pS-eKL3%3nkH}(yKdj@YBeB0nHgEt6o z!nVO%gtuYG;2pwU*fn_9;5~!)aR1i>2!3O*4+n3pH!MDcL#o$DYUeB+3Xz{pE=HKv z&oN1dD4&!AG25?<=csC2M|I;n%CvK19uUnVA``Oueu(lH+bTazsx$%At*L66l`mBw z@p6($1Qm#qnuRsadh=vFgGIhsXOZH&3MIw+67!@+kO6f~c~vbWzFTyX6sWd&DvI%> zMm|3@Z)DJSnjnAfmL0Rj=}?rYyhlZn<+Jcqib0lRMAllU;C@@lS}ih}*Q@zqG+3T{tJodfX3G`&~bjKd+^7 zOI_m-i*YWdh}=*Qb@h}tHnnVL1znkc{>8n!DjYWj<>aabHPEdvA1Fs+s@w_n^mj`} zbd`S}&MzlPu5VAwYs%2!fK@89v2MN8tx^H? ze|nD;CO3)3Ym4LRtCP-^`*4^@xkEm=r>9*V)OwJWiJZy&&7aWXcfjQBT^yPHmSeJ z%BL(?LS;&9ns#IQSRdY_N#DAogtcvX0YX@BadOm6@oMeoMK!@6y&A k=}nrX-ZT9vH*0QWi?m;-RKZtGOTN}GN~O=aVQty}1H_@$`2YX_ literal 1786 zcma)7OK;mo5av>pL@Sc~wq?s{c`0B4g@EK(6h$6(iv+b`KB#!Se>pKf7;JmiLK{lzrs`xdi4y|784cS>e zTh$T)7-yX$v-uW}EO1Y#F>uxCPq=cMRS!cn@}=^V;(FVGs7{-Gwe3(E9-HQhq*Donbf@ zA|76zPcY1%VGxc{K1oNS=w?RK&q`H4FLnJ$E4Stb-rT}7ChglMs=hc@)x#hQ1HfKI z)v{bh>4kD7zPOAef^tPl#lakl=Hj?PkYJBVmkOY&r(=<#svajn6f5^(m`6WH`K;I; z;4j`n@{TZoI7-oP9N{#Od4g$PG@pud?^I+_9*I=dPl7bKKv}d-r5HsqdUSFwdUolj z5#%{tUmL3WLjZ|cR%{$!O;JXehUgvsh=I&{Me8WY(Gw%@Q6%$mvGP+b7Lzf!+4}>5z{A&t1|&YoFy~!DvQDsb9sHc zvyu#FbH%*Cd|qI#3*4X1)Mh}L7AemtFrJiwX$NmLKU~&k&cDT%!w+ zB48HEXsW9yD>_>)F<^FIv#GJDdIZXOJPxGX)ElbPl51FUZ4tF{bbI^j3z<${unm@M z^P3ZK&ZkSZl?^9V?NO8la^|4Rbjm>m*uEr&U5!)~(MzxGmgZP#f!#%j>3 xD@SujY7&>JTh($OuR=8W%t}U9PxN=i7`-nB<$hh(=o|gdkZIzqSxvTM{|CGq`)vRK diff --git a/models/__pycache__/teacher_attendance.cpython-310.pyc b/models/__pycache__/teacher_attendance.cpython-310.pyc index 2b0084854a3aeb157879ea64c4cee6ed9be21521..7f5b1fa87739d131afc2c2b543b992f281a9236b 100644 GIT binary patch delta 171 zcmZ3_HIa)qpO=@50SIKW`!nn(@-AX5n7BcarRZm|cKl%}NSm1r{FVk<5w%FIi@#p04!k{Y7PT*Lvi{uW13YGG++QEJNMgN)gm VjhUF47&#}Kv(zy1P2R#%4FFRYFlYb( delta 202 zcmbQpwVsPNpO=@50SLC-=*Wnh$h(NKXyOJ%z7+Oe<|vL-wk*yRjuf_ucO~`NQg~80 zds(7*fr5M~yeWLWj8Xil0t*CF_)`QHGNlNn2(>UYGe!xe2nRE0icD5z^z)G}PR_{B z&(SL`P0C75F3~GVO-#;6Ez--(OUu8-9s=QoXfoYmD=sO@%uBz;QIuL(npu>Za*M?! ru_RTKxrhVkv?5L*F?khZHoGPxSYWd#6EhPd*JMeS8b*Q1(^#qjuxmKQ diff --git a/models/application.py b/models/application.py index 5983490..c6819e5 100644 --- a/models/application.py +++ b/models/application.py @@ -9,15 +9,29 @@ class SchoolApplication(models.Model): _description = 'Student Application' _order = 'name' _rec_name = 'name' - - # _inherit = ['mail.thread', 'mail.activity.mixin'] + _inherit = ['mail.thread', 'mail.activity.mixin'] name = fields.Char(string="Student Name", required=True,) email = fields.Char(string="Email", ) phone_no = fields.Char(string="Phone Number") image = fields.Binary("Profile Photo", store=True) address = fields.Text(string="Address") - class_name = fields.Char(string="Class") + class_name = fields.Selection([ + ('1', 'Class 1'), + ('2', 'Class 2'), + ('3', 'Class 3'), + ('4', 'Class 4'), + ('5', 'Class 5'), + ('6', 'Class 6'), + ('7', 'Class 7'), + ('8', 'Class 8'), + ('9', 'Class 9'), + ('10', 'Class 10'), + ('11', 'Class 11'), + ('12', 'Class 12'), + ], string="Class", required=True) + + academic_year = fields.Char(string="Academic Year") gender = fields.Selection([ ('male', 'Male'), ('female', 'Female'), @@ -74,18 +88,31 @@ class SchoolApplication(models.Model): if not re.fullmatch(r'\d{10}', record.phone_no or ''): raise ValidationError("Phone number must contain exactly 10 digits.") - def action_send_message(self): - for record in self: - raise UserError("Send Message clicked for %s" % record.name) + def action_show_id_card(self): + self.ensure_one() + return { + 'type': 'ir.actions.act_window', + 'name': 'ID Card', + 'view_mode': 'form', + 'res_model': 'school.application', + 'res_id': self.id, + 'view_id': self.env.ref('school_management.view_school_id_card_form').id, + 'target': 'new', # or 'current' for full page + } - def action_log_note(self): - for record in self: - raise UserError("Log Note clicked for %s" % record.name) + + @api.depends('application_id') + def _compute_student_id(self): + for rec in self: + rec.student_id = str(rec.application_id.id) if rec.application_id else '' - def action_schedule_activity(self): - for record in self: - raise UserError("Activity clicked for %s" % record.name) - - # def get_default_image(self): - # with open('/path/to/sample.jpg', 'rb') as f: - # return base64.b64encode(f.read()) \ No newline at end of file + # def action_open_id_card_wizard(self): + # return { + # 'type': 'ir.actions.act_window', + # 'name': 'Generate ID Card', + # 'res_model': 'wizard.generate.id.card', + # 'view_mode': 'form', + # 'target': 'new', + # 'context': {'default_application_id': self.id}, + # } + \ No newline at end of file diff --git a/models/enrollment.py b/models/enrollment.py index 51281aa..8d4e73a 100644 --- a/models/enrollment.py +++ b/models/enrollment.py @@ -1,14 +1,32 @@ -from odoo import models, fields -from odoo.exceptions import UserError +from odoo import models, fields, api +_inherit = ['mail.thread', 'mail.activity.mixin'] + class SchoolEnrollment(models.Model): _name = 'school.enrollment' _description = 'Enrollment' + + + application_id = fields.Many2one('school.application', string="Student", required=True) + school_id = fields.Many2one('res.company', string="School", default=lambda self: self.env.company) + student_id = fields.Char(string="Student ID", compute='_compute_student_id', store=True) + student_name = fields.Many2one('school.application', string="Student", ondelete='set null') + image = fields.Binary("Profile Photo", store=True) + class_name = fields.Selection([ + ('1', 'Class 1'), + ('2', 'Class 2'), + ('3', 'Class 3'), + ('4', 'Class 4'), + ('5', 'Class 5'), + ('6', 'Class 6'), + ('7', 'Class 7'), + ('8', 'Class 8'), + ('9', 'Class 9'), + ('10', 'Class 10'), + ('11', 'Class 11'), + ('12', 'Class 12'), + ], string="Class", required=True) - student_id = fields.Many2one('school.application', string="Student", ondelete='set null') - image = fields.Binary(string="Profile Photo") - school_name = fields.Char(string="School") - class_name = fields.Char(string="Class") course = fields.Char(string="Course") session = fields.Char(string="Session") academic_year = fields.Char(string="Academic Year") @@ -34,14 +52,7 @@ class SchoolEnrollment(models.Model): course_id = fields.Many2one('school.course', string='Course', ondelete='cascade', required=True) student_id = fields.Many2one('res.partner', string='Student', required=True) - def action_send_message(self): - for record in self: - raise UserError("Send Message clicked for %s" % record.name) - - def action_log_note(self): - for record in self: - raise UserError("Log Note clicked for %s" % record.name) - - def action_schedule_activity(self): - for record in self: - raise UserError("Activity clicked for %s" % record.name) \ No newline at end of file + @api.depends('application_id') + def _compute_student_id(self): + for rec in self: + rec.student_id = str(rec.application_id.id) if rec.application_id else '' \ No newline at end of file diff --git a/models/enrollment_fee_summary.py b/models/enrollment_fee_summary.py index dfbd60c..66f7e14 100644 --- a/models/enrollment_fee_summary.py +++ b/models/enrollment_fee_summary.py @@ -6,6 +6,7 @@ class EnrollmentFeeSummary(models.Model): _description = 'Fee Summary Line' enrollment_id = fields.Many2one('school.enrollment', string="Enrollment") + student_ref = fields.Many2one('school.student', string="Student") total_fees = fields.Float(string="Total Fees") paid_fees = fields.Float(string="Paid Fees") fee_slip_amount = fields.Float(string="Fee Slip Amount") diff --git a/models/enrollment_subject.py b/models/enrollment_subject.py index 6cde80b..5989691 100644 --- a/models/enrollment_subject.py +++ b/models/enrollment_subject.py @@ -8,7 +8,21 @@ class EnrollmentSubject(models.Model): enrollment_id = fields.Many2one('school.enrollment', string="Enrollment") subject_id = fields.Many2one('school.subject', string="Subject Name", required=True) subject_name = fields.Char(string="Subject Name") - class_name = fields.Char(string="Class") + class_name = fields.Selection([ + ('1', 'Class 1'), + ('2', 'Class 2'), + ('3', 'Class 3'), + ('4', 'Class 4'), + ('5', 'Class 5'), + ('6', 'Class 6'), + ('7', 'Class 7'), + ('8', 'Class 8'), + ('9', 'Class 9'), + ('10', 'Class 10'), + ('11', 'Class 11'), + ('12', 'Class 12'), + ], string="Class", required=True) + academic_year = fields.Char(string="Academic Year") status = fields.Selection([ ('active', 'Active'), diff --git a/models/fee_element.py b/models/fee_element.py new file mode 100644 index 0000000..1879c44 --- /dev/null +++ b/models/fee_element.py @@ -0,0 +1,8 @@ +from odoo import models, fields + +class FeeElement(models.Model): + _name = 'school.fee.element' + _description = 'Fee Element' + + name = fields.Char("Fee Component", required=True) + description = fields.Text("Description") diff --git a/models/fee_structure.py b/models/fee_structure.py new file mode 100644 index 0000000..4c270da --- /dev/null +++ b/models/fee_structure.py @@ -0,0 +1,66 @@ +from odoo import models, fields, api + +class SchoolFeeStructure(models.Model): + _name = 'school.fee.structure' + _description = 'Fee Structure' + + name = fields.Char(string="Structure Name", compute='_compute_name', store=True) + class_name = fields.Selection([ + ('1', 'Class 1'), + ('2', 'Class 2'), + ('3', 'Class 3'), + ('4', 'Class 4'), + ('5', 'Class 5'), + ('6', 'Class 6'), + ('7', 'Class 7'), + ('8', 'Class 8'), + ('9', 'Class 9'), + ('10', 'Class 10'), + ('11', 'Class 11'), + ('12', 'Class 12'), + ], string="Class", required=True) + + tuition_fee = fields.Float(string="Tuition Fees") + admission_fee = fields.Float(string="Admission Charges") + annual_charge = fields.Float(string="Annual Charges") + total_fee = fields.Float(string="Total Fee", compute="_compute_total_fee", store=True) + + component_line_ids = fields.One2many('school.fee.component', 'structure_id', string="Fee Components", readonly=True) + + @api.depends('class_name') + def _compute_name(self): + for rec in self: + rec.name = f"Fee Structure for Class {rec.class_name}" if rec.class_name else "" + + @api.depends('tuition_fee', 'admission_fee', 'annual_charge') + def _compute_total_fee(self): + for rec in self: + rec.total_fee = (rec.tuition_fee or 0) + (rec.admission_fee or 0) + (rec.annual_charge or 0) + + @api.onchange('class_name') + def _onchange_class_name(self): + fee_data = { + '1': {'admission_fee': 5000, 'tuition_fee': 72000, 'annual_charge': 1000}, + '2': {'admission_fee': 6000, 'tuition_fee': 84000, 'annual_charge': 1000}, + '3': {'admission_fee': 6500, 'tuition_fee': 90000, 'annual_charge': 1000}, + '4': {'admission_fee': 7000, 'tuition_fee': 96000, 'annual_charge': 1000}, + '5': {'admission_fee': 7500, 'tuition_fee': 100000, 'annual_charge': 1000}, + '6': {'admission_fee': 8000, 'tuition_fee': 105000, 'annual_charge': 1000}, + '7': {'admission_fee': 8500, 'tuition_fee': 110000, 'annual_charge': 1000}, + '8': {'admission_fee': 9000, 'tuition_fee': 115000, 'annual_charge': 1000}, + '9': {'admission_fee': 9500, 'tuition_fee': 120000, 'annual_charge': 1000}, + '10': {'admission_fee': 10000, 'tuition_fee': 125000, 'annual_charge': 1000}, + '11': {'admission_fee': 11000, 'tuition_fee': 130000, 'annual_charge': 1000}, + '12': {'admission_fee': 12000, 'tuition_fee': 135000, 'annual_charge': 1000}, + } + + if self.class_name: + values = fee_data.get(self.class_name, {}) + self.admission_fee = values.get('admission_fee', 0) + self.tuition_fee = values.get('tuition_fee', 0) + self.annual_charge = values.get('annual_charge', 0) + + self.component_line_ids = [(5, 0, 0)] # Clear + self.component_line_ids = [(0, 0, {'component_name': 'Admission Charges', 'amount': self.admission_fee}), + (0, 0, {'component_name': 'Tuition Fees', 'amount': self.tuition_fee}), + (0, 0, {'component_name': 'Annual Charges', 'amount': self.annual_charge})] diff --git a/models/schedule.py b/models/schedule.py index b0e5f5c..b835cde 100644 --- a/models/schedule.py +++ b/models/schedule.py @@ -1,12 +1,27 @@ from odoo import models, fields from odoo.exceptions import UserError +_inherit = ['mail.thread', 'mail.activity.mixin'] class SchoolClassSchedule(models.Model): _name = 'school.class.schedule' _description = 'Class Schedule' title = fields.Char(string="Title", required=True) - class_name = fields.Char(string="Class") + class_name = fields.Selection([ + ('1', 'Class 1'), + ('2', 'Class 2'), + ('3', 'Class 3'), + ('4', 'Class 4'), + ('5', 'Class 5'), + ('6', 'Class 6'), + ('7', 'Class 7'), + ('8', 'Class 8'), + ('9', 'Class 9'), + ('10', 'Class 10'), + ('11', 'Class 11'), + ('12', 'Class 12'), + ], string="Class", required=True) + subject = fields.Char(string="Subject") teacher = fields.Char(string="Teacher") secondary_teacher = fields.Char(string="Secondary Teacher") diff --git a/models/school_class.py b/models/school_class.py index d8d0c9a..577a7b5 100644 --- a/models/school_class.py +++ b/models/school_class.py @@ -1,25 +1,52 @@ -from odoo import models, fields -from odoo.exceptions import UserError -import base64 +from odoo import models, fields, api class SchoolClass(models.Model): _name = 'school.class' _description = 'Class' - name = fields.Char(string='Class Name', required=True) + related_subject_ids = fields.One2many('school.subject', 'class_name', string='Subjects') + name = fields.Selection([ + ('Class 1', 'Class 1'), + ('Class 2', 'Class 2'), + ('Class 3', 'Class 3'), + ('Class 4', 'Class 4'), + ('Class 5', 'Class 5'), + ('Class 6', 'Class 6'), + ('Class 7', 'Class 7'), + ('Class 8', 'Class 8'), + ('Class 9', 'Class 9'), + ('Class 10', 'Class 10'), + ('Class 11', 'Class 11'), + ('Class 12', 'Class 12'), + ], string="Class Name", required=True) + subject_ids = fields.Many2many('school.subject', string='Subjects') - school = fields.Char(string='School') + school = fields.Many2one('res.company', string="School", default=lambda self: self.env.company) is_optional = fields.Boolean(string='Optional') class_teacher = fields.Many2one('res.users', string='Class Teacher') - - def action_send_message(self): - for record in self: - raise UserError("Send Message clicked for %s" % record.name) - def action_log_note(self): - for record in self: - raise UserError("Log Note clicked for %s" % record.name) + @api.onchange('name') + def _onchange_name_set_subjects(self): + if not self.name: + self.subject_ids = False + return + + subject_map = { + 'Class 1': ['math', 'english', 'science', 'mil'], + 'Class 2': ['math', 'english', 'science', 'drawing', 'mil'], + 'Class 3': ['math', 'english', 'science', 'odia', 'drawing', 'english_grammar'], + 'Class 4': ['math', 'english', 'science', 'odia', 'drawing', 'english_grammar'], + 'Class 5': ['math', 'english', 'science', 'odia', 'history', 'drawing', 'english_grammar'], + 'Class 6': ['math', 'english', 'science', 'geography', 'mil', 'english_grammar'], + 'Class 7': ['math', 'english', 'science', 'political_science', 'mil', 'english_grammar', 'history', 'geography'], + 'Class 8': ['math', 'english', 'science', 'political_science', 'mil', 'english_grammar', 'history', 'geography'], + 'Class 9': ['math', 'english', 'physical_science', 'life_science', 'english_grammar', 'economic_science', 'history', 'geography'], + 'Class 10': ['math', 'english', 'physical_science', 'life_science', 'english_grammar', 'economic_science', 'history', 'geography'], + 'Class 11': ['physics', 'chemistry', 'math', 'biology', 'english', 'english_grammar', 'computer_science', 'mil', 'economic_science'], + 'Class 12': ['physics', 'chemistry', 'math', 'biology', 'computer_science', 'english_grammar', 'english', 'mil', 'economic_science'], + } + + subject_codes = subject_map.get(self.name, []) + subjects = self.env['school.subject'].search([('name', 'in', subject_codes)]) + self.subject_ids = [(6, 0, subjects.ids)] # This sets all - def action_schedule_activity(self): - for record in self: - raise UserError("Activity clicked for %s" % record.name) \ No newline at end of file diff --git a/models/school_course.py b/models/school_course.py index 3f69791..af31434 100644 --- a/models/school_course.py +++ b/models/school_course.py @@ -1,14 +1,15 @@ from odoo import models, fields -from odoo.exceptions import UserError class SchoolCourse(models.Model): _name = 'school.course' _description = 'Course' - + + application_id = fields.Many2one('school.application', string="Student", required=True) name = fields.Char(string='Course Name', required=True) class_id = fields.Many2one('school.class', string='Class') teacher = fields.Many2one('res.users', string='Teacher') + student_name = fields.Char(related='application_id.name', string="Student Name", store=True) start_date = fields.Date(string='Started On') end_date = fields.Date(string='End Date') total_capacity = fields.Integer(string='Total Capacity') @@ -21,14 +22,4 @@ class SchoolCourse(models.Model): - def action_send_message(self): - for record in self: - raise UserError("Send Message clicked for %s" % record.name) - - def action_log_note(self): - for record in self: - raise UserError("Log Note clicked for %s" % record.name) - - def action_schedule_activity(self): - for record in self: - raise UserError("Activity clicked for %s" % record.name) \ No newline at end of file + \ No newline at end of file diff --git a/models/school_course_attendance.py b/models/school_course_attendance.py index aa7cc37..01a74e2 100644 --- a/models/school_course_attendance.py +++ b/models/school_course_attendance.py @@ -1,25 +1,15 @@ from odoo import models, fields -from odoo.exceptions import UserError + class SchoolCourseAttendance(models.Model): _name = 'school.course.attendance' _description = 'Course Attendance' - + + application_id = fields.Many2one('school.application', string="Student", required=True) course_id = fields.Many2one('school.course', string='Course', ondelete='cascade') - student_id = fields.Many2one('res.partner', string='Student') + student_name = fields.Char(related='application_id.name', string="Student Name", store=True) is_present = fields.Boolean(string='Present') class_id = fields.Many2one('school.class', string='Class') - - def action_send_message(self): - for record in self: - raise UserError("Send Message clicked for %s" % record.name) - - def action_log_note(self): - for record in self: - raise UserError("Log Note clicked for %s" % record.name) - - def action_schedule_activity(self): - for record in self: - raise UserError("Activity clicked for %s" % record.name) \ No newline at end of file + \ No newline at end of file diff --git a/models/school_course_schedule.py b/models/school_course_schedule.py index 3197b4b..decf9ce 100644 --- a/models/school_course_schedule.py +++ b/models/school_course_schedule.py @@ -1,5 +1,6 @@ from odoo import models, fields from odoo.exceptions import UserError +_inherit = ['mail.thread', 'mail.activity.mixin'] class SchoolCourseSchedule(models.Model): _name = 'school.course.schedule' diff --git a/models/school_course_student.py b/models/school_course_student.py index 6f31215..88ffe7f 100644 --- a/models/school_course_student.py +++ b/models/school_course_student.py @@ -3,6 +3,8 @@ from odoo import models, fields class SchoolCourseStudent(models.Model): _name = 'school.course.student' _description = 'Enrolled Student' - + + application_id = fields.Many2one('school.application', string="Student", required=True) course_id = fields.Many2one('school.course', string='Course', ondelete='cascade') student_id = fields.Many2one('res.partner', string='Student') + student_name = fields.Char(related='application_id.name', string="Student Name", store=True) \ No newline at end of file diff --git a/models/school_fee_structure_line.py b/models/school_fee_structure_line.py new file mode 100644 index 0000000..d3f3967 --- /dev/null +++ b/models/school_fee_structure_line.py @@ -0,0 +1,10 @@ +from odoo import models, fields, api + +class SchoolFeeComponent(models.Model): + _name = 'school.fee.component' + _description = 'Fee Component' + + structure_id = fields.Many2one('school.fee.structure', string="Fee Structure") + component_name = fields.Char(string="Component") + amount = fields.Float(string="Amount") + diff --git a/models/school_student.py b/models/school_student.py new file mode 100644 index 0000000..7a328bd --- /dev/null +++ b/models/school_student.py @@ -0,0 +1,52 @@ +from odoo import models, fields, api +from odoo.exceptions import UserError + +class SchoolStudent(models.Model): + _name = 'school.student' + _description = 'Student' + + application_id = fields.Many2one('school.application', string="Application", required=True) + + # Use computed char field instead of invalid related field + student_id = fields.Char(string="Student ID", compute='_compute_student_id', store=True) + + profile_photo = fields.Binary(related='application_id.image', string="Profile Photo", store=True) + student_name = fields.Char(related='application_id.name', string="Student Name", store=True) + school_id = fields.Many2one('res.company', string="School", default=lambda self: self.env.company) + enrollment_date = fields.Date(string="Enrollment Date") + class_name = fields.Selection([ + ('1', 'Class 1'), + ('2', 'Class 2'), + ('3', 'Class 3'), + ('4', 'Class 4'), + ('5', 'Class 5'), + ('6', 'Class 6'), + ('7', 'Class 7'), + ('8', 'Class 8'), + ('9', 'Class 9'), + ('10', 'Class 10'), + ('11', 'Class 11'), + ('12', 'Class 12'), + ], string="Class", required=True) + academic_year = fields.Char(string="Academic Year") + session_status = fields.Selection([ + ('active', 'Active'), + ('completed', 'Completed'), + ('suspended', 'Suspended') + ], string="Session Status") + payment_term = fields.Char(string="Payment Term") + + def action_generate_payment_slip(self): + return { + 'type': 'ir.actions.act_window', + 'name': 'Fee Slip', + 'res_model': 'school.enrollment.fee.summary', + 'view_mode': 'tree,form', + 'domain': [('student_ref', '=', self.id)], + 'target': 'current', + } + + @api.depends('application_id') + def _compute_student_id(self): + for rec in self: + rec.student_id = str(rec.application_id.id) if rec.application_id else '' diff --git a/models/school_subject.py b/models/school_subject.py index c6b5106..814d930 100644 --- a/models/school_subject.py +++ b/models/school_subject.py @@ -1,27 +1,87 @@ -from odoo import models, fields +from odoo import models, fields, api from odoo.exceptions import UserError -import base64 class SchoolSubject(models.Model): _name = 'school.subject' _description = 'Subject' - name = fields.Char(string='Subject Name', required=True) - class_id = fields.Many2one('school.class', string='Class') + name = fields.Selection([ + ('math', 'Math'), + ('english', 'English'), + ('science', 'Science'), + ('physical_science', 'Physical Science'), + ('life_science', 'Life Science'), + ('geography', 'Geography'), + ('history', 'History'), + ('political_science', 'Political Science'), + ('economic_science', 'Economic Science'), + ('physics', 'Physics'), + ('chemistry', 'Chemistry'), + ('biology', 'Biology'), + ('it', 'IT'), + ('computer_science', 'Computer Science'), + ('mil', 'MIL'), + ('odia', 'Odia'), + ('english_grammar', 'English Grammar'), + ('drawing', 'Drawing'), + ('odia_grammar', 'Odia Grammar'), + ], string="Subject", required=True) + + class_name = fields.Selection([ + ('Class 1', 'Class 1'), + ('Class 2', 'Class 2'), + ('Class 3', 'Class 3'), + ('Class 4', 'Class 4'), + ('Class 5', 'Class 5'), + ('Class 6', 'Class 6'), + ('Class 7', 'Class 7'), + ('Class 8', 'Class 8'), + ('Class 9', 'Class 9'), + ('Class 10', 'Class 10'), + ('Class 11', 'Class 11'), + ('Class 12', 'Class 12'), + ], string="Class Name", required=True) + lesson_plan = fields.Text(string='Lesson Plan') teacher = fields.Many2one('res.users', string='Teacher') lesson_plan_line_ids = fields.One2many('school.subject.lesson', 'subject_id', string='Lesson Plans') teacher_info_line_ids = fields.One2many('school.subject.teacher.info', 'subject_id', string="Teacher Info") - - def action_send_message(self): - for record in self: - raise UserError("Send Message clicked for %s" % record.name) + @api.depends('class_name') + def _compute_subjects(self): + subject_mapping = { + 'Class 1': ['Math', 'English', 'Science', 'MIL'], + 'Class 2': ['Math', 'English', 'Science', 'Drawing', 'MIL'], + 'Class 3': ['Math', 'English', 'Science', 'Odia', 'Drawing', 'English Grammar'], + 'Class 4': ['Math', 'English', 'Science', 'Odia', 'Drawing', 'English Grammar'], + 'Class 5': ['Math', 'English', 'Science', 'Odia', 'History', 'Drawing', 'English Grammar'], + 'Class 6': ['Math', 'English', 'Science', 'Geography', 'MIL', 'English Grammar'], + 'Class 7': ['Math', 'English', 'Science', 'Political Science', 'MIL', 'English Grammar', 'History', 'Geography'], + 'Class 8': ['Math', 'English', 'Science', 'Political Science', 'MIL', 'English Grammar', 'History', 'Geography'], + 'Class 9': ['Math', 'English', 'Physical Science', 'Life Science', 'English Grammar', 'Economic Science', 'History', 'Geography'], + 'Class 10': ['Math', 'English', 'Physical Science', 'Life Science', 'English Grammar', 'Economic Science', 'History', 'Geography'], + 'Class 11': ['Physics', 'Chemistry', 'Math', 'Biology', 'English', 'English Grammar', 'Computer Science', 'MIL', 'Economic Science'], + 'Class 12': ['Physics', 'Chemistry', 'Math', 'Biology', 'Computer Science', 'English Grammar', 'English', 'MIL', 'Economic Science'], + } + for rec in self: + rec.subject_list = ', '.join(subject_mapping.get(rec.class_name, [])) + def action_generate_subjects(self): + if not self.class_name: + raise UserError("Please select a class name first.") - def action_log_note(self): - for record in self: - raise UserError("Log Note clicked for %s" % record.name) + existing_subjects = self.search([ + ('class_name', '=', self.class_name) + ]).mapped('name') - def action_schedule_activity(self): - for record in self: - raise UserError("Activity clicked for %s" % record.name) \ No newline at end of file + subject_list = self.get_subjects_by_class().get(self.class_name, []) + + new_subjects = [sub for sub in subject_list if sub not in existing_subjects] + + for subject in new_subjects: + self.create({ + 'class_name': self.class_name, + 'name': subject, + }) + + if not new_subjects: + raise UserError("All subjects for this class already exist.") diff --git a/models/school_subject_teacher_info.py b/models/school_subject_teacher_info.py index cc27f90..1949564 100644 --- a/models/school_subject_teacher_info.py +++ b/models/school_subject_teacher_info.py @@ -1,34 +1,34 @@ -from odoo import models, fields -from odoo.exceptions import UserError +from odoo import models, fields, api class SchoolSubjectTeacherInfo(models.Model): _name = 'school.subject.teacher.info' _description = 'Subject Teacher Info' subject_id = fields.Many2one('school.subject', string='Subject', required=True, ondelete='cascade') - employee_name = fields.Char(string='Teacher Name') - phone = fields.Char(string='Phone') - email = fields.Char(string='Email') + + # Related fields to auto-fetch from related subject's teacher (res.users) + teacher_user_id = fields.Many2one(related='subject_id.teacher', string="Teacher User", store=True) + employee_name = fields.Char(string='Teacher Name', compute="_compute_teacher_fields", store=True) + phone = fields.Char(string='Phone', compute="_compute_teacher_fields", store=True) + email = fields.Char(string='Email', compute="_compute_teacher_fields", store=True) + profile_photo = fields.Binary(string="Profile Photo", compute="_compute_teacher_fields", store=True) + + # Editable fields for extra info activity = fields.Char(string='Activity') activity_deadline = fields.Date(string='New Activity Deadline') department = fields.Char(string='Department') job_position = fields.Char(string='Job Position') manager = fields.Char(string='Manager') - profile_photo = fields.Binary(string="Profile Photo", attachment=True) address = fields.Text(string="Address") experience = fields.Integer(string="Experience (Years)") date_of_birth = fields.Date(string="Date of Birth") join_date = fields.Date(string="Join Date") - - def action_send_message(self): - for record in self: - raise UserError("Send Message clicked for %s" % record.employee_name) - - def action_log_note(self): - for record in self: - raise UserError("Log Note clicked for %s" % record.employee_name) - - def action_schedule_activity(self): - for record in self: - raise UserError("Activity clicked for %s" % record.employee_name) + @api.depends('subject_id.teacher') + def _compute_teacher_fields(self): + for rec in self: + user = rec.subject_id.teacher + rec.employee_name = user.name if user else '' + rec.email = user.email if user else '' + rec.phone = user.phone if user else '' + rec.profile_photo = user.image_1920 if user else False diff --git a/models/teacher_attendance.py b/models/teacher_attendance.py index 080edfc..455ff0e 100644 --- a/models/teacher_attendance.py +++ b/models/teacher_attendance.py @@ -6,7 +6,7 @@ class TeacherAttendance(models.Model): _description = 'Teacher Attendance' _order = 'date desc' - teacher_id = fields.Many2one('school.subject.teacher.info', string='Teacher', required=True) + teacher_id = fields.Many2one('res.partner', string='Student') date = fields.Date(string='Date', required=True, default=fields.Date.today) attendance_status = fields.Selection([ ('present', 'Present'), diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index dc9143f..018e9b8 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -22,4 +22,9 @@ access_school_config_settings,School Config Settings,model_school_config_setting access_school_fees_report,Fees Report,model_school_fees_report,,1,1,1,1 access_school_transcript_report,Transcript Report,model_school_transcript_report,,1,1,1,1 access_school_scholarship_report,Scholarship Report,model_school_scholarship_report,,1,1,1,1 -access_school_report_card,Report Card,model_school_report_card,,1,1,1,1 \ No newline at end of file +access_school_report_card,Report Card,model_school_report_card,,1,1,1,1 +access_school_student,Student,model_school_student,,1,1,1,1 +access_school_fee_structure,School Fee Structure,model_school_fee_structure,,1,1,1,1 +access_school_fee_element,School Fee Element,model_school_fee_element,,1,1,1,1 +access_school_fee_component,School Fee Component,model_school_fee_component,,1,0,0,0 + diff --git a/views/application.xml b/views/application.xml index fb4e3c9..c9c66a9 100644 --- a/views/application.xml +++ b/views/application.xml @@ -24,12 +24,6 @@
- -
@@ -54,6 +48,12 @@ + +
diff --git a/views/course.xml b/views/course.xml index 4196b8c..28770b2 100644 --- a/views/course.xml +++ b/views/course.xml @@ -36,7 +36,7 @@ - + @@ -47,7 +47,7 @@ - + @@ -75,11 +75,6 @@ -
-
diff --git a/views/course_attendance.xml b/views/course_attendance.xml index 1392767..562f381 100644 --- a/views/course_attendance.xml +++ b/views/course_attendance.xml @@ -5,7 +5,7 @@ school.course.attendance - + @@ -19,15 +19,10 @@
- + -
-
diff --git a/views/enrollment.xml b/views/enrollment.xml index 94fd5c9..27ab32f 100644 --- a/views/enrollment.xml +++ b/views/enrollment.xml @@ -7,7 +7,7 @@ - + @@ -33,8 +33,8 @@ - - + + @@ -89,7 +89,7 @@ - + @@ -101,12 +101,12 @@
- +
-
Class:
+
Course:
Fees:
Session:
diff --git a/views/fee_element_views.xml b/views/fee_element_views.xml new file mode 100644 index 0000000..b1fbd1c --- /dev/null +++ b/views/fee_element_views.xml @@ -0,0 +1,33 @@ + + + fee.element.form + school.fee.element + +
+ + + + + + +
+
+
+ + + fee.element.list + school.fee.element + + + + + + + + + + Fee Element + school.fee.element + list,form + +
diff --git a/views/fee_structure_views.xml b/views/fee_structure_views.xml new file mode 100644 index 0000000..45a5b06 --- /dev/null +++ b/views/fee_structure_views.xml @@ -0,0 +1,56 @@ + + + + fee.structure.form + school.fee.structure + +
+ + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + fee.structure.list + school.fee.structure + + + + + + + + + + + + + + + Fee Structure + school.fee.structure + list,form + +
diff --git a/views/lesson_views.xml b/views/lesson_views.xml index 5f2d71a..bed84ac 100644 --- a/views/lesson_views.xml +++ b/views/lesson_views.xml @@ -31,11 +31,6 @@ -
-
diff --git a/views/menu.xml b/views/menu.xml index 84b2502..d3f3f56 100644 --- a/views/menu.xml +++ b/views/menu.xml @@ -12,27 +12,27 @@ name="Applications" parent="menu_school_root" action="action_school_application" - sequence="30"/> + sequence="10"/> + sequence="20"/> + sequence="40"/> + sequence="30"/> - + + + + + + + + + diff --git a/views/schedule.xml b/views/schedule.xml index 6326a49..0387595 100644 --- a/views/schedule.xml +++ b/views/schedule.xml @@ -46,11 +46,6 @@ -
-
@@ -82,12 +77,34 @@ + + school.class.schedule.activity + school.class.schedule + + + + + +
+
+
+ Class:
+ Subject:
+ Teacher:
+
+
+
+
+
+
+
+ Class Schedule school.class.schedule - list,form,kanban + list,form,kanban,activity diff --git a/views/school_student_views.xml b/views/school_student_views.xml new file mode 100644 index 0000000..2a09118 --- /dev/null +++ b/views/school_student_views.xml @@ -0,0 +1,105 @@ + + + + + + school.student.list + school.student + + + + + + + + + + + + + + + school.student.form + school.student + +
+ +

Student Information

+ + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + school.student.kanban + school.student + + + + + + + +
+
+
+ +
+
+
+ Class: +
+
+
+
+
+
+
+
+ + + + All Students + school.student + list,form,kanban + +

Create and manage your students here.

+
+
+ + + + + + +
diff --git a/views/school_subject_teacher_views.xml b/views/school_subject_teacher_views.xml index b5b7e2a..aca0cb0 100644 --- a/views/school_subject_teacher_views.xml +++ b/views/school_subject_teacher_views.xml @@ -45,11 +45,6 @@ -
-
diff --git a/views/subject.xml b/views/subject.xml index 622250b..311f597 100644 --- a/views/subject.xml +++ b/views/subject.xml @@ -1,69 +1,87 @@ + + + Generate Subjects + + code + + form + +action = env['school.subject'].create_subjects_for_class(record.class_name) + + + + school.subject.list school.subject - + - + + school.subject.form school.subject -
+ +
+
- + - - - - - - - - - - - - - - - - - - - - - - - - - -
-
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ - Subject + Subjects school.subject list,form diff --git a/views/teacher_attendance_view.xml b/views/teacher_attendance_view.xml index a78e149..c5d6bdb 100644 --- a/views/teacher_attendance_view.xml +++ b/views/teacher_attendance_view.xml @@ -31,6 +31,18 @@ + + school.teacher.attendance.calendar + school.teacher.attendance + + + + + + + + + Teacher Attendance school.teacher.attendance