From 7f352fe89972e65fdf156011b555913018d5887a Mon Sep 17 00:00:00 2001 From: vidhya Date: Thu, 1 Oct 2026 11:16:50 +0530 Subject: [PATCH] Mobile App - additions --- .../__pycache__/__init__.cpython-312.pyc | Bin 181 -> 181 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 312 -> 312 bytes .../__pycache__/attendance.cpython-312.pyc | Bin 1876 -> 1876 bytes .../attendance_line.cpython-312.pyc | Bin 1601 -> 1601 bytes .../attendance_session.cpython-312.pyc | Bin 9077 -> 9077 bytes .../student_inherit.cpython-312.pyc | Bin 3224 -> 3224 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 175 -> 175 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 399 -> 399 bytes .../academic_level.cpython-312.pyc | Bin 2171 -> 2171 bytes .../__pycache__/academic_term.cpython-312.pyc | Bin 3535 -> 3535 bytes .../__pycache__/academic_year.cpython-312.pyc | Bin 4339 -> 4339 bytes .../models/__pycache__/campus.cpython-312.pyc | Bin 3334 -> 3334 bytes .../__pycache__/department.cpython-312.pyc | Bin 2755 -> 2755 bytes .../education_config.cpython-312.pyc | Bin 4493 -> 4493 bytes .../__pycache__/program.cpython-312.pyc | Bin 3406 -> 3406 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 215 -> 215 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 190 -> 190 bytes .../__pycache__/main.cpython-312.pyc | Bin 9275 -> 9275 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 190 -> 190 bytes .../__pycache__/dashboard.cpython-312.pyc | Bin 540 -> 540 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 801 -> 801 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 196 -> 196 bytes .../__pycache__/demo_login.cpython-312.pyc | Bin 3250 -> 3250 bytes .../demo_data_generator.py | 3 +- .../__pycache__/__init__.cpython-312.pyc | Bin 210 -> 210 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 192 -> 192 bytes .../__pycache__/portal_exam.cpython-312.pyc | Bin 6041 -> 6041 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 409 -> 409 bytes .../education_exam.cpython-312.pyc | Bin 13061 -> 13061 bytes .../education_exam_result.cpython-312.pyc | Bin 7257 -> 7257 bytes .../education_exam_type.cpython-312.pyc | Bin 965 -> 965 bytes .../education_grading.cpython-312.pyc | Bin 4720 -> 4720 bytes .../education_student_inherit.cpython-312.pyc | Bin 1573 -> 1573 bytes .../education_subject.cpython-312.pyc | Bin 1536 -> 1536 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 178 -> 178 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 535 -> 535 bytes .../fee_assignment.cpython-312.pyc | Bin 4312 -> 4312 bytes .../__pycache__/fee_category.cpython-312.pyc | Bin 2995 -> 2995 bytes .../__pycache__/fee_structure.cpython-312.pyc | Bin 4199 -> 4199 bytes .../__pycache__/fee_type.cpython-312.pyc | Bin 2448 -> 2448 bytes .../student_discount.cpython-312.pyc | Bin 5304 -> 5304 bytes .../student_inherit.cpython-312.pyc | Bin 4789 -> 4789 bytes .../student_ledger.cpython-312.pyc | Bin 5189 -> 5189 bytes .../student_payment.cpython-312.pyc | Bin 5965 -> 5965 bytes .../student_refund.cpython-312.pyc | Bin 4415 -> 4415 bytes .../student_scholarship.cpython-312.pyc | Bin 5139 -> 5139 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 212 -> 212 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 189 -> 189 bytes .../__pycache__/portal.cpython-312.pyc | Bin 10052 -> 10052 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 438 -> 438 bytes .../models/__pycache__/hostel.cpython-312.pyc | Bin 6472 -> 6472 bytes .../__pycache__/hostel_bed.cpython-312.pyc | Bin 3893 -> 3893 bytes .../hostel_complaint.cpython-312.pyc | Bin 5451 -> 5451 bytes .../__pycache__/hostel_fee.cpython-312.pyc | Bin 8475 -> 8475 bytes .../__pycache__/hostel_floor.cpython-312.pyc | Bin 2631 -> 2631 bytes .../__pycache__/hostel_member.cpython-312.pyc | Bin 12889 -> 12889 bytes .../__pycache__/hostel_room.cpython-312.pyc | Bin 5199 -> 5199 bytes .../hostel_visitor.cpython-312.pyc | Bin 5329 -> 5329 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 213 -> 213 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 188 -> 188 bytes .../__pycache__/main.cpython-312.pyc | Bin 8325 -> 8325 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 580 -> 580 bytes .../education_library.cpython-312.pyc | Bin 1479 -> 1479 bytes .../education_library_book.cpython-312.pyc | Bin 3500 -> 3500 bytes ...ducation_library_book_copy.cpython-312.pyc | Bin 2750 -> 2750 bytes ...education_library_category.cpython-312.pyc | Bin 2444 -> 2444 bytes .../education_library_fine.cpython-312.pyc | Bin 3965 -> 3965 bytes .../education_library_issue.cpython-312.pyc | Bin 8189 -> 8189 bytes .../education_library_member.cpython-312.pyc | Bin 4325 -> 4325 bytes ...cation_library_reservation.cpython-312.pyc | Bin 5580 -> 5580 bytes .../res_config_settings.cpython-312.pyc | Bin 1645 -> 1645 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 209 -> 209 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 184 -> 184 bytes .../__pycache__/main.cpython-312.pyc | Bin 18636 -> 18636 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 336 -> 336 bytes .../education_lms_assignment.cpython-312.pyc | Bin 7923 -> 7923 bytes .../education_lms_content.cpython-312.pyc | Bin 7863 -> 7863 bytes .../education_lms_course.cpython-312.pyc | Bin 5907 -> 5907 bytes .../education_lms_submission.cpython-312.pyc | Bin 13385 -> 13385 bytes addons/education_mobile_api/__init__.py | 3 + addons/education_mobile_api/__manifest__.py | 18 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 216 bytes .../controllers/__init__.py | 3 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 222 bytes .../__pycache__/auth.cpython-312.pyc | Bin 0 -> 5510 bytes .../__pycache__/student.cpython-312.pyc | Bin 0 -> 16404 bytes .../education_mobile_api/controllers/auth.py | 106 ++++++ .../controllers/student.py | 314 ++++++++++++++++++ .../education_mobile_api/models/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 195 bytes .../__pycache__/mobile_device.cpython-312.pyc | Bin 0 -> 955 bytes .../models/mobile_device.py | 11 + .../security/ir.model.access.csv | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 212 -> 212 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 218 -> 218 bytes .../__pycache__/main.cpython-312.pyc | Bin 16026 -> 16026 bytes .../__pycache__/payment.cpython-312.pyc | Bin 6932 -> 6932 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 361 -> 361 bytes .../__pycache__/announcement.cpython-312.pyc | Bin 1657 -> 1657 bytes .../fee_assignment_inherit.cpython-312.pyc | Bin 1748 -> 1748 bytes .../payment_transaction.cpython-312.pyc | Bin 6829 -> 6829 bytes .../res_config_settings.cpython-312.pyc | Bin 4545 -> 4545 bytes .../student_inherit.cpython-312.pyc | Bin 9089 -> 9089 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 281 -> 281 bytes .../payment_service.cpython-312.pyc | Bin 10213 -> 10213 bytes .../razorpay_service.cpython-312.pyc | Bin 8976 -> 8976 bytes .../reconciliation_service.cpython-312.pyc | Bin 10004 -> 10004 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 179 -> 179 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 193 -> 193 bytes .../__pycache__/report_wizard.cpython-312.pyc | Bin 8987 -> 8987 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 178 -> 178 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 225 -> 225 bytes .../academic_config.cpython-312.pyc | Bin 6759 -> 6759 bytes .../__pycache__/student.cpython-312.pyc | Bin 18802 -> 18802 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 215 -> 215 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 190 -> 190 bytes .../__pycache__/main.cpython-312.pyc | Bin 4410 -> 4410 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 243 -> 243 bytes .../education_room.cpython-312.pyc | Bin 1177 -> 1177 bytes .../education_timetable_slot.cpython-312.pyc | Bin 4848 -> 4848 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 220 -> 220 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 197 -> 197 bytes .../__pycache__/portal.cpython-312.pyc | Bin 5810 -> 5810 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 442 -> 442 bytes .../__pycache__/assignment.cpython-312.pyc | Bin 5648 -> 5648 bytes .../__pycache__/attendance.cpython-312.pyc | Bin 3081 -> 3081 bytes .../models/__pycache__/driver.cpython-312.pyc | Bin 2113 -> 2113 bytes .../__pycache__/incident.cpython-312.pyc | Bin 3778 -> 3778 bytes .../models/__pycache__/route.cpython-312.pyc | Bin 1972 -> 1972 bytes .../__pycache__/route_stop.cpython-312.pyc | Bin 2584 -> 2584 bytes .../models/__pycache__/stop.cpython-312.pyc | Bin 1657 -> 1657 bytes .../models/__pycache__/trip.cpython-312.pyc | Bin 4819 -> 4819 bytes .../__pycache__/vehicle.cpython-312.pyc | Bin 4685 -> 4685 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 151 -> 151 bytes admin_cookie.txt | 5 + check.py | 1 + cookie.txt | 5 + create_hierarchy.py | 120 +++++++ create_student.py | 11 + create_student_debug.py | 36 ++ create_student_file.py | 39 +++ create_student_full.py | 23 ++ create_student_full2.py | 30 ++ debug_student.py | 4 + docker-compose.yml | 2 +- fix_demo_data.py | 12 + force_create.py | 43 +++ link.py | 1 + run_demo.py | 7 + setup_demo_student.py | 15 + verify_student.py | 4 + 151 files changed, 818 insertions(+), 2 deletions(-) create mode 100644 addons/education_mobile_api/__init__.py create mode 100644 addons/education_mobile_api/__manifest__.py create mode 100644 addons/education_mobile_api/__pycache__/__init__.cpython-312.pyc create mode 100644 addons/education_mobile_api/controllers/__init__.py create mode 100644 addons/education_mobile_api/controllers/__pycache__/__init__.cpython-312.pyc create mode 100644 addons/education_mobile_api/controllers/__pycache__/auth.cpython-312.pyc create mode 100644 addons/education_mobile_api/controllers/__pycache__/student.cpython-312.pyc create mode 100644 addons/education_mobile_api/controllers/auth.py create mode 100644 addons/education_mobile_api/controllers/student.py create mode 100644 addons/education_mobile_api/models/__init__.py create mode 100644 addons/education_mobile_api/models/__pycache__/__init__.cpython-312.pyc create mode 100644 addons/education_mobile_api/models/__pycache__/mobile_device.cpython-312.pyc create mode 100644 addons/education_mobile_api/models/mobile_device.py create mode 100644 addons/education_mobile_api/security/ir.model.access.csv create mode 100644 admin_cookie.txt create mode 100644 check.py create mode 100644 cookie.txt create mode 100644 create_hierarchy.py create mode 100644 create_student.py create mode 100644 create_student_debug.py create mode 100644 create_student_file.py create mode 100644 create_student_full.py create mode 100644 create_student_full2.py create mode 100644 debug_student.py create mode 100644 fix_demo_data.py create mode 100644 force_create.py create mode 100644 link.py create mode 100644 run_demo.py create mode 100644 setup_demo_student.py create mode 100644 verify_student.py diff --git a/addons/education_attendance/__pycache__/__init__.cpython-312.pyc b/addons/education_attendance/__pycache__/__init__.cpython-312.pyc index 2c19ce7d86964fbf76081c9480db9ce120cd6d25..9c7e84d508c96968953e9dfd7a2ae397779d537d 100644 GIT binary patch delta 21 bcmdnWxRsIjG%qg~0}$*#yE#jABJTj&K)JDE^WdLaf2yp-a delta 23 dcmezB_SKE=G%qg~0}vdZxGgJNdLv)DG5}+D2e$wK diff --git a/addons/education_attendance/models/__pycache__/student_inherit.cpython-312.pyc b/addons/education_attendance/models/__pycache__/student_inherit.cpython-312.pyc index ba92e3d76a3a126d6a62b9e5e26dadd0cba0a4cf..d3a7fdf7e26d81e18a51f7c1032c2623ddb18c5e 100644 GIT binary patch delta 22 ccmbOsIYW~7G%qg~0}$*#yE#jGBX2hk07ixecmMzZ delta 22 ccmbOsIYW~7G%qg~0}vdZxGl?OBX2hk07ZlbWB>pF diff --git a/addons/education_base/__pycache__/__init__.cpython-312.pyc b/addons/education_base/__pycache__/__init__.cpython-312.pyc index 787f33f2660b42afaeec8fb70d95bc11ade46177..f1692ed69b2c7e41c61462adc39008c0adf4e5b8 100644 GIT binary patch delta 21 bcmZ3_xSo;sG%qg~0}$*#yE#jABJUyqKeYy1 delta 21 bcmZ3_xSo;sG%qg~0}vdZxGhU;BJUyqK1T*8 diff --git a/addons/education_base/models/__pycache__/__init__.cpython-312.pyc b/addons/education_base/models/__pycache__/__init__.cpython-312.pyc index a24f4864098c28b134821ade4ce044b127c60080..40a92a5fcf096e754ebf29293e9fd150bce49f4e 100644 GIT binary patch delta 22 ccmeBY?q}vb&CAQh00jHbZqC}Vk++Ev07Q@m!vFvP delta 22 ccmeBY?q}vb&CAQh00f68Zp+%gk++Ev07DE0l>h($ diff --git a/addons/education_base/models/__pycache__/academic_level.cpython-312.pyc b/addons/education_base/models/__pycache__/academic_level.cpython-312.pyc index 8ceab359d2a19bdf712b5f2fb378f1c79c0eeadd..89d5b9aeba132158617d6bbae59d88bbf9853d27 100644 GIT binary patch delta 22 ccmew@@LPcQG%qg~0}$*#yE$v`M&3LQ09Z%|tpET3 delta 22 ccmew@@LPcQG%qg~0}vdZxGn3!M&3LQ09Q~4n*aa+ diff --git a/addons/education_base/models/__pycache__/academic_term.cpython-312.pyc b/addons/education_base/models/__pycache__/academic_term.cpython-312.pyc index 5397b7a2bf8ae481c53dc2463d24b6bd35a77ed0..b96b948dd55cc0e72e6c1a3b76a28635812427ab 100644 GIT binary patch delta 22 ccmX>veO{XPG%qg~0}$*#yE)5lBkv(z08sh|MF0Q* delta 22 ccmX>veO{XPG%qg~0}vdZxGk%GBkv(z08p3*Q2+n{ diff --git a/addons/education_base/models/__pycache__/academic_year.cpython-312.pyc b/addons/education_base/models/__pycache__/academic_year.cpython-312.pyc index 46840fdd3ea0cbbe69f15765cf59af5ef8b7661e..18f6c57e117edcea31e1e7d95fe26d2fc9c46229 100644 GIT binary patch delta 22 ccmeyY_*s$nG%qg~0}$*#yE#i?BkwZ-09S_xq5uE@ delta 22 ccmeyY_*s$nG%qg~0}vdZxGgJfBkwZ-09QT-vj6}9 diff --git a/addons/education_base/models/__pycache__/campus.cpython-312.pyc b/addons/education_base/models/__pycache__/campus.cpython-312.pyc index aa2817fe00e7561327ba8a165fffe7a2b44ba432..5664ba7806d0f78d1a0ff4776445613f4fe4ac53 100644 GIT binary patch delta 22 ccmZpZYLntU&CAQh00jHbZqAC@$orEA07cOU0{{R3 delta 22 ccmZpZYLntU&CAQh00f68Zp-T5$orEA07Wwg0{{R3 diff --git a/addons/education_base/models/__pycache__/department.cpython-312.pyc b/addons/education_base/models/__pycache__/department.cpython-312.pyc index 4d05bcf7889a3b661dd111990bf9dd2b20f2185e..c1aa6d845f749c2db0d1884c1f4ab530583b3a17 100644 GIT binary patch delta 22 ccmX>sdRUbAG%qg~0}$*#yE$vaM&4~)08lXpga7~l delta 22 ccmX>sdRUbAG%qg~0}vdZxGn3^M&4~)08fMmfdBvi diff --git a/addons/education_base/models/__pycache__/education_config.cpython-312.pyc b/addons/education_base/models/__pycache__/education_config.cpython-312.pyc index c1cdac4fa3777094344d480391a5128462b45d12..3195d94d9b77cc55ea4f276bc53b366421e45029 100644 GIT binary patch delta 22 ccmeBG?p5YJ&CAQh00jHbZq8EJ$lD+Y07g&-bpQYW delta 22 ccmeBG?p5YJ&CAQh00f68Zp(_^$lD+Y07cLSdjJ3c diff --git a/addons/education_base/models/__pycache__/program.cpython-312.pyc b/addons/education_base/models/__pycache__/program.cpython-312.pyc index 093ed9d4e1106c895129aa25c18406c7f5b5d6e8..251fc9bcb7854f42bf72dcbf556578fc3c4a6dbb 100644 GIT binary patch delta 22 ccmX>nbxw-+G%qg~0}$*#yE$vlMqWo=08xAg9smFU delta 22 ccmX>nbxw-+G%qg~0}vdZxGn4cMqWo=08u0dEC2ui diff --git a/addons/education_dashboard/__pycache__/__init__.cpython-312.pyc b/addons/education_dashboard/__pycache__/__init__.cpython-312.pyc index 8befeb20bfa2da6b7bc0cc09e22e7389095f8b6d..3c54756409d86c4a7dfa29090b7de9238a4ce2b9 100644 GIT binary patch delta 21 bcmcc4c%6~=G%qg~0}$*#yE#jLBJU{xMui6L delta 21 bcmcc4c%6~=G%qg~0}vdZxGl?YBJU{xMH>dX diff --git a/addons/education_dashboard/controllers/__pycache__/__init__.cpython-312.pyc b/addons/education_dashboard/controllers/__pycache__/__init__.cpython-312.pyc index 753f194a72d72f8727943cc3bf99f67fa5ce8cc7..5d90c9ba71ed171d4d0a302d2e720234a8c7cb4a 100644 GIT binary patch delta 21 bcmdnTxQ~(dG%qg~0}$*#yE#jEBJV~3LKFsu delta 21 bcmdnTxQ~(dG%qg~0}vdZxGhU$BJV~3K&A## diff --git a/addons/education_dashboard/controllers/__pycache__/main.cpython-312.pyc b/addons/education_dashboard/controllers/__pycache__/main.cpython-312.pyc index f493f8b3e70ebbb1fa57464c4e9686c07e50ab5b..8eea5c91930c4589814043c587e260f2c5875d5b 100644 GIT binary patch delta 23 dcmdn(vD<_1G%qg~0}w23-Ii6YwvkU)1prt}2K@j4 delta 23 dcmdn(vD<_1G%qg~0}vdZxGl>z|2Co1B diff --git a/addons/education_exam/models/__pycache__/__init__.cpython-312.pyc b/addons/education_exam/models/__pycache__/__init__.cpython-312.pyc index a0607ea5c8d51408340db0319f247374a86b76e8..9ead79c8b0b5fc2a6d7cbe0d86c93bc4abde199a 100644 GIT binary patch delta 22 ccmbQqJd>ICG%qg~0}$*#yE*IhM&2Gq07j<<^Z)<= delta 22 ccmbQqJd>ICG%qg~0}vdZxGn4AM&2Gq07V`K#Q*>R diff --git a/addons/education_exam/models/__pycache__/education_exam.cpython-312.pyc b/addons/education_exam/models/__pycache__/education_exam.cpython-312.pyc index 50b170e6c999e958506d73bae7949b4eaa31d34c..7966f5c8f1f2ffabcd9da3844c7aa685bbe21fa9 100644 GIT binary patch delta 22 ccmZooYfa-l&CAQh00jHbZq5?l$os(^b delta 22 ccmaE^@LYlSG%qg~0}vdZxGk%5BX5)d093UHFaQ7m diff --git a/addons/education_finance/models/__pycache__/fee_type.cpython-312.pyc b/addons/education_finance/models/__pycache__/fee_type.cpython-312.pyc index db904a2942ec3910f427e3d1ee1c2b08f931d3cf..dfbc7b6f3503d92dcfe6b844591acba572ac8611 100644 GIT binary patch delta 22 ccmbOrJVBWEG%qg~0}$*#yE&_9BX2V&07d2or~m)} delta 22 ccmbOrJVBWEG%qg~0}vdZxGihOM&4#l07U%;nE(I) diff --git a/addons/education_finance/models/__pycache__/student_discount.cpython-312.pyc b/addons/education_finance/models/__pycache__/student_discount.cpython-312.pyc index 13c53d2986567d3ac2cb7454d8a89eff8e695bef..9d57a8eda37f240c0c6632b9e1580651d849aa58 100644 GIT binary patch delta 22 ccmdm?xkHopG%qg~0}$*#yE$voM&8vT08udqhX4Qo delta 22 ccmdm?xkHopG%qg~0}vdZxGn4ZM&8vT08ujsrvLx| diff --git a/addons/education_finance/models/__pycache__/student_inherit.cpython-312.pyc b/addons/education_finance/models/__pycache__/student_inherit.cpython-312.pyc index 05ed766258bcfd0857804670e47baa0a727e8922..8502dd6e20a9e0ae73cc6aa52017891af1be2f13 100644 GIT binary patch delta 22 ccmdn0x>c3;G%qg~0}$*#yE&_ABku|!08eWNQ~&?~ delta 22 ccmdn0x>c3;G%qg~0}vdZxGih*M&1=d08Y6FPyhe` diff --git a/addons/education_finance/models/__pycache__/student_ledger.cpython-312.pyc b/addons/education_finance/models/__pycache__/student_ledger.cpython-312.pyc index 8dd416f22901919e6879d680dc1b0c27b24a20ca..89e93a10f396e1944187bd9b4cb24c2f2f5a001c 100644 GIT binary patch delta 22 ccmX@Aaa4o%G%qg~0}$*#yE#jLBd>)B08j=7xc~qF delta 22 ccmX@Aaa4o%G%qg~0}vdZxGk%GBd>)B08j4*)Bpeg diff --git a/addons/education_finance/models/__pycache__/student_payment.cpython-312.pyc b/addons/education_finance/models/__pycache__/student_payment.cpython-312.pyc index 0f289189533c26105553f08076b3aa0b2180ed0f..9bcad71ab4262accdebe000cb3a920ea9a690cfe 100644 GIT binary patch delta 22 ccmX@BcUF)0G%qg~0}$*#yE$vxMqUST090HDM*si- delta 22 ccmX@BcUF)0G%qg~0}vdZxGn4ZMqUST092X>a{vGU diff --git a/addons/education_finance/models/__pycache__/student_refund.cpython-312.pyc b/addons/education_finance/models/__pycache__/student_refund.cpython-312.pyc index 9fd6a37a7f1ace4478b957be2dbe69897b0817f1..82601bd9db689e81e4b58afa19ecdf3392281b2b 100644 GIT binary patch delta 22 ccmdn5v|ow$G%qg~0}$*#yE$v+MqVR908niQ5&!@I delta 22 ccmdn5v|ow$G%qg~0}vdZxGn4bMqVR908k_cBLDyZ diff --git a/addons/education_finance/models/__pycache__/student_scholarship.cpython-312.pyc b/addons/education_finance/models/__pycache__/student_scholarship.cpython-312.pyc index 78f4f115a8cbdc7177f50c87965c1309b6eaeaa3..a209e9bf2b544b7d4e1b0dd00a3f515ce367ecc9 100644 GIT binary patch delta 23 dcmbQNFBkxK^07ab!jsO4v delta 22 ccmdnSyp5UnG%qg~0}vdZxGn3>M&6Z-07_8@CjbBd diff --git a/addons/education_hostel/models/__pycache__/hostel.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel.cpython-312.pyc index c49a0b1877b991d806a956b8e527861bf91e6762..a23e14ae3b811b3f09b2bd5a54c4f4aa706c2ee1 100644 GIT binary patch delta 23 dcmX?Mbi#=5G%qg~0}wo9-G%qg~0}z<7Zp)g>zmd;Y6aY=L1^xg4 delta 23 dcmX@Dby|z>G%qg~0}vdZxGhUqU?ZQcC;(Lc29N*% diff --git a/addons/education_hostel/models/__pycache__/hostel_fee.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel_fee.cpython-312.pyc index ef143884b82a22c6ead9b39c6424a9a1f6f2c221..a1a9364036ad8587a431bfebf611ff9438d75aea 100644 GIT binary patch delta 23 dcmbR3G~0>qG%qg~0}v##Zp%uO+{nkP2mndB1*!l5 delta 23 dcmbR3G~0>qG%qg~0}vdZxGhUXY9k-7A^=eG23G(8 diff --git a/addons/education_hostel/models/__pycache__/hostel_floor.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel_floor.cpython-312.pyc index 25daf3ad8f6489695522b5deabb32e46f0cf6e85..558c653229a31420dd0612cf81f665ed12ce4a48 100644 GIT binary patch delta 22 ccmX>ua$JP>G%qg~0}$M0*_O3_Bd-+~07{PrWdHyG delta 22 ccmX>ua$JP>G%qg~0}vdZxGn3^MqVo}08b1D3jhEB diff --git a/addons/education_hostel/models/__pycache__/hostel_member.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel_member.cpython-312.pyc index 8307786b584716139da66efd7d35923e14b65038..1ea655859440c54c0ae26858b0eaba682f65c540 100644 GIT binary patch delta 23 dcmcbaax;bRG%qg~0}v>(Zp%_s-^k}}1OQg520{P; delta 23 dcmcbaax;bRG%qg~0}vdZxGhUkVG%qg~0}#At*_Nfdk=IEC08KFlKL7v# delta 22 ccmX@FabAP>G%qg~0}vdZxGk%1Bd?PP08#P>0RR91 diff --git a/addons/education_hostel/models/__pycache__/hostel_visitor.cpython-312.pyc b/addons/education_hostel/models/__pycache__/hostel_visitor.cpython-312.pyc index f2cf6fd781755e36b2f7a9d3ce34f69587c74d2d..47b31bc3000191d76a9ec39869c388a811d6fe0f 100644 GIT binary patch delta 22 ccmcbpc~O)1G%qg~0}!~fZp%{H$a_Qt07#Ms6#xJL delta 22 ccmcbpc~O)1G%qg~0}vdZxGk%5BkvIr08?29ga7~l diff --git a/addons/education_library/__pycache__/__init__.cpython-312.pyc b/addons/education_library/__pycache__/__init__.cpython-312.pyc index 93b6d63c7c9359ee7a1b6d306bef45eda47989de..31c049db862d5e8627f4e264aeaa1d82a9e3a927 100644 GIT binary patch delta 21 bcmcc0c$Ja&G%qg~0}$*#yE#jLBJT+RMl%NI delta 21 bcmcc0c$Ja&G%qg~0}vdZxGl?YBJT+RM9BuU diff --git a/addons/education_library/controllers/__pycache__/__init__.cpython-312.pyc b/addons/education_library/controllers/__pycache__/__init__.cpython-312.pyc index 0715051606a71e189bf17596a79bb1b137064e35..9ba5a6815ea0d86eb686d8d32010bd2e6bc6a17f 100644 GIT binary patch delta 21 bcmdnPxQCJVG%qg~0}$*#yE#jEBJX+tLBa-r delta 21 bcmdnPxQCJVG%qg~0}vdZxGhU$BJX+tKvV`y diff --git a/addons/education_library/controllers/__pycache__/main.cpython-312.pyc b/addons/education_library/controllers/__pycache__/main.cpython-312.pyc index 28138f19c173afc9a15df83577b9e713d5fbb1fb..5c59771ebb78ae1a3ac8d4b8c145a7049e7d83c3 100644 GIT binary patch delta 23 dcmZp5Y<1*2&CAQh00jHbZqAx3v5~J_0RU2a2R;A* delta 23 dcmZp5Y<1*2&CAQh00f68Zp*Tk+{jn1002%{2B-i4 diff --git a/addons/education_library/models/__pycache__/__init__.cpython-312.pyc b/addons/education_library/models/__pycache__/__init__.cpython-312.pyc index ccb8470d29180613a601b0fa2c0bc5dca2f2bdc7..2fdf77a0b454762871834e1ab4272fed82c2aa6b 100644 GIT binary patch delta 22 ccmX@Ya)gEVG%qg~0}$*#yE!XjBd<9V07~@+g#Z8m delta 22 ccmX@Ya)gEVG%qg~0}vdZxGgJjBd<9V07-iWSpWb4 diff --git a/addons/education_library/models/__pycache__/education_library.cpython-312.pyc b/addons/education_library/models/__pycache__/education_library.cpython-312.pyc index 40b99b12aea9b8c4b01f85c55a93a68734b1ecf8..4b99d2e4d8666dc5213ff9adc579dcae01ce1fd2 100644 GIT binary patch delta 23 dcmX@keVm)`G%qg~0}$*#yE*F@(?-6XtN>Ra2gCpX delta 23 dcmX@keVm)`G%qg~0}vdZxGjr^c_ZIWRsc`62BH7} diff --git a/addons/education_library/models/__pycache__/education_library_book.cpython-312.pyc b/addons/education_library/models/__pycache__/education_library_book.cpython-312.pyc index 99542977b52ef8f43e951cb74698b6740923e73c..5cfd56d32d8681e94e3fe0a853b88b79d9f83edb 100644 GIT binary patch delta 22 ccmZ1@y+)e%G%qg~0}$*#yE)5XBkz1(07|e1&Hw-a delta 22 ccmZ1@y+)e%G%qg~0}vdZxGgJqBkz1(07_g9YZG%qg~0}$*#yE*GW`$oQeegI=L2p|9e delta 23 dcmew>_g9YZG%qg~0}vdZxGl?qVWw delta 23 dcmX@3eMXz_G%qg~0}vdZxGl?zk@3t#M!wU$yj%=G5PW@eR+#NZzI`45Yx)RT delta 25 gcmX>zk@3t#M!wU$yj%=GaAe}PtaEl7`Sy7L0C3w000000 diff --git a/addons/education_lms/models/__pycache__/__init__.cpython-312.pyc b/addons/education_lms/models/__pycache__/__init__.cpython-312.pyc index ceb59c7cf1984d1774d6e4f88bd8d83affe6a3f7..b8a05542ef300cf4df5bdb90f39e31afc940502e 100644 GIT binary patch delta 22 ccmcb>bb*QYG%qg~0}$*#yE$v>MqXz|08Qlv;Q#;t delta 22 ccmcb>bb*QYG%qg~0}vdUxGihuMqXz|08Cp3u>b%7 diff --git a/addons/education_lms/models/__pycache__/education_lms_assignment.cpython-312.pyc b/addons/education_lms/models/__pycache__/education_lms_assignment.cpython-312.pyc index 9088b0ad9c20d3b3cf4dba20ea41660602a27390..679171c7f1e813de718222e4f34bd20932849413 100644 GIT binary patch delta 23 dcmext``MQ7G%qg~0}$*#yE$u%@J7C;asXxq2#^2( delta 23 dcmext``MQ7G%qg~0}vdUxGhUYWFy~GIRId(2gLvY diff --git a/addons/education_lms/models/__pycache__/education_lms_content.cpython-312.pyc b/addons/education_lms/models/__pycache__/education_lms_content.cpython-312.pyc index 97f22978abfbed3063e9bc1e5b317e58cc8594af..ba70222543865921897864006ceba146d65b6b30 100644 GIT binary patch delta 23 dcmdmPyWN)WG%qg~0}$*#yE*Hu&_=$MasXS;2lM~{ delta 23 dcmdmPyWN)WG%qg~0}vdUxGl>{cq89RIRI9W2QB~r diff --git a/addons/education_lms/models/__pycache__/education_lms_course.cpython-312.pyc b/addons/education_lms/models/__pycache__/education_lms_course.cpython-312.pyc index 504824b980ed1073124e532dc33decbe51b97cfc..ea60a730cd03a780a56cd82aee30adf815515489 100644 GIT binary patch delta 22 ccmbQNH(8JOG%qg~0}$*#yE#i@BQKjc07vcy8vpj&d=0-ki698yA2!j9s delta 23 dcmX?^aWaGNG%qg~0}vdUxGn3T) diff --git a/addons/education_mobile_api/__init__.py b/addons/education_mobile_api/__init__.py new file mode 100644 index 0000000..3b38916 --- /dev/null +++ b/addons/education_mobile_api/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +from . import models +from . import controllers diff --git a/addons/education_mobile_api/__manifest__.py b/addons/education_mobile_api/__manifest__.py new file mode 100644 index 0000000..a2bae7c --- /dev/null +++ b/addons/education_mobile_api/__manifest__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +{ + 'name': 'Education Mobile API', + 'version': '1.0', + 'summary': 'REST API for Mobile Application', + 'description': """ + Dedicated REST API layer in Odoo specifically for the mobile application. + """, + 'category': 'Education', + 'author': 'Antigravity', + 'depends': ['base', 'web', 'education_portal'], + 'data': [ + 'security/ir.model.access.csv', + ], + 'installable': True, + 'application': False, + 'auto_install': False, +} diff --git a/addons/education_mobile_api/__pycache__/__init__.cpython-312.pyc b/addons/education_mobile_api/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..887d138ff7b0679eb9a4b2c8dc045850f29fcfa6 GIT binary patch literal 216 zcmX@j%ge<81dBuVX1N3D#~=<2FhLogWq^$73@HpLj5!Rsj8Tk?AT|?_%@oDN$WY0w z$?}pBs6>L#Y72x9CzfR9=f&sdCuQcO#wQkJ>c_`t=4F<|$LkeT{^GC! j+EAL4YFESwGy-I6F*lI-z|6?V_>@899)n~NJCF|mOrO5RHDgvizTtNBm+pZ7nhW#q~?|QX)@npC}IXm7O?<{l?2Cg-29}>oYeTlf=vD7{JfH){G6QBqGJ8{_{_Y_lK6PN pg34bUHo5sJr8%i~MVvt6Kz0{%1BnmJjEsy=8HDaJh!(K}`2apkH(>w( literal 0 HcmV?d00001 diff --git a/addons/education_mobile_api/controllers/__pycache__/auth.cpython-312.pyc b/addons/education_mobile_api/controllers/__pycache__/auth.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3b4fee17113701b83ad917f3f90078e3776e5244 GIT binary patch literal 5510 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 literal 0 HcmV?d00001 diff --git a/addons/education_mobile_api/controllers/auth.py b/addons/education_mobile_api/controllers/auth.py new file mode 100644 index 0000000..5efa522 --- /dev/null +++ b/addons/education_mobile_api/controllers/auth.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +import json +import logging +from odoo import http +from odoo.http import request +from odoo.exceptions import AccessError, AccessDenied + +_logger = logging.getLogger(__name__) + +def json_response(success, data=None, error_code=None, error_message=None, status=200): + if success: + body = { + "success": True, + "data": data or {} + } + else: + body = { + "success": False, + "error": { + "code": error_code or "ERROR", + "message": error_message or "An error occurred" + } + } + + return request.make_response( + json.dumps(body), + headers=[('Content-Type', 'application/json')], + status=status + ) + +class MobileAuth(http.Controller): + + @http.route('/api/mobile/v1/auth/login', type='http', auth='none', methods=['POST'], csrf=False, cors='*') + def login(self, **kwargs): + try: + data = json.loads(request.httprequest.data) + email = data.get('email') + password = data.get('password') + + if not email or not password: + return json_response(False, error_code="INVALID_REQUEST", error_message="Email and password are required", status=400) + + db = request.db or request.env.registry.db_name + + # Authenticate creates a session securely + credential = {'login': email, 'password': password, 'type': 'password'} + auth_info = request.session.authenticate(request.env, credential) + uid = auth_info.get('uid') + if not uid: + return json_response(False, error_code="AUTH_FAILED", error_message="Invalid email or password", status=401) + + request.update_env(user=uid) + user = request.env['res.users'].sudo().browse(uid) + student = user.student_id + + return json_response(True, data={ + "user": { + "id": user.id, + "name": user.name, + "email": user.login, + "role": "student" if student else "user" + }, + "student": { + "id": student.id, + "name": student.full_name + } if student else None + }) + + except (AccessError, AccessDenied): + return json_response(False, error_code="AUTH_FAILED", error_message="Invalid email or password", status=401) + except Exception as e: + _logger.exception("Login error") + return json_response(False, error_code="SERVER_ERROR", error_message=str(e), status=500) + + @http.route('/api/mobile/v1/auth/logout', type='http', auth='public', methods=['POST'], csrf=False, cors='*') + def logout(self, **kwargs): + if request.env.user._is_public(): + return json_response(False, error_code="AUTH_REQUIRED", error_message="Authentication required", status=401) + try: + request.session.logout(keep_db=True) + return json_response(True, data={"message": "Logged out successfully"}) + except Exception as e: + return json_response(False, error_code="SERVER_ERROR", error_message=str(e), status=500) + + @http.route('/api/mobile/v1/auth/me', type='http', auth='public', methods=['GET'], cors='*') + def get_me(self, **kwargs): + if request.env.user._is_public(): + return json_response(False, error_code="AUTH_REQUIRED", error_message="Authentication required", status=401) + try: + user = request.env.user + student = user.student_id + + return json_response(True, data={ + "user": { + "id": user.id, + "name": user.name, + "email": user.login, + "role": "student" if student else "user" + }, + "student": { + "id": student.id, + "name": student.full_name + } if student else None + }) + except Exception as e: + return json_response(False, error_code="SERVER_ERROR", error_message=str(e), status=500) diff --git a/addons/education_mobile_api/controllers/student.py b/addons/education_mobile_api/controllers/student.py new file mode 100644 index 0000000..9e635d9 --- /dev/null +++ b/addons/education_mobile_api/controllers/student.py @@ -0,0 +1,314 @@ +# -*- coding: utf-8 -*- +import json +import logging +from datetime import datetime, date +from odoo import http +from odoo.http import request + +_logger = logging.getLogger(__name__) + +def json_response(success, data=None, error_code=None, error_message=None, status=200): + if success: + body = { + "success": True, + "data": data or {} + } + else: + body = { + "success": False, + "error": { + "code": error_code or "ERROR", + "message": error_message or "An error occurred" + } + } + + return request.make_response( + json.dumps(body, default=str), + headers=[('Content-Type', 'application/json')], + status=status + ) + +def require_student(func): + def wrapper(self, *args, **kwargs): + if request.env.user._is_public(): + return json_response(False, error_code="AUTH_REQUIRED", error_message="Authentication required", status=401) + + student = request.env.user.sudo().student_id + if not student: + return json_response(False, error_code="STUDENT_NOT_LINKED", error_message="No student profile is linked to this account", status=403) + + return func(self, student, *args, **kwargs) + return wrapper + +def format_float_time(float_time): + hours = int(float_time) + minutes = int(round((float_time - hours) * 60)) + if minutes == 60: + minutes = 0 + hours += 1 + hours = hours % 24 + am_pm = 'AM' if hours < 12 else 'PM' + display_hours = hours % 12 + if display_hours == 0: + display_hours = 12 + return f"{display_hours:02d}:{minutes:02d} {am_pm}" + +class MobileStudent(http.Controller): + + def _get_rel(self, record): + if record: + return {"id": record.id, "name": record.name} + return None + + @http.route('/api/mobile/v1/student/profile', type='http', auth='public', methods=['GET'], cors='*') + @require_student + def get_profile(self, student, **kwargs): + try: + data = { + "id": student.id, + "student_id": student.student_id, + "admission_number": student.admission_number, + "roll_number": student.roll_number, + "full_name": student.full_name, + "email": student.email, + "mobile": student.mobile, + "gender": student.gender, + "date_of_birth": student.date_of_birth, + "status": student.status, + "campus": self._get_rel(student.campus_id), + "department": self._get_rel(student.department_id), + "program": self._get_rel(student.program_id), + "level": self._get_rel(student.level_id), + "academic_year": self._get_rel(student.academic_year_id), + "academic_term": self._get_rel(student.academic_term_id), + "batch": self._get_rel(student.batch_id), + "semester": self._get_rel(student.semester_id), + "section": self._get_rel(student.section_id) + } + return json_response(True, data=data) + except Exception as e: + return json_response(False, error_code="SERVER_ERROR", error_message=str(e), status=500) + + def _get_attendance_summary(self, student, from_date=None, to_date=None): + domain = [('student_id', '=', student.id)] + if from_date: + domain.append(('date', '>=', from_date)) + if to_date: + domain.append(('date', '<=', to_date)) + + records = request.env['education.attendance'].search(domain) + + total_sessions = len(records) + present = len([a for a in records if a.status == 'present']) + absent = len([a for a in records if a.status == 'absent']) + late = len([a for a in records if a.status == 'late']) + medical_leave = len([a for a in records if a.status == 'medical_leave']) + on_duty = len([a for a in records if a.status == 'on_duty']) + + effective_present = present + on_duty + (late * 0.5) + percentage = round((effective_present / total_sessions * 100), 1) if total_sessions > 0 else 100.0 + + return { + "percentage": percentage, + "present": present, + "absent": absent, + "late": late, + "medical_leave": medical_leave, + "on_duty": on_duty + } + + def _get_timetable_slots(self, student, date_filter=None): + if not student.program_id or not student.academic_year_id: + return [] + + domain = [ + ('program_id', '=', student.program_id.id), + ('academic_year_id', '=', student.academic_year_id.id), + ('active', '=', True) + ] + + if student.academic_term_id: + domain += ['|', ('term_id', '=', False), ('term_id', '=', student.academic_term_id.id)] + else: + domain += [('term_id', '=', False)] + + if student.batch_id: + domain += ['|', ('batch_id', '=', False), ('batch_id', '=', student.batch_id.id)] + else: + domain += [('batch_id', '=', False)] + + if date_filter: + domain += [('date', '=', date_filter)] + + slots = request.env['education.timetable.slot'].sudo().search(domain, order="date asc, start_time asc") + + return [{ + "id": s.id, + "date": s.date, + "day": s.date.strftime('%A') if s.date else '', + "start_time": format_float_time(s.start_time), + "end_time": format_float_time(s.end_time), + "subject": self._get_rel(s.subject_id), + "faculty": self._get_rel(s.faculty_id), + "room": self._get_rel(s.room_id) + } for s in slots] + + @http.route('/api/mobile/v1/student/dashboard', type='http', auth='public', methods=['GET'], cors='*') + @require_student + def get_dashboard(self, student, **kwargs): + try: + today = date.today() + + # Upcoming Exams + exams = request.env['education.exam'].sudo().search_read([ + ('state', 'in', ['scheduled', 'ongoing']), + ('program_id', '=', student.program_id.id), + ('academic_year_id', '=', student.academic_year_id.id), + ], fields=['id', 'name', 'state', 'start_date'], order='start_date asc', limit=5) + + # Announcements + announcements = request.env['education.announcement'].search_read( + [('active', '=', True)], + fields=['id', 'name', 'date', 'summary'], + order='date desc, id desc', + limit=5 + ) + + # Recent Results + results = request.env['education.exam.result'].search([ + ('student_id', '=', student.id), + ('published', '=', True) + ], order='published_date desc, id desc', limit=5) + + results_data = [] + for r in results: + results_data.append({ + "id": r.id, + "exam": self._get_rel(r.exam_id), + "percentage": r.percentage, + "grade": r.grade_id.name if r.grade_id else None, + "status": r.result_status + }) + + data = { + "student": { + "id": student.id, + "full_name": student.full_name, + "program": self._get_rel(student.program_id) + }, + "attendance": self._get_attendance_summary(student), + "today_timetable": self._get_timetable_slots(student, date_filter=today), + "upcoming_exams": exams, + "recent_results": results_data, + "announcements": announcements + } + return json_response(True, data=data) + except Exception as e: + return json_response(False, error_code="SERVER_ERROR", error_message=str(e), status=500) + + @http.route('/api/mobile/v1/student/attendance', type='http', auth='public', methods=['GET'], cors='*') + @require_student + def get_attendance(self, student, **kwargs): + try: + from_date = kwargs.get('from_date') + to_date = kwargs.get('to_date') + + if from_date: + from_date = datetime.strptime(from_date, '%Y-%m-%d').date() + if to_date: + to_date = datetime.strptime(to_date, '%Y-%m-%d').date() + + summary = self._get_attendance_summary(student, from_date, to_date) + + domain = [('student_id', '=', student.id)] + if from_date: + domain.append(('date', '>=', from_date)) + if to_date: + domain.append(('date', '<=', to_date)) + + records = request.env['education.attendance'].search_read( + domain, + fields=['id', 'date', 'status'], + order='date desc, id desc', + limit=100 + ) + + return json_response(True, data={ + "summary": summary, + "records": records + }) + except ValueError: + return json_response(False, error_code="INVALID_DATE", error_message="Dates must be in YYYY-MM-DD format", status=400) + except Exception as e: + return json_response(False, error_code="SERVER_ERROR", error_message=str(e), status=500) + + @http.route('/api/mobile/v1/student/timetable', type='http', auth='public', methods=['GET'], cors='*') + @require_student + def get_timetable(self, student, **kwargs): + try: + slots = self._get_timetable_slots(student) + return json_response(True, data={"slots": slots}) + except Exception as e: + return json_response(False, error_code="SERVER_ERROR", error_message=str(e), status=500) + + @http.route('/api/mobile/v1/student/exams', type='http', auth='public', methods=['GET'], cors='*') + @require_student + def get_exams(self, student, **kwargs): + try: + exams = request.env['education.exam'].sudo().search([ + ('program_id', '=', student.program_id.id), + ('academic_year_id', '=', student.academic_year_id.id), + ], order='start_date desc') + + exams_data = [{ + "id": exam.id, + "name": exam.name, + "state": exam.state, + "start_date": exam.start_date, + "end_date": exam.end_date, + "program": self._get_rel(exam.program_id), + "academic_year": self._get_rel(exam.academic_year_id) + } for exam in exams] + + return json_response(True, data={"exams": exams_data}) + except Exception as e: + return json_response(False, error_code="SERVER_ERROR", error_message=str(e), status=500) + + @http.route('/api/mobile/v1/student/results', type='http', auth='public', methods=['GET'], cors='*') + @require_student + def get_results(self, student, **kwargs): + try: + results = request.env['education.exam.result'].search([ + ('student_id', '=', student.id), + ('published', '=', True) + ], order='published_date desc, id desc') + + results_data = [] + for r in results: + lines = [] + for line in r.line_ids: + lines.append({ + "subject": self._get_rel(line.subject_id), + "max_marks": line.max_marks, + "pass_marks": line.pass_marks, + "obtained_marks": line.obtained_marks, + "percentage": line.percentage, + "grade": line.grade_id.name if line.grade_id else None, + "status": line.status + }) + + results_data.append({ + "id": r.id, + "exam": self._get_rel(r.exam_id), + "total_max_marks": r.total_max_marks, + "total_obtained_marks": r.total_obtained_marks, + "percentage": r.percentage, + "grade": r.grade_id.name if r.grade_id else None, + "status": r.result_status, + "published_date": r.published_date, + "lines": lines + }) + + return json_response(True, data={"results": results_data}) + except Exception as e: + return json_response(False, error_code="SERVER_ERROR", error_message=str(e), status=500) diff --git a/addons/education_mobile_api/models/__init__.py b/addons/education_mobile_api/models/__init__.py new file mode 100644 index 0000000..3a63efc --- /dev/null +++ b/addons/education_mobile_api/models/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import mobile_device diff --git a/addons/education_mobile_api/models/__pycache__/__init__.cpython-312.pyc b/addons/education_mobile_api/models/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f0fd3729052046912e550c66c55b0ede1955672 GIT binary patch literal 195 zcmX@j%ge<81gk^#W|;u##~=<2FhLog1%Qm{3@HpLj5!Rsj8Tk?43$ip%r6;%!kUb? zcysfUGILVnQ&P(^lT-aPnQk!@F$1MmGJFOZ@XJy^H?KrLwW6dbQ8zIqB|ooNKQ*N^ zIk6-&KQA7tH?bg7KQ})mHK$lVK0Y%qvm`!Vub}c5hYe7$G$+-rhy!R6$i89_;{!7z NBjYm$=^{2D2LLq#F{%In literal 0 HcmV?d00001 diff --git a/addons/education_mobile_api/models/__pycache__/mobile_device.cpython-312.pyc b/addons/education_mobile_api/models/__pycache__/mobile_device.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d85de001c235faf2f951c52e33201874d351544 GIT binary patch literal 955 zcmZuwO=uHA6rS1aCYyBASStR2ZQ?;82NM+AOG`nlq)J+q#>=*_teHvNc6TS8-4v5k zgdXb2_7smjD(yiKya|FwFBJlYISC%bn^3*<mA&6jjK1^9Yj z`MCBO0`NmPCrcZEqd5+`009JD;6W35im5=LfD%B;7Cq`*}!pu80$34hgtXS-$OI%VH_Z;{T}W3T#-`M$>i&Ct5_|L4<=UbsFMUROMxvzG(ZcTg1mKA#_{3 zqzmrJr-A?YnR5)D3{D|&ud#Lq)& z->?xPeo#DZD3>W3ZP^W{D5r{VQA8FkG+I>5Wn_fRV1=74&^NAi?)AqDo$~k5iS61e z@{+t>e|P=U?cV4@r_>*x+?npq?9S}@z456|xu3~yZ+^>Uzh<&~lZQ7;hq;Br$1A&_+HsX#iA+2P^;p delta 23 dcmbPYHpPtZG%qg~0}vdUxGk$fcq1R1GyqSL266xZ diff --git a/addons/education_portal/models/__pycache__/__init__.cpython-312.pyc b/addons/education_portal/models/__pycache__/__init__.cpython-312.pyc index fd3aad1daca8b42ad2e794fda00dffea82a73aca..f8966893d111751b5533430abdcab32ef882ee56 100644 GIT binary patch delta 22 ccmaFK^pc79G%qg~0}$*#yE$voM&1}k08(-XIRF3v delta 22 ccmaFK^pc79G%qg~0}vdUxGih>M&1}k08s4*3IG5A diff --git a/addons/education_portal/models/__pycache__/announcement.cpython-312.pyc b/addons/education_portal/models/__pycache__/announcement.cpython-312.pyc index 25f1cb72e70aef84a12c8d70ff30c49776445501..5654ea7bdefafba8a8468c1d3736880e8cc38890 100644 GIT binary patch delta 22 ccmey#^OJ}7G%qg~0}$*#yE$w9M&2AY09ObHj{pDw delta 22 ccmey#^OJ}7G%qg~0}vdUxGn4CM&2AY09EVR delta 22 ccmZp4Z*=E9&CAQh00e7ocV&Iv$XlWe07)PQ;{X5v diff --git a/addons/education_portal/services/__pycache__/__init__.cpython-312.pyc b/addons/education_portal/services/__pycache__/__init__.cpython-312.pyc index 9abd365fd9b8d8db2f130fe1c1d2ffca814dbb90..494afc4c4e4b43d9ece6074562769d613e8db24c 100644 GIT binary patch delta 22 ccmbQqG?R(<{9 delta 22 ccmbQqG?R(Hucv2&Vu5 delta 23 dcmaFr|J0xFG%qg~0}vdUxGih8%0|BH>HuVH2v-0A diff --git a/addons/education_portal/services/__pycache__/razorpay_service.cpython-312.pyc b/addons/education_portal/services/__pycache__/razorpay_service.cpython-312.pyc index 7ac0c7ab43ec481dd99865939c079bb7290d1228..a986414ce53b703f7abab3f88acbc6b442007e44 100644 GIT binary patch delta 23 dcmbQ>Ho=YWG%qg~0}$*#yE&^+W+NYyG5}Ln2E+gW delta 23 dcmbQ>Ho=YWG%qg~0}vdUxGhUeb|W8?G5}9!1~vcy diff --git a/addons/education_portal/services/__pycache__/reconciliation_service.cpython-312.pyc b/addons/education_portal/services/__pycache__/reconciliation_service.cpython-312.pyc index 29917b0b31e03ba39791787c2730794b1aa50a73..c6d7ecd3cea72beb1022f87ac61ac28ec99780bb 100644 GIT binary patch delta 23 dcmbQ@H^q@aU&m_Isj5@27mwn diff --git a/addons/education_reports/__pycache__/__init__.cpython-312.pyc b/addons/education_reports/__pycache__/__init__.cpython-312.pyc index fc0f20dbf9edf978d693c950edbdf0253abf8efa..74a28f8d670720352e3cfc3b367e91ea8029a733 100644 GIT binary patch delta 21 bcmdnYxS5gnG%qg~0}$*#yE#j2BJVN)KwSoC delta 21 bcmdnYxS5gnG%qg~0}vdUxGhV3BJVN)KKBMS diff --git a/addons/education_reports/wizards/__pycache__/__init__.cpython-312.pyc b/addons/education_reports/wizards/__pycache__/__init__.cpython-312.pyc index db5db8412ac587d7d155d465da5b736fc6c6d0e8..3a95771b5b36441d84a90962d6f67e92380fda03 100644 GIT binary patch delta 21 bcmX@ec#x6zG%qg~0}$*#yE#i{BJUOeLbC># delta 21 bcmX@ec#x6zG%qg~0}vdUxGhU|BJUOeK}`l_ diff --git a/addons/education_reports/wizards/__pycache__/report_wizard.cpython-312.pyc b/addons/education_reports/wizards/__pycache__/report_wizard.cpython-312.pyc index 6db4d2eca5982b788be81d6016f9fb1aef9d9077..5f7cdb824d2ac0cceda8ee2845d73848cde75ba3 100644 GIT binary patch delta 22 ccmbR3HrtK&G%qg~0}$*#yE#jKBQKva08Kpxb^rhX delta 22 ccmbR3HrtK&G%qg~0}vdUxGn3{MqWN;08aJ>?EnA( diff --git a/addons/education_student/__pycache__/__init__.cpython-312.pyc b/addons/education_student/__pycache__/__init__.cpython-312.pyc index e5d4a8da1ae587ac0e7370bfe958f1915a86854e..fac8a4457b646f228455c0cbd24b8d160f193bba 100644 GIT binary patch delta 21 bcmdnQxQUVXG%qg~0}$*#yE#jABJWZFKrjYm delta 21 bcmdnQxQUVXG%qg~0}vdUxGhU;BJWZFKFS6$ diff --git a/addons/education_student/models/__pycache__/__init__.cpython-312.pyc b/addons/education_student/models/__pycache__/__init__.cpython-312.pyc index 45d3e262b761cb843ed58aec88c2ba61c369fa27..b723c91c5cad70b1e8f0ae39b480fa53c802eabb 100644 GIT binary patch delta 21 bcmaFJ_>htJG%qg~0}$*#yE)5bBJULdNHYfz delta 21 bcmaFJ_>htJG%qg~0}vdUxGl?UBJULdM$rb| diff --git a/addons/education_student/models/__pycache__/academic_config.cpython-312.pyc b/addons/education_student/models/__pycache__/academic_config.cpython-312.pyc index 6b8719e95c3b2af7a35f522437d732d2728db31a..d3f504188ed068d309f5c8c6612e22ebdbd38e4b 100644 GIT binary patch delta 22 ccmaEE^4x^?G%qg~0}$*#yE)5aBX5)x09Zi>RsaA1 delta 22 ccmaEE^4x^?G%qg~0}vdUxGn3#M&2kX09i{1ssI20 diff --git a/addons/education_student/models/__pycache__/student.cpython-312.pyc b/addons/education_student/models/__pycache__/student.cpython-312.pyc index 53b4559cfe6b4ada0f13bafeba35aedb102bc682..75a2158bfcd497d169a8d7551667f1d23b12473e 100644 GIT binary patch delta 25 fcmew~iSg4UM!wU$yj%=Gu>b7ltT~1o`BFRqceDuV delta 25 fcmew~iSg4UM!wU$yj%=GaAe}PthGiP`BFRqc1;M# diff --git a/addons/education_timetable/__pycache__/__init__.cpython-312.pyc b/addons/education_timetable/__pycache__/__init__.cpython-312.pyc index 0fc45fcc3f7c33b2fae2f905982231c6c968e843..1ab03a616c1d386f9b3d9c2e03590d9b0f197e98 100644 GIT binary patch delta 21 bcmcc4c%6~=G%qg~0}$*#yE#jLBJU{xMui6L delta 21 bcmcc4c%6~=G%qg~0}vdUxGl?YBJU{xMI#2g diff --git a/addons/education_timetable/controllers/__pycache__/__init__.cpython-312.pyc b/addons/education_timetable/controllers/__pycache__/__init__.cpython-312.pyc index eaf7878efc27bc892126e69e60bb81448ca97026..585a9a40e31b309f702d69b2546dddc0a1e41cca 100644 GIT binary patch delta 21 bcmdnTxQ~(dG%qg~0}$*#yE#jEBJV~3LKFsu delta 21 bcmdnTxQ~(dG%qg~0}vdUxGhU$BJV~3K&}Q; diff --git a/addons/education_timetable/controllers/__pycache__/main.cpython-312.pyc b/addons/education_timetable/controllers/__pycache__/main.cpython-312.pyc index b398eae6c10d8b2a2fde024afecd70f026f7855e..16a910a28cebda5604540d65a208a23d932dc8c3 100644 GIT binary patch delta 23 dcmdm`v`dNaG%qg~0}$*#yE$vM&_+HTK>$_~2N(bV delta 23 dcmdm`v`dNaG%qg~0}vdUxGhUYcq5;VAOKM7237z7 diff --git a/addons/education_timetable/models/__pycache__/__init__.cpython-312.pyc b/addons/education_timetable/models/__pycache__/__init__.cpython-312.pyc index fd1b90de7b2d076f094a24e23f8698d4d79884f7..1b3642b115c5b1f9b81da4ba5f0ff116a5fa2998 100644 GIT binary patch delta 21 bcmey&_?eOSG%qg~0}$*#yE)5cBJVQ*OH~I} delta 21 bcmey&_?eOSG%qg~0}vdUxGl?VBJVQ*N%IFJ diff --git a/addons/education_timetable/models/__pycache__/education_room.cpython-312.pyc b/addons/education_timetable/models/__pycache__/education_room.cpython-312.pyc index 34621d90383094d6db5713771156f817725ef4d7..5a8da6379664852d9cc4d4bf488cb3ae7d215e72 100644 GIT binary patch delta 22 ccmbQqIg^w3G%qg~0}$*#yE)5$BX18207WhahX4Qo delta 22 ccmbQqIg^w3G%qg~0}vdUxGgJTBX18207K;lWB>pF diff --git a/addons/education_timetable/models/__pycache__/education_timetable_slot.cpython-312.pyc b/addons/education_timetable/models/__pycache__/education_timetable_slot.cpython-312.pyc index 159099e6223018898ca04db8becc953c61c2c7f1..3c8fd350a845858f0b2e4054fe783c3d632e1b02 100644 GIT binary patch delta 22 ccmeyM`azZVG%qg~0}$*#yE#jKBkyA&09T*~q5uE@ delta 22 ccmeyM`azZVG%qg~0}vdUxGk%2BkyA&09Tv`zyJUM diff --git a/addons/education_transportation/__pycache__/__init__.cpython-312.pyc b/addons/education_transportation/__pycache__/__init__.cpython-312.pyc index 93b2e4ba155f35b2034dc18eba12362ad398d990..ba9fbb5e7a2a155d77d582be1a6509857f1ac811 100644 GIT binary patch delta 21 bcmcb^c!!bqG%qg~0}$*L-Ik?4k@q|RLQDol delta 21 bcmcb^c!!bqG%qg~0}vdUxGl?YBJX(sMeqj7 diff --git a/addons/education_transportation/controllers/__pycache__/__init__.cpython-312.pyc b/addons/education_transportation/controllers/__pycache__/__init__.cpython-312.pyc index 10ee48321bc26454e60264767a3a2d733d741af4..f8dd52ddd042c6c33f0978dbb02d96d2997b40fb 100644 GIT binary patch delta 21 bcmX@gc$AU%G%qg~0}z}M-IgUfk#`3GKCK1y delta 21 bcmX@gc$AU%G%qg~0}vdUxGhU;BJU0WLDdFo diff --git a/addons/education_transportation/controllers/__pycache__/portal.cpython-312.pyc b/addons/education_transportation/controllers/__pycache__/portal.cpython-312.pyc index 18ae84688ec3fec985ce3efdfeff93d76350fa70..1a4d9a5d4a8b20dc9ed76309efd8a5d13da7c5a7 100644 GIT binary patch delta 23 dcmdm_yGfVtG%qg~0}z}M+m^LLU?blWF#u772JZj> delta 23 dcmdm_yGfVtG%qg~0}vdUxGhUUa3kLmF#u952Gall diff --git a/addons/education_transportation/models/__pycache__/__init__.cpython-312.pyc b/addons/education_transportation/models/__pycache__/__init__.cpython-312.pyc index d9de16d3545781b9b24c143f97e4bf27424900ca..30155fc76402997b75e0fd14939a275f4b74db25 100644 GIT binary patch delta 22 ccmdnRyo;IlG%qg~0}vb$-IjHHBkx*907k(EqW}N^ delta 22 ccmdnRyo;IlG%qg~0}vdUxGn3#M&7lI07}jWC;$Ke diff --git a/addons/education_transportation/models/__pycache__/assignment.cpython-312.pyc b/addons/education_transportation/models/__pycache__/assignment.cpython-312.pyc index dd126193240259f3f08880fa91f4339c0e7bf9ba..11116a6332e082f4479789b16abec762ed41e90c 100644 GIT binary patch delta 22 ccmbQBGeL*oa8Q8vG%qg~0}wnC-IkTHk=KL+07y3m7ytkO delta 22 ccmX>oa8Q8vG%qg~0}vdUxGk%FBd-Yu0869>l>h($ diff --git a/addons/education_transportation/models/__pycache__/incident.cpython-312.pyc b/addons/education_transportation/models/__pycache__/incident.cpython-312.pyc index 291988b88e112407a4b17b98bf1e172a7e289c2a..bc9a276a1cb82b5921e990f86697c5882765a960 100644 GIT binary patch delta 22 ccmX>kdq|e|G%qg~0}yD4ZOh`^$h(yf07Dc7qW}N^ delta 22 ccmX>kdq|e|G%qg~0}vdUxGl?SBkxu|08L#6>i_@% diff --git a/addons/education_transportation/models/__pycache__/route.cpython-312.pyc b/addons/education_transportation/models/__pycache__/route.cpython-312.pyc index bf750de4bcb22a464c1432082660ffaa13ea9bf5..ea157ad23af82a33dd6c106e458b20432777ab14 100644 GIT binary patch delta 22 ccmdnOzlERoG%qg~0}y-`-IjG|Bkyu{07)$d*#H0l delta 22 ccmdnOzlERoG%qg~0}vdUxGn46M&9M@088=*LI3~& diff --git a/addons/education_transportation/models/__pycache__/route_stop.cpython-312.pyc b/addons/education_transportation/models/__pycache__/route_stop.cpython-312.pyc index 845ca539db38abeef97edd626ccc39aceba5e28b..3d056b84ed8fe854d0c8073376f491519438349b 100644 GIT binary patch delta 22 ccmbOsGDC#-G%qg~0}$}3Z_Dc3$ji+I06UHa1^@s6 delta 22 ccmbOsGDC#-G%qg~0}vdUxGihhMqX|%07caXLjV8( diff --git a/addons/education_transportation/models/__pycache__/stop.cpython-312.pyc b/addons/education_transportation/models/__pycache__/stop.cpython-312.pyc index 660e7cde079c4a46acaff3d935e4ed759d361877..c9a7f632ca045c45d13e5b04c60a243312f1d3fb 100644 GIT binary patch delta 22 ccmey#^OJ}7G%qg~0}#9t-Imp{kvE4808$+W-T(jq delta 22 ccmey#^OJ}7G%qg~0}vdUxGih$M&2AY096nNNdN!< diff --git a/addons/education_transportation/models/__pycache__/trip.cpython-312.pyc b/addons/education_transportation/models/__pycache__/trip.cpython-312.pyc index 03d908a1779384486e43672f9fcf8e2345559c4e..7c1402054a0bd4ae5a237f05694e46af977eb4df 100644 GIT binary patch delta 23 dcmcbtdRdk4G%qg~0}zOaZOeMdy^-&z5CBjs2D$(M delta 23 dcmcbtdRdk4G%qg~0}vdUxGhVSXCvQHAplnU2Pyyn diff --git a/addons/education_transportation/models/__pycache__/vehicle.cpython-312.pyc b/addons/education_transportation/models/__pycache__/vehicle.cpython-312.pyc index 1da6f0d6fbf59f1daee5f4986a41d7a258d745c4..f492e56de81c069bbe3596003c38574b996b14eb 100644 GIT binary patch delta 22 ccmX@Ba#n@+G%qg~0}!yNZ_8S~k=H>807q^G;Q#;t delta 22 ccmX@Ba#n@+G%qg~0}vdUxGn4LMqURY08-osQ2+n{ diff --git a/addons/theme_student_erp_custom/__pycache__/__init__.cpython-312.pyc b/addons/theme_student_erp_custom/__pycache__/__init__.cpython-312.pyc index 93a30c1f35b8485a431ebb44f0698da4292402c5..2079040daa4195943cc108e025a1e0aedfe65e2e 100644 GIT binary patch delta 21 bcmbQvIGvIAG%qg~0}#|*+>#|Rk+%x~Is*mT delta 21 bcmbQvIGvIAG%qg~0}vdUxGhU^B5xM}I)eq{ diff --git a/admin_cookie.txt b/admin_cookie.txt new file mode 100644 index 0000000..9176cb6 --- /dev/null +++ b/admin_cookie.txt @@ -0,0 +1,5 @@ +# Netscape HTTP Cookie File +# https://curl.se/docs/http-cookies.html +# This file was generated by libcurl! Edit at your own risk. + +#HttpOnly_localhost FALSE / FALSE 1791398610 session_id QyP2Dv9gXDQDiEsdHgcts59e_0IShDwGzoEV1zGasI1Oror7_TKp7JNvwE0vfpOrmzjtG8stomCv2bGLU13R diff --git a/check.py b/check.py new file mode 100644 index 0000000..750de39 --- /dev/null +++ b/check.py @@ -0,0 +1 @@ +user = env["res.users"].search([("login", "=", "demo.student")]); student = env["education.student"].search([("id", "=", 10)]); print("USER:", user.id); print("STUDENT PORTAL USER:", student.portal_user_id.id); print("USER STUDENT_ID:", user.student_id.id) diff --git a/cookie.txt b/cookie.txt new file mode 100644 index 0000000..8027897 --- /dev/null +++ b/cookie.txt @@ -0,0 +1,5 @@ +# Netscape HTTP Cookie File +# https://curl.se/docs/http-cookies.html +# This file was generated by libcurl! Edit at your own risk. + +#HttpOnly_localhost FALSE / FALSE 1791400398 session_id -6czEnFIBCUg-AjKn1mVRwr5HWUfiuiG36uF145raY7smG8fyIWvAeSFMPc3CV5dtckCKLLSYBlDsHJfz7DI diff --git a/create_hierarchy.py b/create_hierarchy.py new file mode 100644 index 0000000..f2c9055 --- /dev/null +++ b/create_hierarchy.py @@ -0,0 +1,120 @@ +import traceback + +def get_or_create(model, domain, vals): + rec = env[model].search(domain, limit=1) + if not rec: + rec = env[model].create(vals) + print(f"Created {model}: {rec.id}") + else: + print(f"Found {model}: {rec.id}") + return rec + +try: + # 1. Company + company = env["res.company"].search([], limit=1) + + # 2. Campus + campus = get_or_create("education.campus", [("name", "=", "Test Campus")], { + "name": "Test Campus", + "company_id": company.id, + "code": "TC" + }) + + # 3. Department + dept = get_or_create("education.department", [("name", "=", "Test Dept")], { + "name": "Test Dept", + "company_id": company.id, + "campus_id": campus.id, + "code": "TD" + }) + + # 4. Academic Level + level = get_or_create("education.academic.level", [("name", "=", "Test Level")], { + "name": "Test Level", + "company_id": company.id, + "code": "TL" + }) + + # 5. Program + program = get_or_create("education.program", [("name", "=", "Test Program")], { + "name": "Test Program", + "department_id": dept.id, + "level_id": level.id, + "code": "TP" + }) + + # 6. Academic Year + year = get_or_create("education.academic.year", [("name", "=", "Test Year")], { + "name": "Test Year", + "company_id": company.id, + "start_date": "2026-01-01", + "end_date": "2026-12-31" + }) + + # 7. Academic Term + term = get_or_create("education.academic.term", [("name", "=", "Test Term")], { + "name": "Test Term", + "academic_year_id": year.id, + "start_date": "2026-01-01", + "end_date": "2026-06-30" + }) + + # 8. Batch + batch = get_or_create("education.batch", [("name", "=", "Test Batch")], { + "name": "Test Batch", + "program_id": program.id, + "academic_year_id": year.id, + "start_date": "2026-01-01", + "end_date": "2026-12-31" + }) + + # 9. Semester + semester = get_or_create("education.semester", [("name", "=", "Test Semester")], { + "name": "Test Semester", + "program_id": program.id, + "academic_year_id": year.id, + "sequence": 1 + }) + + # res.users (demo.student) + user = env["res.users"].search([("login", "=", "demo.student")], limit=1) + + # 10. Student + student = env["education.student"].search([("portal_user_id", "=", user.id)], limit=1) + if not student: + student = env["education.student"].create({ + "full_name": "Demo Student", + "first_name": "Demo", + "last_name": "Student", + "email": "demo.student@example.com", + "portal_user_id": user.id, + "company_id": company.id, + "campus_id": campus.id, + "department_id": dept.id, + "level_id": level.id, + "program_id": program.id, + "academic_year_id": year.id, + "academic_term_id": term.id, + "batch_id": batch.id, + "semester_id": semester.id, + "current_semester_id": semester.id, + "date_of_birth": "2000-01-01", + "gender": "other", + "admission_number": "ADM-9999", + "student_id": "STU-9999", + "status": "active" + }) + print(f"Created Student: {student.id}") + else: + print(f"Found Student: {student.id}") + + env.cr.commit() + with open('/mnt/extra-addons/success.log', 'w') as f: + f.write(f"ALL DONE. Student ID: {student.id}\n") + print("SUCCESS") + +except Exception as e: + print("FAILED") + traceback.print_exc() + with open('/mnt/extra-addons/error.log', 'w') as f: + f.write(traceback.format_exc()) diff --git a/create_student.py b/create_student.py new file mode 100644 index 0000000..15eb9f6 --- /dev/null +++ b/create_student.py @@ -0,0 +1,11 @@ +user = env["res.users"].search([("login", "=", "demo.student")], limit=1) +if user: + student = env["education.student"].create({ + "full_name": "Demo Student", + "first_name": "Demo", + "last_name": "Student", + "email": "demo.student@example.com", + "portal_user_id": user.id, + }) + env.cr.commit() + print("CREATED STUDENT ID:", student.id, "LINKED TO USER ID:", user.id) diff --git a/create_student_debug.py b/create_student_debug.py new file mode 100644 index 0000000..f9e3713 --- /dev/null +++ b/create_student_debug.py @@ -0,0 +1,36 @@ +import traceback +try: + campus = env["education.campus"].search([], limit=1) + if not campus: + campus = env["education.campus"].create({"name": "Test Campus"}) + dept = env["education.department"].search([], limit=1) + if not dept: + dept = env["education.department"].create({"name": "Test Dept"}) + prog = env["education.program"].search([], limit=1) + if not prog: + prog = env["education.program"].create({"name": "Test Program"}) + year = env["education.academic.year"].search([], limit=1) + if not year: + year = env["education.academic.year"].create({"name": "2026"}) + user = env["res.users"].search([("login", "=", "demo.student")], limit=1) + + student = env["education.student"].create({ + "full_name": "Demo Student", + "first_name": "Demo", + "last_name": "Student", + "email": "demo.student@example.com", + "portal_user_id": user.id if user else False, + "campus_id": campus.id, + "department_id": dept.id, + "program_id": prog.id, + "academic_year_id": year.id, + "date_of_birth": "2000-01-01", + "gender": "other", + "admission_number": "ADM-9999", + "student_id": "STU-9999" + }) + env.cr.commit() + print("SUCCESS, STUDENT ID:", student.id) +except Exception as e: + print("ERROR DURING CREATE:") + traceback.print_exc() diff --git a/create_student_file.py b/create_student_file.py new file mode 100644 index 0000000..9232ed2 --- /dev/null +++ b/create_student_file.py @@ -0,0 +1,39 @@ +import traceback +with open('/tmp/student_create.log', 'w') as f: + try: + campus = env["education.campus"].search([], limit=1) + if not campus: + campus = env["education.campus"].create({"name": "Test Campus"}) + dept = env["education.department"].search([], limit=1) + if not dept: + dept = env["education.department"].create({"name": "Test Dept"}) + prog = env["education.program"].search([], limit=1) + if not prog: + prog = env["education.program"].create({"name": "Test Program"}) + year = env["education.academic.year"].search([], limit=1) + if not year: + year = env["education.academic.year"].create({"name": "2026"}) + user = env["res.users"].search([("login", "=", "demo.student")], limit=1) + + f.write(f"Campus: {campus.id}, Dept: {dept.id}, Prog: {prog.id}, Year: {year.id}, User: {user.id}\n") + + student = env["education.student"].create({ + "full_name": "Demo Student", + "first_name": "Demo", + "last_name": "Student", + "email": "demo.student@example.com", + "portal_user_id": user.id if user else False, + "campus_id": campus.id, + "department_id": dept.id, + "program_id": prog.id, + "academic_year_id": year.id, + "date_of_birth": "2000-01-01", + "gender": "other", + "admission_number": "ADM-9999", + "student_id": "STU-9999" + }) + env.cr.commit() + f.write(f"SUCCESS, STUDENT ID: {student.id}\n") + except Exception as e: + f.write("ERROR DURING CREATE:\n") + f.write(traceback.format_exc()) diff --git a/create_student_full.py b/create_student_full.py new file mode 100644 index 0000000..868efb5 --- /dev/null +++ b/create_student_full.py @@ -0,0 +1,23 @@ +campus = env["education.campus"].search([], limit=1) +dept = env["education.department"].search([], limit=1) +prog = env["education.program"].search([], limit=1) +year = env["education.academic.year"].search([], limit=1) +user = env["res.users"].search([("login", "=", "demo.student")], limit=1) +if user and campus and dept and prog and year: + student = env["education.student"].create({ + "full_name": "Demo Student", + "first_name": "Demo", + "last_name": "Student", + "email": "demo.student@example.com", + "portal_user_id": user.id, + "campus_id": campus.id, + "department_id": dept.id, + "program_id": prog.id, + "academic_year_id": year.id, + "date_of_birth": "2000-01-01", + "gender": "other", + "admission_number": "ADM-9999", + "student_id": "STU-9999" + }) + env.cr.commit() + print("CREATED FULL STUDENT:", student.id) diff --git a/create_student_full2.py b/create_student_full2.py new file mode 100644 index 0000000..a03de90 --- /dev/null +++ b/create_student_full2.py @@ -0,0 +1,30 @@ +campus = env["education.campus"].search([], limit=1) +if not campus: + campus = env["education.campus"].create({"name": "Test Campus"}) +dept = env["education.department"].search([], limit=1) +if not dept: + dept = env["education.department"].create({"name": "Test Dept"}) +prog = env["education.program"].search([], limit=1) +if not prog: + prog = env["education.program"].create({"name": "Test Program"}) +year = env["education.academic.year"].search([], limit=1) +if not year: + year = env["education.academic.year"].create({"name": "2026"}) +user = env["res.users"].search([("login", "=", "demo.student")], limit=1) +if user: + student = env["education.student"].create({ + "full_name": "Demo Student", + "first_name": "Demo", + "last_name": "Student", + "email": "demo.student@example.com", + "portal_user_id": user.id, + "campus_id": campus.id, + "department_id": dept.id, + "program_id": prog.id, + "academic_year_id": year.id, + "date_of_birth": "2000-01-01", + "gender": "other", + "admission_number": "ADM-9999", + "student_id": "STU-9999" + }) + env.cr.commit() diff --git a/debug_student.py b/debug_student.py new file mode 100644 index 0000000..84a5cb4 --- /dev/null +++ b/debug_student.py @@ -0,0 +1,4 @@ +user = env["res.users"].search([("login", "=", "demo.student")], limit=1) +print("USER:", user.id) +print("STUDENTS:", user.student_ids.ids) +print("PROPERTY:", user.student_id) diff --git a/docker-compose.yml b/docker-compose.yml index f91c3eb..2f5ec6d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,7 +22,7 @@ services: USER: odoo PASSWORD: odoo LIST_DB: "True" - command: odoo --proxy-mode -i education_base,education_student,education_attendance,education_finance,education_dashboard,education_exam,education_lms,education_portal,education_reports,education_timetable,education_hostel,education_transportation,education_demo_data + command: odoo --proxy-mode -i education_base,education_student,education_attendance,education_finance,education_dashboard,education_exam,education_lms,education_portal,education_reports,education_timetable,education_hostel,education_transportation,education_demo_data,education_mobile_api volumes: - client1_odoo_data:/var/lib/odoo - ./addons:/mnt/extra-addons diff --git a/fix_demo_data.py b/fix_demo_data.py new file mode 100644 index 0000000..1caa678 --- /dev/null +++ b/fix_demo_data.py @@ -0,0 +1,12 @@ +import sys +sys.path.append("/mnt/extra-addons") +sys.path.append("/usr/lib/python3/dist-packages/odoo/addons") +from education_demo_data.demo_data_generator import generate_demo_data + +try: + generate_demo_data(env) + print("DEMO DATA GENERATED SUCCESSFULLY") +except Exception as e: + import traceback + traceback.print_exc() + diff --git a/force_create.py b/force_create.py new file mode 100644 index 0000000..b2c9f2a --- /dev/null +++ b/force_create.py @@ -0,0 +1,43 @@ +import sys +import traceback +try: + user = env["res.users"].search([("login", "=", "demo.student")], limit=1) + + c = env["res.company"].search([], limit=1) + campus = env["education.campus"].search([], limit=1) or env["education.campus"].create({"name": "Test", "company_id": c.id}) + dept = env["education.department"].search([], limit=1) or env["education.department"].create({"name": "Test", "company_id": c.id, "campus_id": campus.id}) + level = env["education.academic.level"].search([], limit=1) or env["education.academic.level"].create({"name": "Test", "company_id": c.id}) + prog = env["education.program"].search([], limit=1) or env["education.program"].create({"name": "Test", "code": "T", "department_id": dept.id, "level_id": level.id}) + year = env["education.academic.year"].search([], limit=1) or env["education.academic.year"].create({"name": "Test", "company_id": c.id, "start_date": "2026-01-01", "end_date": "2026-12-31"}) + term = env["education.academic.term"].search([], limit=1) or env["education.academic.term"].create({"name": "Test", "academic_year_id": year.id, "start_date": "2026-01-01", "end_date": "2026-12-31"}) + batch = env["education.batch"].search([], limit=1) or env["education.batch"].create({"name": "Test", "program_id": prog.id, "academic_year_id": year.id}) + sem = env["education.semester"].search([], limit=1) or env["education.semester"].create({"name": "Test", "program_id": prog.id, "academic_year_id": year.id, "sequence": 1}) + + student = env["education.student"].create({ + "full_name": "Demo Student", + "first_name": "Demo", + "last_name": "Student", + "email": "demo.student@example.com", + "portal_user_id": user.id, + "company_id": c.id, + "campus_id": campus.id, + "department_id": dept.id, + "level_id": level.id, + "program_id": prog.id, + "academic_year_id": year.id, + "academic_term_id": term.id, + "batch_id": batch.id, + "semester_id": sem.id, + "current_semester_id": sem.id, + "date_of_birth": "2000-01-01", + "gender": "other", + "admission_number": "ADM-9999", + "student_id": "STU-9999", + "status": "active" + }) + env.cr.commit() + with open('/mnt/extra-addons/error.log', 'w') as f: + f.write("SUCCESS: " + str(student.id)) +except Exception as e: + with open('/mnt/extra-addons/error.log', 'w') as f: + f.write(traceback.format_exc()) diff --git a/link.py b/link.py new file mode 100644 index 0000000..68cf826 --- /dev/null +++ b/link.py @@ -0,0 +1 @@ +user = env["res.users"].search([("login", "=", "demo.student")]); env["education.student"].search([], limit=1).write({"portal_user_id": user.id}); env.cr.commit() diff --git a/run_demo.py b/run_demo.py new file mode 100644 index 0000000..291b525 --- /dev/null +++ b/run_demo.py @@ -0,0 +1,7 @@ +import traceback +try: + from odoo.addons.education_demo_data.demo_data_generator import generate_demo_data + generate_demo_data(env) + print("DEMO_GEN_SUCCESS") +except Exception: + traceback.print_exc() diff --git a/setup_demo_student.py b/setup_demo_student.py new file mode 100644 index 0000000..8ad0484 --- /dev/null +++ b/setup_demo_student.py @@ -0,0 +1,15 @@ +user = env["res.users"].search([("login", "=", "demo.student")], limit=1) +if user: + student = env["education.student"].search([], limit=1) + if student: + student.write({"portal_user_id": user.id}) + env.cr.commit() + print("LINKED STUDENT ID:", student.id, "TO USER ID:", user.id) + else: + print("NO STUDENT FOUND") +else: + print("NO USER FOUND") + +print("USER:", user.id) +print("USER STUDENT:", user.student_id.id) +print("STUDENT NAME:", user.student_id.full_name) diff --git a/verify_student.py b/verify_student.py new file mode 100644 index 0000000..d94b2ed --- /dev/null +++ b/verify_student.py @@ -0,0 +1,4 @@ +user = env["res.users"].search([("login", "=", "demo.student")], limit=1) +print("USER:", user.id) +print("USER STUDENT:", user.student_id.id) +print("STUDENT NAME:", user.student_id.full_name)