├── .copier-answers.yml ├── .editorconfig ├── .eslintrc.yml ├── .flake8 ├── .github ├── auto_assign.yml ├── dependabot.yml └── workflows │ ├── auto-assign-pr.yml │ ├── auto-assign.yml │ ├── cla.yml │ ├── code-analysis.yml │ ├── pre-commit.yml │ ├── stale.yml │ └── test.yml ├── .gitignore ├── .isort.cfg ├── .pre-commit-config.yaml ├── .prettierrc.yml ├── .pylintrc ├── .pylintrc-mandatory ├── COPYRIGHT ├── LICENSE ├── README.md ├── g2p_connect_demo ├── README.rst ├── __init__.py ├── __manifest__.py ├── data │ ├── sample_data.xml │ └── users_data.xml ├── models │ ├── __init__.py │ ├── generate_change_request.py │ ├── generate_group.py │ ├── group.py │ ├── individual.py │ └── registrant.py ├── readme │ └── DESCRIPTION.rst ├── security │ └── ir.model.access.csv ├── static │ └── description │ │ ├── icon.png │ │ └── index.html ├── tests │ ├── __init__.py │ └── test_compute_indicator_fields.py └── views │ ├── generate_change_request_data_view.xml │ ├── generate_data_view.xml │ ├── groups_view.xml │ └── individuals_view.xml ├── license_header.txt ├── requirements.txt ├── setup ├── .setuptools-odoo-make-default-ignore ├── README ├── _metapackage │ ├── VERSION.txt │ └── setup.py ├── g2p_connect_demo │ ├── odoo │ │ └── addons │ │ │ └── g2p_connect_demo │ └── setup.py ├── spp_base_demo │ ├── odoo │ │ └── addons │ │ │ └── spp_base_demo │ └── setup.py ├── spp_change_request_add_children_demo │ ├── odoo │ │ └── addons │ │ │ └── spp_change_request_add_children_demo │ └── setup.py ├── spp_custom_filter_ui │ ├── odoo │ │ └── addons │ │ │ └── spp_custom_filter_ui │ └── setup.py ├── spp_demo │ ├── odoo │ │ └── addons │ │ │ └── spp_demo │ └── setup.py └── spp_event_demo │ ├── odoo │ └── addons │ │ └── spp_event_demo │ └── setup.py ├── spp_base_demo ├── README.rst ├── __init__.py ├── __manifest__.py ├── data │ └── users_data.xml ├── i18n │ └── spp_base_demo.pot ├── readme │ └── DESCRIPTION.rst └── static │ └── description │ ├── icon.png │ └── index.html ├── spp_change_request_add_children_demo ├── README.rst ├── __init__.py ├── __manifest__.py ├── data │ ├── change_request_sequence.xml │ ├── change_request_stage.xml │ ├── dms.xml │ └── id_type.xml ├── i18n │ └── spp_change_request_add_children_demo.pot ├── models │ ├── __init__.py │ ├── change_request.py │ ├── change_request_add_children.py │ ├── change_request_add_children_validation_sequence.py │ └── group_membership.py ├── security │ ├── change_request_security.xml │ └── ir.model.access.csv ├── static │ └── description │ │ └── icon.png └── views │ └── change_request_add_children_view.xml ├── spp_custom_filter_ui ├── README.rst ├── __init__.py ├── __manifest__.py └── models │ ├── __init__.py │ └── res_partner.py ├── spp_demo ├── README.rst ├── __init__.py ├── __manifest__.py ├── data │ └── res_lang_data.xml ├── models │ ├── __init__.py │ ├── generate_group.py │ ├── generate_program.py │ ├── group.py │ └── individual.py ├── readme │ └── DESCRIPTION.rst ├── security │ └── ir.model.access.csv ├── static │ └── description │ │ ├── icon.png │ │ └── index.html └── views │ ├── generate_data_view.xml │ └── generate_program_view.xml ├── spp_event_demo ├── README.rst ├── __init__.py ├── __manifest__.py ├── i18n │ ├── ar.po │ ├── ckb.po │ ├── fr.po │ └── spp_event_demo.pot ├── models │ ├── __init__.py │ ├── house_visit.py │ ├── phone_survey.py │ ├── registrant.py │ └── school_enrolment.py ├── readme │ └── DESCRIPTION.rst ├── security │ └── ir.model.access.csv ├── static │ └── description │ │ ├── icon.png │ │ └── index.html ├── tests │ ├── __init__.py │ ├── test_event_house_visit.py │ ├── test_event_phone_survey.py │ └── test_event_schoolenrolment_record.py ├── views │ ├── house_visit_view.xml │ ├── phone_survey_view.xml │ └── registrant_view.xml └── wizard │ ├── __init__.py │ ├── create_event_house_visit_wizard.py │ ├── create_event_house_visit_wizard.xml │ ├── create_event_phone_survey_wizard.py │ ├── create_event_phone_survey_wizard.xml │ ├── create_event_school_enrolment_wizard.py │ ├── create_event_school_enrolment_wizard.xml │ └── create_event_wizard.py ├── test-requirements.txt └── vulnerability_disclosure_policy.md /.copier-answers.yml: -------------------------------------------------------------------------------- 1 | # Do NOT update manually; changes here will be overwritten by Copier 2 | _commit: 79935fe 3 | _src_path: https://github.com/openspp/openspp-odoo-addons-repo-template.git 4 | ci: GitHub 5 | dependency_installation_mode: OCA 6 | generate_requirements_txt: true 7 | github_check_license: false 8 | github_ci_extra_env: {} 9 | github_enable_codecov: true 10 | github_enable_makepot: true 11 | github_enable_stale_action: true 12 | github_enforce_dev_status_compatibility: false 13 | include_wkhtmltopdf: false 14 | odoo_version: 15.0 15 | org_name: OpenSPP.org 16 | org_slug: openspp 17 | rebel_module_groups: [] 18 | repo_description: OpenSPP Demo Repo 19 | repo_name: OpenSPP Demo 20 | repo_slug: openspp-demo 21 | repo_website: https://github.com/openspp/openspp-demo 22 | travis_apt_packages: [] 23 | travis_apt_sources: [] 24 | 25 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Configuration for known file extensions 2 | [*.{css,js,json,less,md,py,rst,sass,scss,xml,yaml,yml}] 3 | charset = utf-8 4 | end_of_line = lf 5 | indent_size = 4 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{json,yml,yaml,rst,md}] 11 | indent_size = 2 12 | 13 | # Do not configure editor for libs and autogenerated content 14 | [{*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst}] 15 | charset = unset 16 | end_of_line = unset 17 | indent_size = unset 18 | indent_style = unset 19 | insert_final_newline = false 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | env: 2 | browser: true 3 | es6: true 4 | 5 | # See https://github.com/OCA/odoo-community.org/issues/37#issuecomment-470686449 6 | parserOptions: 7 | ecmaVersion: 2019 8 | 9 | overrides: 10 | - files: 11 | - "**/*.esm.js" 12 | - "**/*.js" 13 | parserOptions: 14 | sourceType: module 15 | 16 | # Globals available in Odoo that shouldn't produce errorings 17 | globals: 18 | _: readonly 19 | $: readonly 20 | fuzzy: readonly 21 | jQuery: readonly 22 | moment: readonly 23 | odoo: readonly 24 | openerp: readonly 25 | owl: readonly 26 | 27 | # Styling is handled by Prettier, so we only need to enable AST rules; 28 | # see https://github.com/OCA/maintainer-quality-tools/pull/618#issuecomment-558576890 29 | rules: 30 | accessor-pairs: warn 31 | array-callback-return: warn 32 | callback-return: warn 33 | capitalized-comments: 34 | - warn 35 | - always 36 | - ignoreConsecutiveComments: true 37 | ignoreInlineComments: true 38 | complexity: 39 | - warn 40 | - 15 41 | constructor-super: warn 42 | dot-notation: warn 43 | eqeqeq: warn 44 | global-require: warn 45 | handle-callback-err: warn 46 | id-blacklist: warn 47 | id-match: warn 48 | init-declarations: error 49 | max-depth: warn 50 | max-nested-callbacks: warn 51 | max-statements-per-line: warn 52 | no-alert: warn 53 | no-array-constructor: warn 54 | no-caller: warn 55 | no-case-declarations: warn 56 | no-class-assign: warn 57 | no-cond-assign: error 58 | no-const-assign: error 59 | no-constant-condition: warn 60 | no-control-regex: warn 61 | no-debugger: error 62 | no-delete-var: warn 63 | no-div-regex: warn 64 | no-dupe-args: error 65 | no-dupe-class-members: error 66 | no-dupe-keys: error 67 | no-duplicate-case: error 68 | no-duplicate-imports: error 69 | no-else-return: warn 70 | no-empty-character-class: warn 71 | no-empty-function: error 72 | no-empty-pattern: error 73 | no-empty: warn 74 | no-eq-null: error 75 | no-eval: error 76 | no-ex-assign: error 77 | no-extend-native: warn 78 | no-extra-bind: warn 79 | no-extra-boolean-cast: warn 80 | no-extra-label: warn 81 | no-fallthrough: warn 82 | no-func-assign: error 83 | no-global-assign: error 84 | no-implicit-coercion: 85 | - warn 86 | - allow: ["~"] 87 | no-implicit-globals: warn 88 | no-implied-eval: warn 89 | no-inline-comments: warn 90 | no-inner-declarations: warn 91 | no-invalid-regexp: warn 92 | no-irregular-whitespace: warn 93 | no-iterator: warn 94 | no-label-var: warn 95 | no-labels: warn 96 | no-lone-blocks: warn 97 | no-lonely-if: error 98 | no-mixed-requires: error 99 | no-multi-str: warn 100 | no-native-reassign: error 101 | no-negated-condition: warn 102 | no-negated-in-lhs: error 103 | no-new-func: warn 104 | no-new-object: warn 105 | no-new-require: warn 106 | no-new-symbol: warn 107 | no-new-wrappers: warn 108 | no-new: warn 109 | no-obj-calls: warn 110 | no-octal-escape: warn 111 | no-octal: warn 112 | no-param-reassign: warn 113 | no-path-concat: warn 114 | no-process-env: warn 115 | no-process-exit: warn 116 | no-proto: warn 117 | no-prototype-builtins: warn 118 | no-redeclare: warn 119 | no-regex-spaces: warn 120 | no-restricted-globals: warn 121 | no-restricted-imports: warn 122 | no-restricted-modules: warn 123 | no-restricted-syntax: warn 124 | no-return-assign: error 125 | no-script-url: warn 126 | no-self-assign: warn 127 | no-self-compare: warn 128 | no-sequences: warn 129 | no-shadow-restricted-names: warn 130 | no-shadow: warn 131 | no-sparse-arrays: warn 132 | no-sync: warn 133 | no-this-before-super: warn 134 | no-throw-literal: warn 135 | no-undef-init: warn 136 | no-undef: error 137 | no-unmodified-loop-condition: warn 138 | no-unneeded-ternary: error 139 | no-unreachable: error 140 | no-unsafe-finally: error 141 | no-unused-expressions: error 142 | no-unused-labels: error 143 | no-unused-vars: error 144 | no-use-before-define: error 145 | no-useless-call: warn 146 | no-useless-computed-key: warn 147 | no-useless-concat: warn 148 | no-useless-constructor: warn 149 | no-useless-escape: warn 150 | no-useless-rename: warn 151 | no-void: warn 152 | no-with: warn 153 | operator-assignment: [error, always] 154 | prefer-const: warn 155 | radix: warn 156 | require-yield: warn 157 | sort-imports: warn 158 | spaced-comment: [error, always] 159 | strict: [error, function] 160 | use-isnan: error 161 | valid-jsdoc: 162 | - warn 163 | - prefer: 164 | arg: param 165 | argument: param 166 | augments: extends 167 | constructor: class 168 | exception: throws 169 | func: function 170 | method: function 171 | prop: property 172 | return: returns 173 | virtual: abstract 174 | yield: yields 175 | preferType: 176 | array: Array 177 | bool: Boolean 178 | boolean: Boolean 179 | number: Number 180 | object: Object 181 | str: String 182 | string: String 183 | requireParamDescription: false 184 | requireReturn: false 185 | requireReturnDescription: false 186 | requireReturnType: false 187 | valid-typeof: warn 188 | yoda: warn 189 | -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 110 3 | max-complexity = 16 4 | # B = bugbear 5 | # B9 = bugbear opinionated (incl line length) 6 | select = C,E,F,W,B,B9 7 | # E203: whitespace before ':' (black behaviour) 8 | # E501: flake8 line length (covered by bugbear B950) 9 | # W503: line break before binary operator (black behaviour) 10 | ignore = E203,E501,W503 11 | per-file-ignores= 12 | __init__.py:F401 13 | -------------------------------------------------------------------------------- /.github/auto_assign.yml: -------------------------------------------------------------------------------- 1 | # Set to true to add reviewers to PRs 2 | addReviewers: true 3 | 4 | # Set to 'author' to add PR's author as a assignee 5 | addAssignees: author 6 | 7 | # A list of reviewers to be added to PRs (GitHub user name) 8 | reviewers: 9 | - jeremi 10 | - gonzalesedwin1123 11 | - emjay0921 12 | - reichie020212 13 | 14 | # A number of reviewers added to the PR 15 | # Set 0 to add all the reviewers (default: 0) 16 | numberOfReviewers: 0 17 | 18 | # A list of keywords to be skipped the process if PR's title include it 19 | skipKeywords: 20 | - wip 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | # Check for updates to GitHub Actions every weekday 12 | interval: "weekly" 13 | -------------------------------------------------------------------------------- /.github/workflows/auto-assign-pr.yml: -------------------------------------------------------------------------------- 1 | name: Auto Assign PR 2 | on: 3 | pull_request: 4 | types: [opened, ready_for_review] 5 | jobs: 6 | add-reviews: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: kentaro-m/auto-assign-action@v1.2.4 10 | -------------------------------------------------------------------------------- /.github/workflows/auto-assign.yml: -------------------------------------------------------------------------------- 1 | name: Auto Assign 2 | on: 3 | issues: 4 | types: [opened] 5 | pull_request: 6 | types: [opened] 7 | jobs: 8 | run: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: bubkoo/auto-assign@v1 12 | with: 13 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 14 | CONFIG_FILE: .github/auto-assign.yml 15 | -------------------------------------------------------------------------------- /.github/workflows/cla.yml: -------------------------------------------------------------------------------- 1 | name: "CLA Assistant" 2 | on: 3 | issue_comment: 4 | types: [created] 5 | pull_request_target: 6 | types: [opened, closed, synchronize] 7 | 8 | jobs: 9 | CLAssistant: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: "CLA Assistant" 13 | if: 14 | (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA 15 | Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' 16 | # Beta Release 17 | uses: contributor-assistant/github-action@v2.2.0 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | # the below token should have repo scope and must be manually added by you in the repository's secret 21 | PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} 22 | with: 23 | path-to-signatures: "signatures/version1/cla.json" 24 | path-to-document: "https://github.com/openspp/openspp-cla/tree/main" # e.g. a CLA or a DCO document 25 | # branch should not be protected 26 | branch: "main" 27 | allowlist: dependabot-preview[bot],greenkeeper[bot],dependabot[bot] 28 | remote-organization-name: openspp 29 | remote-repository-name: openspp-cla 30 | #below are the optional inputs - If the optional inputs are not given, then default values will be taken 31 | #remote-organization-name: enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository) 32 | #remote-repository-name: enter the remote repository name where the signatures should be stored (Default is storing the signatures in the same repository) 33 | #create-file-commit-message: 'For example: Creating file for storing CLA Signatures' 34 | #signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo' 35 | #custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign' 36 | #custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA' 37 | #custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.' 38 | #lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true) 39 | #use-dco-flag: true - If you are using DCO instead of CLA 40 | -------------------------------------------------------------------------------- /.github/workflows/code-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "Code Scanning - Action" 2 | 3 | on: 4 | push: 5 | branches: 6 | - "{{ odoo_version }}" 7 | pull_request: 8 | branches: 9 | - "{{ odoo_version }}" 10 | schedule: 11 | # ┌───────────── minute (0 - 59) 12 | # │ ┌───────────── hour (0 - 23) 13 | # │ │ ┌───────────── day of the month (1 - 31) 14 | # │ │ │ ┌───────────── month (1 - 12 or JAN-DEC) 15 | # │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT) 16 | # │ │ │ │ │ 17 | # │ │ │ │ │ 18 | # │ │ │ │ │ 19 | # * * * * * 20 | - cron: '30 1 * * 2' 21 | 22 | jobs: 23 | CodeQL-Build: 24 | # CodeQL runs on ubuntu-latest, windows-latest, and macos-latest 25 | runs-on: ubuntu-latest 26 | 27 | permissions: 28 | # required for all workflows 29 | security-events: write 30 | 31 | # only required for workflows in private repositories 32 | actions: read 33 | contents: read 34 | strategy: 35 | fail-fast: false 36 | matrix: 37 | language: [ 'python' ] 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v3 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v2 46 | with: 47 | languages: ${{ matrix.language }} 48 | # Override language selection by uncommenting this and choosing your languages 49 | # with: 50 | # languages: go, javascript, csharp, python, cpp, java, ruby 51 | 52 | # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). 53 | # If this step fails, then you should remove it and run the build manually (see below). 54 | - name: Autobuild 55 | uses: github/codeql-action/autobuild@v2 56 | 57 | # ℹ️ Command-line programs to run using the OS shell. 58 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 59 | 60 | # ✏️ If the Autobuild fails above, remove it and uncomment the following 61 | # three lines and modify them (or add more) to build your code if your 62 | # project uses a compiled language 63 | 64 | #- run: | 65 | # make bootstrap 66 | # make release 67 | 68 | - name: Perform CodeQL Analysis 69 | uses: github/codeql-action/analyze@v2 70 | 71 | - name: TruffleHog OSS 72 | uses: trufflesecurity/trufflehog@main 73 | with: 74 | path: ./ 75 | base: ${{ github.event.repository.default_branch }} 76 | head: HEAD 77 | extra_args: --debug --only-verified 78 | -------------------------------------------------------------------------------- /.github/workflows/pre-commit.yml: -------------------------------------------------------------------------------- 1 | name: pre-commit 2 | 3 | on: push 4 | 5 | jobs: 6 | pre-commit: 7 | runs-on: ubuntu-22.04 8 | steps: 9 | - uses: actions/checkout@v2 10 | - uses: actions/setup-python@v2 11 | - name: Get python version 12 | run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV 13 | - uses: actions/cache@v1 14 | with: 15 | path: ~/.cache/pre-commit 16 | key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} 17 | - name: Install pre-commit 18 | run: pip install pre-commit 19 | - name: Run pre-commit 20 | run: pre-commit run --all-files --show-diff-on-failure --color=always 21 | - name: Check that all files generated by pre-commit are in git 22 | run: | 23 | newfiles="$(git ls-files --others --exclude-from=.gitignore)" 24 | if [ "$newfiles" != "" ] ; then 25 | echo "Please check-in the following files:" 26 | echo "$newfiles" 27 | exit 1 28 | fi 29 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Mark stale issues and pull requests 2 | 3 | on: 4 | schedule: 5 | - cron: "0 12 * * 0" 6 | 7 | jobs: 8 | stale: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Stale PRs and issues policy 12 | uses: actions/stale@v4 13 | with: 14 | repo-token: ${{ secrets.GITHUB_TOKEN }} 15 | # General settings. 16 | ascending: true 17 | remove-stale-when-updated: true 18 | # Pull Requests settings. 19 | # 120+30 day stale policy for PRs 20 | # * Except PRs marked as "no stale" 21 | days-before-pr-stale: 120 22 | days-before-pr-close: 30 23 | exempt-pr-labels: "no stale" 24 | stale-pr-label: "stale" 25 | stale-pr-message: > 26 | There hasn't been any activity on this pull request in the past 4 months, so it has been marked as 27 | stale and it will be closed automatically if no further activity occurs in the next 30 days. 28 | 29 | If you want this PR to never become stale, please ask a PSC member to apply the "no stale" label. 30 | # Issues settings. 31 | # 180+30 day stale policy for open issues 32 | # * Except Issues marked as "no stale" 33 | days-before-issue-stale: 180 34 | days-before-issue-close: 30 35 | exempt-issue-labels: "no stale,needs more information" 36 | stale-issue-label: "stale" 37 | stale-issue-message: > 38 | There hasn't been any activity on this issue in the past 6 months, so it has been marked as stale 39 | and it will be closed automatically if no further activity occurs in the next 30 days. 40 | 41 | If you want this issue to never become stale, please ask a PSC member to apply the "no stale" 42 | label. 43 | 44 | # 15+30 day stale policy for issues pending more information 45 | # * Issues that are pending more information 46 | # * Except Issues marked as "no stale" 47 | - name: Needs more information stale issues policy 48 | uses: actions/stale@v4 49 | with: 50 | repo-token: ${{ secrets.GITHUB_TOKEN }} 51 | ascending: true 52 | only-labels: "needs more information" 53 | exempt-issue-labels: "no stale" 54 | days-before-stale: 15 55 | days-before-close: 30 56 | days-before-pr-stale: -1 57 | days-before-pr-close: -1 58 | remove-stale-when-updated: true 59 | stale-issue-label: "stale" 60 | stale-issue-message: > 61 | This issue needs more information and there hasn't been any activity recently, so it has been 62 | marked as stale and it will be closed automatically if no further activity occurs in the next 30 63 | days. 64 | 65 | If you think this is a mistake, please ask a PSC member to remove the "needs more information" 66 | label. 67 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - "15.0*" 7 | push: 8 | branches: 9 | - "15.0" 10 | - "rc/15.0*" 11 | - "15.0-ocabot-*" 12 | env: 13 | OCA_GIT_USER_NAME: openspp 14 | OCA_GIT_USER_EMAIL: bot@openspp.org 15 | jobs: 16 | unreleased-deps: 17 | runs-on: ubuntu-latest 18 | name: Detect unreleased dependencies 19 | steps: 20 | - uses: actions/checkout@v2 21 | - run: | 22 | for reqfile in requirements.txt test-requirements.txt ; do 23 | if [ -f ${reqfile} ] ; then 24 | result=0 25 | # reject non-comment lines that contain a / (i.e. URLs, relative paths) 26 | grep "^[^#].*/" ${reqfile} || result=$? 27 | if [ $result -eq 0 ] ; then 28 | echo "Unreleased dependencies found in ${reqfile}." 29 | # exit 1 30 | fi 31 | fi 32 | done 33 | test: 34 | runs-on: ubuntu-22.04 35 | container: ${{ matrix.container }} 36 | name: ${{ matrix.name }} 37 | strategy: 38 | fail-fast: false 39 | matrix: 40 | include: 41 | - container: ghcr.io/oca/oca-ci/py3.8-odoo15.0:latest 42 | makepot: "true" 43 | name: test with Odoo 44 | - container: ghcr.io/oca/oca-ci/py3.8-ocb15.0:latest 45 | name: test with OCB 46 | services: 47 | postgres: 48 | image: postgres:9.6 49 | env: 50 | POSTGRES_USER: odoo 51 | POSTGRES_PASSWORD: odoo 52 | POSTGRES_DB: odoo 53 | ports: 54 | - 5432:5432 55 | steps: 56 | - uses: actions/checkout@v2 57 | with: 58 | persist-credentials: false 59 | - name: Install addons and dependencies 60 | run: oca_install_addons 61 | - name: Check licenses 62 | run: manifestoo -d . check-licenses 63 | continue-on-error: true 64 | - name: Check development status 65 | run: manifestoo -d . check-dev-status --default-dev-status=Beta 66 | continue-on-error: true 67 | - name: Initialize test db 68 | run: oca_init_test_database 69 | - name: Run tests 70 | run: oca_run_tests 71 | - uses: codecov/codecov-action@v1 72 | - name: Update .pot files 73 | run: oca_export_and_push_pot https://x-access-token:${{ secrets.GIT_PUSH_TOKEN }}@github.com/${{ github.repository }} 74 | if: ${{ matrix.makepot == 'true' && github.event_name == 'push' && github.repository_owner == 'openspp' }} 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | /.venv 5 | /.pytest_cache 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | env/ 13 | bin/ 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | eggs/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | *.eggs 26 | 27 | # Installer logs 28 | pip-log.txt 29 | pip-delete-this-directory.txt 30 | 31 | # Unit test / coverage reports 32 | htmlcov/ 33 | .tox/ 34 | .coverage 35 | .cache 36 | nosetests.xml 37 | coverage.xml 38 | 39 | # Translations 40 | *.mo 41 | 42 | # Pycharm 43 | .idea 44 | 45 | # Eclipse 46 | .settings 47 | 48 | # Visual Studio cache/options directory 49 | .vs/ 50 | .vscode 51 | 52 | # OSX Files 53 | .DS_Store 54 | 55 | # Django stuff: 56 | *.log 57 | 58 | # Mr Developer 59 | .mr.developer.cfg 60 | .project 61 | .pydevproject 62 | 63 | # Rope 64 | .ropeproject 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # Backup files 70 | *~ 71 | *.swp 72 | 73 | # OCA rules 74 | !static/lib/ 75 | -------------------------------------------------------------------------------- /.isort.cfg: -------------------------------------------------------------------------------- 1 | [settings] 2 | ; see https://github.com/psf/black 3 | multi_line_output=3 4 | include_trailing_comma=True 5 | force_grid_wrap=0 6 | combine_as_imports=True 7 | use_parentheses=True 8 | line_length=110 9 | known_odoo=odoo 10 | known_odoo_addons=odoo.addons 11 | sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER 12 | default_section=THIRDPARTY 13 | ensure_newline_before_comments = True 14 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | exclude: | 2 | (?x) 3 | # NOT INSTALLABLE ADDONS 4 | # END NOT INSTALLABLE ADDONS 5 | # Files and folders generated by bots, to avoid loops 6 | ^setup/|/static/description/index\.html$| 7 | # We don't want to mess with tool-generated files 8 | .svg$|/tests/([^/]+/)?cassettes/|^.copier-answers.yml$|^.github/| 9 | # Maybe reactivate this when all README files include prettier ignore tags? 10 | ^README\.md$| 11 | # Library files can have extraneous formatting (even minimized) 12 | /static/(src/)?lib/| 13 | # Repos using Sphinx to generate docs don't need prettying 14 | ^docs/_templates/.*\.html$| 15 | # You don't usually want a bot to modify your legal texts 16 | (LICENSE.*|COPYING.*) 17 | default_language_version: 18 | python: python3 19 | node: "14.18.0" 20 | repos: 21 | - repo: local 22 | hooks: 23 | # These files are most likely copier diff rejection junks; if found, 24 | # review them manually, fix the problem (if needed) and remove them 25 | - id: forbidden-files 26 | name: forbidden files 27 | entry: found forbidden files; remove them 28 | language: fail 29 | files: "\\.rej$" 30 | - id: en-po-files 31 | name: en.po files cannot exist 32 | entry: found a en.po file 33 | language: fail 34 | files: '[a-zA-Z0-9_]*/i18n/en\.po$' 35 | - repo: https://github.com/oca/maintainer-tools 36 | rev: dfba427ba03900b69e0a7f2c65890dc48921d36a 37 | hooks: 38 | # update the NOT INSTALLABLE ADDONS section above 39 | - id: oca-update-pre-commit-excluded-addons 40 | - id: oca-fix-manifest-website 41 | args: ["https://github.com/openspp/openspp-demo"] 42 | - id: oca-gen-addon-readme 43 | args: 44 | - --addons-dir=. 45 | - --org-name=openspp 46 | - --repo-name=openspp-demo 47 | - --branch=15.0 48 | stages: [manual] 49 | - id: oca-gen-addons-table 50 | stages: [manual] 51 | - id: oca-gen-addon-icon 52 | args: 53 | - --addons-dir=. 54 | stages: [manual] 55 | - repo: https://github.com/myint/autoflake 56 | rev: v1.4 57 | hooks: 58 | - id: autoflake 59 | args: 60 | - --expand-star-imports 61 | - --ignore-init-module-imports 62 | - --in-place 63 | - --remove-all-unused-imports 64 | - --remove-duplicate-keys 65 | - --remove-unused-variables 66 | - repo: https://github.com/psf/black 67 | rev: 22.3.0 68 | hooks: 69 | - id: black 70 | - repo: https://github.com/pre-commit/mirrors-prettier 71 | rev: v2.4.1 72 | hooks: 73 | - id: prettier 74 | name: prettier (with plugin-xml) 75 | additional_dependencies: 76 | - "prettier@2.4.1" 77 | - "@prettier/plugin-xml@1.1.0" 78 | args: 79 | - --plugin=@prettier/plugin-xml 80 | files: \.(css|htm|html|js|json|jsx|less|md|scss|toml|ts|xml|yaml|yml)$ 81 | - repo: https://github.com/pre-commit/mirrors-eslint 82 | rev: v7.32.0 83 | hooks: 84 | - id: eslint 85 | verbose: true 86 | args: 87 | - --color 88 | - --fix 89 | - repo: https://github.com/pre-commit/pre-commit-hooks 90 | rev: v4.0.1 91 | hooks: 92 | - id: trailing-whitespace 93 | # exclude autogenerated files 94 | exclude: /README\.rst$|\.pot?$ 95 | - id: end-of-file-fixer 96 | # exclude autogenerated files 97 | exclude: /README\.rst$|\.pot?$ 98 | - id: debug-statements 99 | - id: fix-encoding-pragma 100 | args: ["--remove"] 101 | - id: check-case-conflict 102 | - id: check-docstring-first 103 | - id: check-executables-have-shebangs 104 | - id: check-merge-conflict 105 | # exclude files where underlines are not distinguishable from merge conflicts 106 | exclude: /README\.rst$|^docs/.*\.rst$ 107 | - id: check-symlinks 108 | - id: check-xml 109 | - id: mixed-line-ending 110 | args: ["--fix=lf"] 111 | - repo: https://github.com/asottile/pyupgrade 112 | rev: v2.29.0 113 | hooks: 114 | - id: pyupgrade 115 | args: ["--keep-percent-format"] 116 | - repo: https://github.com/PyCQA/isort 117 | rev: 5.12.0 118 | hooks: 119 | - id: isort 120 | name: isort except __init__.py 121 | args: 122 | - --settings=. 123 | exclude: /__init__\.py$ 124 | - repo: https://github.com/acsone/setuptools-odoo 125 | rev: 3.1.8 126 | hooks: 127 | - id: setuptools-odoo-make-default 128 | - id: setuptools-odoo-get-requirements 129 | args: 130 | - --output 131 | - requirements.txt 132 | - --header 133 | - "# generated from manifests external_dependencies" 134 | - repo: https://github.com/PyCQA/flake8 135 | rev: 3.9.2 136 | hooks: 137 | - id: flake8 138 | name: flake8 139 | additional_dependencies: ["flake8-bugbear==21.9.2"] 140 | - repo: https://github.com/OCA/pylint-odoo 141 | rev: 7.0.2 142 | hooks: 143 | - id: pylint_odoo 144 | name: pylint with optional checks 145 | args: 146 | - --rcfile=.pylintrc 147 | - --exit-zero 148 | verbose: true 149 | - id: pylint_odoo 150 | args: 151 | - --rcfile=.pylintrc-mandatory 152 | # - repo: https://github.com/Lucas-C/pre-commit-hooks 153 | # rev: v1.3.1 154 | # hooks: 155 | # - id: forbid-crlf 156 | # - id: remove-crlf 157 | # - id: insert-license 158 | # files: \.py$ 159 | # args: 160 | # - --license-filepath 161 | # - license_header.txt 162 | # - repo: https://github.com/Lucas-C/pre-commit-hooks-safety 163 | # rev: v1.3.0 164 | # hooks: 165 | # - id: python-safety-dependencies-check 166 | # files: requirements.txt 167 | -------------------------------------------------------------------------------- /.prettierrc.yml: -------------------------------------------------------------------------------- 1 | # Defaults for all prettier-supported languages. 2 | # Prettier will complete this with settings from .editorconfig file. 3 | bracketSpacing: false 4 | printWidth: 110 5 | proseWrap: always 6 | semi: true 7 | trailingComma: "es5" 8 | xmlWhitespaceSensitivity: "strict" 9 | -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | [MASTER] 4 | load-plugins=pylint_odoo 5 | score=n 6 | 7 | [ODOOLINT] 8 | readme_template_url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst" 9 | manifest_required_authors=OpenSPP.org 10 | manifest_required_keys=license 11 | manifest_deprecated_keys=description,active 12 | license_allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3 13 | valid_odoo_versions=15.0 14 | 15 | [MESSAGES CONTROL] 16 | disable=all 17 | 18 | # This .pylintrc contains optional AND mandatory checks and is meant to be 19 | # loaded in an IDE to have it check everything, in the hope this will make 20 | # optional checks more visible to contributors who otherwise never look at a 21 | # green travis to see optional checks that failed. 22 | # .pylintrc-mandatory containing only mandatory checks is used the pre-commit 23 | # config as a blocking check. 24 | 25 | enable=anomalous-backslash-in-string, 26 | api-one-deprecated, 27 | api-one-multi-together, 28 | assignment-from-none, 29 | attribute-deprecated, 30 | class-camelcase, 31 | dangerous-default-value, 32 | dangerous-view-replace-wo-priority, 33 | development-status-allowed, 34 | duplicate-id-csv, 35 | duplicate-key, 36 | duplicate-xml-fields, 37 | duplicate-xml-record-id, 38 | eval-referenced, 39 | eval-used, 40 | incoherent-interpreter-exec-perm, 41 | license-allowed, 42 | manifest-author-string, 43 | manifest-deprecated-key, 44 | manifest-required-author, 45 | manifest-required-key, 46 | manifest-version-format, 47 | method-compute, 48 | method-inverse, 49 | method-required-super, 50 | method-search, 51 | openerp-exception-warning, 52 | pointless-statement, 53 | pointless-string-statement, 54 | print-used, 55 | redundant-keyword-arg, 56 | redundant-modulename-xml, 57 | reimported, 58 | relative-import, 59 | return-in-init, 60 | rst-syntax-error, 61 | sql-injection, 62 | too-few-format-args, 63 | translation-field, 64 | translation-required, 65 | unreachable, 66 | use-vim-comment, 67 | wrong-tabs-instead-of-spaces, 68 | xml-syntax-error, 69 | attribute-string-redundant, 70 | character-not-valid-in-resource-link, 71 | consider-merging-classes-inherited, 72 | context-overridden, 73 | create-user-wo-reset-password, 74 | dangerous-filter-wo-user, 75 | dangerous-qweb-replace-wo-priority, 76 | deprecated-data-xml-node, 77 | deprecated-openerp-xml-node, 78 | duplicate-po-message-definition, 79 | except-pass, 80 | file-not-used, 81 | invalid-commit, 82 | manifest-maintainers-list, 83 | missing-newline-extrafiles, 84 | missing-readme, 85 | missing-return, 86 | odoo-addons-relative-import, 87 | old-api7-method-defined, 88 | po-msgstr-variables, 89 | po-syntax-error, 90 | renamed-field-parameter, 91 | resource-not-exist, 92 | str-format-used, 93 | test-folder-imported, 94 | translation-contains-variable, 95 | translation-positional-used, 96 | unnecessary-utf8-coding-comment, 97 | website-manifest-key-not-valid-uri, 98 | xml-attribute-translatable, 99 | xml-deprecated-qweb-directive, 100 | xml-deprecated-tree-attribute, 101 | # messages that do not cause the lint step to fail 102 | consider-merging-classes-inherited, 103 | create-user-wo-reset-password, 104 | dangerous-filter-wo-user, 105 | deprecated-module, 106 | file-not-used, 107 | invalid-commit, 108 | missing-manifest-dependency, 109 | missing-newline-extrafiles, 110 | missing-readme, 111 | no-utf8-coding-comment, 112 | odoo-addons-relative-import, 113 | old-api7-method-defined, 114 | redefined-builtin, 115 | too-complex, 116 | unnecessary-utf8-coding-comment 117 | 118 | 119 | [REPORTS] 120 | msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg} 121 | output-format=colorized 122 | reports=no 123 | -------------------------------------------------------------------------------- /.pylintrc-mandatory: -------------------------------------------------------------------------------- 1 | 2 | [MASTER] 3 | load-plugins=pylint_odoo 4 | score=n 5 | 6 | [ODOOLINT] 7 | readme_template_url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst" 8 | manifest_required_authors=OpenSPP.org 9 | manifest_required_keys=license 10 | manifest_deprecated_keys=description,active 11 | license_allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3 12 | valid_odoo_versions=15.0 13 | 14 | [MESSAGES CONTROL] 15 | disable=all 16 | 17 | enable=anomalous-backslash-in-string, 18 | api-one-deprecated, 19 | api-one-multi-together, 20 | assignment-from-none, 21 | attribute-deprecated, 22 | class-camelcase, 23 | dangerous-default-value, 24 | dangerous-view-replace-wo-priority, 25 | development-status-allowed, 26 | duplicate-id-csv, 27 | duplicate-key, 28 | duplicate-xml-fields, 29 | duplicate-xml-record-id, 30 | eval-referenced, 31 | eval-used, 32 | incoherent-interpreter-exec-perm, 33 | license-allowed, 34 | manifest-author-string, 35 | manifest-deprecated-key, 36 | manifest-required-author, 37 | manifest-required-key, 38 | manifest-version-format, 39 | method-compute, 40 | method-inverse, 41 | method-required-super, 42 | method-search, 43 | openerp-exception-warning, 44 | pointless-statement, 45 | pointless-string-statement, 46 | print-used, 47 | redundant-keyword-arg, 48 | redundant-modulename-xml, 49 | reimported, 50 | relative-import, 51 | return-in-init, 52 | rst-syntax-error, 53 | sql-injection, 54 | too-few-format-args, 55 | translation-field, 56 | translation-required, 57 | unreachable, 58 | use-vim-comment, 59 | wrong-tabs-instead-of-spaces, 60 | xml-syntax-error, 61 | attribute-string-redundant, 62 | character-not-valid-in-resource-link, 63 | consider-merging-classes-inherited, 64 | context-overridden, 65 | create-user-wo-reset-password, 66 | dangerous-filter-wo-user, 67 | dangerous-qweb-replace-wo-priority, 68 | deprecated-data-xml-node, 69 | deprecated-openerp-xml-node, 70 | duplicate-po-message-definition, 71 | except-pass, 72 | file-not-used, 73 | invalid-commit, 74 | manifest-maintainers-list, 75 | missing-newline-extrafiles, 76 | missing-readme, 77 | missing-return, 78 | odoo-addons-relative-import, 79 | old-api7-method-defined, 80 | po-msgstr-variables, 81 | po-syntax-error, 82 | renamed-field-parameter, 83 | resource-not-exist, 84 | str-format-used, 85 | test-folder-imported, 86 | translation-contains-variable, 87 | translation-positional-used, 88 | unnecessary-utf8-coding-comment, 89 | website-manifest-key-not-valid-uri, 90 | xml-attribute-translatable, 91 | xml-deprecated-qweb-directive, 92 | xml-deprecated-tree-attribute 93 | 94 | [REPORTS] 95 | msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg} 96 | output-format=colorized 97 | reports=no 98 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | 2 | Most of the files are 3 | 4 | Copyright (c) 2022 OpenSPP.org 5 | 6 | Many files also contain contributions from third 7 | parties. In this case the original copyright of 8 | the contributions can be traced through the 9 | history of the source version control system. 10 | 11 | When that is not the case, the files contain a prominent 12 | notice stating the original copyright and applicable 13 | license, or come with their own dedicated COPYRIGHT 14 | and/or LICENSE file. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [![Pre-commit Status](https://github.com/openspp/openspp-demo/actions/workflows/pre-commit.yml/badge.svg?branch=15.0)](https://github.com/openspp/openspp-demo/actions/workflows/pre-commit.yml?query=branch%3A15.0) 4 | [![Build Status](https://github.com/openspp/openspp-demo/actions/workflows/test.yml/badge.svg?branch=15.0)](https://github.com/openspp/openspp-demo/actions/workflows/test.yml?query=branch%3A15.0) 5 | [![codecov](https://codecov.io/gh/openspp/openspp-demo/branch/15.0/graph/badge.svg)](https://codecov.io/gh/openspp/openspp-demo) 6 | 7 | [![Translation Status](https://translate.openspp.org/widgets/openspp/-/svg-badge.svg)](https://translate.openspp.org/engage/openspp/?utm_source=widget) 8 | 9 | 10 | 11 | # OpenSPP Demo 12 | 13 | OpenSPP Demo Repo 14 | 15 | 16 | 17 | 18 | 19 | [//]: # (addons) 20 | 21 | Available addons 22 | ---------------- 23 | addon | version | maintainers | summary 24 | --- | --- | --- | --- 25 | [g2p_connect_demo](g2p_connect_demo/) | 15.0.0.0.0 | [![jeremi](https://github.com/jeremi.png?size=30px)](https://github.com/jeremi) [![gonzalesedwin1123](https://github.com/gonzalesedwin1123.png?size=30px)](https://github.com/gonzalesedwin1123) | G2P Connect Demo 26 | [spp_base_demo](spp_base_demo/) | 15.0.0.0.0 | [![jeremi](https://github.com/jeremi.png?size=30px)](https://github.com/jeremi) [![gonzalesedwin1123](https://github.com/gonzalesedwin1123.png?size=30px)](https://github.com/gonzalesedwin1123) | OpenSPP Base Demo 27 | [spp_change_request_add_children_demo](spp_change_request_add_children_demo/) | 15.0.0.0.0 | [![jeremi](https://github.com/jeremi.png?size=30px)](https://github.com/jeremi) [![gonzalesedwin1123](https://github.com/gonzalesedwin1123.png?size=30px)](https://github.com/gonzalesedwin1123) | CR Demo: Add Child/Member 28 | [spp_custom_filter_ui](spp_custom_filter_ui/) | 15.0.0.0.0 | [![nhatnm0612](https://github.com/nhatnm0612.png?size=30px)](https://github.com/nhatnm0612) | Base config for SPP Custom Filter to only display useful fields 29 | [spp_demo](spp_demo/) | 15.0.0.0.0 | [![jeremi](https://github.com/jeremi.png?size=30px)](https://github.com/jeremi) [![gonzalesedwin1123](https://github.com/gonzalesedwin1123.png?size=30px)](https://github.com/gonzalesedwin1123) | OpenSPP Demo 30 | [spp_event_demo](spp_event_demo/) | 15.0.0.0.0 | [![jeremi](https://github.com/jeremi.png?size=30px)](https://github.com/jeremi) [![gonzalesedwin1123](https://github.com/gonzalesedwin1123.png?size=30px)](https://github.com/gonzalesedwin1123) [![emjay0921](https://github.com/emjay0921.png?size=30px)](https://github.com/emjay0921) | Event Data Demo 31 | [//]: # (end addons) 32 | 33 | 34 | 35 | ## Licenses 36 | 37 | This repository is licensed under [LGPL-3.0](LICENSE). 38 | 39 | However, each module can have a totally different license, as long as they adhere to OpenSPP.org 40 | policy. Consult each module's `__manifest__.py` file, which contains a `license` key 41 | that explains its license. 42 | 43 | ---- 44 | 45 | -------------------------------------------------------------------------------- /g2p_connect_demo/README.rst: -------------------------------------------------------------------------------- 1 | ================ 2 | G2P Connect Demo 3 | ================ 4 | 5 | .. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 6 | !! This file is generated by oca-gen-addon-readme !! 7 | !! changes will be overwritten. !! 8 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 9 | 10 | .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png 11 | :target: https://odoo-community.org/page/development-status 12 | :alt: Alpha 13 | .. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png 14 | :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html 15 | :alt: License: LGPL-3 16 | .. |badge3| image:: https://img.shields.io/badge/github-openspp%2Fopenspp--demo-lightgray.png?logo=github 17 | :target: https://github.com/openspp/openspp-demo/tree/15.0/g2p_connect_demo 18 | :alt: openspp/openspp-demo 19 | 20 | |badge1| |badge2| |badge3| 21 | 22 | OpenG2P Connect Demo 23 | 24 | .. IMPORTANT:: 25 | This is an alpha version, the data model and design can change at any time without warning. 26 | Only for development or testing purpose, do not use in production. 27 | `More details on development status `_ 28 | 29 | **Table of contents** 30 | 31 | .. contents:: 32 | :local: 33 | 34 | Bug Tracker 35 | =========== 36 | 37 | Bugs are tracked on `GitHub Issues `_. 38 | In case of trouble, please check there if your issue has already been reported. 39 | If you spotted it first, help us smashing it by providing a detailed and welcomed 40 | `feedback `_. 41 | 42 | Do not contact contributors directly about support or help with technical issues. 43 | 44 | Credits 45 | ======= 46 | 47 | Authors 48 | ~~~~~~~ 49 | 50 | * OpenSPP.org 51 | 52 | Maintainers 53 | ~~~~~~~~~~~ 54 | 55 | .. |maintainer-jeremi| image:: https://github.com/jeremi.png?size=40px 56 | :target: https://github.com/jeremi 57 | :alt: jeremi 58 | .. |maintainer-gonzalesedwin1123| image:: https://github.com/gonzalesedwin1123.png?size=40px 59 | :target: https://github.com/gonzalesedwin1123 60 | :alt: gonzalesedwin1123 61 | 62 | Current maintainers: 63 | 64 | |maintainer-jeremi| |maintainer-gonzalesedwin1123| 65 | 66 | This module is part of the `openspp/openspp-demo `_ project on GitHub. 67 | 68 | You are welcome to contribute. 69 | -------------------------------------------------------------------------------- /g2p_connect_demo/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of OpenG2P. See LICENSE file for full copyright and licensing details. 2 | 3 | from . import models 4 | -------------------------------------------------------------------------------- /g2p_connect_demo/__manifest__.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | { 3 | "name": "G2P Connect Demo", 4 | "category": "OpenSPP", 5 | "version": "15.0.0.0.0", 6 | "sequence": 1, 7 | "author": "OpenSPP.org", 8 | "website": "https://github.com/openspp/openspp-demo", 9 | "license": "LGPL-3", 10 | "development_status": "Alpha", 11 | "maintainers": ["jeremi", "gonzalesedwin1123"], 12 | "depends": [ 13 | "spp_base_demo", 14 | "g2p_registry_base", 15 | "g2p_registry_individual", 16 | "g2p_registry_group", 17 | "g2p_registry_membership", 18 | "g2p_programs", 19 | "g2p_bank", 20 | "spp_custom_field", 21 | # "spp_custom_fields_ui", 22 | "g2p_entitlement_cash", 23 | # "spp_dashboard", 24 | "spp_idpass", 25 | "spp_idqueue", 26 | # "spp_helpdesk", 27 | "spp_area", 28 | "spp_change_request", 29 | "spp_event_data", 30 | "spp_service_points", 31 | "theme_openspp", 32 | # "spp_pos", 33 | # "spp_sms", 34 | "queue_job", 35 | "spp_change_request_add_children_demo", 36 | ], 37 | "external_dependencies": {"python": ["faker"]}, 38 | "data": [ 39 | "security/ir.model.access.csv", 40 | "data/users_data.xml", 41 | "data/sample_data.xml", 42 | "views/generate_data_view.xml", 43 | "views/generate_change_request_data_view.xml", 44 | "views/groups_view.xml", 45 | "views/individuals_view.xml", 46 | ], 47 | "assets": {}, 48 | "demo": [], 49 | "images": [], 50 | "application": True, 51 | "installable": True, 52 | "auto_install": False, 53 | } 54 | -------------------------------------------------------------------------------- /g2p_connect_demo/data/sample_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Branch 5 | 6 | 7 | 8 | Branch 9 | 10 | 11 | 12 | 13 | 201 14 | Demo Area 1 15 | 16 | 17 | 18 | 202 19 | Demo Area 2 20 | 21 | 22 | 23 | 24 | 25 | 1 26 | Demo Branch 1 27 | 28 | 29 | 30 | 2 31 | Demo Branch 2 32 | 33 | 34 | 35 | 36 | 37 | 101 38 | Demo Center 1 39 | 40 | 41 | 42 | 43 | 102 44 | Demo Center 2 45 | 46 | 47 | 48 | 49 | 50 | 201 51 | Demo Center 201 52 | 53 | 54 | 55 | 56 | 202 57 | Demo Center 202 58 | 59 | 60 | 61 | 62 | 63 | Agent 1 64 | 65 | 66 | 67 | Agent 2 68 | 69 | 70 | 71 | Agent 3 72 | 73 | 74 | 75 | Agent 4 76 | 77 | 78 | 79 | Agent 5 80 | 81 | 82 | 83 | Agent 6 84 | 85 | 86 | 87 | Agent 7 88 | 89 | 90 | 91 | Agent 8 92 | 93 | 94 | 95 | Agent 9 96 | 97 | 98 | 99 | Agent 10 100 | 101 | 102 | 103 | Agent 11 104 | 105 | 106 | 107 | Agent 12 108 | 109 | 110 | 111 | Agent 13 112 | 113 | 114 | 115 | Agent 14 116 | 117 | 118 | 119 | Agent 15 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /g2p_connect_demo/data/users_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CR Creator 7 | cr_creator 8 | atMnSaWYymYD 9 | cr_creator@yourorg.example.com 10 | inbox 11 | 15 | 16 | 17 | CR Validator 18 | cr_validator 19 | atMnSaWYymYD 20 | cr_validator@yourorg.example.com 21 | inbox 22 | 26 | 27 | 28 | CR Validator HQ 29 | cr_validator_hq 30 | atMnSaWYymYD 31 | cr_validator_hq@yourorg.example.com 32 | inbox 33 | 37 | 38 | 39 | CR Administrator 40 | cr_administrator 41 | atMnSaWYymYD 42 | cr_administrator@yourorg.example.com 43 | inbox 44 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /g2p_connect_demo/models/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of OpenG2P. See LICENSE file for full copyright and licensing details. 2 | 3 | from . import registrant 4 | from . import generate_group 5 | from . import generate_change_request 6 | from . import individual 7 | from . import group 8 | -------------------------------------------------------------------------------- /g2p_connect_demo/models/generate_change_request.py: -------------------------------------------------------------------------------- 1 | # Part of OpenG2P. See LICENSE file for full copyright and licensing details. 2 | import datetime 3 | import logging 4 | import math 5 | import random 6 | 7 | from dateutil.relativedelta import relativedelta 8 | from faker import Faker 9 | 10 | from odoo import _, api, fields, models 11 | from odoo.exceptions import UserError 12 | 13 | from odoo.addons.queue_job.delay import group 14 | 15 | _logger = logging.getLogger(__name__) 16 | 17 | 18 | class OpenG2PGenerateChangeRequestData(models.Model): 19 | _name = "g2p.generate.change.request.data" 20 | 21 | name = fields.Char() 22 | num_crs = fields.Integer("Number of CRs", default=1) 23 | state = fields.Selection( 24 | selection=[ 25 | ("draft", "Draft"), 26 | ("generate", "Generated"), 27 | ], 28 | default="draft", 29 | ) 30 | 31 | def generate_sample_data(self): 32 | # Get 50 registrants to be selected randomly in the CR registrant_id 33 | registrants = self.env["res.partner"].search( 34 | [ 35 | ("is_registrant", "=", True), 36 | ("is_group", "=", True), 37 | ("group_membership_ids", "!=", False), 38 | ], 39 | limit=50, 40 | ) 41 | if registrants: 42 | registrant_ids = registrants.mapped("id") 43 | else: 44 | raise UserError( 45 | _( 46 | "There are no registrants that can be used for generating change requests." 47 | ) 48 | ) 49 | # Get all membership kinds 50 | membership_kinds = self.env["g2p.group.membership.kind"].search([]) 51 | if membership_kinds: 52 | membership_kinds.mapped("id") 53 | else: 54 | raise UserError(_("There are no membership kinds defined.")) 55 | 56 | batches = math.ceil(self.num_crs / 1000) 57 | jobs = [] 58 | for _i in range(0, batches): 59 | jobs.append( 60 | self.delayable()._generate_sample_data( 61 | res_id=self.id, 62 | registrant_ids=registrant_ids, 63 | membership_kinds=membership_kinds, 64 | ) 65 | ) 66 | main_job = group(*jobs) 67 | main_job.on_done(self.delayable().mark_as_done()) 68 | main_job.delay() 69 | 70 | @api.model 71 | def _generate_sample_data(self, **kwargs): 72 | """ 73 | Generate sample data for testing 74 | Returns: 75 | """ 76 | res_id = kwargs.get("res_id") 77 | res = self.browse(res_id) 78 | 79 | registrants = kwargs.get("registrant_ids") 80 | membership_kinds = kwargs.get("membership_kinds") 81 | num_crs = min(res.num_crs, 1000) 82 | 83 | cr_sample_data = [] 84 | for i in range(0, num_crs): 85 | # Prepare spp.change.request fields data 86 | request_type = "spp.change.request.add.children" 87 | registrant_id = random.choice(registrants) 88 | 89 | # Get applicants based on registrant_id 90 | registrant = self.env["res.partner"].search([("id", "=", registrant_id)])[0] 91 | if registrant.lang: 92 | lang = registrant.lang 93 | else: 94 | lang = registrant.company_id.partner_id.lang 95 | fake = Faker(lang) 96 | _logger.debug("Registrant Name: %s" % registrant.name) 97 | _logger.debug("Registrant Language: %s" % lang) 98 | applicant_ids = registrant.group_membership_ids.mapped("individual.id") 99 | applicant_id = random.choice(applicant_ids) 100 | 101 | # TODO: Fix error in phone number format 102 | applicant = self.env["res.partner"].search([("id", "=", applicant_id)]) 103 | if applicant.phone: 104 | applicant_phone = applicant.phone 105 | else: 106 | applicant_phone = fake.phone_number() 107 | 108 | cr_vals = { 109 | "request_type": request_type, 110 | "registrant_id": registrant_id, 111 | "applicant_id": applicant_id, 112 | "applicant_phone": applicant_phone, 113 | } 114 | _logger.debug("Processing #%s Data: %s" % (i, cr_vals)) 115 | cr_sample_data.append(cr_vals) 116 | 117 | _logger.debug( 118 | "Sample CR Data: Total: %s \nData: %s" 119 | % (len(cr_sample_data), cr_sample_data) 120 | ) 121 | 122 | generated_crs = self.env["spp.change.request"].create(cr_sample_data) 123 | generated_crs.create_request_detail_demo() 124 | 125 | # Store spp.change.reques.add.children data 126 | for crd in generated_crs: 127 | family_name = fake.last_name() 128 | gender = random.choice(["Female", "Male"] * 50) 129 | given_name = ( 130 | fake.first_name_male() if gender == "Male" else fake.first_name_female() 131 | ) 132 | addl_name = fake.last_name() 133 | birth_place = fake.address() 134 | birthdate_not_exact = random.choice([True, False] * 50) 135 | date_start = datetime.datetime.now() - relativedelta(years=100) 136 | date_end = datetime.datetime.now() 137 | birthdate = fake.date_between_dates( 138 | date_start=date_start, date_end=date_end 139 | ).isoformat() 140 | # phone = fake.phone_number() 141 | uid_number = str(random.randint(100000000000, 999999999999)) 142 | kind = random.choice(membership_kinds) 143 | applicant_relation = random.choice(["father", "mother", "grandfather"] * 50) 144 | 145 | crd.request_type_ref_id.update( 146 | { 147 | "family_name": family_name, 148 | "given_name": given_name, 149 | "addl_name": addl_name, 150 | "gender": gender, 151 | "birth_place": birth_place, 152 | "birthdate_not_exact": birthdate_not_exact, 153 | "birthdate": birthdate, 154 | # "phone": phone, 155 | "uid_number": uid_number, 156 | "kind": kind, 157 | "applicant_relation": applicant_relation, 158 | } 159 | ) 160 | 161 | def mark_as_done(self): 162 | self.update({"state": "generate"}) 163 | -------------------------------------------------------------------------------- /g2p_connect_demo/models/individual.py: -------------------------------------------------------------------------------- 1 | # Part of OpenG2P. See LICENSE file for full copyright and licensing details. 2 | import logging 3 | 4 | from odoo import fields, models 5 | 6 | _logger = logging.getLogger(__name__) 7 | 8 | 9 | class G2PIndividual(models.Model): 10 | _inherit = "res.partner" 11 | 12 | # Demo 1 13 | z_cst_indv_cyclone_aug_2022_injured = fields.Boolean( 14 | "Injured during Cyclone Aug 2022" 15 | ) 16 | z_cst_indv_disability_level = fields.Integer("Disability level") # 0-100 17 | z_cst_indv_receive_government_benefits = fields.Boolean( 18 | "Receive government benefits" 19 | ) 20 | z_cst_indv_cyclone_aug_2022_lost_livestock = fields.Boolean( 21 | "Lost significant livestock during Cyclone Aug 2022" 22 | ) 23 | z_cst_indv_cyclone_aug_2022_lost_primary_source_income = fields.Boolean( 24 | "Lost primary source income during Cyclone Aug 2022" 25 | ) 26 | 27 | # Demo 2 28 | z_cst_indv_has_birth_certificate = fields.Boolean("Has birth certificate") 29 | -------------------------------------------------------------------------------- /g2p_connect_demo/models/registrant.py: -------------------------------------------------------------------------------- 1 | # Part of OpenG2P. See LICENSE file for full copyright and licensing details. 2 | from odoo import api, fields, models 3 | 4 | 5 | class G2PRegistrant(models.Model): 6 | _inherit = "res.partner" 7 | 8 | full_address = fields.Text(compute="_compute_address", string="Address") 9 | 10 | @api.depends("street", "street2", "city", "zip") 11 | def _compute_address(self): 12 | for rec in self: 13 | full_address = "" 14 | if rec.street: 15 | full_address = rec.street 16 | if rec.street2: 17 | full_address += f" {rec.street2}" 18 | if rec.city: 19 | full_address += f" {rec.city}" 20 | if rec.zip: 21 | full_address += f" {rec.zip}" 22 | rec.full_address = full_address 23 | -------------------------------------------------------------------------------- /g2p_connect_demo/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | OpenG2P Connect Demo 2 | -------------------------------------------------------------------------------- /g2p_connect_demo/security/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | g2p_generate_data_admin,Generate Data Admin Access,g2p_connect_demo.model_g2p_generate_data,g2p_registry_base.group_g2p_admin,1,1,1,1 3 | g2p_generate_change_request_data_admin,Generate Change Request Data Admin Access,g2p_connect_demo.model_g2p_generate_change_request_data,g2p_registry_base.group_g2p_admin,1,1,1,1 4 | -------------------------------------------------------------------------------- /g2p_connect_demo/static/description/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenSPP/openspp-demo/0e0bac6fcf59fcf5a6a3e795082a5ccec7f1591b/g2p_connect_demo/static/description/icon.png -------------------------------------------------------------------------------- /g2p_connect_demo/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of OpenG2P Registry. See LICENSE file for full copyright and licensing details. 2 | 3 | from . import test_compute_indicator_fields 4 | -------------------------------------------------------------------------------- /g2p_connect_demo/views/generate_change_request_data_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | view_generate_change_request_data_tree 8 | g2p.generate.change.request.data 9 | 1 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | view_generate_change_request_data_form 21 | g2p.generate.change.request.data 22 | 1 23 | 24 |
25 |
26 | 27 |
28 | 29 |
30 | 42 |
43 |
44 |
53 | 54 |
55 |
56 |
57 |
58 | 59 | 60 | Generate Change Request Data 61 | ir.actions.act_window 62 | g2p.generate.change.request.data 63 | tree,form 64 | {} 65 | [] 66 | 67 |

68 | Generate Change Request Data 69 |

70 | Click the create button to enter the new record. 71 |

72 |
73 |
74 | 75 | 76 | 77 | tree 78 | 79 | 80 | 81 | 82 | 83 | 84 | form 85 | 86 | 87 | 88 | 89 | 96 | 97 |
98 | -------------------------------------------------------------------------------- /g2p_connect_demo/views/generate_data_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | view_generate_data_tree 8 | g2p.generate.data 9 | 1 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | view_generate_data_form 21 | g2p.generate.data 22 | 1 23 | 24 |
25 |
26 | 33 | 34 |
35 | 36 |
37 | 49 |
50 |
51 |
60 | 61 |
62 |
63 |
64 |
65 | 66 | 67 | Generate Data 68 | ir.actions.act_window 69 | g2p.generate.data 70 | tree,form 71 | {} 72 | [] 73 | 74 |

75 | Generate Data 76 |

77 | Click the create button to enter the new record. 78 |

79 |
80 |
81 | 82 | 83 | 84 | tree 85 | 86 | 87 | 88 | 89 | 90 | 91 | form 92 | 93 | 94 | 95 | 96 | 103 | 104 |
105 | -------------------------------------------------------------------------------- /g2p_connect_demo/views/groups_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | view_groups_list_tree_demo 8 | res.partner 9 | 10 | 11 | 12 | 1 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | view_groups_form_demo 21 | res.partner 22 | 23 | 24 | 25 | 1 26 | 27 | 28 | 29 | 35 | 36 | Address 37 | 38 |
39 | 44 | 50 | 56 | 62 | 68 |
69 |
70 |
71 |
72 |
73 | 74 |
75 | -------------------------------------------------------------------------------- /g2p_connect_demo/views/individuals_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | view_individuals_list_tree_demo 8 | res.partner 9 | 10 | 11 | 12 | 1 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | view_individuals_form_demo 21 | res.partner 22 | 23 | 24 | 25 | 1 26 | 27 | 28 | 29 | 35 | 36 | Address 37 | 38 |
39 | 44 | 50 | 56 | 62 | 68 |
69 |
70 |
71 |
72 |
73 | 74 |
75 | -------------------------------------------------------------------------------- /license_header.txt: -------------------------------------------------------------------------------- 1 | Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # generated from manifests external_dependencies 2 | faker 3 | -------------------------------------------------------------------------------- /setup/.setuptools-odoo-make-default-ignore: -------------------------------------------------------------------------------- 1 | # addons listed in this file are ignored by 2 | # setuptools-odoo-make-default (one addon per line) 3 | -------------------------------------------------------------------------------- /setup/README: -------------------------------------------------------------------------------- 1 | To learn more about this directory, please visit 2 | https://pypi.python.org/pypi/setuptools-odoo 3 | -------------------------------------------------------------------------------- /setup/_metapackage/VERSION.txt: -------------------------------------------------------------------------------- 1 | 15.0.20230209.0 -------------------------------------------------------------------------------- /setup/_metapackage/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open('VERSION.txt', 'r') as f: 4 | version = f.read().strip() 5 | 6 | setuptools.setup( 7 | name="odoo-addons-openspp-openspp-demo", 8 | description="Meta package for openspp-openspp-demo Odoo addons", 9 | version=version, 10 | install_requires=[ 11 | 'odoo-addon-g2p_connect_demo>=15.0dev,<15.1dev', 12 | 'odoo-addon-spp_base_demo>=15.0dev,<15.1dev', 13 | 'odoo-addon-spp_change_request_add_children_demo>=15.0dev,<15.1dev', 14 | 'odoo-addon-spp_custom_filter_ui>=15.0dev,<15.1dev', 15 | 'odoo-addon-spp_demo>=15.0dev,<15.1dev', 16 | 'odoo-addon-spp_event_demo>=15.0dev,<15.1dev', 17 | ], 18 | classifiers=[ 19 | 'Programming Language :: Python', 20 | 'Framework :: Odoo', 21 | 'Framework :: Odoo :: 15.0', 22 | ] 23 | ) 24 | -------------------------------------------------------------------------------- /setup/g2p_connect_demo/odoo/addons/g2p_connect_demo: -------------------------------------------------------------------------------- 1 | ../../../../g2p_connect_demo -------------------------------------------------------------------------------- /setup/g2p_connect_demo/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/spp_base_demo/odoo/addons/spp_base_demo: -------------------------------------------------------------------------------- 1 | ../../../../spp_base_demo -------------------------------------------------------------------------------- /setup/spp_base_demo/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/spp_change_request_add_children_demo/odoo/addons/spp_change_request_add_children_demo: -------------------------------------------------------------------------------- 1 | ../../../../spp_change_request_add_children_demo -------------------------------------------------------------------------------- /setup/spp_change_request_add_children_demo/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/spp_custom_filter_ui/odoo/addons/spp_custom_filter_ui: -------------------------------------------------------------------------------- 1 | ../../../../spp_custom_filter_ui -------------------------------------------------------------------------------- /setup/spp_custom_filter_ui/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/spp_demo/odoo/addons/spp_demo: -------------------------------------------------------------------------------- 1 | ../../../../spp_demo -------------------------------------------------------------------------------- /setup/spp_demo/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /setup/spp_event_demo/odoo/addons/spp_event_demo: -------------------------------------------------------------------------------- 1 | ../../../../spp_event_demo -------------------------------------------------------------------------------- /setup/spp_event_demo/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | setup_requires=['setuptools-odoo'], 5 | odoo_addon=True, 6 | ) 7 | -------------------------------------------------------------------------------- /spp_base_demo/README.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | OpenSPP Base Demo 3 | ================= 4 | 5 | .. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 6 | !! This file is generated by oca-gen-addon-readme !! 7 | !! changes will be overwritten. !! 8 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 9 | 10 | .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png 11 | :target: https://odoo-community.org/page/development-status 12 | :alt: Beta 13 | .. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png 14 | :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html 15 | :alt: License: LGPL-3 16 | .. |badge3| image:: https://img.shields.io/badge/github-openspp%2Fopenspp--demo-lightgray.png?logo=github 17 | :target: https://github.com/openspp/openspp-demo/tree/15.0/spp_base_demo 18 | :alt: openspp/openspp-demo 19 | 20 | |badge1| |badge2| |badge3| 21 | 22 | OpenSPP Base demo 23 | 24 | **Table of contents** 25 | 26 | .. contents:: 27 | :local: 28 | 29 | Bug Tracker 30 | =========== 31 | 32 | Bugs are tracked on `GitHub Issues `_. 33 | In case of trouble, please check there if your issue has already been reported. 34 | If you spotted it first, help us smashing it by providing a detailed and welcomed 35 | `feedback `_. 36 | 37 | Do not contact contributors directly about support or help with technical issues. 38 | 39 | Credits 40 | ======= 41 | 42 | Authors 43 | ~~~~~~~ 44 | 45 | * OpenSPP.org 46 | 47 | Maintainers 48 | ~~~~~~~~~~~ 49 | 50 | .. |maintainer-jeremi| image:: https://github.com/jeremi.png?size=40px 51 | :target: https://github.com/jeremi 52 | :alt: jeremi 53 | .. |maintainer-gonzalesedwin1123| image:: https://github.com/gonzalesedwin1123.png?size=40px 54 | :target: https://github.com/gonzalesedwin1123 55 | :alt: gonzalesedwin1123 56 | 57 | Current maintainers: 58 | 59 | |maintainer-jeremi| |maintainer-gonzalesedwin1123| 60 | 61 | This module is part of the `openspp/openspp-demo `_ project on GitHub. 62 | 63 | You are welcome to contribute. 64 | -------------------------------------------------------------------------------- /spp_base_demo/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | 3 | # from . import models 4 | -------------------------------------------------------------------------------- /spp_base_demo/__manifest__.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | { 3 | "name": "OpenSPP Base Demo", 4 | "category": "OpenSPP", 5 | "version": "15.0.0.0.0", 6 | "sequence": 1, 7 | "author": "OpenSPP.org", 8 | "website": "https://github.com/openspp/openspp-demo", 9 | "license": "LGPL-3", 10 | "development_status": "Beta", 11 | "maintainers": ["jeremi", "gonzalesedwin1123"], 12 | "depends": [ 13 | "g2p_registry_base", 14 | "g2p_programs", 15 | "spp_helpdesk", 16 | ], 17 | "data": [ 18 | "data/users_data.xml", 19 | ], 20 | "assets": {}, 21 | "demo": [], 22 | "images": [], 23 | "application": True, 24 | "installable": True, 25 | "auto_install": False, 26 | } 27 | -------------------------------------------------------------------------------- /spp_base_demo/data/users_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | registrar 6 | registrar 7 | demo 8 | 12 | 13 | 14 | 15 | program manager 16 | program_manager 17 | demo 18 | 22 | 23 | 24 | 25 | program validator 26 | program_validator 27 | demo 28 | 32 | 33 | 34 | 35 | finance validator 36 | finance_validator 37 | demo 38 | 42 | 43 | 44 | 45 | support person 46 | support_person 47 | demo 48 | 52 | 53 | 54 | 55 | OpenSPP Admin 56 | sppadmin 57 | demo 58 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /spp_base_demo/i18n/spp_base_demo.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # 4 | msgid "" 5 | msgstr "" 6 | "Project-Id-Version: Odoo Server 15.0\n" 7 | "Report-Msgid-Bugs-To: \n" 8 | "Last-Translator: \n" 9 | "Language-Team: \n" 10 | "MIME-Version: 1.0\n" 11 | "Content-Type: text/plain; charset=UTF-8\n" 12 | "Content-Transfer-Encoding: \n" 13 | "Plural-Forms: \n" 14 | -------------------------------------------------------------------------------- /spp_base_demo/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | OpenSPP Base demo 2 | -------------------------------------------------------------------------------- /spp_base_demo/static/description/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenSPP/openspp-demo/0e0bac6fcf59fcf5a6a3e795082a5ccec7f1591b/spp_base_demo/static/description/icon.png -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/README.rst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenSPP/openspp-demo/0e0bac6fcf59fcf5a6a3e795082a5ccec7f1591b/spp_change_request_add_children_demo/README.rst -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/__manifest__.py: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CR Demo: Add Child/Member", 3 | "category": "OpenSPP", 4 | "version": "15.0.0.0.0", 5 | "sequence": 1, 6 | "author": "OpenSPP.org", 7 | "website": "https://github.com/openspp/openspp-demo", 8 | "license": "LGPL-3", 9 | "development_status": "Alpha", 10 | "maintainers": ["jeremi", "gonzalesedwin1123"], 11 | "depends": [ 12 | "spp_change_request", 13 | "g2p_registry_base", 14 | "g2p_registry_individual", 15 | "g2p_registry_group", 16 | "g2p_registry_membership", 17 | "spp_service_points", 18 | ], 19 | "data": [ 20 | "security/change_request_security.xml", 21 | "security/ir.model.access.csv", 22 | "data/dms.xml", 23 | "data/change_request_stage.xml", 24 | "data/change_request_sequence.xml", 25 | "data/id_type.xml", 26 | "views/change_request_add_children_view.xml", 27 | ], 28 | "assets": {}, 29 | "demo": [], 30 | "images": [], 31 | "application": True, 32 | "installable": True, 33 | "auto_install": False, 34 | } 35 | -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/data/change_request_sequence.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 10 9 | 10 | spp.change.request.add.children 11 | 12 | both 13 | 14 | 15 | 16 | 20 17 | 18 | spp.change.request.add.children 19 | 20 | both 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/data/change_request_stage.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | Local 9 | 10 | 11 | 12 | HQ 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/data/dms.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Change Request: Add Children 6 | file 7 | 8 | 9 | 10 | 11 | 12 | 13 | Identification Documents 14 | 15 | 16 | Certificates 17 | 18 | 19 | Request Form Document 20 | 21 | 22 | 23 | 24 | Add Children Request Form 25 | 26 | 27 | 28 | 29 | Birth Certificate 30 | 31 | 32 | 33 | 34 | Applicant UID Card 35 | 36 | 37 | 38 | 39 | Custody Certificate 40 | 41 | 42 | 43 | 44 | UID Card 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/data/id_type.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Unified ID 6 | individual 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import group_membership 2 | from . import change_request 3 | from . import change_request_add_children 4 | from . import change_request_add_children_validation_sequence 5 | -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/models/change_request.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from odoo import Command, api, models 4 | 5 | _logger = logging.getLogger(__name__) 6 | 7 | 8 | class ChangeRequestBaseCustomDemo(models.Model): 9 | 10 | _inherit = "spp.change.request" 11 | 12 | def create_request_detail_demo(self): 13 | """ 14 | A version of spp.change.request create_request_detail function 15 | that does not check the applicant's phone number and 16 | does not load the CR details form 17 | :return: 18 | """ 19 | for rec in self: 20 | if rec.state in ("draft", "pending"): 21 | # Set the request_type_ref_id 22 | res_model = rec.request_type 23 | # Set the dms directory 24 | _logger.debug( 25 | "Change Request: DMS Directory Creation (%s)" 26 | % len(self.dms_directory_ids) 27 | ) 28 | storage = self.env.ref(self.env[res_model].DMS_STORAGE) 29 | dmsval = { 30 | "storage_id": storage.id, 31 | "res_model": res_model, 32 | "is_root_directory": True, 33 | "name": rec.name, 34 | "group_ids": [(4, storage.field_default_group_id.id)], 35 | } 36 | 37 | # Prepare CR type model data 38 | cr_type_vals = { 39 | "registrant_id": rec.registrant_id.id, 40 | "applicant_id": rec.applicant_id.id, 41 | "change_request_id": rec.id, 42 | "dms_directory_ids": [(Command.create(dmsval))], 43 | } 44 | 45 | # Create the change request detail record 46 | ref_id = self.env[res_model].create(cr_type_vals) 47 | directory_id = ref_id.dms_directory_ids[0].id 48 | 49 | self.env["dms.directory"].create( 50 | { 51 | "name": "Applicant", 52 | "parent_id": directory_id, 53 | "is_root_directory": False, 54 | } 55 | ) 56 | 57 | # Upload Scanned IDs to DMS 58 | dms_file_ids = [] 59 | for id_fld in ["id_document_details", "qr_code_details"]: 60 | if rec[id_fld]: 61 | dms_id_doc = rec._get_id_doc_vals(directory_id, id_fld) 62 | if dms_id_doc: 63 | dms_file_ids.append(Command.create(dms_id_doc)) 64 | if dms_file_ids: 65 | ref_id.update({"dms_file_ids": dms_file_ids}) 66 | 67 | ref_id._onchange_registrant_id() 68 | request_type_ref_id = f"{res_model},{ref_id.id}" 69 | _logger.debug("DEBUG! request_type_ref_id: %s", request_type_ref_id) 70 | rec.update( 71 | { 72 | "request_type_ref_id": request_type_ref_id, 73 | "id_document_details": "", 74 | } 75 | ) 76 | 77 | # Temporary solution to phone number fo 78 | # def _check_phone_exist(self): 79 | # pass 80 | 81 | @api.constrains("registrant_id", "applicant_phone") 82 | def _check_applicant_phone(self): 83 | # Temporary solution to phone number format error 84 | pass 85 | -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/models/change_request_add_children_validation_sequence.py: -------------------------------------------------------------------------------- 1 | from odoo import api, models 2 | 3 | 4 | class ChangeRequestAddChildrenValidationSequence(models.Model): 5 | _inherit = "spp.change.request.validation.sequence" 6 | 7 | @api.model 8 | def _selection_request_type_ref_id(self): 9 | selection = super()._selection_request_type_ref_id() 10 | new_request_type = ("spp.change.request.add.children", "Add Children") 11 | if new_request_type not in selection: 12 | selection.append(new_request_type) 13 | return selection 14 | -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/models/group_membership.py: -------------------------------------------------------------------------------- 1 | from odoo import fields, models 2 | 3 | 4 | class SPPGroupMembership(models.Model): 5 | _inherit = "spp.change.request.group.members" 6 | 7 | group_add_children_id = fields.Many2one("spp.change.request.add.children") 8 | -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/security/change_request_security.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CR Demo: Add Children allowed validators 6 | 10 | 11 | [] 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/security/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | spp_change_request_add_children_demo_admin,Change Request Demo Type:Add Children Admin Access,spp_change_request_add_children_demo.model_spp_change_request_add_children,g2p_registry_base.group_g2p_admin,1,1,1,1 3 | spp_change_request_add_children_demo_registrar,Change Request Demo Type:Add Children Registrar Access,spp_change_request_add_children_demo.model_spp_change_request_add_children,g2p_registry_base.group_g2p_registrar,1,0,0,0 4 | 5 | spp_change_request_add_children_demo_validator,Change Request Demo Type:Add Children Validator Access,spp_change_request_add_children_demo.model_spp_change_request_add_children,spp_change_request.group_spp_change_request_validator,1,1,0,0 6 | 7 | spp_change_request_add_children_demo_hq_validator,Change Request Demo Type:Add Children HQ Validator Access,spp_change_request_add_children_demo.model_spp_change_request_add_children,spp_change_request.group_spp_change_request_hq_validator,1,1,0,0 8 | 9 | spp_change_request_add_children_demo_administrator,Change Request Demo Type:Add Children Administrator Access,spp_change_request_add_children_demo.model_spp_change_request_add_children,spp_change_request.group_spp_change_request_administrator,1,1,0,0 10 | 11 | spp_change_request_add_children_demo_applicator,Change Request Demo Type:Add Children Applicator Access,spp_change_request_add_children_demo.model_spp_change_request_add_children,spp_change_request.group_spp_change_request_applicator,1,1,0,0 12 | 13 | spp_change_request_add_children_demo_agent,Change Request Demo Type:Add Children Agent Access,spp_change_request_add_children_demo.model_spp_change_request_add_children,spp_change_request.group_spp_change_request_agent,1,1,1,1 14 | -------------------------------------------------------------------------------- /spp_change_request_add_children_demo/static/description/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenSPP/openspp-demo/0e0bac6fcf59fcf5a6a3e795082a5ccec7f1591b/spp_change_request_add_children_demo/static/description/icon.png -------------------------------------------------------------------------------- /spp_custom_filter_ui/README.rst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenSPP/openspp-demo/0e0bac6fcf59fcf5a6a3e795082a5ccec7f1591b/spp_custom_filter_ui/README.rst -------------------------------------------------------------------------------- /spp_custom_filter_ui/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | -------------------------------------------------------------------------------- /spp_custom_filter_ui/__manifest__.py: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SPP Custom Filter Base config", 3 | "version": "15.0.0.0.0", 4 | "summary": "Base config for SPP Custom Filter to only display useful fields", 5 | "author": "OpenSPP.org", 6 | "maintainers": ["nhatnm0612"], 7 | "website": "https://github.com/openspp/openspp-demo", 8 | "license": "LGPL-3", 9 | "depends": ["spp_custom_filter"], 10 | "auto_install": False, 11 | "application": False, 12 | } 13 | -------------------------------------------------------------------------------- /spp_custom_filter_ui/models/__init__.py: -------------------------------------------------------------------------------- 1 | from . import res_partner 2 | -------------------------------------------------------------------------------- /spp_custom_filter_ui/models/res_partner.py: -------------------------------------------------------------------------------- 1 | from odoo import fields, models 2 | 3 | 4 | class ResPartner(models.Model): 5 | _name = "res.partner" 6 | _inherit = ["res.partner", "custom.filter.mixin"] 7 | 8 | active = fields.Boolean(allow_filter=True) 9 | name = fields.Char(allow_filter=True) 10 | address = fields.Text(allow_filter=True) 11 | phone = fields.Char(allow_filter=True) 12 | kind = fields.Many2one(comodel_name="g2p.group.kind", allow_filter=True) 13 | category_id = fields.Many2many( 14 | comodel_name="res.partner.category", allow_filter=True 15 | ) 16 | registration_date = fields.Date(allow_filter=True) 17 | disabled = fields.Boolean(allow_filter=True) 18 | company_id = fields.Many2one(comodel_name="res.company", allow_filter=True) 19 | is_partial_group = fields.Boolean(allow_filter=True) 20 | email = fields.Char(allow_filter=True) 21 | create_date = fields.Datetime(allow_filter=True) 22 | create_uid = fields.Many2one(comodel_name="res.users", allow_filter=True) 23 | write_date = fields.Datetime(allow_filter=True) 24 | write_uid = fields.Many2one(comodel_name="res.users", allow_filter=True) 25 | disabled_by = fields.Many2one(comodel_name="res.users", allow_filter=True) 26 | disabled_reason = fields.Text(allow_filter=True) 27 | is_registrant = fields.Boolean(allow_filter=True) 28 | is_group = fields.Boolean(allow_filter=True) 29 | addl_name = fields.Char(allow_filter=True) 30 | birth_place = fields.Char(allow_filter=True) 31 | birthdate = fields.Date(allow_filter=True) 32 | birthdate_not_exact = fields.Boolean(allow_filter=True) 33 | family_name = fields.Char(allow_filter=True) 34 | # gender = fields.Selection(allow_filter=True) 35 | given_name = fields.Char(allow_filter=True) 36 | group_membership_ids = fields.One2many(allow_filter=True) 37 | id_pdf = fields.Binary(allow_filter=True) 38 | id_pdf_filename = fields.Char(allow_filter=True) 39 | individual_membership_ids = fields.One2many(allow_filter=True) 40 | kind_as_str = fields.Char(allow_filter=True) 41 | phone_number_ids = fields.One2many(allow_filter=True) 42 | program_membership_ids = fields.One2many(allow_filter=True) 43 | reg_ids = fields.One2many(allow_filter=True) 44 | related_1_ids = fields.One2many(allow_filter=True) 45 | related_2_ids = fields.One2many(allow_filter=True) 46 | -------------------------------------------------------------------------------- /spp_demo/README.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | OpenSPP Demo 3 | ============ 4 | 5 | .. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 6 | !! This file is generated by oca-gen-addon-readme !! 7 | !! changes will be overwritten. !! 8 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 9 | 10 | .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png 11 | :target: https://odoo-community.org/page/development-status 12 | :alt: Beta 13 | .. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png 14 | :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html 15 | :alt: License: AGPL-3 16 | .. |badge3| image:: https://img.shields.io/badge/github-openspp%2Fopenspp--demo-lightgray.png?logo=github 17 | :target: https://github.com/openspp/openspp-demo/tree/15.0/spp_demo 18 | :alt: openspp/openspp-demo 19 | 20 | |badge1| |badge2| |badge3| 21 | 22 | OpenSPP Newland Demo 23 | 24 | **Table of contents** 25 | 26 | .. contents:: 27 | :local: 28 | 29 | Bug Tracker 30 | =========== 31 | 32 | Bugs are tracked on `GitHub Issues `_. 33 | In case of trouble, please check there if your issue has already been reported. 34 | If you spotted it first, help us smashing it by providing a detailed and welcomed 35 | `feedback `_. 36 | 37 | Do not contact contributors directly about support or help with technical issues. 38 | 39 | Credits 40 | ======= 41 | 42 | Authors 43 | ~~~~~~~ 44 | 45 | * OpenSPP.org 46 | 47 | Maintainers 48 | ~~~~~~~~~~~ 49 | 50 | .. |maintainer-jeremi| image:: https://github.com/jeremi.png?size=40px 51 | :target: https://github.com/jeremi 52 | :alt: jeremi 53 | .. |maintainer-gonzalesedwin1123| image:: https://github.com/gonzalesedwin1123.png?size=40px 54 | :target: https://github.com/gonzalesedwin1123 55 | :alt: gonzalesedwin1123 56 | 57 | Current maintainers: 58 | 59 | |maintainer-jeremi| |maintainer-gonzalesedwin1123| 60 | 61 | This module is part of the `openspp/openspp-demo `_ project on GitHub. 62 | 63 | You are welcome to contribute. 64 | -------------------------------------------------------------------------------- /spp_demo/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | 3 | from . import models 4 | -------------------------------------------------------------------------------- /spp_demo/__manifest__.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | { 3 | "name": "OpenSPP Demo", 4 | "category": "OpenSPP", 5 | "version": "15.0.0.0.1", 6 | "sequence": 1, 7 | "author": "OpenSPP.org", 8 | "website": "https://github.com/openspp/openspp-demo", 9 | "license": "AGPL-3", 10 | "development_status": "Beta", 11 | "maintainers": ["jeremi", "gonzalesedwin1123"], 12 | "depends": [ 13 | "spp_base_demo", 14 | "g2p_registry_base", 15 | "g2p_registry_individual", 16 | "g2p_registry_group", 17 | "g2p_registry_membership", 18 | "g2p_programs", 19 | "spp_custom_field", 20 | "spp_custom_field_recompute_daily", 21 | "spp_idpass", 22 | "spp_helpdesk", 23 | "spp_area", 24 | "theme_openspp", 25 | "spp_pos", 26 | "spp_sms", 27 | "queue_job", 28 | ], 29 | "external_dependencies": {"python": ["faker"]}, 30 | "data": [ 31 | "data/res_lang_data.xml", 32 | "security/ir.model.access.csv", 33 | "views/generate_data_view.xml", 34 | "views/generate_program_view.xml", 35 | ], 36 | "assets": {}, 37 | "demo": [], 38 | "images": [], 39 | "application": True, 40 | "installable": True, 41 | "auto_install": False, 42 | } 43 | -------------------------------------------------------------------------------- /spp_demo/data/res_lang_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /spp_demo/models/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | 3 | # from . import individual 4 | # from . import group 5 | from . import generate_group 6 | from . import generate_program 7 | from . import individual 8 | from . import group 9 | -------------------------------------------------------------------------------- /spp_demo/models/generate_group.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | import datetime 3 | import hashlib 4 | import logging 5 | import math 6 | import random 7 | 8 | from dateutil.relativedelta import relativedelta 9 | from faker import Faker 10 | 11 | from odoo import api, fields, models 12 | 13 | _logger = logging.getLogger(__name__) 14 | 15 | 16 | class G2PGenerateData(models.Model): 17 | _name = "spp.generate.data" 18 | 19 | name = fields.Char() 20 | num_groups = fields.Integer("Number of Groups", default=1) 21 | state = fields.Selection( 22 | selection=[ 23 | ("draft", "Draft"), 24 | ("generate", "Generated"), 25 | ], 26 | default="draft", 27 | ) 28 | 29 | def generate_sample_data(self): 30 | # celery = { 31 | # "countdown": 3, 32 | # "retry": True, 33 | # "retry_policy": {"max_retries": 2, "interval_start": 2}, 34 | # } 35 | batches = math.ceil(self.num_groups / 1000) 36 | for _i in range(0, batches): 37 | # self.env["celery.task"].call_task( 38 | # self._name, "_generate_sample_data", res_id=self.id, celery=celery 39 | # ) 40 | self.with_delay()._generate_sample_data(res_id=self.id) 41 | 42 | @api.model 43 | def _generate_sample_data(self, **kwargs): 44 | """ 45 | Generate sample data for testing 46 | Returns: 47 | 48 | """ 49 | res_id = kwargs.get("res_id") 50 | res = self.browse(res_id) 51 | locales = [ 52 | "cs_CZ", 53 | "en_US", 54 | "de_CH", 55 | "ar_AA", 56 | "de_DE", 57 | "en_GB", 58 | "en_IE", 59 | "en_TH", 60 | "es_ES", 61 | "es_MX", 62 | "fr_FR", 63 | "hi_IN", 64 | "hr_HR", 65 | "it_IT", 66 | "zh_CN", 67 | ] 68 | fake = Faker(locales) 69 | 70 | # Get available gender field selections 71 | sex_choices = self.env["res.partner"]._fields["gender"].selection 72 | sex_choices = [sex[0] for sex in sex_choices] 73 | sex_choice_range = sex_choices * 50 74 | 75 | age_group_range = ["A", "C"] * 2 + ["E"] 76 | group_size_range = ( 77 | list(range(1, 2)) * 2 + list(range(3, 5)) * 4 + list(range(6, 8)) 78 | ) 79 | 80 | group_membership_kind_head_id = self.env.ref( 81 | "g2p_registry_membership.group_membership_kind_head" 82 | ).id 83 | group_kind_household_id = self.env.ref( 84 | "g2p_registry_group.group_kind_household" 85 | ).id 86 | group_kind_family_id = self.env.ref("g2p_registry_group.group_kind_family").id 87 | 88 | num_groups = min(res.num_groups, 1000) 89 | for i in range(0, num_groups): 90 | locale = random.choice(locales) 91 | group_size = random.choice(group_size_range) 92 | last_name = fake[locale].last_name() 93 | 94 | registration_date = ( 95 | fake[locale] 96 | .date_between_dates( 97 | date_start=datetime.datetime.now() - relativedelta(weeks=4), 98 | date_end=datetime.datetime.now(), 99 | ) 100 | .isoformat() 101 | ) 102 | 103 | head = res._generate_individual_data( 104 | fake[locale], 105 | last_name, 106 | sex_choice_range, 107 | age_group_range, 108 | registration_date, 109 | ) 110 | 111 | head["is_head"] = True 112 | 113 | group_id = ( 114 | "demo." + hashlib.md5(f"{last_name} {i}".encode("UTF-8")).hexdigest() 115 | ) 116 | 117 | group_kind = random.choice([group_kind_household_id, group_kind_family_id]) 118 | 119 | group = { 120 | "id": group_id, 121 | "name": last_name, 122 | "is_group": True, 123 | "is_registrant": True, 124 | "registration_date": registration_date, 125 | "kind": group_kind, 126 | } 127 | 128 | create_group_id = self.env["res.partner"].create(group) 129 | 130 | head["id"] = f"{group_id}-0" 131 | members = [head] 132 | 133 | for i in range(group_size - 1): 134 | data = res._generate_individual_data( 135 | fake[locale], 136 | last_name, 137 | sex_choice_range, 138 | age_group_range, 139 | registration_date, 140 | ) 141 | 142 | data["id"] = f"{group_id}-{i+1}" 143 | members.append(data) 144 | 145 | # add this on membership 146 | if random.randint(0, 2) == 0: 147 | members[0]["is_principal_recipient"] = True 148 | else: 149 | members[random.randint(0, group_size - 1)][ 150 | "is_principal_recipient" 151 | ] = True 152 | 153 | for member in members: 154 | is_head = True if (member and member.get("is_head")) else False 155 | is_principal_recipient = ( 156 | True if (member and member.get("is_principal_recipient")) else False 157 | ) 158 | 159 | if is_head: 160 | member.pop("is_head", None) 161 | member.pop("is_principal_recipient", None) 162 | create_member_id = self.env["res.partner"].create(member) 163 | self.env["g2p.group.membership"].create( 164 | { 165 | "group": create_group_id.id, 166 | "individual": create_member_id.id, 167 | "kind": [ 168 | ( 169 | 4, 170 | group_membership_kind_head_id, 171 | ) 172 | ], 173 | } 174 | ) 175 | 176 | elif is_principal_recipient: 177 | member.pop("is_head", None) 178 | member.pop("is_principal_recipient", None) 179 | create_member_id = self.env["res.partner"].create(member) 180 | self.env["g2p.group.membership"].create( 181 | { 182 | "group": create_group_id.id, 183 | "individual": create_member_id.id, 184 | "kind": [], 185 | } 186 | ) 187 | 188 | else: 189 | create_member_id = self.env["res.partner"].create(member) 190 | self.env["g2p.group.membership"].create( 191 | { 192 | "group": create_group_id.id, 193 | "individual": create_member_id.id, 194 | } 195 | ) 196 | 197 | if res.state == "draft": 198 | res.update({"state": "generate"}) 199 | 200 | msg = "Task Queue called task: model [%s] and method [%s]." % ( 201 | self._name, 202 | "_generate_sample_data", 203 | ) 204 | _logger.info(msg) 205 | return {"result": msg, "res_model": self._name, "res_ids": [res_id]} 206 | # _logger.info("-" * 80) 207 | # _logger.info(json.dumps({"group": group, "members": members}, indent=4)) 208 | 209 | def _generate_individual_data( 210 | self, fake, last_name, sex_choice_range, age_group_range, registration_date 211 | ): 212 | sex = random.choice(sex_choice_range) 213 | age_group = random.choice(age_group_range) 214 | first_name = ( 215 | fake.first_name_male() if sex == "Male" else fake.first_name_female() 216 | ) 217 | different_last_name = random.randint(0, 100) < 10 218 | if age_group == "C": 219 | date_start = datetime.datetime.now() - relativedelta(years=17) 220 | date_end = datetime.datetime.now() 221 | elif age_group == "A": 222 | date_start = datetime.datetime.now() - relativedelta(years=65) 223 | date_end = datetime.datetime.now() - relativedelta(years=18) 224 | else: 225 | date_start = datetime.datetime.now() - relativedelta(years=100) 226 | date_end = datetime.datetime.now() - relativedelta(years=65) 227 | 228 | if different_last_name: 229 | last_name = fake.last_name() 230 | 231 | medical_condition = 0 232 | if random.randint(0, 100) < 5: 233 | medical_condition = random.randint(10, 100) 234 | 235 | disability_level = 0 236 | if random.randint(0, 100) < 2: 237 | disability_level = random.randint(10, 100) 238 | 239 | pregnancy_start = None 240 | lactation_start = None 241 | if sex == "Female" and age_group == "A": 242 | rnd = random.randint(0, 100) 243 | if rnd < 15: 244 | pregnancy_start = fake.date_between_dates( 245 | date_start=datetime.datetime.now() - relativedelta(months=9), 246 | date_end=datetime.datetime.now(), 247 | ).isoformat() 248 | elif rnd > 80: 249 | lactation_start = fake.date_between_dates( 250 | date_start=datetime.datetime.now() - relativedelta(months=24), 251 | date_end=datetime.datetime.now(), 252 | ).isoformat() 253 | 254 | dob = fake.date_between_dates( 255 | date_start=date_start, date_end=date_end 256 | ).isoformat() 257 | 258 | fullname = "{} {}".format(first_name, last_name) 259 | 260 | return { 261 | "name": fullname, 262 | "given_name": first_name, 263 | "family_name": last_name, 264 | "gender": sex, 265 | "birthdate": dob, 266 | "is_registrant": True, 267 | "is_group": False, 268 | "registration_date": registration_date, 269 | "z_cst_indv_disability_level": disability_level, 270 | "z_cst_indv_medical_condition": medical_condition, 271 | "z_cst_indv_pregnancy_start": pregnancy_start, 272 | "z_cst_indv_lactation_start": lactation_start, 273 | } 274 | -------------------------------------------------------------------------------- /spp_demo/models/generate_program.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | import hashlib 3 | import logging 4 | import random 5 | 6 | from odoo import fields, models 7 | 8 | _logger = logging.getLogger(__name__) 9 | 10 | 11 | class OpenSPPGenerateProgramData(models.Model): 12 | _name = "spp.generate.program.data" 13 | 14 | name = fields.Char() 15 | num_programs = fields.Integer("Number of Programs", default=1) 16 | num_beneficicaries = fields.Integer("Number of Beneficiary", default=1) 17 | num_cycles = fields.Integer("Number of Cycles", default=1) 18 | # beneficiary_ids = fields.Many2many( 19 | # "g2p.program_membership", string="Beneficiaries", readonly=False 20 | # ) 21 | cycle_ids = fields.Many2many("g2p.cycle", string="Cycle", readonly=True) 22 | state = fields.Selection( 23 | selection=[ 24 | ("draft", "Draft"), 25 | ("generate", "Generated Program"), 26 | ("approve", "Approved All Entitlements"), 27 | ], 28 | default="draft", 29 | ) 30 | 31 | def generate_program_data(self): 32 | """ 33 | Generate program data for testing 34 | Returns: 35 | 36 | """ 37 | 38 | group_target_type_range = ["group", "individual"] 39 | cycle_auto_approve_range = [True, False] 40 | cycle_duration_range = [30] * 5 + [15, 60] 41 | 42 | ticket_name_range = ["Need to Fix", "Issue"] 43 | ticket_disc_beneficiary_range = ["Name", "Address", "Birthdate", "Group Member"] 44 | ticket_disc_cycle_range = ["Voucher", "Entitlement Expiration"] 45 | 46 | for i in range(0, self.num_programs): 47 | program_name = f"GenProgram {i+1}" 48 | target_type = random.choice(group_target_type_range) 49 | 50 | program_id = ( 51 | "demo." + hashlib.md5(f"{program_name} {i}".encode("UTF-8")).hexdigest() 52 | ) 53 | 54 | program_data = { 55 | "id": program_id, 56 | "name": program_name, 57 | "target_type": target_type, 58 | } 59 | 60 | # # create_program_id = program_data 61 | create_program_id = self.env["g2p.program"].create(program_data) 62 | _logger.debug( 63 | f"program--- {create_program_id}: {create_program_id.target_type}" 64 | ) 65 | 66 | # Default Enrollment indicator 67 | 68 | domain = [("is_registrant", "=", True)] 69 | eligibility_domain = ["&", ["is_registrant", "=", True]] 70 | if target_type == "group": 71 | domain.extend([("is_group", "=", True)]) 72 | eligibility_domain.append(["is_group", "=", True]) 73 | else: 74 | domain.extend([("is_group", "=", False)]) 75 | eligibility_domain.append(["is_group", "!=", True]) 76 | 77 | vals = {} 78 | # Default Eligibility Manager 79 | def_eli_mgr_obj = "g2p.program_membership.manager.default" 80 | eligibility_manager_data = { 81 | "name": "Default", 82 | "program_id": create_program_id.id, 83 | "eligibility_domain": str(eligibility_domain), 84 | } 85 | 86 | def_eli_mgr_id = self.env[def_eli_mgr_obj].create(eligibility_manager_data) 87 | 88 | # Add a new record to eligibility manager parent model 89 | eli_man_obj = self.env["g2p.eligibility.manager"] 90 | eli_mgr_id = eli_man_obj.create( 91 | { 92 | "program_id": create_program_id.id, 93 | "manager_ref_id": "%s,%s" 94 | % (def_eli_mgr_obj, str(def_eli_mgr_id.id)), 95 | } 96 | ) 97 | 98 | vals.update({"eligibility_managers": [(4, eli_mgr_id.id)]}) 99 | 100 | auto_approve_entitlements = random.choice(cycle_auto_approve_range) 101 | cycle_duration = random.choice(cycle_duration_range) 102 | # Cycle Manageer 103 | # TODO: approver_group_id 104 | def_cycle_mgr_obj = "g2p.cycle.manager.default" 105 | cycle_manager_data = { 106 | "name": "Default", 107 | "program_id": create_program_id.id, 108 | "auto_approve_entitlements": auto_approve_entitlements, 109 | "cycle_duration": cycle_duration, 110 | "approver_group_id": self.env.ref( 111 | "g2p_registry_base.group_g2p_admin" 112 | ).id, 113 | } 114 | def_cycle_mgr_id = self.env[def_cycle_mgr_obj].create(cycle_manager_data) 115 | 116 | # Add a new record to cycle manager parent model 117 | cycle_man_obj = self.env["g2p.cycle.manager"] 118 | cycle_man_id = cycle_man_obj.create( 119 | { 120 | "program_id": create_program_id.id, 121 | "manager_ref_id": "%s,%s" 122 | % (def_cycle_mgr_obj, str(def_cycle_mgr_id.id)), 123 | } 124 | ) 125 | vals.update({"cycle_managers": [(4, cycle_man_id.id)]}) 126 | 127 | # # Entitle Manageer 128 | # # TODO: entitlement_validation_group_id 129 | def_prog_ent_mgr_obj = "g2p.program.entitlement.manager.default" 130 | entitlement_manager_data = { 131 | "name": "Default", 132 | "program_id": create_program_id.id, 133 | "amount_per_cycle": random.choice([1000, 2000, 3000]), 134 | "amount_per_individual_in_group": random.choice([1000, 2000, 3000]), 135 | "max_individual_in_group": random.randint(0, 10), 136 | "entitlement_validation_group_id": None, 137 | } 138 | 139 | def_prog_ent_mgr_id = self.env[def_prog_ent_mgr_obj].create( 140 | entitlement_manager_data 141 | ) 142 | 143 | # Add a new record to entitlement manager parent model 144 | prog_ent_obj = self.env["g2p.program.entitlement.manager"] 145 | prog_ent_id = prog_ent_obj.create( 146 | { 147 | "program_id": create_program_id.id, 148 | "manager_ref_id": "%s,%s" 149 | % (def_prog_ent_mgr_obj, str(def_prog_ent_mgr_id.id)), 150 | } 151 | ) 152 | vals.update({"entitlement_managers": [(4, prog_ent_id.id)]}) 153 | 154 | # Create Beneficiaries 155 | benificiaries_count = self.num_beneficicaries 156 | registrant_ids = ( 157 | self.env["res.partner"].search(domain, limit=benificiaries_count).ids 158 | ) 159 | 160 | _logger.debug(f"registrant_ids-- {len(registrant_ids)} : {registrant_ids}") 161 | 162 | benificiary_lines = [] 163 | for r_id in range(len(registrant_ids)): 164 | benificiary_data = { 165 | "partner_id": registrant_ids[r_id], 166 | "program_id": create_program_id.id, 167 | } 168 | benificiary_lines.append((0, 0, benificiary_data)) 169 | 170 | vals.update({"program_membership_ids": benificiary_lines}) 171 | 172 | # self.cycle_ids = [(4, beneficiary_id.id for beneficiary_id in benificiary_lines)] 173 | # Complete the program data 174 | create_program_id.update(vals) 175 | 176 | # Enroll Registrant 177 | create_program_id.enroll_eligible_registrants() 178 | 179 | # Create New Cycle 180 | # TODO: generate cycles 181 | program_manager = create_program_id.get_manager( 182 | create_program_id.MANAGER_PROGRAM 183 | ) 184 | 185 | ###################################################################################### 186 | # cycle_id = program_manager.new_cycle() 187 | for _i in range(0, self.num_cycles): 188 | cycle_id = program_manager.new_cycle() 189 | 190 | _logger.debug(f"cycle--- {cycle_id}") 191 | 192 | # Create Entitlements 193 | cycle_manager = create_program_id.get_manager( 194 | create_program_id.MANAGER_CYCLE 195 | ) 196 | cycle_manager.prepare_entitlements(cycle_id) 197 | 198 | self.cycle_ids = [(4, cycle_id.id)] 199 | 200 | # # Create Program Funds 201 | entitlement_ids = cycle_id.entitlement_ids 202 | 203 | # # initital_amount 204 | total_initial_amount = sum(a.initial_amount for a in entitlement_ids) 205 | 206 | program_fund_data = { 207 | "name": "Draft", 208 | "program_id": create_program_id.id, 209 | "amount": total_initial_amount, 210 | } 211 | 212 | # # Create and Post Program fund 213 | create_prog_fund_id = self.env["g2p.program.fund"].create( 214 | program_fund_data 215 | ) 216 | create_prog_fund_id.post_fund() 217 | 218 | if create_prog_fund_id.state == "posted": 219 | cycle_id.to_approve() 220 | _logger.debug(f"cycle_id--- {cycle_id.state}") 221 | 222 | # # Create Helpdesk Tickets in Cycle 223 | cycle_beneficiary_ids = cycle_id.get_beneficiaries(["enrolled"]).mapped( 224 | "partner_id.id" 225 | ) 226 | for beneficiary_id in cycle_beneficiary_ids: 227 | tx_name = random.choice(ticket_name_range) 228 | tx_desc = random.choice(ticket_disc_cycle_range) 229 | self.env["helpdesk.ticket"].create( 230 | { 231 | "name": tx_name, 232 | "partner_id": beneficiary_id, 233 | "cycle_id": cycle_id.id, 234 | "description": f"{tx_name} in {tx_desc}", 235 | "priority": str(random.randint(0, 3)), 236 | } 237 | ) 238 | 239 | ###################################################################################### 240 | # Create Helpdesk Tickets in Beneficiaries 241 | beneficiary_ids = create_program_id.get_beneficiaries(["enrolled"]).mapped( 242 | "partner_id.id" 243 | ) 244 | 245 | for beneficiary_id in beneficiary_ids: 246 | tx_name = random.choice(ticket_name_range) 247 | tx_desc = random.choice(ticket_disc_beneficiary_range) 248 | self.env["helpdesk.ticket"].create( 249 | { 250 | "name": tx_name, 251 | "partner_id": beneficiary_id, 252 | "program_id": create_program_id.id, 253 | "description": f"{tx_name} in {tx_desc}", 254 | "priority": str(random.randint(0, 3)), 255 | } 256 | ) 257 | 258 | if self.state == "draft": 259 | self.update({"state": "generate"}) 260 | 261 | # _logger.info("-" * 80) 262 | # _logger.info( 263 | # json.dumps( 264 | # { 265 | # "program_data": program_data, 266 | # "eligibility_manager_data": eligibility_manager_data, 267 | # "cycle_manager_data": cycle_manager_data, 268 | # "entitlement_manager_data": entitlement_manager_data, 269 | # }, 270 | # indent=4, 271 | # ) 272 | # ) 273 | 274 | def approve_entitlements(self): 275 | if self.cycle_ids: 276 | for cycle in self.cycle_ids: 277 | if cycle.state == "to_approve": 278 | for entitlement in cycle.entitlement_ids: 279 | if entitlement.state == "draft": 280 | entitlement.approve_entitlement() 281 | # cycle.approve() 282 | self.update({"state": "approve"}) 283 | -------------------------------------------------------------------------------- /spp_demo/models/individual.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | import logging 3 | 4 | from odoo import fields, models 5 | 6 | _logger = logging.getLogger(__name__) 7 | 8 | 9 | class G2PIndividual(models.Model): 10 | _inherit = "res.partner" 11 | 12 | z_cst_indv_medical_condition = fields.Integer( 13 | "chronic illness/medical conditions level" 14 | ) # 0-100 15 | z_cst_indv_disability_level = fields.Integer("Disability level") # 0-100 16 | z_cst_indv_pregnancy_start = fields.Date( 17 | "Pregnancy start" 18 | ) # We set a date to be able to clean it later 19 | z_cst_indv_lactation_start = fields.Date( 20 | "Lactation start" 21 | ) # We set a date to be able to clean it later 22 | -------------------------------------------------------------------------------- /spp_demo/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | OpenSPP Newland Demo 2 | -------------------------------------------------------------------------------- /spp_demo/security/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | spp_generate_data_admin,Generate Data Admin Access,spp_demo.model_spp_generate_data,g2p_registry_base.group_g2p_admin,1,1,1,1 3 | spp_generate_program_data_admin,Generate Program Data Admin Access,spp_demo.model_spp_generate_program_data,g2p_registry_base.group_g2p_admin,1,1,1,1 4 | -------------------------------------------------------------------------------- /spp_demo/static/description/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenSPP/openspp-demo/0e0bac6fcf59fcf5a6a3e795082a5ccec7f1591b/spp_demo/static/description/icon.png -------------------------------------------------------------------------------- /spp_demo/views/generate_data_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | view_generate_data_tree 8 | spp.generate.data 9 | 1 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | view_generate_data_form 21 | spp.generate.data 22 | 1 23 | 24 |
25 |
26 | 33 | 34 |
35 | 36 |
37 | 49 |
50 |
51 |
60 | 61 |
62 |
63 |
64 |
65 | 66 | 67 | Generate Data 68 | ir.actions.act_window 69 | spp.generate.data 70 | tree,form 71 | {} 72 | [] 73 | 74 |

75 | Generate Data 76 |

77 | Click the create button to enter the new record. 78 |

79 |
80 |
81 | 82 | 83 | 84 | tree 85 | 86 | 87 | 88 | 89 | 90 | 91 | form 92 | 93 | 94 | 95 | 96 | 103 | 104 |
105 | -------------------------------------------------------------------------------- /spp_demo/views/generate_program_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | view_generate_program_tree 8 | spp.generate.program.data 9 | 1 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | view_generate_program_form 21 | spp.generate.program.data 22 | 1 23 | 24 |
25 |
26 | 27 |
28 | 29 |
30 | 42 | 54 |
55 |
56 |
75 | 76 | 77 | 78 | 79 | 80 | 81 |
82 |
83 |
84 |
85 | 86 | 87 | Generate Program Data 88 | ir.actions.act_window 89 | spp.generate.program.data 90 | tree,form 91 | {} 92 | [] 93 | 94 |

95 | Generate Program Data 96 |

97 | Click the create button to enter the new record. 98 |

99 |
100 |
101 | 102 | 103 | 104 | tree 105 | 106 | 107 | 108 | 109 | 110 | 111 | form 112 | 113 | 114 | 115 | 116 | 123 | 124 |
125 | -------------------------------------------------------------------------------- /spp_event_demo/README.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Event Data Demo 3 | =============== 4 | 5 | .. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 6 | !! This file is generated by oca-gen-addon-readme !! 7 | !! changes will be overwritten. !! 8 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 9 | 10 | .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png 11 | :target: https://odoo-community.org/page/development-status 12 | :alt: Beta 13 | .. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png 14 | :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html 15 | :alt: License: LGPL-3 16 | .. |badge3| image:: https://img.shields.io/badge/github-openspp%2Fopenspp--registry-lightgray.png?logo=github 17 | :target: https://github.com/openspp/openspp-registry/tree/15.0/spp_event_demo 18 | :alt: openspp/openspp-registry 19 | 20 | |badge1| |badge2| |badge3| 21 | 22 | OpenSPP Event data demo and tests 23 | 24 | **Table of contents** 25 | 26 | .. contents:: 27 | :local: 28 | 29 | Bug Tracker 30 | =========== 31 | 32 | Bugs are tracked on `GitHub Issues `_. 33 | In case of trouble, please check there if your issue has already been reported. 34 | If you spotted it first, help us smashing it by providing a detailed and welcomed 35 | `feedback `_. 36 | 37 | Do not contact contributors directly about support or help with technical issues. 38 | 39 | Credits 40 | ======= 41 | 42 | Authors 43 | ~~~~~~~ 44 | 45 | * OpenSPP.org 46 | 47 | Maintainers 48 | ~~~~~~~~~~~ 49 | 50 | .. |maintainer-jeremi| image:: https://github.com/jeremi.png?size=40px 51 | :target: https://github.com/jeremi 52 | :alt: jeremi 53 | .. |maintainer-gonzalesedwin1123| image:: https://github.com/gonzalesedwin1123.png?size=40px 54 | :target: https://github.com/gonzalesedwin1123 55 | :alt: gonzalesedwin1123 56 | .. |maintainer-emjay0921| image:: https://github.com/emjay0921.png?size=40px 57 | :target: https://github.com/emjay0921 58 | :alt: emjay0921 59 | 60 | Current maintainers: 61 | 62 | |maintainer-jeremi| |maintainer-gonzalesedwin1123| |maintainer-emjay0921| 63 | 64 | This module is part of the `openspp/openspp-registry `_ project on GitHub. 65 | 66 | You are welcome to contribute. 67 | -------------------------------------------------------------------------------- /spp_event_demo/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | 3 | from . import models 4 | from . import wizard 5 | -------------------------------------------------------------------------------- /spp_event_demo/__manifest__.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | 3 | 4 | { 5 | "name": "Event Data Demo", 6 | "category": "OpenSPP", 7 | "version": "15.0.0.0.0", 8 | "sequence": 1, 9 | "author": "OpenSPP.org", 10 | "website": "https://github.com/openspp/openspp-demo", 11 | "license": "LGPL-3", 12 | "development_status": "Beta", 13 | "maintainers": ["jeremi", "gonzalesedwin1123", "emjay0921"], 14 | "depends": ["base", "spp_event_data"], 15 | "data": [ 16 | "security/ir.model.access.csv", 17 | "views/house_visit_view.xml", 18 | "views/phone_survey_view.xml", 19 | "views/registrant_view.xml", 20 | "wizard/create_event_house_visit_wizard.xml", 21 | "wizard/create_event_phone_survey_wizard.xml", 22 | "wizard/create_event_school_enrolment_wizard.xml", 23 | ], 24 | "assets": {}, 25 | "demo": [], 26 | "images": [], 27 | "application": True, 28 | "installable": True, 29 | "auto_install": False, 30 | } 31 | -------------------------------------------------------------------------------- /spp_event_demo/i18n/ar.po: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * spp_event_demo 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 15.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "PO-Revision-Date: 2023-02-24 02:22+0000\n" 10 | "Last-Translator: Ammar ALBAYATI \n" 11 | "Language-Team: Arabic \n" 13 | "Language: ar\n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " 18 | "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" 19 | "X-Generator: Weblate 4.14\n" 20 | 21 | #. module: spp_event_demo 22 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_partner__active_house_visit 23 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_users__active_house_visit 24 | msgid "Active House Visit" 25 | msgstr "" 26 | 27 | #. module: spp_event_demo 28 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_partner__active_phone_survey 29 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_users__active_phone_survey 30 | msgid "Active Phone Survey" 31 | msgstr "" 32 | 33 | #. module: spp_event_demo 34 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.create_event_house_visit_form_view 35 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.create_event_phone_survey_form_view 36 | msgid "Cancel" 37 | msgstr "الغاء" 38 | 39 | #. module: spp_event_demo 40 | #: model_terms:ir.actions.act_window,help:spp_event_demo.action_spp_event_house_visit 41 | msgid "" 42 | "Click the create button to enter the configuration of the House Visit Event." 43 | msgstr "" 44 | 45 | #. module: spp_event_demo 46 | #: model_terms:ir.actions.act_window,help:spp_event_demo.action_spp_event_phone_survey 47 | msgid "" 48 | "Click the create button to enter the configuration of the Phone Survey Event." 49 | msgstr "" 50 | 51 | #. module: spp_event_demo 52 | #: model:ir.model,name:spp_event_demo.model_res_partner 53 | msgid "Contact" 54 | msgstr "اتصال" 55 | 56 | #. module: spp_event_demo 57 | #: model:ir.model,name:spp_event_demo.model_spp_create_event_house_visit_wizard 58 | msgid "Create Event House Visit Wizard" 59 | msgstr "" 60 | 61 | #. module: spp_event_demo 62 | #: model:ir.model,name:spp_event_demo.model_spp_create_event_phone_survey_wizard 63 | msgid "Create Event Phone Survey Wizard" 64 | msgstr "" 65 | 66 | #. module: spp_event_demo 67 | #: model:ir.model,name:spp_event_demo.model_spp_create_event_wizard 68 | msgid "Create Event Wizard" 69 | msgstr "" 70 | 71 | #. module: spp_event_demo 72 | #: model_terms:ir.actions.act_window,help:spp_event_demo.action_spp_event_house_visit 73 | msgid "Create a new House Visit Event!" 74 | msgstr "" 75 | 76 | #. module: spp_event_demo 77 | #: model_terms:ir.actions.act_window,help:spp_event_demo.action_spp_event_phone_survey 78 | msgid "Create a new Phone Survey Event!" 79 | msgstr "" 80 | 81 | #. module: spp_event_demo 82 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__create_uid 83 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__create_uid 84 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__create_uid 85 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__create_uid 86 | msgid "Created by" 87 | msgstr "انشأ من قبل" 88 | 89 | #. module: spp_event_demo 90 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__create_date 91 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__create_date 92 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__create_date 93 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__create_date 94 | msgid "Created on" 95 | msgstr "انشأ على" 96 | 97 | #. module: spp_event_demo 98 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_partner__dms_directory_ids 99 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__dms_directory_ids 100 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__dms_directory_ids 101 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_wizard__dms_directory_ids 102 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__dms_directory_ids 103 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__dms_directory_ids 104 | #, fuzzy 105 | msgid "DMS Directories" 106 | msgstr "دليل الوثائق" 107 | 108 | #. module: spp_event_demo 109 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__description 110 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__description 111 | msgid "Description" 112 | msgstr "" 113 | 114 | #. module: spp_event_demo 115 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__disabled 116 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__disabled 117 | msgid "Disabled" 118 | msgstr "ايقاف" 119 | 120 | #. module: spp_event_demo 121 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__display_name 122 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__display_name 123 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__display_name 124 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__display_name 125 | msgid "Display Name" 126 | msgstr "الاسم" 127 | 128 | #. module: spp_event_demo 129 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__event_id 130 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__event_id 131 | msgid "Event" 132 | msgstr "" 133 | 134 | #. module: spp_event_demo 135 | #: model:ir.actions.act_window,name:spp_event_demo.action_spp_event_house_visit 136 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.view_spp_event_house_visit_form 137 | msgid "Event Data: House Visit" 138 | msgstr "" 139 | 140 | #. module: spp_event_demo 141 | #: model:ir.actions.act_window,name:spp_event_demo.action_spp_event_phone_survey 142 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.view_spp_event_phone_survey_form 143 | msgid "Event Data: Phone Survey" 144 | msgstr "" 145 | 146 | #. module: spp_event_demo 147 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_wizard__event_data_model 148 | msgid "Event Type" 149 | msgstr "" 150 | 151 | #. module: spp_event_demo 152 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__farm_size_acre 153 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__farm_size_acre 154 | msgid "Farm Size Acre" 155 | msgstr "" 156 | 157 | #. module: spp_event_demo 158 | #: model:ir.model,name:spp_event_demo.model_spp_event_house_visit 159 | #: model:ir.model.fields.selection,name:spp_event_demo.selection__spp_create_event_wizard__event_data_model__spp_event_house_visit 160 | msgid "House Visit" 161 | msgstr "" 162 | 163 | #. module: spp_event_demo 164 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__id 165 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__id 166 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__id 167 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__id 168 | msgid "ID" 169 | msgstr "" 170 | 171 | #. module: spp_event_demo 172 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__is_farm 173 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__is_farm 174 | msgid "Is Farm" 175 | msgstr "" 176 | 177 | #. module: spp_event_demo 178 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard____last_update 179 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard____last_update 180 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit____last_update 181 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey____last_update 182 | msgid "Last Modified on" 183 | msgstr "تاريخ آخر تعديل" 184 | 185 | #. module: spp_event_demo 186 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__write_uid 187 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__write_uid 188 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__write_uid 189 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__write_uid 190 | msgid "Last Updated by" 191 | msgstr "آخر تحديث بواسطة" 192 | 193 | #. module: spp_event_demo 194 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__write_date 195 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__write_date 196 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__write_date 197 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__write_date 198 | msgid "Last Updated on" 199 | msgstr "آخر تحديث في" 200 | 201 | #. module: spp_event_demo 202 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__no_food_stock 203 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__no_food_stock 204 | msgid "No Food Stock" 205 | msgstr "" 206 | 207 | #. module: spp_event_demo 208 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__number_of_cows 209 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__number_of_cows 210 | msgid "Number Of Cows" 211 | msgstr "" 212 | 213 | #. module: spp_event_demo 214 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__number_of_pigs 215 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__number_of_pigs 216 | msgid "Number Of Pigs" 217 | msgstr "" 218 | 219 | #. module: spp_event_demo 220 | #: model:ir.model,name:spp_event_demo.model_spp_event_phone_survey 221 | #: model:ir.model.fields.selection,name:spp_event_demo.selection__spp_create_event_wizard__event_data_model__spp_event_phone_survey 222 | msgid "Phone Survey" 223 | msgstr "" 224 | 225 | #. module: spp_event_demo 226 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__photo 227 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__photo 228 | msgid "Photo" 229 | msgstr "" 230 | 231 | #. module: spp_event_demo 232 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__photo_filename 233 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__photo_filename 234 | msgid "Photo Filename" 235 | msgstr "" 236 | 237 | #. module: spp_event_demo 238 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.create_event_house_visit_form_view 239 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.create_event_phone_survey_form_view 240 | msgid "Save" 241 | msgstr "حفظ" 242 | 243 | #. module: spp_event_demo 244 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__summary 245 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__summary 246 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__summary 247 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__summary 248 | msgid "Summary" 249 | msgstr "" 250 | -------------------------------------------------------------------------------- /spp_event_demo/i18n/ckb.po: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * spp_event_demo 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 15.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: Automatically generated\n" 10 | "Language-Team: none\n" 11 | "Language: ckb\n" 12 | "MIME-Version: 1.0\n" 13 | "Content-Type: text/plain; charset=UTF-8\n" 14 | "Content-Transfer-Encoding: \n" 15 | "Plural-Forms: nplurals=2; plural=n != 1;\n" 16 | 17 | #. module: spp_event_demo 18 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_partner__active_house_visit 19 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_users__active_house_visit 20 | msgid "Active House Visit" 21 | msgstr "" 22 | 23 | #. module: spp_event_demo 24 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_partner__active_phone_survey 25 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_users__active_phone_survey 26 | msgid "Active Phone Survey" 27 | msgstr "" 28 | 29 | #. module: spp_event_demo 30 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.create_event_house_visit_form_view 31 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.create_event_phone_survey_form_view 32 | msgid "Cancel" 33 | msgstr "" 34 | 35 | #. module: spp_event_demo 36 | #: model_terms:ir.actions.act_window,help:spp_event_demo.action_spp_event_house_visit 37 | msgid "" 38 | "Click the create button to enter the configuration of the House Visit Event." 39 | msgstr "" 40 | 41 | #. module: spp_event_demo 42 | #: model_terms:ir.actions.act_window,help:spp_event_demo.action_spp_event_phone_survey 43 | msgid "" 44 | "Click the create button to enter the configuration of the Phone Survey Event." 45 | msgstr "" 46 | 47 | #. module: spp_event_demo 48 | #: model:ir.model,name:spp_event_demo.model_res_partner 49 | msgid "Contact" 50 | msgstr "" 51 | 52 | #. module: spp_event_demo 53 | #: model:ir.model,name:spp_event_demo.model_spp_create_event_house_visit_wizard 54 | msgid "Create Event House Visit Wizard" 55 | msgstr "" 56 | 57 | #. module: spp_event_demo 58 | #: model:ir.model,name:spp_event_demo.model_spp_create_event_phone_survey_wizard 59 | msgid "Create Event Phone Survey Wizard" 60 | msgstr "" 61 | 62 | #. module: spp_event_demo 63 | #: model:ir.model,name:spp_event_demo.model_spp_create_event_wizard 64 | msgid "Create Event Wizard" 65 | msgstr "" 66 | 67 | #. module: spp_event_demo 68 | #: model_terms:ir.actions.act_window,help:spp_event_demo.action_spp_event_house_visit 69 | msgid "Create a new House Visit Event!" 70 | msgstr "" 71 | 72 | #. module: spp_event_demo 73 | #: model_terms:ir.actions.act_window,help:spp_event_demo.action_spp_event_phone_survey 74 | msgid "Create a new Phone Survey Event!" 75 | msgstr "" 76 | 77 | #. module: spp_event_demo 78 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__create_uid 79 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__create_uid 80 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__create_uid 81 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__create_uid 82 | msgid "Created by" 83 | msgstr "" 84 | 85 | #. module: spp_event_demo 86 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__create_date 87 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__create_date 88 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__create_date 89 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__create_date 90 | msgid "Created on" 91 | msgstr "" 92 | 93 | #. module: spp_event_demo 94 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_partner__dms_directory_ids 95 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__dms_directory_ids 96 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__dms_directory_ids 97 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_wizard__dms_directory_ids 98 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__dms_directory_ids 99 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__dms_directory_ids 100 | msgid "DMS Directories" 101 | msgstr "" 102 | 103 | #. module: spp_event_demo 104 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__description 105 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__description 106 | msgid "Description" 107 | msgstr "" 108 | 109 | #. module: spp_event_demo 110 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__disabled 111 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__disabled 112 | msgid "Disabled" 113 | msgstr "" 114 | 115 | #. module: spp_event_demo 116 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__display_name 117 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__display_name 118 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__display_name 119 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__display_name 120 | msgid "Display Name" 121 | msgstr "" 122 | 123 | #. module: spp_event_demo 124 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__event_id 125 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__event_id 126 | msgid "Event" 127 | msgstr "" 128 | 129 | #. module: spp_event_demo 130 | #: model:ir.actions.act_window,name:spp_event_demo.action_spp_event_house_visit 131 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.view_spp_event_house_visit_form 132 | msgid "Event Data: House Visit" 133 | msgstr "" 134 | 135 | #. module: spp_event_demo 136 | #: model:ir.actions.act_window,name:spp_event_demo.action_spp_event_phone_survey 137 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.view_spp_event_phone_survey_form 138 | msgid "Event Data: Phone Survey" 139 | msgstr "" 140 | 141 | #. module: spp_event_demo 142 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_wizard__event_data_model 143 | msgid "Event Type" 144 | msgstr "" 145 | 146 | #. module: spp_event_demo 147 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__farm_size_acre 148 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__farm_size_acre 149 | msgid "Farm Size Acre" 150 | msgstr "" 151 | 152 | #. module: spp_event_demo 153 | #: model:ir.model,name:spp_event_demo.model_spp_event_house_visit 154 | #: model:ir.model.fields.selection,name:spp_event_demo.selection__spp_create_event_wizard__event_data_model__spp_event_house_visit 155 | msgid "House Visit" 156 | msgstr "" 157 | 158 | #. module: spp_event_demo 159 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__id 160 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__id 161 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__id 162 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__id 163 | msgid "ID" 164 | msgstr "" 165 | 166 | #. module: spp_event_demo 167 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__is_farm 168 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__is_farm 169 | msgid "Is Farm" 170 | msgstr "" 171 | 172 | #. module: spp_event_demo 173 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard____last_update 174 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard____last_update 175 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit____last_update 176 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey____last_update 177 | msgid "Last Modified on" 178 | msgstr "" 179 | 180 | #. module: spp_event_demo 181 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__write_uid 182 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__write_uid 183 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__write_uid 184 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__write_uid 185 | msgid "Last Updated by" 186 | msgstr "" 187 | 188 | #. module: spp_event_demo 189 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__write_date 190 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__write_date 191 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__write_date 192 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__write_date 193 | msgid "Last Updated on" 194 | msgstr "" 195 | 196 | #. module: spp_event_demo 197 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__no_food_stock 198 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__no_food_stock 199 | msgid "No Food Stock" 200 | msgstr "" 201 | 202 | #. module: spp_event_demo 203 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__number_of_cows 204 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__number_of_cows 205 | msgid "Number Of Cows" 206 | msgstr "" 207 | 208 | #. module: spp_event_demo 209 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__number_of_pigs 210 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__number_of_pigs 211 | msgid "Number Of Pigs" 212 | msgstr "" 213 | 214 | #. module: spp_event_demo 215 | #: model:ir.model,name:spp_event_demo.model_spp_event_phone_survey 216 | #: model:ir.model.fields.selection,name:spp_event_demo.selection__spp_create_event_wizard__event_data_model__spp_event_phone_survey 217 | msgid "Phone Survey" 218 | msgstr "" 219 | 220 | #. module: spp_event_demo 221 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__photo 222 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__photo 223 | msgid "Photo" 224 | msgstr "" 225 | 226 | #. module: spp_event_demo 227 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__photo_filename 228 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__photo_filename 229 | msgid "Photo Filename" 230 | msgstr "" 231 | 232 | #. module: spp_event_demo 233 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.create_event_house_visit_form_view 234 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.create_event_phone_survey_form_view 235 | msgid "Save" 236 | msgstr "" 237 | 238 | #. module: spp_event_demo 239 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__summary 240 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__summary 241 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__summary 242 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__summary 243 | msgid "Summary" 244 | msgstr "" 245 | -------------------------------------------------------------------------------- /spp_event_demo/i18n/spp_event_demo.pot: -------------------------------------------------------------------------------- 1 | # Translation of Odoo Server. 2 | # This file contains the translation of the following modules: 3 | # * spp_event_demo 4 | # 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: Odoo Server 15.0\n" 8 | "Report-Msgid-Bugs-To: \n" 9 | "Last-Translator: \n" 10 | "Language-Team: \n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: \n" 14 | "Plural-Forms: \n" 15 | 16 | #. module: spp_event_demo 17 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_partner__active_house_visit 18 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_users__active_house_visit 19 | msgid "Active House Visit" 20 | msgstr "" 21 | 22 | #. module: spp_event_demo 23 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_partner__active_phone_survey 24 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_users__active_phone_survey 25 | msgid "Active Phone Survey" 26 | msgstr "" 27 | 28 | #. module: spp_event_demo 29 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.create_event_house_visit_form_view 30 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.create_event_phone_survey_form_view 31 | msgid "Cancel" 32 | msgstr "" 33 | 34 | #. module: spp_event_demo 35 | #: model_terms:ir.actions.act_window,help:spp_event_demo.action_spp_event_house_visit 36 | msgid "" 37 | "Click the create button to enter the configuration of the House Visit Event." 38 | msgstr "" 39 | 40 | #. module: spp_event_demo 41 | #: model_terms:ir.actions.act_window,help:spp_event_demo.action_spp_event_phone_survey 42 | msgid "" 43 | "Click the create button to enter the configuration of the Phone Survey " 44 | "Event." 45 | msgstr "" 46 | 47 | #. module: spp_event_demo 48 | #: model:ir.model,name:spp_event_demo.model_res_partner 49 | msgid "Contact" 50 | msgstr "" 51 | 52 | #. module: spp_event_demo 53 | #: model:ir.model,name:spp_event_demo.model_spp_create_event_house_visit_wizard 54 | msgid "Create Event House Visit Wizard" 55 | msgstr "" 56 | 57 | #. module: spp_event_demo 58 | #: model:ir.model,name:spp_event_demo.model_spp_create_event_phone_survey_wizard 59 | msgid "Create Event Phone Survey Wizard" 60 | msgstr "" 61 | 62 | #. module: spp_event_demo 63 | #: model:ir.model,name:spp_event_demo.model_spp_create_event_wizard 64 | msgid "Create Event Wizard" 65 | msgstr "" 66 | 67 | #. module: spp_event_demo 68 | #: model_terms:ir.actions.act_window,help:spp_event_demo.action_spp_event_house_visit 69 | msgid "Create a new House Visit Event!" 70 | msgstr "" 71 | 72 | #. module: spp_event_demo 73 | #: model_terms:ir.actions.act_window,help:spp_event_demo.action_spp_event_phone_survey 74 | msgid "Create a new Phone Survey Event!" 75 | msgstr "" 76 | 77 | #. module: spp_event_demo 78 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__create_uid 79 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__create_uid 80 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__create_uid 81 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__create_uid 82 | msgid "Created by" 83 | msgstr "" 84 | 85 | #. module: spp_event_demo 86 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__create_date 87 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__create_date 88 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__create_date 89 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__create_date 90 | msgid "Created on" 91 | msgstr "" 92 | 93 | #. module: spp_event_demo 94 | #: model:ir.model.fields,field_description:spp_event_demo.field_res_partner__dms_directory_ids 95 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__dms_directory_ids 96 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__dms_directory_ids 97 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_wizard__dms_directory_ids 98 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__dms_directory_ids 99 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__dms_directory_ids 100 | msgid "DMS Directories" 101 | msgstr "" 102 | 103 | #. module: spp_event_demo 104 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__description 105 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__description 106 | msgid "Description" 107 | msgstr "" 108 | 109 | #. module: spp_event_demo 110 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__disabled 111 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__disabled 112 | msgid "Disabled" 113 | msgstr "" 114 | 115 | #. module: spp_event_demo 116 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__display_name 117 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__display_name 118 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__display_name 119 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__display_name 120 | msgid "Display Name" 121 | msgstr "" 122 | 123 | #. module: spp_event_demo 124 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__event_id 125 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__event_id 126 | msgid "Event" 127 | msgstr "" 128 | 129 | #. module: spp_event_demo 130 | #: model:ir.actions.act_window,name:spp_event_demo.action_spp_event_house_visit 131 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.view_spp_event_house_visit_form 132 | msgid "Event Data: House Visit" 133 | msgstr "" 134 | 135 | #. module: spp_event_demo 136 | #: model:ir.actions.act_window,name:spp_event_demo.action_spp_event_phone_survey 137 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.view_spp_event_phone_survey_form 138 | msgid "Event Data: Phone Survey" 139 | msgstr "" 140 | 141 | #. module: spp_event_demo 142 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_wizard__event_data_model 143 | msgid "Event Type" 144 | msgstr "" 145 | 146 | #. module: spp_event_demo 147 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__farm_size_acre 148 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__farm_size_acre 149 | msgid "Farm Size Acre" 150 | msgstr "" 151 | 152 | #. module: spp_event_demo 153 | #: model:ir.model,name:spp_event_demo.model_spp_event_house_visit 154 | #: model:ir.model.fields.selection,name:spp_event_demo.selection__spp_create_event_wizard__event_data_model__spp_event_house_visit 155 | msgid "House Visit" 156 | msgstr "" 157 | 158 | #. module: spp_event_demo 159 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__id 160 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__id 161 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__id 162 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__id 163 | msgid "ID" 164 | msgstr "" 165 | 166 | #. module: spp_event_demo 167 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__is_farm 168 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__is_farm 169 | msgid "Is Farm" 170 | msgstr "" 171 | 172 | #. module: spp_event_demo 173 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard____last_update 174 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard____last_update 175 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit____last_update 176 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey____last_update 177 | msgid "Last Modified on" 178 | msgstr "" 179 | 180 | #. module: spp_event_demo 181 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__write_uid 182 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__write_uid 183 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__write_uid 184 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__write_uid 185 | msgid "Last Updated by" 186 | msgstr "" 187 | 188 | #. module: spp_event_demo 189 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__write_date 190 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__write_date 191 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__write_date 192 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__write_date 193 | msgid "Last Updated on" 194 | msgstr "" 195 | 196 | #. module: spp_event_demo 197 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__no_food_stock 198 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__no_food_stock 199 | msgid "No Food Stock" 200 | msgstr "" 201 | 202 | #. module: spp_event_demo 203 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__number_of_cows 204 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__number_of_cows 205 | msgid "Number Of Cows" 206 | msgstr "" 207 | 208 | #. module: spp_event_demo 209 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__number_of_pigs 210 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__number_of_pigs 211 | msgid "Number Of Pigs" 212 | msgstr "" 213 | 214 | #. module: spp_event_demo 215 | #: model:ir.model,name:spp_event_demo.model_spp_event_phone_survey 216 | #: model:ir.model.fields.selection,name:spp_event_demo.selection__spp_create_event_wizard__event_data_model__spp_event_phone_survey 217 | msgid "Phone Survey" 218 | msgstr "" 219 | 220 | #. module: spp_event_demo 221 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__photo 222 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__photo 223 | msgid "Photo" 224 | msgstr "" 225 | 226 | #. module: spp_event_demo 227 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__photo_filename 228 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__photo_filename 229 | msgid "Photo Filename" 230 | msgstr "" 231 | 232 | #. module: spp_event_demo 233 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.create_event_house_visit_form_view 234 | #: model_terms:ir.ui.view,arch_db:spp_event_demo.create_event_phone_survey_form_view 235 | msgid "Save" 236 | msgstr "" 237 | 238 | #. module: spp_event_demo 239 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_house_visit_wizard__summary 240 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_create_event_phone_survey_wizard__summary 241 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_house_visit__summary 242 | #: model:ir.model.fields,field_description:spp_event_demo.field_spp_event_phone_survey__summary 243 | msgid "Summary" 244 | msgstr "" 245 | -------------------------------------------------------------------------------- /spp_event_demo/models/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | 3 | from . import house_visit 4 | from . import phone_survey 5 | from . import school_enrolment 6 | from . import registrant 7 | -------------------------------------------------------------------------------- /spp_event_demo/models/house_visit.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | 3 | 4 | from odoo import fields, models 5 | 6 | 7 | class OpenSPPHouseVisit(models.Model): 8 | _name = "spp.event.house.visit" 9 | _description = "House Visit" 10 | 11 | summary = fields.Char() 12 | is_farm = fields.Boolean(default=False) 13 | farm_size_acre = fields.Float() 14 | photo = fields.Binary() 15 | photo_filename = fields.Char() 16 | number_of_pigs = fields.Integer() 17 | number_of_cows = fields.Integer() 18 | no_food_stock = fields.Integer() 19 | disabled = fields.Boolean(default=False) 20 | 21 | def get_view_id(self): 22 | """ 23 | This retrieves the View ID of this model 24 | """ 25 | return ( 26 | self.env["ir.ui.view"] 27 | .search([("model", "=", self._name), ("type", "=", "form")], limit=1) 28 | .id 29 | ) 30 | -------------------------------------------------------------------------------- /spp_event_demo/models/phone_survey.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | 3 | 4 | from odoo import fields, models 5 | 6 | 7 | class OpenSPPPhoneSurvey(models.Model): 8 | _name = "spp.event.phone.survey" 9 | _description = "Phone Survey" 10 | 11 | summary = fields.Char() 12 | description = fields.Text() 13 | 14 | def get_view_id(self): 15 | """ 16 | This retrieves the View ID of this model 17 | """ 18 | return ( 19 | self.env["ir.ui.view"] 20 | .search([("model", "=", self._name), ("type", "=", "form")], limit=1) 21 | .id 22 | ) 23 | -------------------------------------------------------------------------------- /spp_event_demo/models/registrant.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | 3 | from odoo import api, fields, models 4 | 5 | 6 | class OpenSPPRegistrant(models.Model): 7 | _inherit = "res.partner" 8 | 9 | active_house_visit = fields.Many2one( 10 | "spp.event.data", compute="_compute_active_house_visit" 11 | ) 12 | active_phone_survey = fields.Many2one( 13 | "spp.event.data", compute="_compute_active_phone_survey" 14 | ) 15 | 16 | active_school_enrolment_record = fields.Many2one( 17 | "spp.event.data", compute="_compute_active_school_enrolment_record" 18 | ) 19 | 20 | @api.depends("event_data_ids") 21 | def _compute_active_house_visit(self): 22 | """ 23 | This computes the active house visit of the registrant 24 | """ 25 | for rec in self: 26 | rec.active_house_visit = rec._get_active_event_id("spp.event.house.visit") 27 | 28 | @api.depends("event_data_ids") 29 | def _compute_active_phone_survey(self): 30 | """ 31 | This computes the active phone survey of the registrant 32 | """ 33 | for rec in self: 34 | rec.active_phone_survey = rec._get_active_event_id("spp.event.phone.survey") 35 | 36 | @api.depends("event_data_ids") 37 | def _compute_active_school_enrolment_record(self): 38 | """ 39 | This computes the active school enrolment record of the registrant 40 | """ 41 | for rec in self: 42 | rec.active_school_enrolment_record = rec._get_active_event_id( 43 | "spp.event.schoolenrolment.record" 44 | ) 45 | -------------------------------------------------------------------------------- /spp_event_demo/models/school_enrolment.py: -------------------------------------------------------------------------------- 1 | # Part of OpenSPP. See LICENSE file for full copyright and licensing details. 2 | 3 | 4 | from odoo import fields, models 5 | 6 | 7 | class OpenSPPSchoolEnrolmentRecord(models.Model): 8 | _name = "spp.event.schoolenrolment.record" 9 | _description = "School Enrolment Record" 10 | 11 | school_name = fields.Char() 12 | enrolment_type = fields.Char() 13 | date = fields.Date() 14 | 15 | def get_view_id(self): 16 | """ 17 | This retrieves the View ID of this model 18 | """ 19 | return ( 20 | self.env["ir.ui.view"] 21 | .search([("model", "=", self._name), ("type", "=", "form")], limit=1) 22 | .id 23 | ) 24 | -------------------------------------------------------------------------------- /spp_event_demo/readme/DESCRIPTION.rst: -------------------------------------------------------------------------------- 1 | OpenSPP Event data demo and tests 2 | -------------------------------------------------------------------------------- /spp_event_demo/security/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | spp_house_visit_admin,House Visit Admin Access,spp_event_demo.model_spp_event_house_visit,g2p_registry_base.group_g2p_admin,1,1,1,1 3 | spp_create_event_house_visit_wizard_admin,Create Event House Visit Wizard Admin Access,spp_event_demo.model_spp_create_event_house_visit_wizard,g2p_registry_base.group_g2p_admin,1,1,1,1 4 | 5 | spp_phone_survey_admin,Phone Survey Admin Access,spp_event_demo.model_spp_event_phone_survey,g2p_registry_base.group_g2p_admin,1,1,1,1 6 | spp_create_event_phone_survey_wizard_admin,Create Event Phone Survey Wizard Admin Access,spp_event_demo.model_spp_create_event_phone_survey_wizard,g2p_registry_base.group_g2p_admin,1,1,1,1 7 | 8 | spp_schoolenrolment_record_admin,School Enrolment Record Admin Access,spp_event_demo.model_spp_event_schoolenrolment_record,g2p_registry_base.group_g2p_admin,1,1,1,1 9 | spp_create_event_schoolenrolment_record_wizard_admin,Create Event School Enrolment Record Wizard Admin Access,spp_event_demo.model_spp_create_event_schoolenrolment_record_wizard,g2p_registry_base.group_g2p_admin,1,1,1,1 10 | -------------------------------------------------------------------------------- /spp_event_demo/static/description/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenSPP/openspp-demo/0e0bac6fcf59fcf5a6a3e795082a5ccec7f1591b/spp_event_demo/static/description/icon.png -------------------------------------------------------------------------------- /spp_event_demo/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Part of Newlogic G2P. See LICENSE file for full copyright and licensing details. 2 | 3 | from . import test_event_house_visit 4 | from . import test_event_phone_survey 5 | from . import test_event_schoolenrolment_record 6 | -------------------------------------------------------------------------------- /spp_event_demo/tests/test_event_house_visit.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from odoo.tests import tagged 4 | from odoo.tests.common import TransactionCase 5 | 6 | _logger = logging.getLogger(__name__) 7 | 8 | 9 | @tagged("post_install", "-at_install") 10 | class EventHouseVisitTest(TransactionCase): 11 | @classmethod 12 | def setUpClass(cls): 13 | super(EventHouseVisitTest, cls).setUpClass() 14 | 15 | # Initial Setup of Variables 16 | cls.group_1 = cls.env["res.partner"].create( 17 | { 18 | "name": "Group 1", 19 | "is_registrant": True, 20 | "is_group": True, 21 | } 22 | ) 23 | cls.house_visit_1 = cls.env["spp.event.house.visit"].create( 24 | { 25 | "summary": "Testing Visit", 26 | "is_farm": True, 27 | "farm_size_acre": 50, 28 | } 29 | ) 30 | cls.event_data_1 = cls.env["spp.event.data"].create( 31 | { 32 | "partner_id": cls.group_1.id, 33 | "model": "spp.event.house.visit", 34 | "res_id": cls.house_visit_1.id, 35 | } 36 | ) 37 | 38 | def test_01_check_active_house_visit(self): 39 | self.group_1._compute_active_house_visit() 40 | self.assertEqual( 41 | self.group_1.active_house_visit.id, 42 | self.event_data_1.id, 43 | ) 44 | 45 | def test_02_check_name(self): 46 | self.assertIn( 47 | "House Visit", 48 | self.group_1.active_house_visit.name, 49 | ) 50 | 51 | def test_03_recheck_active_house_visit_after_entering_new_visit(self): 52 | vals_house = { 53 | "summary": "Testing Visit 2", 54 | "is_farm": True, 55 | "farm_size_acre": 50, 56 | } 57 | house_visit_2 = self.env["spp.event.house.visit"].create(vals_house) 58 | vals_event_data = { 59 | "partner_id": self.group_1.id, 60 | "model": "spp.event.house.visit", 61 | "res_id": house_visit_2.id, 62 | } 63 | event_data_2 = self.env["spp.event.data"].create(vals_event_data) 64 | 65 | self.group_1._compute_active_house_visit() 66 | self.assertEqual( 67 | self.group_1.active_house_visit.id, 68 | event_data_2.id, 69 | ) 70 | -------------------------------------------------------------------------------- /spp_event_demo/tests/test_event_phone_survey.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from odoo.tests import tagged 4 | from odoo.tests.common import TransactionCase 5 | 6 | _logger = logging.getLogger(__name__) 7 | 8 | 9 | @tagged("post_install", "-at_install") 10 | class EventPhoneSurveyTest(TransactionCase): 11 | @classmethod 12 | def setUpClass(cls): 13 | super(EventPhoneSurveyTest, cls).setUpClass() 14 | 15 | # Initial Setup of Variables 16 | cls.group_1 = cls.env["res.partner"].create( 17 | { 18 | "name": "Group 1", 19 | "is_registrant": True, 20 | "is_group": True, 21 | } 22 | ) 23 | cls.phone_survey_1 = cls.env["spp.event.phone.survey"].create( 24 | { 25 | "summary": "Testing Visit", 26 | "description": "This visit is for testing only", 27 | } 28 | ) 29 | cls.event_data_1 = cls.env["spp.event.data"].create( 30 | { 31 | "partner_id": cls.group_1.id, 32 | "model": "spp.event.phone.survey", 33 | "res_id": cls.phone_survey_1.id, 34 | } 35 | ) 36 | 37 | def test_01_check_active_phone_survey(self): 38 | self.group_1._compute_active_phone_survey() 39 | self.assertEqual( 40 | self.group_1.active_phone_survey.id, 41 | self.event_data_1.id, 42 | ) 43 | 44 | def test_02_check_name(self): 45 | self.assertIn( 46 | "Phone Survey", 47 | self.group_1.active_phone_survey.name, 48 | ) 49 | 50 | def test_03_recheck_active_phone_survey_after_entering_new_visit(self): 51 | vals_phone = { 52 | "summary": "Testing Visit 2", 53 | "description": "This visit is for testing again", 54 | } 55 | phone_survey_2 = self.env["spp.event.phone.survey"].create(vals_phone) 56 | 57 | vals_event_data = { 58 | "partner_id": self.group_1.id, 59 | "model": "spp.event.phone.survey", 60 | "res_id": phone_survey_2.id, 61 | } 62 | event_data_2 = self.env["spp.event.data"].create(vals_event_data) 63 | self.group_1._compute_active_phone_survey() 64 | self.assertEqual( 65 | self.group_1.active_phone_survey.id, 66 | event_data_2.id, 67 | ) 68 | -------------------------------------------------------------------------------- /spp_event_demo/tests/test_event_schoolenrolment_record.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from odoo.tests import tagged 4 | from odoo.tests.common import TransactionCase 5 | 6 | _logger = logging.getLogger(__name__) 7 | 8 | 9 | @tagged("post_install", "-at_install") 10 | class EventSchoolEnrolmentRecordTest(TransactionCase): 11 | @classmethod 12 | def setUpClass(cls): 13 | super(EventSchoolEnrolmentRecordTest, cls).setUpClass() 14 | 15 | # Initial Setup of Variables 16 | cls.person_1 = cls.env["res.partner"].create( 17 | { 18 | "name": "Person 1", 19 | "is_registrant": True, 20 | "is_group": False, 21 | } 22 | ) 23 | cls.school_enrolment_1 = cls.env["spp.event.schoolenrolment.record"].create( 24 | { 25 | "school_name": "Village School", 26 | "enrolment_type": "Secondary school", 27 | "date": "2023-10-24", 28 | } 29 | ) 30 | cls.event_data_1 = cls.env["spp.event.data"].create( 31 | { 32 | "partner_id": cls.person_1.id, 33 | "model": "spp.event.schoolenrolment.record", 34 | "res_id": cls.school_enrolment_1.id, 35 | } 36 | ) 37 | 38 | def test_01_check_active_school_enrolment_record(self): 39 | self.person_1._compute_active_school_enrolment_record() 40 | self.assertEqual( 41 | self.person_1.active_school_enrolment_record.id, 42 | self.event_data_1.id, 43 | ) 44 | 45 | def test_02_check_description(self): 46 | self.assertIn( 47 | "School Enrolment Record", 48 | self.person_1.active_school_enrolment_record.name, 49 | ) 50 | 51 | def test_03_recheck_active_phone_survey_after_entering_new_visit(self): 52 | vals_school = { 53 | "school_name": "University of the Valley", 54 | "enrolment_type": "University", 55 | "date": "2028-10-24", 56 | } 57 | school_enrolment_report_2 = self.env["spp.event.schoolenrolment.record"].create( 58 | vals_school 59 | ) 60 | 61 | vals_event_data = { 62 | "partner_id": self.person_1.id, 63 | "model": "spp.event.schoolenrolment.record", 64 | "res_id": school_enrolment_report_2.id, 65 | } 66 | event_data_2 = self.env["spp.event.data"].create(vals_event_data) 67 | self.person_1._compute_active_school_enrolment_record() 68 | self.assertEqual( 69 | self.person_1.active_school_enrolment_record.id, 70 | event_data_2.id, 71 | ) 72 | -------------------------------------------------------------------------------- /spp_event_demo/views/house_visit_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | view_spp_event_house_visit_tree 4 | spp.event.house.visit 5 | 1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | view_spp_event_house_visit_form 18 | spp.event.house.visit 19 | 200 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 |
41 |
42 | 43 | 44 | Event Data: House Visit 45 | ir.actions.act_window 46 | spp.event.house.visit 47 | tree,form 48 | {} 49 | [] 50 | 51 |

52 | Create a new House Visit Event! 53 |

54 | Click the create button to enter the configuration of the House Visit Event. 55 |

56 |
57 |
58 | 59 | 60 | 61 | tree 62 | 63 | 64 | 65 | 66 | 67 | 68 | form 69 | 70 | 71 | 72 | 73 |
74 | -------------------------------------------------------------------------------- /spp_event_demo/views/phone_survey_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | view_spp_event_phone_survey_tree 4 | spp.event.phone.survey 5 | 1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | view_spp_event_phone_survey_form 16 | spp.event.phone.survey 17 | 200 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 |
28 |
29 | 30 | 31 | Event Data: Phone Survey 32 | ir.actions.act_window 33 | spp.event.phone.survey 34 | tree,form 35 | {} 36 | [] 37 | 38 |

39 | Create a new Phone Survey Event! 40 |

41 | Click the create button to enter the configuration of the Phone Survey Event. 42 |

43 |
44 |
45 | 46 | 47 | 48 | tree 49 | 50 | 51 | 52 | 53 | 54 | 55 | form 56 | 57 | 58 | 59 | 60 |
61 | -------------------------------------------------------------------------------- /spp_event_demo/views/registrant_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | view_groups_event_house_visit_form 5 | res.partner 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /spp_event_demo/wizard/__init__.py: -------------------------------------------------------------------------------- 1 | from . import create_event_wizard 2 | from . import create_event_house_visit_wizard 3 | from . import create_event_phone_survey_wizard 4 | from . import create_event_school_enrolment_wizard 5 | -------------------------------------------------------------------------------- /spp_event_demo/wizard/create_event_house_visit_wizard.py: -------------------------------------------------------------------------------- 1 | # Part of OpenG2P. See LICENSE file for full copyright and licensing details. 2 | 3 | from odoo import fields, models 4 | 5 | 6 | class SPPCreateEventHouseVisitWizard(models.TransientModel): 7 | _name = "spp.create.event.house.visit.wizard" 8 | _description = "Create Event House Visit Wizard" 9 | 10 | event_id = fields.Many2one("spp.event.data") 11 | summary = fields.Char() 12 | is_farm = fields.Boolean(default=False) 13 | farm_size_acre = fields.Float() 14 | photo = fields.Binary() 15 | photo_filename = fields.Char() 16 | number_of_pigs = fields.Integer() 17 | number_of_cows = fields.Integer() 18 | no_food_stock = fields.Integer() 19 | disabled = fields.Boolean(default=False) 20 | 21 | def create_event(self): 22 | for rec in self: 23 | vals_list = [ 24 | { 25 | "summary": rec.summary or False, 26 | "is_farm": rec.is_farm or False, 27 | "farm_size_acre": rec.farm_size_acre or False, 28 | "photo": rec.photo or False, 29 | "photo_filename": rec.photo_filename or False, 30 | "number_of_pigs": rec.number_of_pigs or False, 31 | "number_of_cows": rec.number_of_cows or False, 32 | "no_food_stock": rec.no_food_stock or False, 33 | "disabled": rec.disabled or False, 34 | } 35 | ] 36 | event = self.env["spp.event.house.visit"].create(vals_list) 37 | rec.event_id.res_id = event.id 38 | 39 | return event 40 | -------------------------------------------------------------------------------- /spp_event_demo/wizard/create_event_house_visit_wizard.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | create_event_house_visit_form_view 8 | spp.create.event.house.visit.wizard 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
32 |
33 |
34 |
35 |
36 | -------------------------------------------------------------------------------- /spp_event_demo/wizard/create_event_phone_survey_wizard.py: -------------------------------------------------------------------------------- 1 | # Part of OpenG2P. See LICENSE file for full copyright and licensing details. 2 | 3 | from odoo import fields, models 4 | 5 | 6 | class SPPCreateEventPhoneSurveyWizard(models.TransientModel): 7 | _name = "spp.create.event.phone.survey.wizard" 8 | _description = "Create Event Phone Survey Wizard" 9 | 10 | event_id = fields.Many2one("spp.event.data") 11 | summary = fields.Char() 12 | description = fields.Text() 13 | 14 | def create_event(self): 15 | for rec in self: 16 | vals_list = [ 17 | { 18 | "description": rec.description or False, 19 | "summary": rec.summary or False, 20 | } 21 | ] 22 | event = self.env["spp.event.phone.survey"].create(vals_list) 23 | rec.event_id.res_id = event.id 24 | 25 | return event 26 | -------------------------------------------------------------------------------- /spp_event_demo/wizard/create_event_phone_survey_wizard.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | create_event_phone_survey_form_view 8 | spp.create.event.phone.survey.wizard 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
21 |
22 |
23 |
24 |
25 | -------------------------------------------------------------------------------- /spp_event_demo/wizard/create_event_school_enrolment_wizard.py: -------------------------------------------------------------------------------- 1 | # Part of OpenG2P. See LICENSE file for full copyright and licensing details. 2 | 3 | from odoo import fields, models 4 | 5 | 6 | class SPPCreateEventSchoolEnrolmentWizard(models.TransientModel): 7 | _name = "spp.create.event.schoolenrolment.record.wizard" 8 | _description = "Create Event School Enrolment Wizard" 9 | 10 | event_id = fields.Many2one("spp.event.data") 11 | school_name = fields.Char() 12 | enrolment_type = fields.Char() 13 | date = fields.Date() 14 | 15 | def create_event(self): 16 | for rec in self: 17 | vals_list = [ 18 | { 19 | "school_name": rec.school_name or False, 20 | "enrolment_type": rec.enrolment_type or False, 21 | "date": rec.date or False, 22 | } 23 | ] 24 | event = self.env["spp.event.schoolenrolment.record"].create(vals_list) 25 | rec.event_id.res_id = event.id 26 | 27 | return event 28 | -------------------------------------------------------------------------------- /spp_event_demo/wizard/create_event_school_enrolment_wizard.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | create_event_school_enrolment_form_view 8 | spp.create.event.schoolenrolment.record.wizard 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 |
23 |
24 |
25 |
26 | -------------------------------------------------------------------------------- /spp_event_demo/wizard/create_event_wizard.py: -------------------------------------------------------------------------------- 1 | # Part of OpenG2P. See LICENSE file for full copyright and licensing details. 2 | 3 | from odoo import fields, models 4 | 5 | 6 | class SPPCreateEventWizard(models.TransientModel): 7 | _inherit = "spp.create.event.wizard" 8 | 9 | event_data_model = fields.Selection( 10 | selection_add=[ 11 | ("spp.event.house.visit", "House Visit"), 12 | ("spp.event.phone.survey", "Phone Survey"), 13 | ("spp.event.schoolenrolment.record", "School Enrolment Record"), 14 | ] 15 | ) 16 | -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | git+https://github.com/OpenG2P/openg2p-registry@15.0-develop#subdirectory=setup/g2p_registry_base 2 | git+https://github.com/OpenG2P/openg2p-registry@15.0-develop#subdirectory=setup/g2p_registry_group 3 | git+https://github.com/OpenG2P/openg2p-registry@15.0-develop#subdirectory=setup/g2p_registry_individual 4 | git+https://github.com/OpenG2P/openg2p-registry@15.0-develop#subdirectory=setup/g2p_registry_membership 5 | git+https://github.com/OpenG2P/openg2p-registry@15.0-develop#subdirectory=setup/g2p_bank 6 | git+https://github.com/OpenG2P/openg2p-program@15.0-develop#subdirectory=setup/g2p_programs 7 | git+https://github.com/openspp/openspp-registry@15.0#subdirectory=setup/spp_area 8 | git+https://github.com/openspp/openspp-registry@15.0#subdirectory=setup/spp_custom_field 9 | git+https://github.com/openspp/openspp-registry@15.0#subdirectory=setup/spp_custom_fields_ui 10 | git+https://github.com/openspp/openspp-odoo-external-dependencies@15.0#subdirectory=setup/odoo_dynamic_dashboard 11 | git+https://github.com/openspp/openspp-program@15.0#subdirectory=setup/spp_dashboard 12 | git+https://github.com/openspp/openspp-registry@15.0#subdirectory=setup/spp_idpass 13 | git+https://github.com/openspp/openspp-registry@15.0#subdirectory=setup/spp_idqueue 14 | git+https://github.com/openspp/openspp-registry@15.0#subdirectory=setup/spp_service_points 15 | git+https://github.com/openspp/openspp-registry@15.0#subdirectory=setup/spp_event_data 16 | git+https://github.com/openspp/openspp-registry@15.0#subdirectory=setup/spp_scan_id_document 17 | git+https://github.com/openspp/openspp-registry@15.0#subdirectory=setup/spp_change_request 18 | git+https://github.com/openspp/openspp-theme@15.0#subdirectory=setup/theme_openspp 19 | git+https://github.com/openspp/openspp-program@15.0#subdirectory=setup/spp_pos 20 | git+https://github.com/openspp/openspp-program@15.0#subdirectory=setup/spp_programs 21 | git+https://github.com/openspp/openspp-grievance-redress-mechanism@15.0#subdirectory=setup/spp_helpdesk 22 | git+https://github.com/openspp/openspp-communication@15.0#subdirectory=setup/spp_sms 23 | git+https://github.com/openspp/openspp-program@15.0#subdirectory=setup/g2p_entitlement_cash 24 | git+https://github.com/OpenSPP/openspp-registry@15.0#subdirectory=setup/spp_custom_filter 25 | -------------------------------------------------------------------------------- /vulnerability_disclosure_policy.md: -------------------------------------------------------------------------------- 1 | # OpenSPP Vulnerability Disclosure Policy 2 | 3 | ## Introduction 4 | 5 | OpenSPP welcomes feedback from security researchers and the general public to help improve our security. If 6 | you believe you have discovered a vulnerability, privacy issue, exposed data, or other security issues in any 7 | of our assets, we want to hear from you. This policy outlines steps for reporting vulnerabilities to us, what 8 | we expect, what you can expect from us. 9 | 10 | ## Systems in Scope 11 | 12 | This policy applies to any digital assets owned, operated, or maintained by OpenSPP. 13 | 14 | ## Out of Scope 15 | 16 | - Assets or other equipment not owned by parties participating in this policy. 17 | 18 | Vulnerabilities discovered or suspected in out-of-scope systems should be reported to the appropriate vendor 19 | or applicable authority. 20 | 21 | ## Our Commitments 22 | 23 | When working with us, according to this policy, you can expect us to: 24 | 25 | - Respond to your report promptly, and work with you to understand and validate your report; 26 | - Strive to keep you informed about the progress of a vulnerability as it is processed; 27 | - Work to remediate discovered vulnerabilities in a timely manner, within our operational constraints; and 28 | - Extend Safe Harbor for your vulnerability research that is related to this policy. 29 | 30 | ## Our Expectations 31 | 32 | In participating in our vulnerability disclosure program in good faith, we ask that you: 33 | 34 | - Play by the rules, including following this policy and any other relevant agreements. If there is any 35 | inconsistency between this policy and any other applicable terms, the terms of this policy will prevail; 36 | - Report any vulnerability you’ve discovered promptly; 37 | - Avoid violating the privacy of others, disrupting our systems, destroying data, and/or harming user 38 | experience; 39 | - Use only the Official Channels to discuss vulnerability information with us; 40 | - Provide us a reasonable amount of time (at least 120 days from the initial report) to resolve the issue 41 | before you disclose it publicly; 42 | - Perform testing only on in-scope systems, and respect systems and activities which are out-of-scope; 43 | - If a vulnerability provides unintended access to data: Limit the amount of data you access to the minimum 44 | required for effectively demonstrating a Proof of Concept; and cease testing and submit a report immediately 45 | if you encounter any user data during testing, such as Personally Identifiable Information (PII), Personal 46 | Healthcare Information (PHI), credit card data, or proprietary information; 47 | - You should only interact with test accounts you own or with explicit permission from the account holder; and 48 | - Do not engage in extortion. 49 | 50 | ## Official Channels 51 | 52 | Please report security issues via email: disclosure@openspp.org, providing all relevant information. The more 53 | details you provide, the easier it will be for us to triage and fix the issue. 54 | 55 | ## Safe Harbor 56 | 57 | When conducting vulnerability research, according to this policy, we consider this research conducted under 58 | this policy to be: 59 | 60 | - Authorized concerning any applicable anti-hacking laws, and we will not initiate or support legal action 61 | against you for accidental, good-faith violations of this policy; 62 | - Authorized concerning any relevant anti-circumvention laws, and we will not bring a claim against you for 63 | circumvention of technology controls; 64 | - Exempt from restrictions in our Terms of Service (TOS) and/or Acceptable Usage Policy (AUP) that would 65 | interfere with conducting security research, and we waive those restrictions on a limited basis; and 66 | - Lawful, helpful to the overall security of the Internet, and conducted in good faith. 67 | 68 | You are expected, as always, to comply with all applicable laws. If legal action is initiated by a third party 69 | against you and you have complied with this policy, we will take steps to make it known that your actions were 70 | conducted in compliance with this policy. 71 | 72 | If at any time you have concerns or are uncertain whether your security research is consistent with this 73 | policy, please submit a report through one of our Official Channels before going any further. 74 | 75 | > Note that the Safe Harbor applies only to legal claims under the control of the organization participating 76 | > in this policy, and that the policy does not bind independent third parties. 77 | --------------------------------------------------------------------------------