From b33f25c68858143b9eb4de2fe40a9f083b6c3e6a Mon Sep 17 00:00:00 2001 From: Marc Durepos Date: Tue, 6 May 2025 09:04:12 -0400 Subject: [PATCH] Clean up repository for apps.odoo.com sharing: Remove non-18.0 addons and document them in README.md --- README.md | 106 ++ account_credit_hold/__init__.py | 1 - account_credit_hold/__manifest__.py | 20 - account_credit_hold/migration18.md | 246 --- account_credit_hold/models/__init__.py | 5 - .../models/account_followup.py | 8 - .../models/account_followup_report.py | 12 - account_credit_hold/models/res_partner.py | 80 - account_credit_hold/models/sale_order.py | 17 - account_credit_hold/models/stock_picking.py | 9 - account_credit_hold/readme.md | 40 - .../views/account_followup_views.xml | 49 - .../views/res_partner_views.xml | 34 - .../views/sale_order_views.xml | 18 - .../views/stock_picking_views.xml | 19 - aged_partner_balance_na/__init__.py | 33 - aged_partner_balance_na/__manifest__.py | 32 - aged_partner_balance_na/models/__init__.py | 1 - .../models/aged_partner_balance.py | 245 --- ai_integration/__init__.py | 1 - ai_integration/__manifest__.py | 39 - ai_integration/models/__init__.py | 9 - ai_integration/models/ai_generation_params.py | 42 - ai_integration/models/ai_model.py | 80 - ai_integration/models/ai_model_stats.py | 94 - ai_integration/models/ai_provider.py | 73 - ai_integration/models/ai_provider_instance.py | 106 -- .../models/ai_provider_interface.py | 55 - ai_integration/models/doc_models.md | 90 - ai_integration/models/mixins/__init__.py | 1 - ai_integration/models/mixins/ai_base_mixin.py | 167 -- ai_integration/models/res_company.py | 21 - ai_integration/models/res_config_settings.py | 22 - ai_integration/security/ai_security.xml | 20 - ai_integration/security/ir.model.access.csv | 11 - ai_integration/security/ir_rule.xml | 28 - ai_integration/views/ai_model_stats_views.xml | 118 -- ai_integration/views/ai_model_views.xml | 96 - .../views/ai_provider_instance_views.xml | 107 -- ai_integration/views/ai_provider_views.xml | 88 - ai_integration/views/menu.xml | 51 - ai_integration/views/res_company_views.xml | 14 - .../views/res_config_settings_views.xml | 66 - ai_integration_ollama_api/__init__.py | 1 - ai_integration_ollama_api/__manifest__.py | 36 - .../data/ai_provider_data.xml | 13 - .../data/ai_provider_instance_data.xml | 31 - .../data/ir_model_inherit.xml | 10 - .../data/ollama_provider.xml | 13 - ai_integration_ollama_api/doc/ollama_api.md | 1627 ----------------- .../migrations/1.0.0/post-migration.py | 17 - ai_integration_ollama_api/models/__init__.py | 27 - .../models/ai_provider_instance.py | 153 -- .../models/ai_provider_ollama.py.bak | 35 - .../models/ollama_model_stats.py | 116 -- .../models/ollama_provider.py | 324 ---- .../models/ollama_provider_mixin.py | 274 --- .../security/ir.model.access.csv | 5 - .../views/ai_provider_instance_views.xml | 15 - .../views/ollama_stats_views.xml | 118 -- .../views/ollama_views.xml | 108 -- ai_integration_openai_api/__init__.py | 1 - ai_integration_openai_api/__manifest__.py | 35 - .../data/chatgpt_provider.xml | 14 - ai_integration_openai_api/models/__init__.py | 2 - .../models/chatgpt_instance.py | 48 - .../models/chatgpt_provider.py | 163 -- .../security/ir.model.access.csv | 3 - .../views/chatgpt_instance_views.xml | 106 -- .../__init__.py | 5 - .../__manifest__.py | 21 - .../migration18.md | 87 - .../models/__init__.py | 2 - .../models/mail_wizard_invite.py | 11 - bemade_attachments_cleanup/__init__.py | 1 - bemade_attachments_cleanup/__manifest__.py | 22 - bemade_attachments_cleanup/i18n/fr_CA.po | 37 - bemade_attachments_cleanup/migration18.md | 31 - .../security/ir.model.access.csv | 2 - bemade_attachments_cleanup/wizard/__init__.py | 1 - .../wizard/attachment_cleanup_wizard.py | 45 - .../wizard/attachment_cleanup_wizard_view.xml | 32 - bemade_documents_portal/__init__.py | 2 - bemade_documents_portal/__manifest__.py | 32 - .../controllers/__init__.py | 1 - bemade_documents_portal/controllers/portal.py | 65 - bemade_documents_portal/models/__init__.py | 1 - bemade_documents_portal/models/documents.py | 17 - .../views/document_portal_templates.xml | 112 -- bemade_fetchmail_only_production/README.md | 0 bemade_fetchmail_only_production/__init__.py | 4 - .../__manifest__.py | 20 - .../migration18.md | 31 - .../models/__init__.py | 4 - .../models/fetchmail_server.py | 23 - .../readme/HISTORY.rst | 10 - bemade_fix_quality_report/__init__.py | 0 bemade_fix_quality_report/__manifest__.py | 33 - .../worksheet_custom_report_templates.xml | 8 - bemade_fsm/__init__.py | 3 - bemade_fsm/__manifest__.py | 70 - bemade_fsm/data/fsm_data.xml | 28 - bemade_fsm/i18n/fr.po | 1098 ----------- bemade_fsm/migration18.md | 369 ---- .../migrations/17.0.0.4.0/pre-migrate.py | 81 - bemade_fsm/models/__init__.py | 9 - bemade_fsm/models/fsm_visit.py | 104 -- bemade_fsm/models/product_template.py | 19 - bemade_fsm/models/project.py | 13 - bemade_fsm/models/res_company.py | 8 - bemade_fsm/models/res_partner.py | 61 - bemade_fsm/models/sale_order.py | 163 -- bemade_fsm/models/sale_order_line.py | 294 --- bemade_fsm/models/task.py | 222 --- bemade_fsm/models/task_template.py | 122 -- bemade_fsm/reports/__init__.py | 1 - .../worksheet_custom_report_templates.xml | 588 ------ .../reports/worksheet_custom_reports.py | 13 - .../reports/worksheet_custom_reports.xml | 11 - bemade_fsm/security/ir.model.access.csv | 5 - bemade_fsm/static/src/js/kanban_view.js | 37 - bemade_fsm/static/src/js/list_view.js | 36 - bemade_fsm/static/src/scss/bemade_fsm.scss | 14 - .../static/src/xml/project_view_buttons.xml | 21 - bemade_fsm/tests/__init__.py | 9 - bemade_fsm/tests/test_bemade_fsm_common.py | 284 --- bemade_fsm/tests/test_equipment.py | 32 - bemade_fsm/tests/test_fsm_contact_setting.py | 129 -- bemade_fsm/tests/test_fsm_visit.py | 144 -- bemade_fsm/tests/test_sale_order.py | 363 ---- bemade_fsm/tests/test_settings.py | 48 - bemade_fsm/tests/test_task.py | 154 -- bemade_fsm/tests/test_task_report.py | 43 - bemade_fsm/tests/test_task_template.py | 80 - bemade_fsm/views/menus.xml | 17 - bemade_fsm/views/product_views.xml | 32 - bemade_fsm/views/res_partner.xml | 52 - bemade_fsm/views/sale_order_views.xml | 64 - bemade_fsm/views/task_template_views.xml | 127 -- bemade_fsm/views/task_views.xml | 229 --- bemade_fsm/wizard/__init__.py | 2 - bemade_fsm/wizard/new_task_from_template.py | 57 - bemade_fsm/wizard/new_task_from_template.xml | 29 - bemade_fsm/wizard/res_config_settings.py | 22 - bemade_fsm/wizard/res_config_settings.xml | 24 - bemade_full_formview_from_modal/__init__.py | 0 .../__manifest__.py | 40 - .../migration18.md | 64 - .../src/view_dialogs/form_view_dialog.js | 42 - .../src/view_dialogs/form_view_dialog.xml | 13 - .../tests/test_full_formview_from_modal.js | 45 - .../tests/__init__.py | 1 - .../tests/test_full_formview_from_modal.py | 13 - bemade_git_repos_addons/__init__.py | 2 - bemade_git_repos_addons/__manifest__.py | 63 - .../data/default_directories_data.xml | 26 - bemade_git_repos_addons/models/__init__.py | 4 - bemade_git_repos_addons/models/git_addons.py | 28 - bemade_git_repos_addons/models/git_branch.py | 18 - bemade_git_repos_addons/models/git_repos.py | 84 - .../models/res_settings.py | 23 - .../security/ir.model.access.csv | 11 - .../button_create_repos.xml | 12 - .../button_create_repos_controller.js | 21 - .../button_create_repos_view.js | 13 - .../views/action_and_menu.xml | 31 - .../views/git_addons_views.xml | 36 - .../views/git_repos_views.xml | 34 - .../views/res_settings_views.xml | 44 - bemade_git_repos_addons/wizard/__init__.py | 2 - .../wizard/directory_wizard.py | 83 - .../wizard/directory_wizard_views.xml | 31 - .../wizard/git_repos_wizard.py | 36 - .../wizard/git_repos_wizard_views.xml | 21 - bemade_helpdesk_mailcow_blacklist/__init__.py | 1 - .../__manifest__.py | 37 - .../data/helpdesk_stages.xml | 10 - .../demo/demo.xml | 27 - .../migration18.md | 31 - .../models/__init__.py | 1 - .../models/helpdesk_ticket.py | 27 - .../models/res_partner.py | 11 - .../security/ir.model.access.csv | 2 - .../views/helpdesk_ticket_views.xml | 14 - .../__init__.py | 1 - .../__manifest__.py | 31 - .../migration18.md | 72 - .../models/__init__.py | 1 - .../models/mail_thread.py | 43 - bemade_hide_decimal_on_unit/__init__.py | 5 - bemade_hide_decimal_on_unit/__manifest__.py | 23 - bemade_hide_decimal_on_unit/migration18.md | 72 - .../views/purchase.xml | 31 - bemade_hide_decimal_on_unit/views/sale.xml | 16 - bemade_l10n_ca_payroll/__init__.py | 1 - bemade_l10n_ca_payroll/__manifest__.py | 37 - .../data/hr_payslip_input_type_data.xml | 48 - .../data/hr_salary_rule_data.xml | 146 -- bemade_l10n_ca_payroll/models/__init__.py | 1 - .../models/hr_payroll_structure_type.py | 26 - bemade_l10n_ca_payroll/models/hr_payslip.py | 29 - bemade_mailcow_integration/__init__.py | 3 - bemade_mailcow_integration/__manifest__.py | 45 - .../controllers/controllers.py | 13 - bemade_mailcow_integration/demo/demo.xml | 30 - bemade_mailcow_integration/migration18.md | 95 - .../migrations/15.0.1.0.1/pre-migrate.py | 13 - bemade_mailcow_integration/models/__init__.py | 9 - .../models/mail_alias.py | 29 - bemade_mailcow_integration/models/mailcow.py | 62 - .../models/mailcow_alias.py | 109 -- .../models/mailcow_blacklist.py | 98 - .../models/mailcow_mailbox.py | 148 -- .../models/res_config_settings.py | 32 - .../models/res_users.py | 37 - .../security/ir.model.access.csv | 7 - .../static/description/icon.png | Bin 24034 -> 0 bytes .../static/description/logomailcow.svg | 187 -- .../static/src/js/mailcow.js | 89 - .../static/src/xml/mailcow_templates.xml | 28 - bemade_mailcow_integration/tests/__init__.py | 1 - .../tests/test_mailcow.py | 12 - .../views/mailcow_alias_views.xml | 76 - .../views/mailcow_blacklist_views.xml | 66 - .../views/mailcow_mailbox_views.xml | 82 - .../views/res_config_settings_views.xml | 55 - .../views/res_users_views.xml | 16 - .../views/templates.xml | 24 - bemade_mailcow_integration/views/views.xml | 60 - bemade_margin_vendor_pricelist/__init__.py | 1 - .../__manifest__.py | 31 - .../i18n/bemade_margin_vendor_pricelist.pot | 58 - bemade_margin_vendor_pricelist/i18n/fr.po | 58 - bemade_margin_vendor_pricelist/migration18.md | 93 - .../migrations/17.0.0.0.4/pre-migrate.py | 21 - .../models/__init__.py | 2 - .../models/sale_order.py | 23 - .../models/sale_order_line.py | 117 -- .../tests/__init__.py | 1 - .../tests/test_margins.py | 372 ---- .../views/sale_order.xml | 57 - bemade_module_linker/__init__.py | 12 - bemade_module_linker/__manifest__.py | 24 - bemade_module_linker/migration18.md | 31 - bemade_module_linker/models/__init__.py | 1 - .../models/res_config_settings.py | 8 - .../models/res_modules_link.py | 28 - .../views/res_config_settings_views.xml | 33 - bemade_multiple_billing_contacts/__init__.py | 1 - .../__manifest__.py | 44 - .../models/__init__.py | 3 - .../models/account_move.py | 34 - .../models/res_partner.py | 28 - .../models/sale_order.py | 21 - .../tests/__init__.py | 1 - .../tests/test_billing_contacts.py | 117 -- .../views/account_move_views.xml | 21 - .../views/res_partner_views.xml | 29 - .../views/sale_order_views.xml | 20 - bemade_odoo_partner_scrapper/__init__.py | 3 - bemade_odoo_partner_scrapper/__manifest__.py | 36 - bemade_odoo_partner_scrapper/data/demo.xml | 106 -- .../data/res_partner_relation_type.xml | 43 - .../models/__init__.py | 3 - .../models/res_partner.py | 264 --- .../views/res_partner_views.xml | 83 - .../__init__.py | 1 - .../__manifest__.py | 33 - bemade_open_project_details/__init__.py | 0 bemade_open_project_details/__manifest__.py | 39 - .../views/project_project_views.xml | 20 - bemade_packing_wizard/__init__.py | 4 - bemade_packing_wizard/__manifest__.py | 25 - bemade_packing_wizard/migration18.md | 93 - bemade_packing_wizard/models/__init__.py | 5 - .../models/delivery_carrier.py | 13 - .../models/stock_quant_package.py | 84 - .../views/delivery_carrier_views.xml | 13 - .../views/stock_package_views.xml | 17 - bemade_packing_wizard/wizard/__init__.py | 3 - .../wizard/choose_delivery_package.py | 71 - .../wizard/choose_delivery_package_views.xml | 20 - bemade_partner_email_domain/__init__.py | 2 - bemade_partner_email_domain/__manifest__.py | 38 - .../controllers/__init__.py | 1 - .../controllers/main.py | 40 - .../data/mail_template_data.xml | 106 -- .../data/template_data.xml | 17 - bemade_partner_email_domain/i18n/fr_CA.po | 41 - bemade_partner_email_domain/migration18.md | 93 - .../models/__init__.py | 1 - .../models/res_partner.py | 97 - .../views/res_partner_views.xml | 20 - bemade_partner_root_ancestor/__init__.py | 1 - bemade_partner_root_ancestor/__manifest__.py | 32 - bemade_partner_root_ancestor/migration18.md | 92 - .../models/__init__.py | 1 - .../models/res_partner.py | 18 - .../tests/__init__.py | 1 - .../tests/test_root_ancestor.py | 55 - bemade_payslip_done_as_not_paid/__init__.py | 0 .../__manifest__.py | 31 - .../views/hr_payslip_views.xml | 6 - bemade_picking_upstream/__init__.py | 1 - bemade_picking_upstream/__manifest__.py | 32 - bemade_picking_upstream/migration18.md | 92 - bemade_picking_upstream/models/__init__.py | 1 - .../models/stock_picking.py | 33 - .../views/stock_picking_views.xml | 14 - .../__init__.py | 1 - .../__manifest__.py | 25 - .../migration18.md | 93 - .../models/__init__.py | 3 - .../models/purchase_order.py | 73 - .../models/res_company.py | 59 - .../models/res_config_settings.py | 37 - .../tests/__init__.py | 1 - .../tests/test_purchase_order_overdue.py | 144 -- .../views/res_config_settings_views.xml | 75 - bemade_pwa_config/__init__.py | 2 - bemade_pwa_config/__manifest__.py | 27 - bemade_pwa_config/controllers/__init__.py | 1 - bemade_pwa_config/controllers/main.py | 42 - bemade_pwa_config/i18n/bemade_pwa_config.pot | 58 - bemade_pwa_config/i18n/fr_CA.po | 58 - bemade_pwa_config/migration18.md | 93 - bemade_pwa_config/models/__init__.py | 2 - bemade_pwa_config/models/res_company.py | 47 - .../models/res_config_settings.py | 31 - .../security/ir.model.access.csv | 0 .../views/res_config_settings_views.xml | 27 - bemade_quotation_alternative/__init__.py | 4 - bemade_quotation_alternative/__manifest__.py | 37 - bemade_quotation_alternative/migration18.md | 93 - .../models/__init__.py | 3 - .../models/sale_order.py | 19 - .../security/ir.model.access.csv | 3 - .../views/sale_order_views.xml | 62 - .../wizard/__init__.py | 4 - .../sale_oder_line_duplication_wizard.py | 9 - .../wizard/sale_order_duplication_wizard.py | 105 -- .../sale_order_duplication_wizard_view.xml | 39 - bemade_reordering_rules_chatter/__init__.py | 5 - .../__manifest__.py | 22 - .../migration18.md | 93 - .../models/__init__.py | 1 - .../models/stock_warehouse_orderpoint.py | 19 - .../views/stock_warehouse_orderpoint.xml | 29 - bemade_sale_order_line_number/__manifest__.py | 21 - .../views/sale_order_views.xml | 27 - bemade_search_supplier_code/__init__.py | 5 - bemade_search_supplier_code/__manifest__.py | 24 - bemade_search_supplier_code/migration18.md | 31 - .../models/__init__.py | 1 - .../models/product_product.py | 26 - .../views/product_product_views.xml | 12 - bemade_so_and_po_only_company/__init__.py | 0 bemade_so_and_po_only_company/__manifest__.py | 24 - bemade_so_and_po_only_company/migration18.md | 32 - .../views/purchase_order.xml | 15 - .../views/sale_order.xml | 15 - bemade_so_followers_to_picking/__init__.py | 1 - .../__manifest__.py | 22 - bemade_so_followers_to_picking/migration18.md | 93 - .../models/__init__.py | 1 - .../models/stock_picking.py | 20 - bemade_sports_clinic/__init__.py | 2 - bemade_sports_clinic/__manifest__.py | 63 - bemade_sports_clinic/controllers/__init__.py | 1 - .../controllers/team_staff_portal.py | 110 -- .../data/demo/sports_clinic_demo_data.xml | 189 -- .../data/sports_clinic_data.xml | 87 - bemade_sports_clinic/i18n/fr_CA.po | 1200 ------------ .../migrations/16.0.1.5.4/post-migrate.py | 21 - .../migrations/16.0.1.5.7/post-migrate.py | 22 - .../migrations/16.0.1.5.8/post-migrate.py | 7 - .../migrations/16.0.1.6.0/post-migrate.py | 6 - .../migrations/16.0.1.7.0/post-migrate.py | 23 - .../migrations/16.0.1.7.0/pre-migrate.py | 10 - bemade_sports_clinic/models/__init__.py | 7 - bemade_sports_clinic/models/mail_followers.py | 46 - bemade_sports_clinic/models/patient.py | 332 ---- .../models/patient_contact.py | 35 - bemade_sports_clinic/models/patient_injury.py | 175 -- bemade_sports_clinic/models/res_partner.py | 57 - bemade_sports_clinic/models/res_users.py | 45 - bemade_sports_clinic/models/sports_team.py | 244 --- .../security/ir.model.access.csv | 13 - .../security/sports_clinic_groups.xml | 31 - .../security/sports_clinic_rules.xml | 113 -- .../static/description/icon.png | Bin 30588 -> 0 bytes bemade_sports_clinic/tests/__init__.py | 3 - bemade_sports_clinic/tests/test_patient.py | 222 --- bemade_sports_clinic/tests/test_rights.py | 114 -- bemade_sports_clinic/tests/test_users.py | 35 - .../views/res_partner_views.xml | 24 - .../views/res_users_views.xml | 16 - .../views/sports_clinic_menus.xml | 58 - .../views/sports_clinic_portal_views.xml | 220 --- .../views/sports_patient_injury_views.xml | 69 - .../views/sports_patient_views.xml | 189 -- .../views/sports_team_views.xml | 160 -- bemade_stock_quant_valuation/__init__.py | 1 - bemade_stock_quant_valuation/__manifest__.py | 39 - bemade_stock_quant_valuation/migration18.md | 93 - .../models/__init__.py | 1 - .../models/stock_quant.py | 20 - .../views/stock_account_views.xml | 19 - bemade_time_off_follower/__init__.py | 1 - bemade_time_off_follower/__manifest__.py | 15 - bemade_time_off_follower/migration18.md | 93 - bemade_time_off_follower/models/__init__.py | 2 - bemade_time_off_follower/models/hr_leave.py | 11 - .../models/mail_thread.py | 93 - bemade_time_off_follower/tests/__init__.py | 1 - .../tests/test_mail_thread.py | 64 - .../views/hr_leave_views.xml | 13 - bemade_total_show_currency/__manifest__.py | 41 - .../views/total_template.xml | 14 - .../__init__.py | 1 - .../__manifest__.py | 22 - .../migration18.md | 31 - .../models/__init__.py | 1 - .../models/sale_order.py | 28 - bemade_user_custom_apps_order/__init__.py | 27 - bemade_user_custom_apps_order/__manifest__.py | 42 - .../models/__init__.py | 9 - .../models/ir_ui_menu.py | 84 - .../models/res_users.py | 63 - .../models/res_users_menu_order.py | 28 - .../security/ir.model.access.csv | 3 - .../tests/tours/custom_app_order_tour.js | 19 - .../tests/__init__.py | 1 - .../tests/test_user_custom_app_order.py | 36 - .../views/res_users_view.xml | 33 - .../views/user_menu_sequence.xml | 35 - bemade_user_password_bundle/__init__.py | 3 - bemade_user_password_bundle/__manifest__.py | 28 - bemade_user_password_bundle/migration18.md | 93 - .../models/__init__.py | 4 - .../models/hr_employee.py | 21 - .../models/password_bundle.py | 30 - bemade_utils/__init__.py | 2 - bemade_utils/__manifest__.py | 33 - bemade_utils/migration18.md | 31 - bemade_utils/tests/__init__.py | 2 - bemade_utils/tests/test_patching_test.py | 17 - bemade_utils/tools/__init__.py | 2 - bemade_utils/tools/test.py | 28 - .../__init__.py | 1 - .../__manifest__.py | 40 - .../models/__init__.py | 1 - .../models/mrp_production.py | 41 - .../models/mrp_workorder.py | 27 - .../static/src/mrp_display/mrp_display.esm.js | 18 - .../src/mrp_display/mrp_display_action.esm.js | 14 - .../src/mrp_display/mrp_display_record.esm.js | 9 - .../src/mrp_display/mrp_display_record.xml | 19 - .../tests/__init__.py | 1 - .../tests/test_mrp_production.py | 72 - .../views/mrp_production_views.xml | 23 - commercial_invoice/__init__.py | 4 - commercial_invoice/__manifest__.py | 32 - .../data/commercial_invoice_sequence.xml | 12 - commercial_invoice/models/__init__.py | 2 - commercial_invoice/models/account_move.py | 15 - .../models/commercial_invoice.py | 159 -- commercial_invoice/report/__init__.py | 2 - .../report/commercial_invoice_report.xml | 13 - .../report/report_templates.xml | 257 --- .../security/ir.model.access.csv | 3 - .../views/account_move_views.xml | 15 - .../views/commercial_invoice_views.xml | 128 -- confirm_many2one_create/__init__.py | 0 confirm_many2one_create/__manifest__.py | 37 - .../static/src/js/many2one_field.esm.js | 12 - current_user_as_invoice_user/__init__.py | 1 - current_user_as_invoice_user/__manifest__.py | 30 - .../tests/__init__.py | 1 - .../test_current_user_as_invoice_user.py | 52 - .../wizard/__init__.py | 2 - .../wizard/sale_make_invoice_advance.py | 15 - .../wizard/sale_order.py | 13 - customer_applications/__init__.py | 1 - customer_applications/__manifest__.py | 40 - customer_applications/data/menus_actions.xml | 43 - customer_applications/models/__init__.py | 5 - customer_applications/models/application.py | 36 - .../models/application_specification.py | 42 - .../models/application_specification_key.py | 11 - .../models/application_type.py | 54 - customer_applications/models/res_partner.py | 42 - customer_applications/security/groups.xml | 14 - .../security/ir.model.access.csv | 7 - customer_applications/tests/__init__.py | 1 - .../tests/test_application.py | 59 - .../views/application_type_views.xml | 74 - .../views/application_views.xml | 86 - .../views/res_partner_views.xml | 45 - customer_itch_cycle/__init__.py | 2 - customer_itch_cycle/__manifest__.py | 15 - customer_itch_cycle/models/__init__.py | 3 - .../models/itch_cycle_product_partner.py | 33 - customer_itch_cycle/models/sale_order.py | 44 - .../views/itch_cycle_product_partner_view.xml | 44 - .../views/res_partner_view.xml | 23 - fsm_equipment/__init__.py | 1 - fsm_equipment/__manifest__.py | 38 - .../migrations/17.0.0.2.0/post-migrate.py | 30 - fsm_equipment/models/__init__.py | 4 - fsm_equipment/models/equipment.py | 144 -- fsm_equipment/models/equipment_tag.py | 19 - fsm_equipment/models/res_partner.py | 51 - fsm_equipment/models/task.py | 14 - fsm_equipment/security/ir.model.access.csv | 3 - fsm_equipment/views/equipment_views.xml | 192 -- fsm_equipment/views/project_task_views.xml | 14 - fsm_equipment/views/res_partner_views.xml | 57 - fsm_visit_confirmation/__init__.py | 2 - fsm_visit_confirmation/__manifest__.py | 33 - .../controllers/__init__.py | 1 - fsm_visit_confirmation/controllers/portal.py | 35 - .../data/mail_templates.xml | 47 - fsm_visit_confirmation/models/__init__.py | 1 - fsm_visit_confirmation/models/project_task.py | 9 - .../project_portal_project_task_templates.xml | 10 - impersonate_user/__init__.py | 2 - impersonate_user/__manifest__.py | 40 - impersonate_user/controllers/__init__.py | 1 - impersonate_user/controllers/main.py | 9 - impersonate_user/models/__init__.py | 2 - impersonate_user/models/ir_http.py | 11 - impersonate_user/models/res_users.py | 45 - .../src/systray_unimpersonate_button.esm.js | 27 - .../src/systray_unimpersonate_button.xml | 15 - .../views/impersonation_views.xml | 28 - improved_mo_origin/__init__.py | 1 - improved_mo_origin/__manifest__.py | 38 - improved_mo_origin/models/__init__.py | 1 - improved_mo_origin/models/mrp_production.py | 71 - .../static/src/mrp_display/mrp_display.esm.js | 25 - .../src/mrp_display/mrp_display_action.esm.js | 14 - .../src/mrp_display/mrp_display_record.esm.js | 9 - .../src/mrp_display/mrp_display_record.xml | 30 - improved_mo_origin/tests/__init__.py | 1 - .../tests/test_mrp_production.py | 118 -- .../views/mrp_production_views.xml | 25 - interactive_discuss_ai/__init__.py | 1 - interactive_discuss_ai/__manifest__.py | 46 - interactive_discuss_ai/models/__init__.py | 2 - interactive_discuss_ai/models/ai_assistant.py | 101 - interactive_discuss_ai/models/ai_config.py | 61 - interactive_discuss_ai/models/ai_service.py | 62 - .../security/ir.model.access.csv | 3 - .../static/src/js/ai_assistant_chat.js | 52 - .../static/src/xml/ai_assistant_chat.xml | 12 - .../views/ai_assistant_views.xml | 86 - .../views/ai_config_views.xml | 83 - l10n_ca_pst_reports/__init__.py | 0 l10n_ca_pst_reports/__manifest__.py | 33 - l10n_ca_pst_reports/tests/__init__.py | 1 - .../tests/test_report_tax_numbers.py | 65 - l10n_ca_pst_reports/views/external_layout.xml | 23 - mo_back_to_draft/__init__.py | 1 - mo_back_to_draft/__manifest__.py | 33 - mo_back_to_draft/models/__init__.py | 1 - mo_back_to_draft/models/mrp_production.py | 16 - .../views/mrp_production_views.xml | 16 - msg_attachments_to_mail_message/__init__.py | 1 - .../__manifest__.py | 63 - .../migrations/16.0.1.1/__init__.py | 1 - .../migrations/16.0.1.1/pre-migration.py | 36 - .../migrations/__init__.py | 1 - .../models/__init__.py | 3 - .../models/ir_attachment.py | 842 --------- .../models/mail_thread.py | 23 - .../models/res_config_settings.py | 39 - .../requirements.txt | 3 - .../views/res_config_settings_views.xml | 47 - msg_viewer/__init__.py | 2 - msg_viewer/__manifest__.py | 40 - msg_viewer/controllers/__init__.py | 1 - msg_viewer/controllers/main.py | 88 - msg_viewer/models/__init__.py | 1 - msg_viewer/models/ir_attachment.py | 26 - .../attachment_card_msg.xml | 16 - .../src/components/msg_viewer/msg_viewer.js | 72 - .../src/components/msg_viewer/msg_viewer.xml | 16 - msg_viewer/static/src/css/msg_viewer.css | 48 - msg_viewer/static/src/js/msg_viewer.js | 49 - .../src/lib/components/attachment/index.html | 12 - .../src/lib/components/attachment/index.ts | 30 - .../src/lib/components/attachment/styles.css | 3 - .../lib/components/embedded-msg/index.html | 9 - .../src/lib/components/embedded-msg/index.ts | 26 - .../lib/components/embedded-msg/styles.css | 3 - .../src/lib/components/error/index.html | 1 - .../static/src/lib/components/error/index.ts | 6 - .../src/lib/components/error/styles.css | 4 - .../src/lib/components/message/index.html | 33 - .../src/lib/components/message/index.ts | 79 - .../src/lib/components/message/styles.css | 50 - .../src/lib/components/recipient/index.html | 1 - .../src/lib/components/recipient/index.ts | 48 - .../src/lib/components/recipient/styles.css | 0 .../static/src/lib/components/styles.css | 5 - msg_viewer/static/src/lib/favicon.ico | Bin 4158 -> 0 bytes msg_viewer/static/src/lib/index.html | 50 - .../static/src/lib/msg-viewer-main/.gitignore | 184 -- .../static/src/lib/msg-viewer-main/LICENSE | 21 - .../static/src/lib/msg-viewer-main/README.md | 36 - .../static/src/lib/msg-viewer-main/build.ts | 75 - .../static/src/lib/msg-viewer-main/bun.lockb | Bin 24712 -> 0 bytes .../src/lib/msg-viewer-main/declarations.d.ts | 8 - .../static/src/lib/msg-viewer-main/icon.svg | 12 - .../src/lib/msg-viewer-main/jsconfig.json | 27 - .../lib/components/attachment/index.html | 12 - .../lib/components/attachment/index.ts | 30 - .../lib/components/attachment/styles.css | 3 - .../lib/components/embedded-msg/index.html | 9 - .../lib/components/embedded-msg/index.ts | 26 - .../lib/components/embedded-msg/styles.css | 3 - .../lib/components/error/index.html | 1 - .../lib/components/error/index.ts | 6 - .../lib/components/error/styles.css | 4 - .../lib/components/message/index.html | 33 - .../lib/components/message/index.ts | 79 - .../lib/components/message/styles.css | 50 - .../lib/components/recipient/index.html | 1 - .../lib/components/recipient/index.ts | 48 - .../lib/components/recipient/styles.css | 0 .../msg-viewer-main/lib/components/styles.css | 5 - .../src/lib/msg-viewer-main/lib/favicon.ico | Bin 4158 -> 0 bytes .../src/lib/msg-viewer-main/lib/index.html | 50 - .../lib/resources/google331b65fa04565532.html | 1 - .../msg-viewer-main/lib/resources/robots.txt | 2 - .../lib/msg-viewer-main/lib/scripts/index.ts | 63 - .../msg-viewer-main/lib/scripts/msg/README.md | 37 - .../msg/compound-file/compound-file.ts | 84 - .../compound-file/constants/text-decoder.ts | 1 - .../lib/scripts/msg/compound-file/difat.ts | 34 - .../msg/compound-file/directory/directory.ts | 157 -- .../directory/enums/color-flag.ts | 4 - .../directory/enums/object-type.ts | 6 - .../directory/types/directory-entry.d.ts | 132 -- .../lib/scripts/msg/compound-file/fat.ts | 24 - .../lib/scripts/msg/compound-file/header.ts | 125 -- .../lib/scripts/msg/compound-file/mini-fat.ts | 26 - .../lib/scripts/msg/compound-file/util.ts | 31 - .../lib/scripts/msg/msg-parser.ts | 110 -- .../lib/scripts/msg/package.json | 8 - .../lib/scripts/msg/rtf/decompressor/crc.ts | 19 - .../msg/rtf/decompressor/dictionary.ts | 14 - .../scripts/msg/rtf/decompressor/header.ts | 49 - .../lib/scripts/msg/rtf/rtf-decompressor.ts | 69 - .../scripts/msg/streams/constants/folders.ts | 1 - .../scripts/msg/streams/entry/entry-stream.ts | 45 - .../streams/entry/types/entry-stream-entry.ts | 26 - .../msg/streams/property/properties.ts | 41 - .../msg/streams/property/property-stream.ts | 88 - .../msg/streams/property/property-types.ts | 83 - .../streams/property/types/property-data.d.ts | 49 - .../property/types/property-header.d.ts | 26 - .../property/types/property-stream-entry.d.ts | 7 - .../lib/scripts/msg/types/message.d.ts | 34 - .../lib/scripts/utils/file-size-util.ts | 12 - .../lib/scripts/utils/html-template-util.ts | 20 - .../lib/msg-viewer-main/lib/styles/root.css | 131 -- .../lib/msg-viewer-main/lib/styles/styles.css | 2 - .../src/lib/msg-viewer-main/package-lock.json | 761 -------- .../src/lib/msg-viewer-main/package.json | 20 - msg_viewer/static/src/lib/msg-viewer.js | 36 - msg_viewer/static/src/lib/msg-viewer.zip | Bin 57332 -> 0 bytes .../lib/resources/google331b65fa04565532.html | 1 - .../static/src/lib/resources/robots.txt | 2 - msg_viewer/static/src/lib/scripts/index.ts | 63 - .../static/src/lib/scripts/msg/README.md | 37 - .../msg/compound-file/compound-file.ts | 84 - .../compound-file/constants/text-decoder.ts | 1 - .../lib/scripts/msg/compound-file/difat.ts | 34 - .../msg/compound-file/directory/directory.ts | 157 -- .../directory/enums/color-flag.ts | 4 - .../directory/enums/object-type.ts | 6 - .../directory/types/directory-entry.d.ts | 132 -- .../src/lib/scripts/msg/compound-file/fat.ts | 24 - .../lib/scripts/msg/compound-file/header.ts | 125 -- .../lib/scripts/msg/compound-file/mini-fat.ts | 26 - .../src/lib/scripts/msg/compound-file/util.ts | 31 - .../static/src/lib/scripts/msg/msg-parser.ts | 110 -- .../static/src/lib/scripts/msg/package.json | 8 - .../lib/scripts/msg/rtf/decompressor/crc.ts | 19 - .../msg/rtf/decompressor/dictionary.ts | 14 - .../scripts/msg/rtf/decompressor/header.ts | 49 - .../lib/scripts/msg/rtf/rtf-decompressor.ts | 69 - .../scripts/msg/streams/constants/folders.ts | 1 - .../scripts/msg/streams/entry/entry-stream.ts | 45 - .../streams/entry/types/entry-stream-entry.ts | 26 - .../msg/streams/property/properties.ts | 41 - .../msg/streams/property/property-stream.ts | 88 - .../msg/streams/property/property-types.ts | 83 - .../streams/property/types/property-data.d.ts | 49 - .../property/types/property-header.d.ts | 26 - .../property/types/property-stream-entry.d.ts | 7 - .../src/lib/scripts/msg/types/message.d.ts | 34 - .../src/lib/scripts/utils/file-size-util.ts | 12 - .../lib/scripts/utils/html-template-util.ts | 20 - msg_viewer/static/src/lib/styles/root.css | 131 -- msg_viewer/static/src/lib/styles/styles.css | 2 - .../static/src/models/attachment_card_msg.js | 50 - msg_viewer/test/FACTURE NO. 7005451.msg | Bin 257024 -> 0 bytes msg_viewer/test/analyze_msg.py | 68 - msg_viewer/views/msg_viewer_views.xml | 31 - multi_account_statement_import/__init__.py | 0 .../__manifest__.py | 32 - odoo_proxmox_manager/README.md | 90 - odoo_proxmox_manager/__init__.py | 3 - odoo_proxmox_manager/__manifest__.py | 35 - odoo_proxmox_manager/controllers/__init__.py | 1 - odoo_proxmox_manager/controllers/main.py | 9 - odoo_proxmox_manager/models/__init__.py | 3 - .../models/proxmox_cluster.py | 37 - odoo_proxmox_manager/models/proxmox_server.py | 164 -- odoo_proxmox_manager/models/proxmox_vm.py | 87 - odoo_proxmox_manager/requirements.txt | 2 - .../security/ir.model.access.csv | 9 - .../security/proxmox_security.xml | 39 - .../static/description/icon.png | Bin 833 -> 0 bytes .../proxmox_server_list.js | 32 - .../proxmox_server_list.xml | 10 - .../static/src/js/dashboard_view.js | 51 - .../static/src/js/proxmox_server_list.js | 52 - .../static/src/scss/dashboard.scss | 113 -- .../static/src/xml/dashboard.xml | 57 - .../static/src/xml/proxmox_server_list.xml | 10 - .../views/proxmox_cluster_views.xml | 89 - odoo_proxmox_manager/views/proxmox_menus.xml | 32 - .../views/proxmox_server_views.xml | 108 -- .../views/proxmox_vm_views.xml | 107 -- odoo_proxmox_manager/wizard/__init__.py | 1 - .../wizard/proxmox_server_wizard.py | 98 - .../wizard/proxmox_server_wizard_views.xml | 67 - odoo_rsync_backup/__init__.py | 1 - odoo_rsync_backup/__manifest__.py | 20 - odoo_rsync_backup/data/backup_cron.xml | 14 - odoo_rsync_backup/models/__init__.py | 1 - odoo_rsync_backup/models/rsync_config.py | 185 -- .../security/ir.model.access.csv | 2 - .../views/rsync_config_views.xml | 33 - odoo_to_odoo_bemade/__init__.py | 1 - odoo_to_odoo_bemade/__manifest__.py | 32 - odoo_to_odoo_bemade/data/ir_cron_data.xml | 56 - odoo_to_odoo_bemade/models/__init__.py | 6 - odoo_to_odoo_bemade/models/sync_instance.py | 517 ------ odoo_to_odoo_bemade/models/sync_log.py | 62 - odoo_to_odoo_bemade/models/sync_manager.py | 393 ---- odoo_to_odoo_bemade/models/sync_model.py | 108 -- .../models/sync_model_field.py | 121 -- odoo_to_odoo_bemade/models/sync_queue.py | 68 - .../security/ir.model.access.csv | 7 - .../static/description/icon.png | Bin 13794 -> 0 bytes .../static/description/icon.svg | 30 - .../static/description/index.html | 93 - odoo_to_odoo_bemade/views/menus.xml | 33 - .../views/sync_instance_views.xml | 126 -- odoo_to_odoo_bemade/views/sync_log_views.xml | 98 - .../views/sync_model_views.xml | 129 -- .../views/sync_queue_views.xml | 122 -- odoo_to_odoo_bemade_customer/__init__.py | 1 - odoo_to_odoo_bemade_customer/__manifest__.py | 31 - .../data/ir_cron_data.xml | 56 - .../models/__init__.py | 6 - .../models/sync_config.py | 202 -- .../models/sync_log.py | 131 -- .../models/sync_manager.py | 281 --- .../models/sync_model.py | 176 -- .../models/sync_model_field.py | 117 -- .../models/sync_queue.py | 116 -- .../security/ir.model.access.csv | 13 - .../static/description/icon.png | Bin 13794 -> 0 bytes .../static/description/icon.svg | 30 - .../static/description/index.html | 126 -- odoo_to_odoo_bemade_customer/views/menus.xml | 33 - .../views/sync_instance_views.xml | 129 -- .../views/sync_log_views.xml | 98 - .../views/sync_model_views.xml | 129 -- .../views/sync_queue_views.xml | 122 -- odoo_to_odoo_sync/Spécifications.md | 676 ------- odoo_to_odoo_sync/__init__.py | 1 - odoo_to_odoo_sync/__manifest__.py | 28 - odoo_to_odoo_sync/data/ir_cron_data.xml | 15 - odoo_to_odoo_sync/models/__init__.py | 6 - odoo_to_odoo_sync/models/sync_instance.py | 279 --- odoo_to_odoo_sync/models/sync_log.py | 49 - odoo_to_odoo_sync/models/sync_manager.py | 204 --- odoo_to_odoo_sync/models/sync_model.py | 94 - odoo_to_odoo_sync/models/sync_model_field.py | 41 - odoo_to_odoo_sync/models/sync_queue.py | 204 --- .../security/ir.model.access.csv | 13 - odoo_to_odoo_sync/static/description/icon.png | Bin 13794 -> 0 bytes odoo_to_odoo_sync/static/description/icon.svg | 30 - odoo_to_odoo_sync/views/menus.xml | 45 - .../views/sync_instance_views.xml | 68 - odoo_to_odoo_sync/views/sync_log_views.xml | 51 - odoo_to_odoo_sync/views/sync_model_views.xml | 69 - odoo_to_odoo_sync/views/sync_queue_views.xml | 130 -- partner_equipment_applications/__init__.py | 1 - .../__manifest__.py | 36 - .../models/__init__.py | 2 - .../models/application.py | 29 - .../models/equipment.py | 17 - .../views/application_views.xml | 39 - .../views/equipment_views.xml | 42 - picking_policy_per_customer/__init__.py | 1 - picking_policy_per_customer/__manifest__.py | 23 - .../models/__init__.py | 2 - .../models/res_partner.py | 19 - .../models/sale_order.py | 28 - .../views/res_partner_views.xml | 13 - portal_hide_draft_order_details/__init__.py | 2 - .../__manifest__.py | 34 - portal_hide_draft_order_details/i18n/fr.po | 56 - .../i18n/portal_hide_draft_order_details.pot | 52 - .../models/__init__.py | 1 - .../models/res_company.py | 12 - .../views/sale_order_portal_templates.xml | 50 - .../wizard/__init__.py | 1 - .../wizard/res_config_settings.py | 17 - .../wizard/res_config_settings.xml | 15 - price_update_notifications/__init__.py | 2 - price_update_notifications/__manifest__.py | 39 - .../data/email_templates.xml | 61 - .../data/ir_cron_data.xml | 18 - price_update_notifications/i18n/fr.po | 309 ---- .../i18n/price_update_notifications.pot | 374 ---- price_update_notifications/models/__init__.py | 1 - .../models/price_notice_mailing.py | 132 -- .../security/ir.model.access.csv | 7 - .../views/price_notice_mailing_views.xml | 97 - price_update_notifications/wizard/__init__.py | 1 - .../wizard/send_price_update_notice.py | 83 - .../wizard/send_price_update_notice_views.xml | 36 - purchase_customer_requisition/__init__.py | 1 - purchase_customer_requisition/__manifest__.py | 38 - .../models/__init__.py | 3 - .../models/purchase_order.py | 21 - .../models/purchase_order_line.py | 223 --- .../models/purchase_requisition.py | 12 - .../tests/__init__.py | 1 - .../tests/test_purchase_order.py | 290 --- .../views/purchase_requisition_views.xml | 13 - .../views/purchase_views.xml | 16 - qc_partner_default_lang/__init__.py | 1 - qc_partner_default_lang/__manifest__.py | 14 - qc_partner_default_lang/models/__init__.py | 1 - qc_partner_default_lang/models/res_partner.py | 34 - .../static/description/index.html | 27 - recursive_tree_view/README.md | 42 - recursive_tree_view/__init__.py | 2 - recursive_tree_view/__manifest__.py | 41 - recursive_tree_view/hierarchy-svgrepo-com.svg | 15 - recursive_tree_view/models/__init__.py | 1 - recursive_tree_view/models/models.py | 18 - recursive_tree_view/rng/tree_view.rng | 104 -- .../static/description/icon.png | Bin 1984 -> 0 bytes .../static/description/images/collapsed.png | Bin 184474 -> 0 bytes .../static/description/images/expanded.png | Bin 199669 -> 0 bytes .../description/images/main_screenshot.png | Bin 45334 -> 0 bytes .../static/description/index.html | 97 - .../static/src/list_arch_parser.js | 16 - .../static/src/list_controller.js | 37 - .../static/src/list_renderer.js | 19 - .../static/src/recursive_tree_templates.xml | 40 - .../static/src/relational_model.js | 144 -- .../static/src/tree_recursive_styles.css | 28 - recursive_tree_view/validation.py | 59 - replace_invoicing_user/__init__.py | 2 - replace_invoicing_user/__manifest__.py | 36 - replace_invoicing_user/models/__init__.py | 2 - replace_invoicing_user/models/account_move.py | 193 -- .../models/res_config_settings.py | 52 - replace_invoicing_user/tests/__init__.py | 1 - .../test_current_user_as_invoice_user.py | 183 -- .../views/res_config_settings_views.xml | 34 - replace_invoicing_user/wizard/__init__.py | 2 - .../wizard/sale_make_invoice_advance.py | 62 - replace_invoicing_user/wizard/sale_order.py | 46 - stock_valuation_location/__init__.py | 1 - stock_valuation_location/__manifest__.py | 33 - stock_valuation_location/models/__init__.py | 1 - .../models/stock_valuation_layer.py | 25 - .../views/stock_valuation_layer_views.xml | 29 - temporary_change_image_size/__manifest__.py | 20 - .../views/product_template_views.xml | 13 - theme_durpro/LICENSE | 27 - theme_durpro/__init__.py | 3 - theme_durpro/__manifest__.py | 34 - theme_durpro/data/ir_asset.xml | 43 - theme_durpro/i18n/de.po | 206 --- theme_durpro/i18n/es.po | 207 --- theme_durpro/i18n/fr.po | 206 --- theme_durpro/i18n/it.po | 207 --- theme_durpro/i18n/nl.po | 206 --- theme_durpro/i18n/theme_graphene.pot | 202 -- theme_durpro/i18n/zh_CN.po | 206 --- theme_durpro/models/__init__.py | 3 - theme_durpro/models/theme_durpro.py | 14 - .../static/description/durpro_poster.png | Bin 32744 -> 0 bytes .../static/description/durpro_screenshot.jpg | Bin 84111 -> 0 bytes theme_durpro/static/description/index.html | 2 - .../static/description/theme_durpro.svg | 236 --- .../static/src/img/patterns/bg_pattern_01.jpg | Bin 49367 -> 0 bytes .../static/src/img/patterns/bg_pattern_02.jpg | Bin 38553 -> 0 bytes .../static/src/img/patterns/bg_pattern_03.jpg | Bin 35626 -> 0 bytes .../static/src/img/patterns/bg_pattern_04.jpg | Bin 79959 -> 0 bytes .../static/src/img/patterns/bg_pattern_05.jpg | Bin 45897 -> 0 bytes .../static/src/img/patterns/bg_pattern_06.jpg | Bin 52671 -> 0 bytes .../static/src/img/pictures/bg_image_01.jpg | Bin 82852 -> 0 bytes .../static/src/img/pictures/bg_image_02.jpg | Bin 81771 -> 0 bytes .../static/src/img/pictures/bg_image_03.jpg | Bin 84532 -> 0 bytes .../static/src/img/pictures/bg_image_04.jpg | Bin 69313 -> 0 bytes .../static/src/img/pictures/bg_image_05.jpg | Bin 132385 -> 0 bytes .../static/src/img/pictures/bg_image_06.jpg | Bin 64071 -> 0 bytes .../static/src/img/pictures/bg_image_07.jpg | Bin 80264 -> 0 bytes .../static/src/img/pictures/bg_image_08.jpg | Bin 203311 -> 0 bytes .../static/src/img/pictures/bg_image_09.jpg | Bin 100158 -> 0 bytes .../static/src/img/pictures/bg_image_10.jpg | Bin 73488 -> 0 bytes .../static/src/img/pictures/content_01.jpg | Bin 3726046 -> 0 bytes .../static/src/img/pictures/content_02.jpg | Bin 94594 -> 0 bytes .../static/src/img/pictures/content_03.jpg | Bin 77542 -> 0 bytes .../static/src/img/pictures/content_04.jpg | Bin 99379 -> 0 bytes .../static/src/img/pictures/content_05.jpg | Bin 69993 -> 0 bytes .../static/src/img/pictures/content_06.jpg | Bin 85457 -> 0 bytes .../static/src/img/pictures/content_07.jpg | Bin 69259 -> 0 bytes .../static/src/img/pictures/content_08.jpg | Bin 93051 -> 0 bytes .../static/src/img/pictures/content_09.jpg | Bin 64562 -> 0 bytes .../static/src/img/pictures/content_10.jpg | Bin 200134 -> 0 bytes .../static/src/img/pictures/content_11.jpg | Bin 92251 -> 0 bytes .../static/src/img/pictures/content_12.jpg | Bin 130164 -> 0 bytes .../static/src/img/pictures/content_13.jpg | Bin 111532 -> 0 bytes .../static/src/img/pictures/content_14.jpg | Bin 119900 -> 0 bytes .../static/src/img/pictures/content_15.jpg | Bin 30465 -> 0 bytes .../static/src/img/pictures/content_16.jpg | Bin 28064 -> 0 bytes .../static/src/img/pictures/content_17.jpg | Bin 30993 -> 0 bytes .../static/src/img/pictures/content_18.jpg | Bin 43790 -> 0 bytes .../static/src/img/pictures/content_19.jpg | Bin 27276 -> 0 bytes .../static/src/img/pictures/content_20.jpg | Bin 23539 -> 0 bytes .../static/src/img/pictures/content_21.jpg | Bin 26760 -> 0 bytes .../static/src/img/pictures/content_22.jpg | Bin 84090 -> 0 bytes .../static/src/img/pictures/content_23.jpg | Bin 298113 -> 0 bytes .../static/src/img/pictures/s_numbers.jpg | Bin 1689792 -> 0 bytes .../static/src/img/pictures/s_popup.jpg | Bin 73698 -> 0 bytes .../static/src/img/pictures/uiface_01.jpg | Bin 4150 -> 0 bytes .../static/src/img/pictures/uiface_02.jpg | Bin 6969 -> 0 bytes .../static/src/img/pictures/uiface_03.jpg | Bin 9117 -> 0 bytes .../static/src/img/pictures/uiface_04.jpg | Bin 11952 -> 0 bytes .../static/src/img/pictures/uiface_05.jpg | Bin 26256 -> 0 bytes .../static/src/img/pictures/uiface_06.jpg | Bin 5422 -> 0 bytes .../static/src/img/pictures/uiface_07.jpg | Bin 5474 -> 0 bytes theme_durpro/static/src/js/tour.js | 49 - .../s_showcase_slider/000_variables.scss | 21 - .../static/src/scss/bootstrap_overridden.scss | 3 - .../static/src/scss/custom_styles.scss | 5 - .../static/src/scss/primary_variables.scss | 151 -- .../static/src/scss/secondary_variables.scss | 9 - theme_durpro/views/customizations.xml | 295 --- theme_durpro/views/images_library.xml | 333 ---- wazo_integration/__init__.py | 1 - wazo_integration/__manifest__.py | 19 - wazo_integration/models/__init__.py | 2 - wazo_integration/models/res_company.py | 21 - .../models/res_config_settings.py | 57 - .../views/res_config_settings_views.xml | 62 - website_geoip_extended/__init__.py | 3 - website_geoip_extended/__manifest__.py | 41 - website_geoip_extended/models/__init__.py | 3 - .../models/website_visitor.py | 58 - .../views/website_visitor_views.xml | 40 - 977 files changed, 106 insertions(+), 49159 deletions(-) delete mode 100644 account_credit_hold/__init__.py delete mode 100644 account_credit_hold/__manifest__.py delete mode 100644 account_credit_hold/migration18.md delete mode 100644 account_credit_hold/models/__init__.py delete mode 100644 account_credit_hold/models/account_followup.py delete mode 100644 account_credit_hold/models/account_followup_report.py delete mode 100644 account_credit_hold/models/res_partner.py delete mode 100644 account_credit_hold/models/sale_order.py delete mode 100644 account_credit_hold/models/stock_picking.py delete mode 100644 account_credit_hold/readme.md delete mode 100644 account_credit_hold/views/account_followup_views.xml delete mode 100644 account_credit_hold/views/res_partner_views.xml delete mode 100644 account_credit_hold/views/sale_order_views.xml delete mode 100644 account_credit_hold/views/stock_picking_views.xml delete mode 100644 aged_partner_balance_na/__init__.py delete mode 100644 aged_partner_balance_na/__manifest__.py delete mode 100644 aged_partner_balance_na/models/__init__.py delete mode 100644 aged_partner_balance_na/models/aged_partner_balance.py delete mode 100644 ai_integration/__init__.py delete mode 100644 ai_integration/__manifest__.py delete mode 100644 ai_integration/models/__init__.py delete mode 100644 ai_integration/models/ai_generation_params.py delete mode 100644 ai_integration/models/ai_model.py delete mode 100644 ai_integration/models/ai_model_stats.py delete mode 100644 ai_integration/models/ai_provider.py delete mode 100644 ai_integration/models/ai_provider_instance.py delete mode 100644 ai_integration/models/ai_provider_interface.py delete mode 100644 ai_integration/models/doc_models.md delete mode 100644 ai_integration/models/mixins/__init__.py delete mode 100644 ai_integration/models/mixins/ai_base_mixin.py delete mode 100644 ai_integration/models/res_company.py delete mode 100644 ai_integration/models/res_config_settings.py delete mode 100644 ai_integration/security/ai_security.xml delete mode 100644 ai_integration/security/ir.model.access.csv delete mode 100644 ai_integration/security/ir_rule.xml delete mode 100644 ai_integration/views/ai_model_stats_views.xml delete mode 100644 ai_integration/views/ai_model_views.xml delete mode 100644 ai_integration/views/ai_provider_instance_views.xml delete mode 100644 ai_integration/views/ai_provider_views.xml delete mode 100644 ai_integration/views/menu.xml delete mode 100644 ai_integration/views/res_company_views.xml delete mode 100644 ai_integration/views/res_config_settings_views.xml delete mode 100644 ai_integration_ollama_api/__init__.py delete mode 100644 ai_integration_ollama_api/__manifest__.py delete mode 100644 ai_integration_ollama_api/data/ai_provider_data.xml delete mode 100644 ai_integration_ollama_api/data/ai_provider_instance_data.xml delete mode 100644 ai_integration_ollama_api/data/ir_model_inherit.xml delete mode 100644 ai_integration_ollama_api/data/ollama_provider.xml delete mode 100644 ai_integration_ollama_api/doc/ollama_api.md delete mode 100644 ai_integration_ollama_api/migrations/1.0.0/post-migration.py delete mode 100644 ai_integration_ollama_api/models/__init__.py delete mode 100644 ai_integration_ollama_api/models/ai_provider_instance.py delete mode 100644 ai_integration_ollama_api/models/ai_provider_ollama.py.bak delete mode 100644 ai_integration_ollama_api/models/ollama_model_stats.py delete mode 100644 ai_integration_ollama_api/models/ollama_provider.py delete mode 100644 ai_integration_ollama_api/models/ollama_provider_mixin.py delete mode 100644 ai_integration_ollama_api/security/ir.model.access.csv delete mode 100644 ai_integration_ollama_api/views/ai_provider_instance_views.xml delete mode 100644 ai_integration_ollama_api/views/ollama_stats_views.xml delete mode 100644 ai_integration_ollama_api/views/ollama_views.xml delete mode 100644 ai_integration_openai_api/__init__.py delete mode 100644 ai_integration_openai_api/__manifest__.py delete mode 100644 ai_integration_openai_api/data/chatgpt_provider.xml delete mode 100644 ai_integration_openai_api/models/__init__.py delete mode 100644 ai_integration_openai_api/models/chatgpt_instance.py delete mode 100644 ai_integration_openai_api/models/chatgpt_provider.py delete mode 100644 ai_integration_openai_api/security/ir.model.access.csv delete mode 100644 ai_integration_openai_api/views/chatgpt_instance_views.xml delete mode 100644 bemade_add_follower_no_sendmail_default/__init__.py delete mode 100644 bemade_add_follower_no_sendmail_default/__manifest__.py delete mode 100644 bemade_add_follower_no_sendmail_default/migration18.md delete mode 100644 bemade_add_follower_no_sendmail_default/models/__init__.py delete mode 100644 bemade_add_follower_no_sendmail_default/models/mail_wizard_invite.py delete mode 100644 bemade_attachments_cleanup/__init__.py delete mode 100644 bemade_attachments_cleanup/__manifest__.py delete mode 100644 bemade_attachments_cleanup/i18n/fr_CA.po delete mode 100644 bemade_attachments_cleanup/migration18.md delete mode 100644 bemade_attachments_cleanup/security/ir.model.access.csv delete mode 100644 bemade_attachments_cleanup/wizard/__init__.py delete mode 100644 bemade_attachments_cleanup/wizard/attachment_cleanup_wizard.py delete mode 100644 bemade_attachments_cleanup/wizard/attachment_cleanup_wizard_view.xml delete mode 100644 bemade_documents_portal/__init__.py delete mode 100644 bemade_documents_portal/__manifest__.py delete mode 100644 bemade_documents_portal/controllers/__init__.py delete mode 100644 bemade_documents_portal/controllers/portal.py delete mode 100644 bemade_documents_portal/models/__init__.py delete mode 100644 bemade_documents_portal/models/documents.py delete mode 100644 bemade_documents_portal/views/document_portal_templates.xml delete mode 100644 bemade_fetchmail_only_production/README.md delete mode 100644 bemade_fetchmail_only_production/__init__.py delete mode 100644 bemade_fetchmail_only_production/__manifest__.py delete mode 100644 bemade_fetchmail_only_production/migration18.md delete mode 100644 bemade_fetchmail_only_production/models/__init__.py delete mode 100644 bemade_fetchmail_only_production/models/fetchmail_server.py delete mode 100644 bemade_fetchmail_only_production/readme/HISTORY.rst delete mode 100644 bemade_fix_quality_report/__init__.py delete mode 100644 bemade_fix_quality_report/__manifest__.py delete mode 100644 bemade_fix_quality_report/reports/worksheet_custom_report_templates.xml delete mode 100644 bemade_fsm/__init__.py delete mode 100644 bemade_fsm/__manifest__.py delete mode 100644 bemade_fsm/data/fsm_data.xml delete mode 100644 bemade_fsm/i18n/fr.po delete mode 100644 bemade_fsm/migration18.md delete mode 100644 bemade_fsm/migrations/17.0.0.4.0/pre-migrate.py delete mode 100644 bemade_fsm/models/__init__.py delete mode 100644 bemade_fsm/models/fsm_visit.py delete mode 100644 bemade_fsm/models/product_template.py delete mode 100644 bemade_fsm/models/project.py delete mode 100644 bemade_fsm/models/res_company.py delete mode 100644 bemade_fsm/models/res_partner.py delete mode 100644 bemade_fsm/models/sale_order.py delete mode 100644 bemade_fsm/models/sale_order_line.py delete mode 100644 bemade_fsm/models/task.py delete mode 100644 bemade_fsm/models/task_template.py delete mode 100644 bemade_fsm/reports/__init__.py delete mode 100644 bemade_fsm/reports/worksheet_custom_report_templates.xml delete mode 100644 bemade_fsm/reports/worksheet_custom_reports.py delete mode 100644 bemade_fsm/reports/worksheet_custom_reports.xml delete mode 100644 bemade_fsm/security/ir.model.access.csv delete mode 100644 bemade_fsm/static/src/js/kanban_view.js delete mode 100644 bemade_fsm/static/src/js/list_view.js delete mode 100644 bemade_fsm/static/src/scss/bemade_fsm.scss delete mode 100644 bemade_fsm/static/src/xml/project_view_buttons.xml delete mode 100644 bemade_fsm/tests/__init__.py delete mode 100644 bemade_fsm/tests/test_bemade_fsm_common.py delete mode 100644 bemade_fsm/tests/test_equipment.py delete mode 100644 bemade_fsm/tests/test_fsm_contact_setting.py delete mode 100644 bemade_fsm/tests/test_fsm_visit.py delete mode 100644 bemade_fsm/tests/test_sale_order.py delete mode 100644 bemade_fsm/tests/test_settings.py delete mode 100644 bemade_fsm/tests/test_task.py delete mode 100644 bemade_fsm/tests/test_task_report.py delete mode 100644 bemade_fsm/tests/test_task_template.py delete mode 100644 bemade_fsm/views/menus.xml delete mode 100644 bemade_fsm/views/product_views.xml delete mode 100644 bemade_fsm/views/res_partner.xml delete mode 100644 bemade_fsm/views/sale_order_views.xml delete mode 100644 bemade_fsm/views/task_template_views.xml delete mode 100644 bemade_fsm/views/task_views.xml delete mode 100644 bemade_fsm/wizard/__init__.py delete mode 100644 bemade_fsm/wizard/new_task_from_template.py delete mode 100644 bemade_fsm/wizard/new_task_from_template.xml delete mode 100644 bemade_fsm/wizard/res_config_settings.py delete mode 100644 bemade_fsm/wizard/res_config_settings.xml delete mode 100644 bemade_full_formview_from_modal/__init__.py delete mode 100644 bemade_full_formview_from_modal/__manifest__.py delete mode 100644 bemade_full_formview_from_modal/migration18.md delete mode 100644 bemade_full_formview_from_modal/static/src/view_dialogs/form_view_dialog.js delete mode 100644 bemade_full_formview_from_modal/static/src/view_dialogs/form_view_dialog.xml delete mode 100644 bemade_full_formview_from_modal/static/tests/test_full_formview_from_modal.js delete mode 100644 bemade_full_formview_from_modal/tests/__init__.py delete mode 100644 bemade_full_formview_from_modal/tests/test_full_formview_from_modal.py delete mode 100644 bemade_git_repos_addons/__init__.py delete mode 100644 bemade_git_repos_addons/__manifest__.py delete mode 100644 bemade_git_repos_addons/data/default_directories_data.xml delete mode 100644 bemade_git_repos_addons/models/__init__.py delete mode 100644 bemade_git_repos_addons/models/git_addons.py delete mode 100644 bemade_git_repos_addons/models/git_branch.py delete mode 100644 bemade_git_repos_addons/models/git_repos.py delete mode 100644 bemade_git_repos_addons/models/res_settings.py delete mode 100644 bemade_git_repos_addons/security/ir.model.access.csv delete mode 100644 bemade_git_repos_addons/static/src/views/button_create_repos_list/button_create_repos.xml delete mode 100644 bemade_git_repos_addons/static/src/views/button_create_repos_list/button_create_repos_controller.js delete mode 100644 bemade_git_repos_addons/static/src/views/button_create_repos_list/button_create_repos_view.js delete mode 100644 bemade_git_repos_addons/views/action_and_menu.xml delete mode 100644 bemade_git_repos_addons/views/git_addons_views.xml delete mode 100644 bemade_git_repos_addons/views/git_repos_views.xml delete mode 100644 bemade_git_repos_addons/views/res_settings_views.xml delete mode 100644 bemade_git_repos_addons/wizard/__init__.py delete mode 100644 bemade_git_repos_addons/wizard/directory_wizard.py delete mode 100644 bemade_git_repos_addons/wizard/directory_wizard_views.xml delete mode 100644 bemade_git_repos_addons/wizard/git_repos_wizard.py delete mode 100644 bemade_git_repos_addons/wizard/git_repos_wizard_views.xml delete mode 100644 bemade_helpdesk_mailcow_blacklist/__init__.py delete mode 100644 bemade_helpdesk_mailcow_blacklist/__manifest__.py delete mode 100644 bemade_helpdesk_mailcow_blacklist/data/helpdesk_stages.xml delete mode 100644 bemade_helpdesk_mailcow_blacklist/demo/demo.xml delete mode 100644 bemade_helpdesk_mailcow_blacklist/migration18.md delete mode 100644 bemade_helpdesk_mailcow_blacklist/models/__init__.py delete mode 100644 bemade_helpdesk_mailcow_blacklist/models/helpdesk_ticket.py delete mode 100644 bemade_helpdesk_mailcow_blacklist/models/res_partner.py delete mode 100644 bemade_helpdesk_mailcow_blacklist/security/ir.model.access.csv delete mode 100644 bemade_helpdesk_mailcow_blacklist/views/helpdesk_ticket_views.xml delete mode 100644 bemade_helpdesk_one_ticket_per_email/__init__.py delete mode 100644 bemade_helpdesk_one_ticket_per_email/__manifest__.py delete mode 100644 bemade_helpdesk_one_ticket_per_email/migration18.md delete mode 100644 bemade_helpdesk_one_ticket_per_email/models/__init__.py delete mode 100644 bemade_helpdesk_one_ticket_per_email/models/mail_thread.py delete mode 100644 bemade_hide_decimal_on_unit/__init__.py delete mode 100644 bemade_hide_decimal_on_unit/__manifest__.py delete mode 100644 bemade_hide_decimal_on_unit/migration18.md delete mode 100644 bemade_hide_decimal_on_unit/views/purchase.xml delete mode 100644 bemade_hide_decimal_on_unit/views/sale.xml delete mode 100644 bemade_l10n_ca_payroll/__init__.py delete mode 100644 bemade_l10n_ca_payroll/__manifest__.py delete mode 100644 bemade_l10n_ca_payroll/data/hr_payslip_input_type_data.xml delete mode 100644 bemade_l10n_ca_payroll/data/hr_salary_rule_data.xml delete mode 100644 bemade_l10n_ca_payroll/models/__init__.py delete mode 100644 bemade_l10n_ca_payroll/models/hr_payroll_structure_type.py delete mode 100644 bemade_l10n_ca_payroll/models/hr_payslip.py delete mode 100644 bemade_mailcow_integration/__init__.py delete mode 100644 bemade_mailcow_integration/__manifest__.py delete mode 100644 bemade_mailcow_integration/controllers/controllers.py delete mode 100644 bemade_mailcow_integration/demo/demo.xml delete mode 100644 bemade_mailcow_integration/migration18.md delete mode 100644 bemade_mailcow_integration/migrations/15.0.1.0.1/pre-migrate.py delete mode 100644 bemade_mailcow_integration/models/__init__.py delete mode 100644 bemade_mailcow_integration/models/mail_alias.py delete mode 100644 bemade_mailcow_integration/models/mailcow.py delete mode 100644 bemade_mailcow_integration/models/mailcow_alias.py delete mode 100644 bemade_mailcow_integration/models/mailcow_blacklist.py delete mode 100644 bemade_mailcow_integration/models/mailcow_mailbox.py delete mode 100644 bemade_mailcow_integration/models/res_config_settings.py delete mode 100644 bemade_mailcow_integration/models/res_users.py delete mode 100644 bemade_mailcow_integration/security/ir.model.access.csv delete mode 100644 bemade_mailcow_integration/static/description/icon.png delete mode 100644 bemade_mailcow_integration/static/description/logomailcow.svg delete mode 100644 bemade_mailcow_integration/static/src/js/mailcow.js delete mode 100644 bemade_mailcow_integration/static/src/xml/mailcow_templates.xml delete mode 100644 bemade_mailcow_integration/tests/__init__.py delete mode 100644 bemade_mailcow_integration/tests/test_mailcow.py delete mode 100644 bemade_mailcow_integration/views/mailcow_alias_views.xml delete mode 100644 bemade_mailcow_integration/views/mailcow_blacklist_views.xml delete mode 100644 bemade_mailcow_integration/views/mailcow_mailbox_views.xml delete mode 100644 bemade_mailcow_integration/views/res_config_settings_views.xml delete mode 100644 bemade_mailcow_integration/views/res_users_views.xml delete mode 100644 bemade_mailcow_integration/views/templates.xml delete mode 100644 bemade_mailcow_integration/views/views.xml delete mode 100644 bemade_margin_vendor_pricelist/__init__.py delete mode 100644 bemade_margin_vendor_pricelist/__manifest__.py delete mode 100644 bemade_margin_vendor_pricelist/i18n/bemade_margin_vendor_pricelist.pot delete mode 100644 bemade_margin_vendor_pricelist/i18n/fr.po delete mode 100644 bemade_margin_vendor_pricelist/migration18.md delete mode 100644 bemade_margin_vendor_pricelist/migrations/17.0.0.0.4/pre-migrate.py delete mode 100644 bemade_margin_vendor_pricelist/models/__init__.py delete mode 100644 bemade_margin_vendor_pricelist/models/sale_order.py delete mode 100644 bemade_margin_vendor_pricelist/models/sale_order_line.py delete mode 100644 bemade_margin_vendor_pricelist/tests/__init__.py delete mode 100644 bemade_margin_vendor_pricelist/tests/test_margins.py delete mode 100644 bemade_margin_vendor_pricelist/views/sale_order.xml delete mode 100644 bemade_module_linker/__init__.py delete mode 100644 bemade_module_linker/__manifest__.py delete mode 100644 bemade_module_linker/migration18.md delete mode 100644 bemade_module_linker/models/__init__.py delete mode 100644 bemade_module_linker/models/res_config_settings.py delete mode 100644 bemade_module_linker/models/res_modules_link.py delete mode 100644 bemade_module_linker/views/res_config_settings_views.xml delete mode 100644 bemade_multiple_billing_contacts/__init__.py delete mode 100644 bemade_multiple_billing_contacts/__manifest__.py delete mode 100644 bemade_multiple_billing_contacts/models/__init__.py delete mode 100644 bemade_multiple_billing_contacts/models/account_move.py delete mode 100644 bemade_multiple_billing_contacts/models/res_partner.py delete mode 100644 bemade_multiple_billing_contacts/models/sale_order.py delete mode 100644 bemade_multiple_billing_contacts/tests/__init__.py delete mode 100644 bemade_multiple_billing_contacts/tests/test_billing_contacts.py delete mode 100644 bemade_multiple_billing_contacts/views/account_move_views.xml delete mode 100644 bemade_multiple_billing_contacts/views/res_partner_views.xml delete mode 100644 bemade_multiple_billing_contacts/views/sale_order_views.xml delete mode 100644 bemade_odoo_partner_scrapper/__init__.py delete mode 100644 bemade_odoo_partner_scrapper/__manifest__.py delete mode 100644 bemade_odoo_partner_scrapper/data/demo.xml delete mode 100644 bemade_odoo_partner_scrapper/data/res_partner_relation_type.xml delete mode 100644 bemade_odoo_partner_scrapper/models/__init__.py delete mode 100644 bemade_odoo_partner_scrapper/models/res_partner.py delete mode 100644 bemade_odoo_partner_scrapper/views/res_partner_views.xml delete mode 100644 bemade_odoo_partner_scrapper_js_only/__init__.py delete mode 100644 bemade_odoo_partner_scrapper_js_only/__manifest__.py delete mode 100644 bemade_open_project_details/__init__.py delete mode 100644 bemade_open_project_details/__manifest__.py delete mode 100644 bemade_open_project_details/views/project_project_views.xml delete mode 100644 bemade_packing_wizard/__init__.py delete mode 100644 bemade_packing_wizard/__manifest__.py delete mode 100644 bemade_packing_wizard/migration18.md delete mode 100644 bemade_packing_wizard/models/__init__.py delete mode 100644 bemade_packing_wizard/models/delivery_carrier.py delete mode 100644 bemade_packing_wizard/models/stock_quant_package.py delete mode 100644 bemade_packing_wizard/views/delivery_carrier_views.xml delete mode 100644 bemade_packing_wizard/views/stock_package_views.xml delete mode 100644 bemade_packing_wizard/wizard/__init__.py delete mode 100644 bemade_packing_wizard/wizard/choose_delivery_package.py delete mode 100644 bemade_packing_wizard/wizard/choose_delivery_package_views.xml delete mode 100644 bemade_partner_email_domain/__init__.py delete mode 100644 bemade_partner_email_domain/__manifest__.py delete mode 100644 bemade_partner_email_domain/controllers/__init__.py delete mode 100644 bemade_partner_email_domain/controllers/main.py delete mode 100644 bemade_partner_email_domain/data/mail_template_data.xml delete mode 100644 bemade_partner_email_domain/data/template_data.xml delete mode 100644 bemade_partner_email_domain/i18n/fr_CA.po delete mode 100644 bemade_partner_email_domain/migration18.md delete mode 100644 bemade_partner_email_domain/models/__init__.py delete mode 100644 bemade_partner_email_domain/models/res_partner.py delete mode 100644 bemade_partner_email_domain/views/res_partner_views.xml delete mode 100644 bemade_partner_root_ancestor/__init__.py delete mode 100644 bemade_partner_root_ancestor/__manifest__.py delete mode 100644 bemade_partner_root_ancestor/migration18.md delete mode 100644 bemade_partner_root_ancestor/models/__init__.py delete mode 100644 bemade_partner_root_ancestor/models/res_partner.py delete mode 100644 bemade_partner_root_ancestor/tests/__init__.py delete mode 100644 bemade_partner_root_ancestor/tests/test_root_ancestor.py delete mode 100644 bemade_payslip_done_as_not_paid/__init__.py delete mode 100644 bemade_payslip_done_as_not_paid/__manifest__.py delete mode 100644 bemade_payslip_done_as_not_paid/views/hr_payslip_views.xml delete mode 100644 bemade_picking_upstream/__init__.py delete mode 100644 bemade_picking_upstream/__manifest__.py delete mode 100644 bemade_picking_upstream/migration18.md delete mode 100644 bemade_picking_upstream/models/__init__.py delete mode 100644 bemade_picking_upstream/models/stock_picking.py delete mode 100644 bemade_picking_upstream/views/stock_picking_views.xml delete mode 100644 bemade_purchase_warn_supplier_overdue/__init__.py delete mode 100644 bemade_purchase_warn_supplier_overdue/__manifest__.py delete mode 100644 bemade_purchase_warn_supplier_overdue/migration18.md delete mode 100644 bemade_purchase_warn_supplier_overdue/models/__init__.py delete mode 100644 bemade_purchase_warn_supplier_overdue/models/purchase_order.py delete mode 100644 bemade_purchase_warn_supplier_overdue/models/res_company.py delete mode 100644 bemade_purchase_warn_supplier_overdue/models/res_config_settings.py delete mode 100644 bemade_purchase_warn_supplier_overdue/tests/__init__.py delete mode 100644 bemade_purchase_warn_supplier_overdue/tests/test_purchase_order_overdue.py delete mode 100644 bemade_purchase_warn_supplier_overdue/views/res_config_settings_views.xml delete mode 100644 bemade_pwa_config/__init__.py delete mode 100644 bemade_pwa_config/__manifest__.py delete mode 100644 bemade_pwa_config/controllers/__init__.py delete mode 100644 bemade_pwa_config/controllers/main.py delete mode 100644 bemade_pwa_config/i18n/bemade_pwa_config.pot delete mode 100644 bemade_pwa_config/i18n/fr_CA.po delete mode 100644 bemade_pwa_config/migration18.md delete mode 100644 bemade_pwa_config/models/__init__.py delete mode 100644 bemade_pwa_config/models/res_company.py delete mode 100644 bemade_pwa_config/models/res_config_settings.py delete mode 100644 bemade_pwa_config/security/ir.model.access.csv delete mode 100644 bemade_pwa_config/views/res_config_settings_views.xml delete mode 100644 bemade_quotation_alternative/__init__.py delete mode 100644 bemade_quotation_alternative/__manifest__.py delete mode 100644 bemade_quotation_alternative/migration18.md delete mode 100644 bemade_quotation_alternative/models/__init__.py delete mode 100644 bemade_quotation_alternative/models/sale_order.py delete mode 100644 bemade_quotation_alternative/security/ir.model.access.csv delete mode 100644 bemade_quotation_alternative/views/sale_order_views.xml delete mode 100644 bemade_quotation_alternative/wizard/__init__.py delete mode 100644 bemade_quotation_alternative/wizard/sale_oder_line_duplication_wizard.py delete mode 100644 bemade_quotation_alternative/wizard/sale_order_duplication_wizard.py delete mode 100644 bemade_quotation_alternative/wizard/sale_order_duplication_wizard_view.xml delete mode 100644 bemade_reordering_rules_chatter/__init__.py delete mode 100644 bemade_reordering_rules_chatter/__manifest__.py delete mode 100644 bemade_reordering_rules_chatter/migration18.md delete mode 100644 bemade_reordering_rules_chatter/models/__init__.py delete mode 100644 bemade_reordering_rules_chatter/models/stock_warehouse_orderpoint.py delete mode 100644 bemade_reordering_rules_chatter/views/stock_warehouse_orderpoint.xml delete mode 100644 bemade_sale_order_line_number/__manifest__.py delete mode 100644 bemade_sale_order_line_number/views/sale_order_views.xml delete mode 100644 bemade_search_supplier_code/__init__.py delete mode 100644 bemade_search_supplier_code/__manifest__.py delete mode 100644 bemade_search_supplier_code/migration18.md delete mode 100644 bemade_search_supplier_code/models/__init__.py delete mode 100644 bemade_search_supplier_code/models/product_product.py delete mode 100644 bemade_search_supplier_code/views/product_product_views.xml delete mode 100644 bemade_so_and_po_only_company/__init__.py delete mode 100644 bemade_so_and_po_only_company/__manifest__.py delete mode 100644 bemade_so_and_po_only_company/migration18.md delete mode 100644 bemade_so_and_po_only_company/views/purchase_order.xml delete mode 100644 bemade_so_and_po_only_company/views/sale_order.xml delete mode 100644 bemade_so_followers_to_picking/__init__.py delete mode 100644 bemade_so_followers_to_picking/__manifest__.py delete mode 100644 bemade_so_followers_to_picking/migration18.md delete mode 100644 bemade_so_followers_to_picking/models/__init__.py delete mode 100644 bemade_so_followers_to_picking/models/stock_picking.py delete mode 100644 bemade_sports_clinic/__init__.py delete mode 100644 bemade_sports_clinic/__manifest__.py delete mode 100644 bemade_sports_clinic/controllers/__init__.py delete mode 100644 bemade_sports_clinic/controllers/team_staff_portal.py delete mode 100644 bemade_sports_clinic/data/demo/sports_clinic_demo_data.xml delete mode 100644 bemade_sports_clinic/data/sports_clinic_data.xml delete mode 100644 bemade_sports_clinic/i18n/fr_CA.po delete mode 100644 bemade_sports_clinic/migrations/16.0.1.5.4/post-migrate.py delete mode 100644 bemade_sports_clinic/migrations/16.0.1.5.7/post-migrate.py delete mode 100644 bemade_sports_clinic/migrations/16.0.1.5.8/post-migrate.py delete mode 100644 bemade_sports_clinic/migrations/16.0.1.6.0/post-migrate.py delete mode 100644 bemade_sports_clinic/migrations/16.0.1.7.0/post-migrate.py delete mode 100644 bemade_sports_clinic/migrations/16.0.1.7.0/pre-migrate.py delete mode 100644 bemade_sports_clinic/models/__init__.py delete mode 100644 bemade_sports_clinic/models/mail_followers.py delete mode 100644 bemade_sports_clinic/models/patient.py delete mode 100644 bemade_sports_clinic/models/patient_contact.py delete mode 100644 bemade_sports_clinic/models/patient_injury.py delete mode 100644 bemade_sports_clinic/models/res_partner.py delete mode 100644 bemade_sports_clinic/models/res_users.py delete mode 100644 bemade_sports_clinic/models/sports_team.py delete mode 100644 bemade_sports_clinic/security/ir.model.access.csv delete mode 100644 bemade_sports_clinic/security/sports_clinic_groups.xml delete mode 100644 bemade_sports_clinic/security/sports_clinic_rules.xml delete mode 100644 bemade_sports_clinic/static/description/icon.png delete mode 100644 bemade_sports_clinic/tests/__init__.py delete mode 100644 bemade_sports_clinic/tests/test_patient.py delete mode 100644 bemade_sports_clinic/tests/test_rights.py delete mode 100644 bemade_sports_clinic/tests/test_users.py delete mode 100644 bemade_sports_clinic/views/res_partner_views.xml delete mode 100644 bemade_sports_clinic/views/res_users_views.xml delete mode 100644 bemade_sports_clinic/views/sports_clinic_menus.xml delete mode 100644 bemade_sports_clinic/views/sports_clinic_portal_views.xml delete mode 100644 bemade_sports_clinic/views/sports_patient_injury_views.xml delete mode 100644 bemade_sports_clinic/views/sports_patient_views.xml delete mode 100644 bemade_sports_clinic/views/sports_team_views.xml delete mode 100644 bemade_stock_quant_valuation/__init__.py delete mode 100644 bemade_stock_quant_valuation/__manifest__.py delete mode 100644 bemade_stock_quant_valuation/migration18.md delete mode 100644 bemade_stock_quant_valuation/models/__init__.py delete mode 100644 bemade_stock_quant_valuation/models/stock_quant.py delete mode 100644 bemade_stock_quant_valuation/views/stock_account_views.xml delete mode 100644 bemade_time_off_follower/__init__.py delete mode 100644 bemade_time_off_follower/__manifest__.py delete mode 100644 bemade_time_off_follower/migration18.md delete mode 100644 bemade_time_off_follower/models/__init__.py delete mode 100644 bemade_time_off_follower/models/hr_leave.py delete mode 100644 bemade_time_off_follower/models/mail_thread.py delete mode 100644 bemade_time_off_follower/tests/__init__.py delete mode 100644 bemade_time_off_follower/tests/test_mail_thread.py delete mode 100644 bemade_time_off_follower/views/hr_leave_views.xml delete mode 100644 bemade_total_show_currency/__manifest__.py delete mode 100644 bemade_total_show_currency/views/total_template.xml delete mode 100644 bemade_update_validity_date_when_send_so/__init__.py delete mode 100644 bemade_update_validity_date_when_send_so/__manifest__.py delete mode 100644 bemade_update_validity_date_when_send_so/migration18.md delete mode 100644 bemade_update_validity_date_when_send_so/models/__init__.py delete mode 100644 bemade_update_validity_date_when_send_so/models/sale_order.py delete mode 100644 bemade_user_custom_apps_order/__init__.py delete mode 100644 bemade_user_custom_apps_order/__manifest__.py delete mode 100644 bemade_user_custom_apps_order/models/__init__.py delete mode 100644 bemade_user_custom_apps_order/models/ir_ui_menu.py delete mode 100644 bemade_user_custom_apps_order/models/res_users.py delete mode 100644 bemade_user_custom_apps_order/models/res_users_menu_order.py delete mode 100644 bemade_user_custom_apps_order/security/ir.model.access.csv delete mode 100644 bemade_user_custom_apps_order/static/tests/tours/custom_app_order_tour.js delete mode 100644 bemade_user_custom_apps_order/tests/__init__.py delete mode 100644 bemade_user_custom_apps_order/tests/test_user_custom_app_order.py delete mode 100644 bemade_user_custom_apps_order/views/res_users_view.xml delete mode 100644 bemade_user_custom_apps_order/views/user_menu_sequence.xml delete mode 100644 bemade_user_password_bundle/__init__.py delete mode 100644 bemade_user_password_bundle/__manifest__.py delete mode 100644 bemade_user_password_bundle/migration18.md delete mode 100644 bemade_user_password_bundle/models/__init__.py delete mode 100644 bemade_user_password_bundle/models/hr_employee.py delete mode 100644 bemade_user_password_bundle/models/password_bundle.py delete mode 100644 bemade_utils/__init__.py delete mode 100644 bemade_utils/__manifest__.py delete mode 100644 bemade_utils/migration18.md delete mode 100644 bemade_utils/tests/__init__.py delete mode 100644 bemade_utils/tests/test_patching_test.py delete mode 100644 bemade_utils/tools/__init__.py delete mode 100644 bemade_utils/tools/test.py delete mode 100644 client_name_on_manufacturing_orders/__init__.py delete mode 100644 client_name_on_manufacturing_orders/__manifest__.py delete mode 100644 client_name_on_manufacturing_orders/models/__init__.py delete mode 100644 client_name_on_manufacturing_orders/models/mrp_production.py delete mode 100644 client_name_on_manufacturing_orders/models/mrp_workorder.py delete mode 100644 client_name_on_manufacturing_orders/static/src/mrp_display/mrp_display.esm.js delete mode 100644 client_name_on_manufacturing_orders/static/src/mrp_display/mrp_display_action.esm.js delete mode 100644 client_name_on_manufacturing_orders/static/src/mrp_display/mrp_display_record.esm.js delete mode 100644 client_name_on_manufacturing_orders/static/src/mrp_display/mrp_display_record.xml delete mode 100644 client_name_on_manufacturing_orders/tests/__init__.py delete mode 100644 client_name_on_manufacturing_orders/tests/test_mrp_production.py delete mode 100644 client_name_on_manufacturing_orders/views/mrp_production_views.xml delete mode 100644 commercial_invoice/__init__.py delete mode 100644 commercial_invoice/__manifest__.py delete mode 100644 commercial_invoice/data/commercial_invoice_sequence.xml delete mode 100644 commercial_invoice/models/__init__.py delete mode 100644 commercial_invoice/models/account_move.py delete mode 100644 commercial_invoice/models/commercial_invoice.py delete mode 100644 commercial_invoice/report/__init__.py delete mode 100644 commercial_invoice/report/commercial_invoice_report.xml delete mode 100644 commercial_invoice/report/report_templates.xml delete mode 100644 commercial_invoice/security/ir.model.access.csv delete mode 100644 commercial_invoice/views/account_move_views.xml delete mode 100644 commercial_invoice/views/commercial_invoice_views.xml delete mode 100644 confirm_many2one_create/__init__.py delete mode 100644 confirm_many2one_create/__manifest__.py delete mode 100644 confirm_many2one_create/static/src/js/many2one_field.esm.js delete mode 100644 current_user_as_invoice_user/__init__.py delete mode 100644 current_user_as_invoice_user/__manifest__.py delete mode 100644 current_user_as_invoice_user/tests/__init__.py delete mode 100644 current_user_as_invoice_user/tests/test_current_user_as_invoice_user.py delete mode 100644 current_user_as_invoice_user/wizard/__init__.py delete mode 100644 current_user_as_invoice_user/wizard/sale_make_invoice_advance.py delete mode 100644 current_user_as_invoice_user/wizard/sale_order.py delete mode 100644 customer_applications/__init__.py delete mode 100644 customer_applications/__manifest__.py delete mode 100644 customer_applications/data/menus_actions.xml delete mode 100644 customer_applications/models/__init__.py delete mode 100644 customer_applications/models/application.py delete mode 100644 customer_applications/models/application_specification.py delete mode 100644 customer_applications/models/application_specification_key.py delete mode 100644 customer_applications/models/application_type.py delete mode 100644 customer_applications/models/res_partner.py delete mode 100644 customer_applications/security/groups.xml delete mode 100644 customer_applications/security/ir.model.access.csv delete mode 100644 customer_applications/tests/__init__.py delete mode 100644 customer_applications/tests/test_application.py delete mode 100644 customer_applications/views/application_type_views.xml delete mode 100644 customer_applications/views/application_views.xml delete mode 100644 customer_applications/views/res_partner_views.xml delete mode 100644 customer_itch_cycle/__init__.py delete mode 100644 customer_itch_cycle/__manifest__.py delete mode 100644 customer_itch_cycle/models/__init__.py delete mode 100644 customer_itch_cycle/models/itch_cycle_product_partner.py delete mode 100644 customer_itch_cycle/models/sale_order.py delete mode 100644 customer_itch_cycle/views/itch_cycle_product_partner_view.xml delete mode 100644 customer_itch_cycle/views/res_partner_view.xml delete mode 100644 fsm_equipment/__init__.py delete mode 100644 fsm_equipment/__manifest__.py delete mode 100644 fsm_equipment/migrations/17.0.0.2.0/post-migrate.py delete mode 100644 fsm_equipment/models/__init__.py delete mode 100644 fsm_equipment/models/equipment.py delete mode 100644 fsm_equipment/models/equipment_tag.py delete mode 100644 fsm_equipment/models/res_partner.py delete mode 100644 fsm_equipment/models/task.py delete mode 100644 fsm_equipment/security/ir.model.access.csv delete mode 100644 fsm_equipment/views/equipment_views.xml delete mode 100644 fsm_equipment/views/project_task_views.xml delete mode 100644 fsm_equipment/views/res_partner_views.xml delete mode 100644 fsm_visit_confirmation/__init__.py delete mode 100644 fsm_visit_confirmation/__manifest__.py delete mode 100644 fsm_visit_confirmation/controllers/__init__.py delete mode 100644 fsm_visit_confirmation/controllers/portal.py delete mode 100644 fsm_visit_confirmation/data/mail_templates.xml delete mode 100644 fsm_visit_confirmation/models/__init__.py delete mode 100644 fsm_visit_confirmation/models/project_task.py delete mode 100644 fsm_visit_confirmation/views/project_portal_project_task_templates.xml delete mode 100644 impersonate_user/__init__.py delete mode 100644 impersonate_user/__manifest__.py delete mode 100644 impersonate_user/controllers/__init__.py delete mode 100644 impersonate_user/controllers/main.py delete mode 100644 impersonate_user/models/__init__.py delete mode 100644 impersonate_user/models/ir_http.py delete mode 100644 impersonate_user/models/res_users.py delete mode 100644 impersonate_user/static/src/systray_unimpersonate_button.esm.js delete mode 100644 impersonate_user/static/src/systray_unimpersonate_button.xml delete mode 100644 impersonate_user/views/impersonation_views.xml delete mode 100644 improved_mo_origin/__init__.py delete mode 100644 improved_mo_origin/__manifest__.py delete mode 100644 improved_mo_origin/models/__init__.py delete mode 100644 improved_mo_origin/models/mrp_production.py delete mode 100644 improved_mo_origin/static/src/mrp_display/mrp_display.esm.js delete mode 100644 improved_mo_origin/static/src/mrp_display/mrp_display_action.esm.js delete mode 100644 improved_mo_origin/static/src/mrp_display/mrp_display_record.esm.js delete mode 100644 improved_mo_origin/static/src/mrp_display/mrp_display_record.xml delete mode 100644 improved_mo_origin/tests/__init__.py delete mode 100644 improved_mo_origin/tests/test_mrp_production.py delete mode 100644 improved_mo_origin/views/mrp_production_views.xml delete mode 100644 interactive_discuss_ai/__init__.py delete mode 100644 interactive_discuss_ai/__manifest__.py delete mode 100644 interactive_discuss_ai/models/__init__.py delete mode 100644 interactive_discuss_ai/models/ai_assistant.py delete mode 100644 interactive_discuss_ai/models/ai_config.py delete mode 100644 interactive_discuss_ai/models/ai_service.py delete mode 100644 interactive_discuss_ai/security/ir.model.access.csv delete mode 100644 interactive_discuss_ai/static/src/js/ai_assistant_chat.js delete mode 100644 interactive_discuss_ai/static/src/xml/ai_assistant_chat.xml delete mode 100644 interactive_discuss_ai/views/ai_assistant_views.xml delete mode 100644 interactive_discuss_ai/views/ai_config_views.xml delete mode 100644 l10n_ca_pst_reports/__init__.py delete mode 100644 l10n_ca_pst_reports/__manifest__.py delete mode 100644 l10n_ca_pst_reports/tests/__init__.py delete mode 100644 l10n_ca_pst_reports/tests/test_report_tax_numbers.py delete mode 100644 l10n_ca_pst_reports/views/external_layout.xml delete mode 100644 mo_back_to_draft/__init__.py delete mode 100644 mo_back_to_draft/__manifest__.py delete mode 100644 mo_back_to_draft/models/__init__.py delete mode 100644 mo_back_to_draft/models/mrp_production.py delete mode 100644 mo_back_to_draft/views/mrp_production_views.xml delete mode 100644 msg_attachments_to_mail_message/__init__.py delete mode 100644 msg_attachments_to_mail_message/__manifest__.py delete mode 100644 msg_attachments_to_mail_message/migrations/16.0.1.1/__init__.py delete mode 100644 msg_attachments_to_mail_message/migrations/16.0.1.1/pre-migration.py delete mode 100644 msg_attachments_to_mail_message/migrations/__init__.py delete mode 100644 msg_attachments_to_mail_message/models/__init__.py delete mode 100644 msg_attachments_to_mail_message/models/ir_attachment.py delete mode 100644 msg_attachments_to_mail_message/models/mail_thread.py delete mode 100644 msg_attachments_to_mail_message/models/res_config_settings.py delete mode 100644 msg_attachments_to_mail_message/requirements.txt delete mode 100644 msg_attachments_to_mail_message/views/res_config_settings_views.xml delete mode 100644 msg_viewer/__init__.py delete mode 100644 msg_viewer/__manifest__.py delete mode 100644 msg_viewer/controllers/__init__.py delete mode 100644 msg_viewer/controllers/main.py delete mode 100644 msg_viewer/models/__init__.py delete mode 100644 msg_viewer/models/ir_attachment.py delete mode 100644 msg_viewer/static/src/components/attachment_card_msg/attachment_card_msg.xml delete mode 100644 msg_viewer/static/src/components/msg_viewer/msg_viewer.js delete mode 100644 msg_viewer/static/src/components/msg_viewer/msg_viewer.xml delete mode 100644 msg_viewer/static/src/css/msg_viewer.css delete mode 100644 msg_viewer/static/src/js/msg_viewer.js delete mode 100644 msg_viewer/static/src/lib/components/attachment/index.html delete mode 100644 msg_viewer/static/src/lib/components/attachment/index.ts delete mode 100644 msg_viewer/static/src/lib/components/attachment/styles.css delete mode 100644 msg_viewer/static/src/lib/components/embedded-msg/index.html delete mode 100644 msg_viewer/static/src/lib/components/embedded-msg/index.ts delete mode 100644 msg_viewer/static/src/lib/components/embedded-msg/styles.css delete mode 100644 msg_viewer/static/src/lib/components/error/index.html delete mode 100644 msg_viewer/static/src/lib/components/error/index.ts delete mode 100644 msg_viewer/static/src/lib/components/error/styles.css delete mode 100644 msg_viewer/static/src/lib/components/message/index.html delete mode 100644 msg_viewer/static/src/lib/components/message/index.ts delete mode 100644 msg_viewer/static/src/lib/components/message/styles.css delete mode 100644 msg_viewer/static/src/lib/components/recipient/index.html delete mode 100644 msg_viewer/static/src/lib/components/recipient/index.ts delete mode 100644 msg_viewer/static/src/lib/components/recipient/styles.css delete mode 100644 msg_viewer/static/src/lib/components/styles.css delete mode 100644 msg_viewer/static/src/lib/favicon.ico delete mode 100644 msg_viewer/static/src/lib/index.html delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/.gitignore delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/LICENSE delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/README.md delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/build.ts delete mode 100755 msg_viewer/static/src/lib/msg-viewer-main/bun.lockb delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/declarations.d.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/icon.svg delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/jsconfig.json delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/attachment/index.html delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/attachment/index.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/attachment/styles.css delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/embedded-msg/index.html delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/embedded-msg/index.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/embedded-msg/styles.css delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/error/index.html delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/error/index.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/error/styles.css delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/message/index.html delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/message/index.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/message/styles.css delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/recipient/index.html delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/recipient/index.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/recipient/styles.css delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/components/styles.css delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/favicon.ico delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/index.html delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/resources/google331b65fa04565532.html delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/resources/robots.txt delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/index.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/README.md delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/compound-file/compound-file.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/compound-file/constants/text-decoder.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/compound-file/difat.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/compound-file/directory/directory.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/compound-file/directory/enums/color-flag.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/compound-file/directory/enums/object-type.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/compound-file/directory/types/directory-entry.d.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/compound-file/fat.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/compound-file/header.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/compound-file/mini-fat.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/compound-file/util.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/msg-parser.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/package.json delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/rtf/decompressor/crc.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/rtf/decompressor/dictionary.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/rtf/decompressor/header.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/rtf/rtf-decompressor.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/streams/constants/folders.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/streams/entry/entry-stream.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/streams/entry/types/entry-stream-entry.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/streams/property/properties.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/streams/property/property-stream.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/streams/property/property-types.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/streams/property/types/property-data.d.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/streams/property/types/property-header.d.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/streams/property/types/property-stream-entry.d.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/msg/types/message.d.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/utils/file-size-util.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/scripts/utils/html-template-util.ts delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/styles/root.css delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/lib/styles/styles.css delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/package-lock.json delete mode 100644 msg_viewer/static/src/lib/msg-viewer-main/package.json delete mode 100644 msg_viewer/static/src/lib/msg-viewer.js delete mode 100644 msg_viewer/static/src/lib/msg-viewer.zip delete mode 100644 msg_viewer/static/src/lib/resources/google331b65fa04565532.html delete mode 100644 msg_viewer/static/src/lib/resources/robots.txt delete mode 100644 msg_viewer/static/src/lib/scripts/index.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/README.md delete mode 100644 msg_viewer/static/src/lib/scripts/msg/compound-file/compound-file.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/compound-file/constants/text-decoder.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/compound-file/difat.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/compound-file/directory/directory.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/compound-file/directory/enums/color-flag.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/compound-file/directory/enums/object-type.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/compound-file/directory/types/directory-entry.d.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/compound-file/fat.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/compound-file/header.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/compound-file/mini-fat.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/compound-file/util.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/msg-parser.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/package.json delete mode 100644 msg_viewer/static/src/lib/scripts/msg/rtf/decompressor/crc.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/rtf/decompressor/dictionary.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/rtf/decompressor/header.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/rtf/rtf-decompressor.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/streams/constants/folders.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/streams/entry/entry-stream.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/streams/entry/types/entry-stream-entry.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/streams/property/properties.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/streams/property/property-stream.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/streams/property/property-types.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/streams/property/types/property-data.d.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/streams/property/types/property-header.d.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/streams/property/types/property-stream-entry.d.ts delete mode 100644 msg_viewer/static/src/lib/scripts/msg/types/message.d.ts delete mode 100644 msg_viewer/static/src/lib/scripts/utils/file-size-util.ts delete mode 100644 msg_viewer/static/src/lib/scripts/utils/html-template-util.ts delete mode 100644 msg_viewer/static/src/lib/styles/root.css delete mode 100644 msg_viewer/static/src/lib/styles/styles.css delete mode 100644 msg_viewer/static/src/models/attachment_card_msg.js delete mode 100644 msg_viewer/test/FACTURE NO. 7005451.msg delete mode 100644 msg_viewer/test/analyze_msg.py delete mode 100644 msg_viewer/views/msg_viewer_views.xml delete mode 100644 multi_account_statement_import/__init__.py delete mode 100644 multi_account_statement_import/__manifest__.py delete mode 100644 odoo_proxmox_manager/README.md delete mode 100644 odoo_proxmox_manager/__init__.py delete mode 100644 odoo_proxmox_manager/__manifest__.py delete mode 100644 odoo_proxmox_manager/controllers/__init__.py delete mode 100644 odoo_proxmox_manager/controllers/main.py delete mode 100644 odoo_proxmox_manager/models/__init__.py delete mode 100644 odoo_proxmox_manager/models/proxmox_cluster.py delete mode 100644 odoo_proxmox_manager/models/proxmox_server.py delete mode 100644 odoo_proxmox_manager/models/proxmox_vm.py delete mode 100644 odoo_proxmox_manager/requirements.txt delete mode 100644 odoo_proxmox_manager/security/ir.model.access.csv delete mode 100644 odoo_proxmox_manager/security/proxmox_security.xml delete mode 100644 odoo_proxmox_manager/static/description/icon.png delete mode 100644 odoo_proxmox_manager/static/src/components/proxmox_server_list/proxmox_server_list.js delete mode 100644 odoo_proxmox_manager/static/src/components/proxmox_server_list/proxmox_server_list.xml delete mode 100644 odoo_proxmox_manager/static/src/js/dashboard_view.js delete mode 100644 odoo_proxmox_manager/static/src/js/proxmox_server_list.js delete mode 100644 odoo_proxmox_manager/static/src/scss/dashboard.scss delete mode 100644 odoo_proxmox_manager/static/src/xml/dashboard.xml delete mode 100644 odoo_proxmox_manager/static/src/xml/proxmox_server_list.xml delete mode 100644 odoo_proxmox_manager/views/proxmox_cluster_views.xml delete mode 100644 odoo_proxmox_manager/views/proxmox_menus.xml delete mode 100644 odoo_proxmox_manager/views/proxmox_server_views.xml delete mode 100644 odoo_proxmox_manager/views/proxmox_vm_views.xml delete mode 100644 odoo_proxmox_manager/wizard/__init__.py delete mode 100644 odoo_proxmox_manager/wizard/proxmox_server_wizard.py delete mode 100644 odoo_proxmox_manager/wizard/proxmox_server_wizard_views.xml delete mode 100644 odoo_rsync_backup/__init__.py delete mode 100644 odoo_rsync_backup/__manifest__.py delete mode 100644 odoo_rsync_backup/data/backup_cron.xml delete mode 100644 odoo_rsync_backup/models/__init__.py delete mode 100644 odoo_rsync_backup/models/rsync_config.py delete mode 100644 odoo_rsync_backup/security/ir.model.access.csv delete mode 100644 odoo_rsync_backup/views/rsync_config_views.xml delete mode 100644 odoo_to_odoo_bemade/__init__.py delete mode 100644 odoo_to_odoo_bemade/__manifest__.py delete mode 100644 odoo_to_odoo_bemade/data/ir_cron_data.xml delete mode 100644 odoo_to_odoo_bemade/models/__init__.py delete mode 100644 odoo_to_odoo_bemade/models/sync_instance.py delete mode 100644 odoo_to_odoo_bemade/models/sync_log.py delete mode 100644 odoo_to_odoo_bemade/models/sync_manager.py delete mode 100644 odoo_to_odoo_bemade/models/sync_model.py delete mode 100644 odoo_to_odoo_bemade/models/sync_model_field.py delete mode 100644 odoo_to_odoo_bemade/models/sync_queue.py delete mode 100644 odoo_to_odoo_bemade/security/ir.model.access.csv delete mode 100644 odoo_to_odoo_bemade/static/description/icon.png delete mode 100644 odoo_to_odoo_bemade/static/description/icon.svg delete mode 100644 odoo_to_odoo_bemade/static/description/index.html delete mode 100644 odoo_to_odoo_bemade/views/menus.xml delete mode 100644 odoo_to_odoo_bemade/views/sync_instance_views.xml delete mode 100644 odoo_to_odoo_bemade/views/sync_log_views.xml delete mode 100644 odoo_to_odoo_bemade/views/sync_model_views.xml delete mode 100644 odoo_to_odoo_bemade/views/sync_queue_views.xml delete mode 100644 odoo_to_odoo_bemade_customer/__init__.py delete mode 100644 odoo_to_odoo_bemade_customer/__manifest__.py delete mode 100644 odoo_to_odoo_bemade_customer/data/ir_cron_data.xml delete mode 100644 odoo_to_odoo_bemade_customer/models/__init__.py delete mode 100644 odoo_to_odoo_bemade_customer/models/sync_config.py delete mode 100644 odoo_to_odoo_bemade_customer/models/sync_log.py delete mode 100644 odoo_to_odoo_bemade_customer/models/sync_manager.py delete mode 100644 odoo_to_odoo_bemade_customer/models/sync_model.py delete mode 100644 odoo_to_odoo_bemade_customer/models/sync_model_field.py delete mode 100644 odoo_to_odoo_bemade_customer/models/sync_queue.py delete mode 100644 odoo_to_odoo_bemade_customer/security/ir.model.access.csv delete mode 100644 odoo_to_odoo_bemade_customer/static/description/icon.png delete mode 100644 odoo_to_odoo_bemade_customer/static/description/icon.svg delete mode 100644 odoo_to_odoo_bemade_customer/static/description/index.html delete mode 100644 odoo_to_odoo_bemade_customer/views/menus.xml delete mode 100644 odoo_to_odoo_bemade_customer/views/sync_instance_views.xml delete mode 100644 odoo_to_odoo_bemade_customer/views/sync_log_views.xml delete mode 100644 odoo_to_odoo_bemade_customer/views/sync_model_views.xml delete mode 100644 odoo_to_odoo_bemade_customer/views/sync_queue_views.xml delete mode 100644 odoo_to_odoo_sync/Spécifications.md delete mode 100644 odoo_to_odoo_sync/__init__.py delete mode 100644 odoo_to_odoo_sync/__manifest__.py delete mode 100644 odoo_to_odoo_sync/data/ir_cron_data.xml delete mode 100644 odoo_to_odoo_sync/models/__init__.py delete mode 100644 odoo_to_odoo_sync/models/sync_instance.py delete mode 100644 odoo_to_odoo_sync/models/sync_log.py delete mode 100644 odoo_to_odoo_sync/models/sync_manager.py delete mode 100644 odoo_to_odoo_sync/models/sync_model.py delete mode 100644 odoo_to_odoo_sync/models/sync_model_field.py delete mode 100644 odoo_to_odoo_sync/models/sync_queue.py delete mode 100644 odoo_to_odoo_sync/security/ir.model.access.csv delete mode 100644 odoo_to_odoo_sync/static/description/icon.png delete mode 100644 odoo_to_odoo_sync/static/description/icon.svg delete mode 100644 odoo_to_odoo_sync/views/menus.xml delete mode 100644 odoo_to_odoo_sync/views/sync_instance_views.xml delete mode 100644 odoo_to_odoo_sync/views/sync_log_views.xml delete mode 100644 odoo_to_odoo_sync/views/sync_model_views.xml delete mode 100644 odoo_to_odoo_sync/views/sync_queue_views.xml delete mode 100644 partner_equipment_applications/__init__.py delete mode 100644 partner_equipment_applications/__manifest__.py delete mode 100644 partner_equipment_applications/models/__init__.py delete mode 100644 partner_equipment_applications/models/application.py delete mode 100644 partner_equipment_applications/models/equipment.py delete mode 100644 partner_equipment_applications/views/application_views.xml delete mode 100644 partner_equipment_applications/views/equipment_views.xml delete mode 100644 picking_policy_per_customer/__init__.py delete mode 100644 picking_policy_per_customer/__manifest__.py delete mode 100644 picking_policy_per_customer/models/__init__.py delete mode 100644 picking_policy_per_customer/models/res_partner.py delete mode 100644 picking_policy_per_customer/models/sale_order.py delete mode 100644 picking_policy_per_customer/views/res_partner_views.xml delete mode 100644 portal_hide_draft_order_details/__init__.py delete mode 100644 portal_hide_draft_order_details/__manifest__.py delete mode 100644 portal_hide_draft_order_details/i18n/fr.po delete mode 100644 portal_hide_draft_order_details/i18n/portal_hide_draft_order_details.pot delete mode 100644 portal_hide_draft_order_details/models/__init__.py delete mode 100644 portal_hide_draft_order_details/models/res_company.py delete mode 100644 portal_hide_draft_order_details/views/sale_order_portal_templates.xml delete mode 100644 portal_hide_draft_order_details/wizard/__init__.py delete mode 100644 portal_hide_draft_order_details/wizard/res_config_settings.py delete mode 100644 portal_hide_draft_order_details/wizard/res_config_settings.xml delete mode 100644 price_update_notifications/__init__.py delete mode 100644 price_update_notifications/__manifest__.py delete mode 100644 price_update_notifications/data/email_templates.xml delete mode 100644 price_update_notifications/data/ir_cron_data.xml delete mode 100644 price_update_notifications/i18n/fr.po delete mode 100644 price_update_notifications/i18n/price_update_notifications.pot delete mode 100644 price_update_notifications/models/__init__.py delete mode 100644 price_update_notifications/models/price_notice_mailing.py delete mode 100644 price_update_notifications/security/ir.model.access.csv delete mode 100644 price_update_notifications/views/price_notice_mailing_views.xml delete mode 100644 price_update_notifications/wizard/__init__.py delete mode 100644 price_update_notifications/wizard/send_price_update_notice.py delete mode 100644 price_update_notifications/wizard/send_price_update_notice_views.xml delete mode 100644 purchase_customer_requisition/__init__.py delete mode 100644 purchase_customer_requisition/__manifest__.py delete mode 100644 purchase_customer_requisition/models/__init__.py delete mode 100644 purchase_customer_requisition/models/purchase_order.py delete mode 100644 purchase_customer_requisition/models/purchase_order_line.py delete mode 100644 purchase_customer_requisition/models/purchase_requisition.py delete mode 100644 purchase_customer_requisition/tests/__init__.py delete mode 100644 purchase_customer_requisition/tests/test_purchase_order.py delete mode 100644 purchase_customer_requisition/views/purchase_requisition_views.xml delete mode 100644 purchase_customer_requisition/views/purchase_views.xml delete mode 100644 qc_partner_default_lang/__init__.py delete mode 100644 qc_partner_default_lang/__manifest__.py delete mode 100644 qc_partner_default_lang/models/__init__.py delete mode 100644 qc_partner_default_lang/models/res_partner.py delete mode 100644 qc_partner_default_lang/static/description/index.html delete mode 100644 recursive_tree_view/README.md delete mode 100644 recursive_tree_view/__init__.py delete mode 100644 recursive_tree_view/__manifest__.py delete mode 100644 recursive_tree_view/hierarchy-svgrepo-com.svg delete mode 100644 recursive_tree_view/models/__init__.py delete mode 100644 recursive_tree_view/models/models.py delete mode 100644 recursive_tree_view/rng/tree_view.rng delete mode 100644 recursive_tree_view/static/description/icon.png delete mode 100644 recursive_tree_view/static/description/images/collapsed.png delete mode 100644 recursive_tree_view/static/description/images/expanded.png delete mode 100644 recursive_tree_view/static/description/images/main_screenshot.png delete mode 100644 recursive_tree_view/static/description/index.html delete mode 100644 recursive_tree_view/static/src/list_arch_parser.js delete mode 100644 recursive_tree_view/static/src/list_controller.js delete mode 100644 recursive_tree_view/static/src/list_renderer.js delete mode 100644 recursive_tree_view/static/src/recursive_tree_templates.xml delete mode 100644 recursive_tree_view/static/src/relational_model.js delete mode 100644 recursive_tree_view/static/src/tree_recursive_styles.css delete mode 100644 recursive_tree_view/validation.py delete mode 100644 replace_invoicing_user/__init__.py delete mode 100644 replace_invoicing_user/__manifest__.py delete mode 100644 replace_invoicing_user/models/__init__.py delete mode 100644 replace_invoicing_user/models/account_move.py delete mode 100644 replace_invoicing_user/models/res_config_settings.py delete mode 100644 replace_invoicing_user/tests/__init__.py delete mode 100644 replace_invoicing_user/tests/test_current_user_as_invoice_user.py delete mode 100644 replace_invoicing_user/views/res_config_settings_views.xml delete mode 100644 replace_invoicing_user/wizard/__init__.py delete mode 100644 replace_invoicing_user/wizard/sale_make_invoice_advance.py delete mode 100644 replace_invoicing_user/wizard/sale_order.py delete mode 100644 stock_valuation_location/__init__.py delete mode 100644 stock_valuation_location/__manifest__.py delete mode 100644 stock_valuation_location/models/__init__.py delete mode 100644 stock_valuation_location/models/stock_valuation_layer.py delete mode 100644 stock_valuation_location/views/stock_valuation_layer_views.xml delete mode 100644 temporary_change_image_size/__manifest__.py delete mode 100644 temporary_change_image_size/views/product_template_views.xml delete mode 100644 theme_durpro/LICENSE delete mode 100644 theme_durpro/__init__.py delete mode 100644 theme_durpro/__manifest__.py delete mode 100644 theme_durpro/data/ir_asset.xml delete mode 100644 theme_durpro/i18n/de.po delete mode 100644 theme_durpro/i18n/es.po delete mode 100644 theme_durpro/i18n/fr.po delete mode 100644 theme_durpro/i18n/it.po delete mode 100644 theme_durpro/i18n/nl.po delete mode 100644 theme_durpro/i18n/theme_graphene.pot delete mode 100644 theme_durpro/i18n/zh_CN.po delete mode 100644 theme_durpro/models/__init__.py delete mode 100644 theme_durpro/models/theme_durpro.py delete mode 100644 theme_durpro/static/description/durpro_poster.png delete mode 100644 theme_durpro/static/description/durpro_screenshot.jpg delete mode 100644 theme_durpro/static/description/index.html delete mode 100644 theme_durpro/static/description/theme_durpro.svg delete mode 100755 theme_durpro/static/src/img/patterns/bg_pattern_01.jpg delete mode 100755 theme_durpro/static/src/img/patterns/bg_pattern_02.jpg delete mode 100755 theme_durpro/static/src/img/patterns/bg_pattern_03.jpg delete mode 100755 theme_durpro/static/src/img/patterns/bg_pattern_04.jpg delete mode 100755 theme_durpro/static/src/img/patterns/bg_pattern_05.jpg delete mode 100755 theme_durpro/static/src/img/patterns/bg_pattern_06.jpg delete mode 100755 theme_durpro/static/src/img/pictures/bg_image_01.jpg delete mode 100755 theme_durpro/static/src/img/pictures/bg_image_02.jpg delete mode 100755 theme_durpro/static/src/img/pictures/bg_image_03.jpg delete mode 100755 theme_durpro/static/src/img/pictures/bg_image_04.jpg delete mode 100755 theme_durpro/static/src/img/pictures/bg_image_05.jpg delete mode 100755 theme_durpro/static/src/img/pictures/bg_image_06.jpg delete mode 100755 theme_durpro/static/src/img/pictures/bg_image_07.jpg delete mode 100755 theme_durpro/static/src/img/pictures/bg_image_08.jpg delete mode 100755 theme_durpro/static/src/img/pictures/bg_image_09.jpg delete mode 100755 theme_durpro/static/src/img/pictures/bg_image_10.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_01.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_02.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_03.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_04.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_05.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_06.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_07.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_08.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_09.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_10.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_11.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_12.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_13.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_14.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_15.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_16.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_17.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_18.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_19.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_20.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_21.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_22.jpg delete mode 100644 theme_durpro/static/src/img/pictures/content_23.jpg delete mode 100644 theme_durpro/static/src/img/pictures/s_numbers.jpg delete mode 100644 theme_durpro/static/src/img/pictures/s_popup.jpg delete mode 100644 theme_durpro/static/src/img/pictures/uiface_01.jpg delete mode 100644 theme_durpro/static/src/img/pictures/uiface_02.jpg delete mode 100644 theme_durpro/static/src/img/pictures/uiface_03.jpg delete mode 100644 theme_durpro/static/src/img/pictures/uiface_04.jpg delete mode 100644 theme_durpro/static/src/img/pictures/uiface_05.jpg delete mode 100644 theme_durpro/static/src/img/pictures/uiface_06.jpg delete mode 100644 theme_durpro/static/src/img/pictures/uiface_07.jpg delete mode 100644 theme_durpro/static/src/js/tour.js delete mode 100644 theme_durpro/static/src/old_snippets/s_showcase_slider/000_variables.scss delete mode 100644 theme_durpro/static/src/scss/bootstrap_overridden.scss delete mode 100644 theme_durpro/static/src/scss/custom_styles.scss delete mode 100644 theme_durpro/static/src/scss/primary_variables.scss delete mode 100644 theme_durpro/static/src/scss/secondary_variables.scss delete mode 100644 theme_durpro/views/customizations.xml delete mode 100644 theme_durpro/views/images_library.xml delete mode 100644 wazo_integration/__init__.py delete mode 100644 wazo_integration/__manifest__.py delete mode 100644 wazo_integration/models/__init__.py delete mode 100644 wazo_integration/models/res_company.py delete mode 100644 wazo_integration/models/res_config_settings.py delete mode 100644 wazo_integration/views/res_config_settings_views.xml delete mode 100644 website_geoip_extended/__init__.py delete mode 100644 website_geoip_extended/__manifest__.py delete mode 100644 website_geoip_extended/models/__init__.py delete mode 100644 website_geoip_extended/models/website_visitor.py delete mode 100644 website_geoip_extended/views/website_visitor_views.xml diff --git a/README.md b/README.md index 10389a3..c2c2dcb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,108 @@ # bemade-addons Odoo Addons made by Bemade + +## Addons Ported to 18.0 + +The following addons have been ported to Odoo 18.0 and are available in this repository: + +- account_email_to_pdf (18.0.1.0.0) +- batch_picking_create_one_bill (18.0.1.0.1) +- caldav_sync (18.0.0.7.0) +- customer_product_code_search (18.0.1.0.0) +- delivery_carrier_partner_account (18.0.0.1.2) +- incrementing_sequence_mixin (18.0.1.0.0) +- portal_partner_manager (18.0.1.0.0) +- preamble_on_quotation (18.0.0.1.0) +- product_supplierinfo_tracking (18.0.2.0.5) +- purchase_delivery_carrier (18.0.1.0.0) +- reception_purchase_total (18.0.1.0.0) +- sale_mandatory_customer_reference (18.0.1.0.0) +- sale_order_show_delivery_address (18.0.1.0.0) +- shipping_information_on_customer_invoice (18.0.0.1) +- st_laurent_portal_vendor (18.0.1.0.0) +- st_laurent_vendor_orders (18.0.1.0.0) +- unifi_integration (18.0.1.0.1) + +## Addons To Be Ported from 17.0 to 18.0 + +The following addons need to be ported from Odoo 17.0 to 18.0. They have been temporarily removed from this branch but can be reintegrated following the OCA methodology (creating a patch from 17.0 to bring the code in with its history): + +- account_credit_hold (17.0.1.1.1) +- aged_partner_balance_na +- ai_integration (1.0) +- ai_integration_ollama_api +- ai_integration_openai_api (1.0) +- bemade_add_follower_no_sendmail_default (17.0.0.0.1) +- bemade_attachments_cleanup +- bemade_documents_portal +- bemade_fetchmail_only_production (17.0.0.0.1) +- bemade_fix_quality_report +- bemade_fsm (17.0.0.4.2) +- bemade_full_formview_from_modal +- bemade_git_repos_addons +- bemade_helpdesk_mailcow_blacklist +- bemade_helpdesk_one_ticket_per_email +- bemade_hide_decimal_on_unit (17.0.0.1.1) +- bemade_l10n_ca_payroll +- bemade_mailcow_integration +- bemade_margin_vendor_pricelist +- bemade_module_linker +- bemade_multiple_billing_contacts +- bemade_odoo_partner_scrapper +- bemade_odoo_partner_scrapper_js_only +- bemade_open_project_details +- bemade_packing_wizard +- bemade_partner_email_domain +- bemade_partner_root_ancestor +- bemade_payslip_done_as_not_paid +- bemade_picking_upstream +- bemade_purchase_warn_supplier_overdue (1.0) +- bemade_pwa_config +- bemade_quotation_alternative +- bemade_reordering_rules_chatter (17.0.0.0.1) +- bemade_sale_order_line_number +- bemade_search_supplier_code +- bemade_so_and_po_only_company (17.0.0.0.1) +- bemade_so_followers_to_picking (17.0.0.0.1) +- bemade_sports_clinic +- bemade_stock_quant_valuation +- bemade_time_off_follower (17.0.0.0.3) +- bemade_total_show_currency +- bemade_update_validity_date_when_send_so (17.0.0.0.1) +- bemade_user_custom_apps_order +- bemade_user_password_bundle +- bemade_utils +- client_name_on_manufacturing_orders (17.0.2.0.0) +- commercial_invoice +- confirm_many2one_create (17.0.1.0.0) +- current_user_as_invoice_user +- customer_applications (17.0.1.0.0) +- customer_itch_cycle +- fsm_equipment (17.0.0.2.0) +- fsm_visit_confirmation (17.0.0.1.0) +- impersonate_user (17.0.0.0.1) +- improved_mo_origin (17.0.1.0.0) +- interactive_discuss_ai +- l10n_ca_pst_reports +- mo_back_to_draft +- msg_attachments_to_mail_message +- msg_viewer +- multi_account_statement_import +- odoo_proxmox_manager +- odoo_rsync_backup +- odoo_to_odoo_bemade +- odoo_to_odoo_bemade_customer +- odoo_to_odoo_sync +- partner_equipment_applications (17.0.1.0.0) +- picking_policy_per_customer +- portal_hide_draft_order_details (17.0.1.0.0) +- price_update_notifications (17.0.1.0.0) +- purchase_customer_requisition (1.0) +- qc_partner_default_lang +- recursive_tree_view (17.0.0.0.2) +- replace_invoicing_user +- stock_valuation_location (17.0.1.0.0) +- temporary_change_image_size +- theme_durpro +- wazo_integration +- website_geoip_extended diff --git a/account_credit_hold/__init__.py b/account_credit_hold/__init__.py deleted file mode 100644 index 0650744..0000000 --- a/account_credit_hold/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import models diff --git a/account_credit_hold/__manifest__.py b/account_credit_hold/__manifest__.py deleted file mode 100644 index e60291f..0000000 --- a/account_credit_hold/__manifest__.py +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "Account Credit Hold", - "version": "17.0.1.1.1", - "summary": "Allows setting clients on credit hold, blocking the ability confirm a new sales order.", - "category": "Accounting/Accounting", - "author": "Bemade Inc.", - "maintainer": "Marc Durepos ", - "website": "http://www.bemade.org", - "license": "LGPL-3", - "depends": ["sale", "account_followup", "stock"], - "data": [ - "views/account_followup_views.xml", - "views/sale_order_views.xml", - "views/res_partner_views.xml", - "views/stock_picking_views.xml", - ], - "demo": [], - "installable": True, - "auto_install": False, -} diff --git a/account_credit_hold/migration18.md b/account_credit_hold/migration18.md deleted file mode 100644 index b6f7efd..0000000 --- a/account_credit_hold/migration18.md +++ /dev/null @@ -1,246 +0,0 @@ -# Migration vers Odoo 18.0 - Module account_credit_hold - -## Fonctionnalités -- Ajoute un champ "Place on Credit Hold" sur les lignes de suivi de compte (account_followup.followup.line) -- Ajoute des champs et fonctionnalités sur les partenaires: - - postpone_hold_until: Date de report du blocage - - hold_bg: Champ technique pour le statut de blocage - - on_hold: État calculé du blocage de crédit -- Bloque la confirmation des commandes de vente si le client est en blocage de crédit -- Ajoute des indicateurs visuels (ruban rouge) sur: - - Commandes de vente - - Fiches partenaires - - Transferts de stock -- Ajoute des boutons pour mettre/lever le blocage de crédit dans la vue de suivi des comptes - -## Analyse pour la Migration - -### Dépendances -- sale -- account_followup -- stock - -### Changements Techniques Requis -1. Mettre à jour la version dans __manifest__.py vers 18.0 -2. Vérifier la compatibilité des vues XML avec Odoo 18.0 -3. Vérifier si des changements dans l'API account_followup en 18.0 - -### Points d'Attention -1. Le module utilise l'héritage de vues et de modèles standard d'Odoo: - - account_followup.followup.line - - res.partner - - sale.order - - stock.picking - - account.followup.report - -2. Fonctionnalités critiques à tester après migration: - - Calcul automatique du statut on_hold - - Blocage de la confirmation des commandes - - Nettoyage automatique des reports de blocage expirés (@api.autovacuum) - - Affichage correct des rubans d'avertissement - - Propagation du statut hold aux contacts liés (commercial_partner_id) - -3. Implémentation Technique: - - Utilisation de champs computed avec store=True et compute_sudo=True - - Mécanisme de nettoyage automatique via @api.autovacuum - - Héritage de _execute_followup_partner pour automatisation du hold - - Messages de chatter automatiques lors des changements de statut - -4. Points Spécifiques aux Vues: - - Utilisation du widget web_ribbon pour les indicateurs visuels - - Boutons conditionnels dans la vue de suivi des comptes - - Champs invisibles pour la logique d'affichage (hold_bg, on_hold) - - Groupes de sécurité sur le champ postpone_hold_until - -## Questions et Considérations - -1. Vérifier si Odoo 18.0 n'a pas introduit des fonctionnalités natives similaires dans account_followup: - - Système de blocage automatique des clients - - Gestion des périodes de grâce - - Indicateurs visuels de blocage - -2. Points à valider: - - La structure des vues héritées est-elle identique en 18.0? - - Les champs related et computed fonctionnent-ils de la même manière? - - Le système de suivi des comptes (account_followup) a-t-il évolué? - - Le décorateur @api.autovacuum est-il toujours supporté? - - Le widget web_ribbon utilise-t-il toujours la même API? - -3. Considérations d'Architecture: - - Le mécanisme de propagation du statut hold via commercial_partner_id est-il optimal? - - Possibilité de simplifier la logique de calcul du statut hold? - - Pertinence de stocker le champ hold_bg vs calcul à la demande - -4. Alternatives Potentielles: - - Utiliser le système de credit limit natif d'Odoo avec des règles personnalisées? - - Intégrer avec le système de blocage des partenaires d'Odoo? - - Utiliser les étapes de facturation (invoice_status) plutôt qu'un champ séparé? - -## Alternatives Natives Odoo 18.0 - -### Système de Crédit Natif -1. Odoo 18.0 inclut des fonctionnalités natives de gestion de crédit: - - Champ `credit_limit` sur res.partner - - Configuration du blocage au niveau de la société - - Règles de blocage basées sur: - - Montant de crédit maximum - - Factures échues - - Âge des factures - -2. Possibilités d'utilisation des fonctionnalités natives: - - Utiliser `credit_limit` au lieu de `on_hold` - - Configurer les règles de blocage dans la configuration de la comptabilité - - Utiliser les notifications natives de dépassement de crédit - -### Améliorations Possibles -1. Intégration avec le système natif: - - Synchroniser notre `on_hold` avec le système natif de blocage - - Utiliser les API natives de vérification de crédit - - Conserver uniquement les fonctionnalités non disponibles nativement - -2. Simplification du code: - - Remplacer les champs custom par des champs natifs quand possible - - Utiliser le système d'alertes natif pour les rubans - - Intégrer avec le système de workflow natif - -## Recommandations pour la Migration - -### Approche "Vanilla First" -1. Évaluer chaque fonctionnalité custom: - - Est-elle disponible nativement dans Odoo 18.0? - - Peut-elle être remplacée par une configuration native? - - Le besoin business existe-t-il toujours? - -2. Prioriser l'utilisation des fonctionnalités natives: - - Système de crédit natif - - Système de workflow natif - - API de notification standard - - Widgets standards de l'interface - -### Modifications Techniques Recommandées -1. Remplacer les attributs obsolètes: - - Supprimer les `attrs` dans les vues (Odoo 16.0+) - - Utiliser `list` au lieu de `tree` (Odoo 17.0+) - - Adapter les widgets aux nouvelles conventions - -2. Optimisation des performances: - - Utiliser les indexes de base de données appropriés - - Optimiser les recherches et calculs - - Implémenter le lazy loading quand possible - -### Plan de Test Approfondi -1. Tests fonctionnels: - - Validation du comportement avec le système natif - - Tests de régression sur les fonctionnalités custom - - Vérification des performances - -2. Tests d'intégration: - - Interaction avec le workflow de vente - - Synchronisation avec la comptabilité - - Comportement avec les autres modules - -## État de la Migration -⚪ En analyse préliminaire - -## Plan de Migration - -### Étape 1: Analyse des Changements Odoo 18.0 -- [ ] Examiner les changements dans account_followup -- [ ] Vérifier les nouvelles fonctionnalités de gestion de crédit -- [ ] Analyser les modifications des vues héritées - -### Étape 2: Adaptation Technique -- [ ] Mise à jour du manifeste -- [ ] Vérification de la compatibilité des décorateurs -- [ ] Adaptation des vues XML si nécessaire -- [ ] Test des champs computed et related - -### Étape 3: Tests Fonctionnels -- [ ] Validation du mécanisme de hold -- [ ] Test de la propagation aux contacts -- [ ] Vérification des nettoyages automatiques -- [ ] Test des indicateurs visuels - -### Étape 4: Optimisation -- [ ] Évaluation des alternatives natives -- [ ] Simplification potentielle du code -- [ ] Amélioration des performances - -## Notes de Version -- Version originale: 17.0.1.1.1 -- Dernière analyse: 26/01/2025 - -## Fonctionnalités Natives dans Odoo 18.0 - -Odoo 18.0 inclut nativement plusieurs fonctionnalités de gestion du crédit : - -1. **Gestion des Limites de Crédit** - - Champ `credit_limit` sur les partenaires - - Champ `use_partner_credit_limit` pour activer/désactiver par partenaire - - Configuration globale `account_use_credit_limit` au niveau de la société - - Champ `credit` pour le total des créances - - Champ `trust` pour le niveau de confiance du débiteur - -2. **Visibilité et Contrôle** - - Champ `show_credit_limit` basé sur la configuration de la société - - Groupes de sécurité pour la gestion des limites de crédit - -### Différences avec Notre Module - -1. **Fonctionnalités à Migrer** - - [ ] Indicateurs visuels spécifiques pour les clients en dépassement - - [ ] Blocage automatique des commandes en dépassement - - [ ] Workflow d'approbation personnalisé - -2. **Fonctionnalités à Adapter** - - [ ] Utiliser les champs natifs plutôt que nos champs customs - - [ ] Intégrer nos règles de blocage avec le système natif - - [ ] Adapter les rapports et vues pour utiliser les champs natifs - -## Plan de Migration - -### Phase 1 : Préparation -1. **Analyse des Données** - - [ ] Identifier les clients avec des limites de crédit - - [ ] Mapper les champs actuels vers les champs natifs - - [ ] Lister les règles de blocage personnalisées - -2. **Configuration** - - [ ] Activer la gestion du crédit dans la configuration de la société - - [ ] Configurer les groupes de sécurité appropriés - - [ ] Préparer les scripts de migration des données - -### Phase 2 : Migration -1. **Migration des Données** - - [ ] Transférer les limites de crédit vers le champ natif - - [ ] Migrer les configurations de blocage - - [ ] Mettre à jour les vues et rapports - -2. **Développement** - - [ ] Adapter le code de blocage des commandes - - [ ] Implémenter les indicateurs visuels manquants - - [ ] Ajouter les fonctionnalités spécifiques non disponibles nativement - -### Phase 3 : Tests -1. **Validation Fonctionnelle** - - [ ] Tester les limites de crédit - - [ ] Vérifier le blocage des commandes - - [ ] Valider les workflows d'approbation - -2. **Tests d'Intégration** - - [ ] Tester avec les autres modules - - [ ] Vérifier la compatibilité avec les processus existants - -## État de la Migration -🟡 En cours d'analyse - Utilisation partielle des fonctionnalités natives - -## Notes Importantes -- La gestion du crédit est maintenant une fonctionnalité native d'Odoo -- Certaines fonctionnalités spécifiques devront être maintenues -- L'approche recommandée est d'utiliser au maximum les fonctionnalités natives et de ne conserver que les extensions nécessaires - -## Prochaines Étapes -1. Valider l'approche avec l'équipe -2. Créer les scripts de migration des données -3. Développer les fonctionnalités manquantes -4. Planifier la formation des utilisateurs \ No newline at end of file diff --git a/account_credit_hold/models/__init__.py b/account_credit_hold/models/__init__.py deleted file mode 100644 index 0c2c11c..0000000 --- a/account_credit_hold/models/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from . import account_followup -from . import res_partner -from . import sale_order -from . import stock_picking -from . import account_followup_report diff --git a/account_credit_hold/models/account_followup.py b/account_credit_hold/models/account_followup.py deleted file mode 100644 index 5af3363..0000000 --- a/account_credit_hold/models/account_followup.py +++ /dev/null @@ -1,8 +0,0 @@ -from odoo import fields, models, api - - -class FollowupLine(models.Model): - _inherit = 'account_followup.followup.line' - - account_hold = fields.Boolean(string="Place on Credit Hold", - help="Place clients on account hold, restricting confirmation of new orders.") diff --git a/account_credit_hold/models/account_followup_report.py b/account_credit_hold/models/account_followup_report.py deleted file mode 100644 index a28efdc..0000000 --- a/account_credit_hold/models/account_followup_report.py +++ /dev/null @@ -1,12 +0,0 @@ -from odoo import models, fields, api, _ - - -class FollowUpReport(models.AbstractModel): - _inherit = 'account.followup.report' - - def _get_line_info(self, followup_line): - res = super()._get_line_info(followup_line) - res.update({ - 'credit_hold': followup_line.account_hold - }) - return res diff --git a/account_credit_hold/models/res_partner.py b/account_credit_hold/models/res_partner.py deleted file mode 100644 index 7cdf9a1..0000000 --- a/account_credit_hold/models/res_partner.py +++ /dev/null @@ -1,80 +0,0 @@ -from odoo import fields, models, api, _ -from datetime import date - - -class Partner(models.Model): - _inherit = "res.partner" - - postpone_hold_until = fields.Date( - string="Postpone Hold", - help="Grace period specific to this partner despite unpaid invoices.", - tracking=True, - ) - - hold_bg = fields.Boolean( - string="Hold (technical)", - compute="_compute_hold_bg", - store=True, - default=False, - compute_sudo=True, - tracking=True, - ) - on_hold = fields.Boolean( - string="Account on Hold", - help="Client account is on hold for unpaid overdue invoices.", - compute="_compute_on_hold", - compute_sudo=True, - ) - - @api.depends("postpone_hold_until", "hold_bg") - def _compute_on_hold(self): - # manually re-compute hold_bg since followup_status doesn't get updated in Python but gets recalculated - # by an SQL query every time - self._compute_hold_bg() - for rec in self: - # If the parent company is on hold, so are all its sub-contacts and subsidiaries - if rec.commercial_partner_id and rec.commercial_partner_id.on_hold: - rec.on_hold = True - return - # If there is no parent company or the parent is not on hold, we compute for ourselves - if rec.hold_bg and not ( - rec.postpone_hold_until and rec.postpone_hold_until > date.today() - ): - rec.on_hold = True - else: - if rec.on_hold: - rec.message_post(_("Credit hold lifted.")) - rec.on_hold = False - - @api.autovacuum - def _cleanup_expired_hold_postponements(self): - expired_holds = self.search([("postpone_hold_until", "<=", date.today())]) - expired_holds.write({"postpone_hold_until": False}) - - def action_credit_hold(self): - for rec in self: - rec.hold_bg = True - rec.message_post(body=_("Placed on credit hold.")) - - def action_lift_credit_hold(self): - for rec in self: - rec.hold_bg = False - rec.message_post(body=_("Credit hold lifted.")) - - def _execute_followup_partner(self, options=None): - res = super()._execute_followup_partner(options) - if self.followup_status == "in_need_of_action": - if self.followup_line_id.account_hold: - self.action_credit_hold() - return res - - @api.depends("followup_status", "followup_line_id") - def _compute_hold_bg(self): - first_followup_level = self._get_first_followup_level() - for rec in self: - prev_hold_bg = rec.hold_bg - level = rec.followup_line_id - if rec.followup_status == "no_action_needed" and not level: - rec.hold_bg = False - else: - rec.hold_bg = prev_hold_bg diff --git a/account_credit_hold/models/sale_order.py b/account_credit_hold/models/sale_order.py deleted file mode 100644 index 390e97e..0000000 --- a/account_credit_hold/models/sale_order.py +++ /dev/null @@ -1,17 +0,0 @@ -from odoo import fields, models, api, _ -from odoo.exceptions import UserError - - -class SaleOrder(models.Model): - _inherit = "sale.order" - - client_on_hold = fields.Boolean(string='Client on Hold', - help="Whether or not a client has been put on hold due to unpaid invoices.", - related="partner_id.on_hold") - - @api.depends('client_on_hold') - def action_confirm(self): - if any(self.mapped('client_on_hold')): - raise UserError(_("This client is on credit hold. No new orders can be confirmed until past-due invoices " - "are paid or the accounting team postpones the hold.")) - super().action_confirm() diff --git a/account_credit_hold/models/stock_picking.py b/account_credit_hold/models/stock_picking.py deleted file mode 100644 index 0d46e32..0000000 --- a/account_credit_hold/models/stock_picking.py +++ /dev/null @@ -1,9 +0,0 @@ -from odoo import fields, models, api - - -class ModelName(models.Model): - _inherit = "stock.picking" - - client_on_hold = fields.Boolean(string='Client on Hold', - help="Whether or not a client has been put on hold due to unpaid invoices.", - related="partner_id.on_hold") diff --git a/account_credit_hold/readme.md b/account_credit_hold/readme.md deleted file mode 100644 index db624c3..0000000 --- a/account_credit_hold/readme.md +++ /dev/null @@ -1,40 +0,0 @@ -# Overview - -This module adds the notion of placing clients on credit hold to the followup levels from the Odoo Enterprise -account_followup module. It adds an option to followup levels to mark clients matching the followup criteria as on -credit hold. This hold restricts the confirmation of new sales orders for these clients. - -Accountant and admin users can set a date until which the account hold will be -postponed on a specific partner's form view. This effectively gives clients an extra -grace period, allowing orders to be confirmed until the period ends. - -# Change Log - -## 17.0.1.0.0 (2024-05-15) - -Various modifications to adapt code to Odoo 17.0 - -## 15.0.2.0.0 (2023-05-04) - -Complete remake of the module, making the "Credit Hold" an action that is either manually or -automatically triggered from the Accounting > Followup Reports section or by setting the automatic application field -on followup levels. - -## 15.0.1.1.0 (2023-05-03) - -Adds a ribbon to stock pickings for clients on hold, and therefore a dependency on stock. - -## 15.0.1.0.2 (2023-05-03) - -Fix to sale order view and sale order confirmation for clients not on hold. - -## 15.0.1.0.1 (2023-05-03) - -Fix clients on hold when status is "outstanding_invoices". - -## 15.0.1.0.0 (2023-05-02) Initial Release - -Initial release of the module, including a setting on follow-up levels to toggle placing on credit hold. Blocks -the confirmation of sales orders for clients on credit hold. Red "Credit Hold" banner appears on sales orders and -partner form view when a client is on credit hold. Credit hold can be postponed by setting the "Postpone Hold" field -on the partner form view. \ No newline at end of file diff --git a/account_credit_hold/views/account_followup_views.xml b/account_credit_hold/views/account_followup_views.xml deleted file mode 100644 index 962cd79..0000000 --- a/account_credit_hold/views/account_followup_views.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - account_credit_hold.account_followup_line.form - account_followup.followup.line - - - - - - - - customer.statements.form.view.inherit - res.partner - - - - - - -
-
- - - - - - - - - - - - - - - - - - -
-
- - - - ai.model.search - ai.model - - - - - - - - - - - - - - - - - - - AI Models - ai.model - list,form - - {'search_default_group_by_provider': 1} - -

- No AI models found -

-

- AI models will be automatically synchronized when you configure and sync a provider instance. -

-
-
- - -
diff --git a/ai_integration/views/ai_provider_instance_views.xml b/ai_integration/views/ai_provider_instance_views.xml deleted file mode 100644 index a3bc669..0000000 --- a/ai_integration/views/ai_provider_instance_views.xml +++ /dev/null @@ -1,107 +0,0 @@ - - - - - ai.provider.instance.list - ai.provider.instance - - - - - - - - - - - - - ai.provider.instance.form - ai.provider.instance - -
-
-
- -
- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
- - - - ai.provider.instance.search - ai.provider.instance - - - - - - - - - - - - - - - - AI Provider Instances - ai.provider.instance - list,form - - {'company_id': False} - -

- Create your first AI provider instance -

-

- Configure AI provider instances to connect to different AI services. -

-
-
- - -
diff --git a/ai_integration/views/ai_provider_views.xml b/ai_integration/views/ai_provider_views.xml deleted file mode 100644 index 7579605..0000000 --- a/ai_integration/views/ai_provider_views.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - ai.provider.tree - ai.provider - list - - - - - - - - - - - - - ai.provider.form - ai.provider - form - -
- -
-
-
-
- - - - - - - - - - - - - - -
-
-
-
- - - - ai.provider.search - ai.provider - search - - - - - - - - - - - - - AI Providers - ai.provider - list,form - {'search_default_active': 1} - -

- No AI providers found -

-

- AI providers are automatically created when you install AI integration modules. -

-
-
- -
diff --git a/ai_integration/views/menu.xml b/ai_integration/views/menu.xml deleted file mode 100644 index 56a0198..0000000 --- a/ai_integration/views/menu.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_integration/views/res_company_views.xml b/ai_integration/views/res_company_views.xml deleted file mode 100644 index 6349ecb..0000000 --- a/ai_integration/views/res_company_views.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - AI Integration - ir.actions.act_window - res.config.settings - form - inline - {'module': 'ai_integration'} - - - - diff --git a/ai_integration/views/res_config_settings_views.xml b/ai_integration/views/res_config_settings_views.xml deleted file mode 100644 index 953574f..0000000 --- a/ai_integration/views/res_config_settings_views.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - AI Integration Settings - ir.actions.act_window - res.config.settings - form - inline - {"module" : "ai_integration"} - - - - res.config.settings.view.form.inherit.ai.integration - res.config.settings - - - -
-

AI Integration

-
-
-
-
- Default Provider Configuration -
- Configure the default AI provider instance and model for this company -
-
-
-
-
-
-
-
-
- -
-
-
- Batch Processing -
- Configure batch processing parameters for AI operations -
-
-
-
-
-
-
-
- - -
- - - - diff --git a/ai_integration_ollama_api/__init__.py b/ai_integration_ollama_api/__init__.py deleted file mode 100644 index 0650744..0000000 --- a/ai_integration_ollama_api/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import models diff --git a/ai_integration_ollama_api/__manifest__.py b/ai_integration_ollama_api/__manifest__.py deleted file mode 100644 index e119cbc..0000000 --- a/ai_integration_ollama_api/__manifest__.py +++ /dev/null @@ -1,36 +0,0 @@ -{ - 'name': 'Ollama Integration', - 'version': '1.0.0', - 'category': 'Technical', - 'summary': 'Integration with Ollama AI models', - 'description': """ -Ollama Integration -================== -This module provides integration with Ollama, allowing you to use local AI models -in your Odoo instance. Features include: - -* Connection to local Ollama server -* Support for all Ollama models -* Automatic model discovery and synchronization -* Configurable model parameters -""", - 'author': 'Bemade', - 'website': 'https://www.bemade.org', - 'depends': [ - 'ai_integration' - ], - 'data': [ - 'data/ai_provider_data.xml', - 'data/ai_provider_instance_data.xml', - 'views/ollama_stats_views.xml', - 'views/ai_provider_instance_views.xml', - 'security/ir.model.access.csv', - ], - 'external_dependencies': { - 'python': ['requests'], - }, - 'installable': True, - 'application': False, - 'auto_install': False, - 'license': 'LGPL-3', -} diff --git a/ai_integration_ollama_api/data/ai_provider_data.xml b/ai_integration_ollama_api/data/ai_provider_data.xml deleted file mode 100644 index fc7228b..0000000 --- a/ai_integration_ollama_api/data/ai_provider_data.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Ollama - ollama - Ollama is a local AI model provider that allows you to run various open-source models locally. - http://localhost:11434 - - - - diff --git a/ai_integration_ollama_api/data/ai_provider_instance_data.xml b/ai_integration_ollama_api/data/ai_provider_instance_data.xml deleted file mode 100644 index 7097bb4..0000000 --- a/ai_integration_ollama_api/data/ai_provider_instance_data.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - Ollama Local - ollama - http://localhost:11434 - llama3.2 - 0.7 - 40 - 0.9 - 1.1 - 4096 - 1024 - 0.05 - 64 - 0 - 1 - 8 - 0 - 5.0 - 0.1 - 8 - 0 - 1.0 - - - - - diff --git a/ai_integration_ollama_api/data/ir_model_inherit.xml b/ai_integration_ollama_api/data/ir_model_inherit.xml deleted file mode 100644 index a1c3091..0000000 --- a/ai_integration_ollama_api/data/ir_model_inherit.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - ai.provider.ollama - - - - diff --git a/ai_integration_ollama_api/data/ollama_provider.xml b/ai_integration_ollama_api/data/ollama_provider.xml deleted file mode 100644 index 03a101a..0000000 --- a/ai_integration_ollama_api/data/ollama_provider.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Ollama - ollama - Local AI models powered by Ollama - http://localhost:11434 - - - - diff --git a/ai_integration_ollama_api/doc/ollama_api.md b/ai_integration_ollama_api/doc/ollama_api.md deleted file mode 100644 index 603b15b..0000000 --- a/ai_integration_ollama_api/doc/ollama_api.md +++ /dev/null @@ -1,1627 +0,0 @@ -# API - -## Endpoints - -- [Generate a completion](#generate-a-completion) -- [Generate a chat completion](#generate-a-chat-completion) -- [Create a Model](#create-a-model) -- [List Local Models](#list-local-models) -- [Show Model Information](#show-model-information) -- [Copy a Model](#copy-a-model) -- [Delete a Model](#delete-a-model) -- [Pull a Model](#pull-a-model) -- [Push a Model](#push-a-model) -- [Generate Embeddings](#generate-embeddings) -- [List Running Models](#list-running-models) -- [Version](#version) - -## Conventions - -### Model names - -Model names follow a `model:tag` format, where `model` can have an optional namespace such as `example/model`. Some examples are `orca-mini:3b-q4_1` and `llama3:70b`. The tag is optional and, if not provided, will default to `latest`. The tag is used to identify a specific version. - -### Durations - -All durations are returned in nanoseconds. - -### Streaming responses - -Certain endpoints stream responses as JSON objects. Streaming can be disabled by providing `{"stream": false}` for these endpoints. - -## Generate a completion - -``` -POST /api/generate -``` - -Generate a response for a given prompt with a provided model. This is a streaming endpoint, so there will be a series of responses. The final response object will include statistics and additional data from the request. - -### Parameters - -- `model`: (required) the [model name](#model-names) -- `prompt`: the prompt to generate a response for -- `suffix`: the text after the model response -- `images`: (optional) a list of base64-encoded images (for multimodal models such as `llava`) - -Advanced parameters (optional): - -- `format`: the format to return a response in. Format can be `json` or a JSON schema -- `options`: additional model parameters listed in the documentation for the [Modelfile](./modelfile.md#valid-parameters-and-values) such as `temperature` -- `system`: system message to (overrides what is defined in the `Modelfile`) -- `template`: the prompt template to use (overrides what is defined in the `Modelfile`) -- `stream`: if `false` the response will be returned as a single response object, rather than a stream of objects -- `raw`: if `true` no formatting will be applied to the prompt. You may choose to use the `raw` parameter if you are specifying a full templated prompt in your request to the API -- `keep_alive`: controls how long the model will stay loaded into memory following the request (default: `5m`) -- `context` (deprecated): the context parameter returned from a previous request to `/generate`, this can be used to keep a short conversational memory - -#### Structured outputs - -Structured outputs are supported by providing a JSON schema in the `format` parameter. The model will generate a response that matches the schema. See the [structured outputs](#request-structured-outputs) example below. - -#### JSON mode - -Enable JSON mode by setting the `format` parameter to `json`. This will structure the response as a valid JSON object. See the JSON mode [example](#request-json-mode) below. - -> [!IMPORTANT] -> It's important to instruct the model to use JSON in the `prompt`. Otherwise, the model may generate large amounts whitespace. - -### Examples - -#### Generate request (Streaming) - -##### Request - -```shell -curl http://localhost:11434/api/generate -d '{ - "model": "llama3.2", - "prompt": "Why is the sky blue?" -}' -``` - -##### Response - -A stream of JSON objects is returned: - -```json -{ - "model": "llama3.2", - "created_at": "2023-08-04T08:52:19.385406455-07:00", - "response": "The", - "done": false -} -``` - -The final response in the stream also includes additional data about the generation: - -- `total_duration`: time spent generating the response -- `load_duration`: time spent in nanoseconds loading the model -- `prompt_eval_count`: number of tokens in the prompt -- `prompt_eval_duration`: time spent in nanoseconds evaluating the prompt -- `eval_count`: number of tokens in the response -- `eval_duration`: time in nanoseconds spent generating the response -- `context`: an encoding of the conversation used in this response, this can be sent in the next request to keep a conversational memory -- `response`: empty if the response was streamed, if not streamed, this will contain the full response - -To calculate how fast the response is generated in tokens per second (token/s), divide `eval_count` / `eval_duration` * `10^9`. - -```json -{ - "model": "llama3.2", - "created_at": "2023-08-04T19:22:45.499127Z", - "response": "", - "done": true, - "context": [1, 2, 3], - "total_duration": 10706818083, - "load_duration": 6338219291, - "prompt_eval_count": 26, - "prompt_eval_duration": 130079000, - "eval_count": 259, - "eval_duration": 4232710000 -} -``` - -#### Request (No streaming) - -##### Request - -A response can be received in one reply when streaming is off. - -```shell -curl http://localhost:11434/api/generate -d '{ - "model": "llama3.2", - "prompt": "Why is the sky blue?", - "stream": false -}' -``` - -##### Response - -If `stream` is set to `false`, the response will be a single JSON object: - -```json -{ - "model": "llama3.2", - "created_at": "2023-08-04T19:22:45.499127Z", - "response": "The sky is blue because it is the color of the sky.", - "done": true, - "context": [1, 2, 3], - "total_duration": 5043500667, - "load_duration": 5025959, - "prompt_eval_count": 26, - "prompt_eval_duration": 325953000, - "eval_count": 290, - "eval_duration": 4709213000 -} -``` - -#### Request (with suffix) - -##### Request - -```shell -curl http://localhost:11434/api/generate -d '{ - "model": "codellama:code", - "prompt": "def compute_gcd(a, b):", - "suffix": " return result", - "options": { - "temperature": 0 - }, - "stream": false -}' -``` - -##### Response - -```json -{ - "model": "codellama:code", - "created_at": "2024-07-22T20:47:51.147561Z", - "response": "\n if a == 0:\n return b\n else:\n return compute_gcd(b % a, a)\n\ndef compute_lcm(a, b):\n result = (a * b) / compute_gcd(a, b)\n", - "done": true, - "done_reason": "stop", - "context": [...], - "total_duration": 1162761250, - "load_duration": 6683708, - "prompt_eval_count": 17, - "prompt_eval_duration": 201222000, - "eval_count": 63, - "eval_duration": 953997000 -} -``` - -#### Request (Structured outputs) - -##### Request - -```shell -curl -X POST http://localhost:11434/api/generate -H "Content-Type: application/json" -d '{ - "model": "llama3.1:8b", - "prompt": "Ollama is 22 years old and is busy saving the world. Respond using JSON", - "stream": false, - "format": { - "type": "object", - "properties": { - "age": { - "type": "integer" - }, - "available": { - "type": "boolean" - } - }, - "required": [ - "age", - "available" - ] - } -}' -``` - -##### Response - -```json -{ - "model": "llama3.1:8b", - "created_at": "2024-12-06T00:48:09.983619Z", - "response": "{\n \"age\": 22,\n \"available\": true\n}", - "done": true, - "done_reason": "stop", - "context": [1, 2, 3], - "total_duration": 1075509083, - "load_duration": 567678166, - "prompt_eval_count": 28, - "prompt_eval_duration": 236000000, - "eval_count": 16, - "eval_duration": 269000000 -} -``` - -#### Request (JSON mode) - -> [!IMPORTANT] -> When `format` is set to `json`, the output will always be a well-formed JSON object. It's important to also instruct the model to respond in JSON. - -##### Request - -```shell -curl http://localhost:11434/api/generate -d '{ - "model": "llama3.2", - "prompt": "What color is the sky at different times of the day? Respond using JSON", - "format": "json", - "stream": false -}' -``` - -##### Response - -```json -{ - "model": "llama3.2", - "created_at": "2023-11-09T21:07:55.186497Z", - "response": "{\n\"morning\": {\n\"color\": \"blue\"\n},\n\"noon\": {\n\"color\": \"blue-gray\"\n},\n\"afternoon\": {\n\"color\": \"warm gray\"\n},\n\"evening\": {\n\"color\": \"orange\"\n}\n}\n", - "done": true, - "context": [1, 2, 3], - "total_duration": 4648158584, - "load_duration": 4071084, - "prompt_eval_count": 36, - "prompt_eval_duration": 439038000, - "eval_count": 180, - "eval_duration": 4196918000 -} -``` - -The value of `response` will be a string containing JSON similar to: - -```json -{ - "morning": { - "color": "blue" - }, - "noon": { - "color": "blue-gray" - }, - "afternoon": { - "color": "warm gray" - }, - "evening": { - "color": "orange" - } -} -``` - -#### Request (with images) - -To submit images to multimodal models such as `llava` or `bakllava`, provide a list of base64-encoded `images`: - -#### Request - -```shell -curl http://localhost:11434/api/generate -d '{ - "model": "llava", - "prompt":"What is in this picture?", - "stream": false, - "images": ["iVBORw0KGgoAAAANSUhEUgAAAG0AAABmCAYAAADBPx+VAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAA3VSURBVHgB7Z27r0zdG8fX743i1bi1ikMoFMQloXRpKFFIqI7LH4BEQ+NWIkjQuSWCRIEoULk0gsK1kCBI0IhrQVT7tz/7zZo888yz1r7MnDl7z5xvsjkzs2fP3uu71nNfa7lkAsm7d++Sffv2JbNmzUqcc8m0adOSzZs3Z+/XES4ZckAWJEGWPiCxjsQNLWmQsWjRIpMseaxcuTKpG/7HP27I8P79e7dq1ars/yL4/v27S0ejqwv+cUOGEGGpKHR37tzJCEpHV9tnT58+dXXCJDdECBE2Ojrqjh071hpNECjx4cMHVycM1Uhbv359B2F79+51586daxN/+pyRkRFXKyRDAqxEp4yMlDDzXG1NPnnyJKkThoK0VFd1ELZu3TrzXKxKfW7dMBQ6bcuWLW2v0VlHjx41z717927ba22U9APcw7Nnz1oGEPeL3m3p2mTAYYnFmMOMXybPPXv2bNIPpFZr1NHn4HMw0KRBjg9NuRw95s8PEcz/6DZELQd/09C9QGq5RsmSRybqkwHGjh07OsJSsYYm3ijPpyHzoiacg35MLdDSIS/O1yM778jOTwYUkKNHWUzUWaOsylE00MyI0fcnOwIdjvtNdW/HZwNLGg+sR1kMepSNJXmIwxBZiG8tDTpEZzKg0GItNsosY8USkxDhD0Rinuiko2gfL/RbiD2LZAjU9zKQJj8RDR0vJBR1/Phx9+PHj9Z7REF4nTZkxzX4LCXHrV271qXkBAPGfP/atWvu/PnzHe4C97F48eIsRLZ9+3a3f/9+87dwP1JxaF7/3r17ba+5l4EcaVo0lj3SBq5kGTJSQmLWMjgYNei2GPT1MuMqGTDEFHzeQSP2wi/jGnkmPJ/nhccs44jvDAxpVcxnq0F6eT8h4ni/iIWpR5lPyA6ETkNXoSukvpJAD3AsXLiwpZs49+fPn5ke4j10TqYvegSfn0OnafC+Tv9ooA/JPkgQysqQNBzagXY55nO/oa1F7qvIPWkRL12WRpMWUvpVDYmxAPehxWSe8ZEXL20sadYIozfmNch4QJPAfeJgW3rNsnzphBKNJM2KKODo1rVOMRYik5ETy3ix4qWNI81qAAirizgMIc+yhTytx0JWZuNI03qsrgWlGtwjoS9XwgUhWGyhUaRZZQNNIEwCiXD16tXcAHUs79co0vSD8rrJCIW98pzvxpAWyyo3HYwqS0+H0BjStClcZJT5coMm6D2LOF8TolGJtK9fvyZpyiC5ePFi9nc/oJU4eiEP0jVoAnHa9wyJycITMP78+eMeP37sXrx44d6+fdt6f82aNdkx1pg9e3Zb5W+RSRE+n+VjksQWifvVaTKFhn5O8my63K8Qabdv33b379/PiAP//vuvW7BggZszZ072/+TJk91YgkafPn166zXB1rQHFvouAWHq9z3SEevSUerqCn2/dDCeta2jxYbr69evk4MHDyY7d+7MjhMnTiTPnz9Pfv/+nfQT2ggpO2dMF8cghuoM7Ygj5iWCqRlGFml0QC/ftGmTmzt3rmsaKDsgBSPh0/8yPeLLBihLkOKJc0jp8H8vUzcxIA1k6QJ/c78tWEyj5P3o4u9+jywNPdJi5rAH9x0KHcl4Hg570eQp3+vHXGyrmEeigzQsQsjavXt38ujRo44LQuDDhw+TW7duRS1HGgMxhNXHgflaNTOsHyKvHK5Ijo2jbFjJBQK9YwFd6RVMzfgRBmEfP37suBBm/p49e1qjEP2mwTViNRo0VJWH1deMXcNK08uUjVUu7s/zRaL+oLNxz1bpANco4npUgX4G2eFbpDFyQoQxojBCpEGSytmOH8qrH5Q9vuzD6ofQylkCUmh8DBAr+q8JCyVNtWQIidKQE9wNtLSQnS4jDSsxNHogzFuQBw4cyM61UKVsjfr3ooBkPSqqQHesUPWVtzi9/vQi1T+rJj7WiTz4Pt/l3LxUkr5P2VYZaZ4URpsE+st/dujQoaBBYokbrz/8TJNQYLSonrPS9kUaSkPeZyj1AWSj+d+VBoy1pIWVNed8P0Ll/ee5HdGRhrHhR5GGN0r4LGZBaj8oFDJitBTJzIZgFcmU0Y8ytWMZMzJOaXUSrUs5RxKnrxmbb5YXO9VGUhtpXldhEUogFr3IzIsvlpmdosVcGVGXFWp2oU9kLFL3dEkSz6NHEY1sjSRdIuDFWEhd8KxFqsRi1uM/nz9/zpxnwlESONdg6dKlbsaMGS4EHFHtjFIDHwKOo46l4TxSuxgDzi+rE2jg+BaFruOX4HXa0Nnf1lwAPufZeF8/r6zD97WK2qFnGjBxTw5qNGPxT+5T/r7/7RawFC3j4vTp09koCxkeHjqbHJqArmH5UrFKKksnxrK7FuRIs8STfBZv+luugXZ2pR/pP9Ois4z+TiMzUUkUjD0iEi1fzX8GmXyuxUBRcaUfykV0YZnlJGKQpOiGB76x5GeWkWWJc3mOrK6S7xdND+W5N6XyaRgtWJFe13GkaZnKOsYqGdOVVVbGupsyA/l7emTLHi7vwTdirNEt0qxnzAvBFcnQF16xh/TMpUuXHDowhlA9vQVraQhkudRdzOnK+04ZSP3DUhVSP61YsaLtd/ks7ZgtPcXqPqEafHkdqa84X6aCeL7YWlv6edGFHb+ZFICPlljHhg0bKuk0CSvVznWsotRu433alNdFrqG45ejoaPCaUkWERpLXjzFL2Rpllp7PJU2a/v7Ab8N05/9t27Z16KUqoFGsxnI9EosS2niSYg9SpU6B4JgTrvVW1flt1sT+0ADIJU2maXzcUTraGCRaL1Wp9rUMk16PMom8QhruxzvZIegJjFU7LLCePfS8uaQdPny4jTTL0dbee5mYokQsXTIWNY46kuMbnt8Kmec+LGWtOVIl9cT1rCB0V8WqkjAsRwta93TbwNYoGKsUSChN44lgBNCoHLHzquYKrU6qZ8lolCIN0Rh6cP0Q3U6I6IXILYOQI513hJaSKAorFpuHXJNfVlpRtmYBk1Su1obZr5dnKAO+L10Hrj3WZW+E3qh6IszE37F6EB+68mGpvKm4eb9bFrlzrok7fvr0Kfv727dvWRmdVTJHw0qiiCUSZ6wCK+7XL/AcsgNyL74DQQ730sv78Su7+t/A36MdY0sW5o40ahslXr58aZ5HtZB8GH64m9EmMZ7FpYw4T6QnrZfgenrhFxaSiSGXtPnz57e9TkNZLvTjeqhr734CNtrK41L40sUQckmj1lGKQ0rC37x544r8eNXRpnVE3ZZY7zXo8NomiO0ZUCj2uHz58rbXoZ6gc0uA+F6ZeKS/jhRDUq8MKrTho9fEkihMmhxtBI1DxKFY9XLpVcSkfoi8JGnToZO5sU5aiDQIW716ddt7ZLYtMQlhECdBGXZZMWldY5BHm5xgAroWj4C0hbYkSc/jBmggIrXJWlZM6pSETsEPGqZOndr2uuuR5rF169a2HoHPdurUKZM4CO1WTPqaDaAd+GFGKdIQkxAn9RuEWcTRyN2KSUgiSgF5aWzPTeA/lN5rZubMmR2bE4SIC4nJoltgAV/dVefZm72AtctUCJU2CMJ327hxY9t7EHbkyJFseq+EJSY16RPo3Dkq1kkr7+q0bNmyDuLQcZBEPYmHVdOBiJyIlrRDq41YPWfXOxUysi5fvtyaj+2BpcnsUV/oSoEMOk2CQGlr4ckhBwaetBhjCwH0ZHtJROPJkyc7UjcYLDjmrH7ADTEBXFfOYmB0k9oYBOjJ8b4aOYSe7QkKcYhFlq3QYLQhSidNmtS2RATwy8YOM3EQJsUjKiaWZ+vZToUQgzhkHXudb/PW5YMHD9yZM2faPsMwoc7RciYJXbGuBqJ1UIGKKLv915jsvgtJxCZDubdXr165mzdvtr1Hz5LONA8jrUwKPqsmVesKa49S3Q4WxmRPUEYdTjgiUcfUwLx589ySJUva3oMkP6IYddq6HMS4o55xBJBUeRjzfa4Zdeg56QZ43LhxoyPo7Lf1kNt7oO8wWAbNwaYjIv5lhyS7kRf96dvm5Jah8vfvX3flyhX35cuX6HfzFHOToS1H4BenCaHvO8pr8iDuwoUL7tevX+b5ZdbBair0xkFIlFDlW4ZknEClsp/TzXyAKVOmmHWFVSbDNw1l1+4f90U6IY/q4V27dpnE9bJ+v87QEydjqx/UamVVPRG+mwkNTYN+9tjkwzEx+atCm/X9WvWtDtAb68Wy9LXa1UmvCDDIpPkyOQ5ZwSzJ4jMrvFcr0rSjOUh+GcT4LSg5ugkW1Io0/SCDQBojh0hPlaJdah+tkVYrnTZowP8iq1F1TgMBBauufyB33x1v+NWFYmT5KmppgHC+NkAgbmRkpD3yn9QIseXymoTQFGQmIOKTxiZIWpvAatenVqRVXf2nTrAWMsPnKrMZHz6bJq5jvce6QK8J1cQNgKxlJapMPdZSR64/UivS9NztpkVEdKcrs5alhhWP9NeqlfWopzhZScI6QxseegZRGeg5a8C3Re1Mfl1ScP36ddcUaMuv24iOJtz7sbUjTS4qBvKmstYJoUauiuD3k5qhyr7QdUHMeCgLa1Ear9NquemdXgmum4fvJ6w1lqsuDhNrg1qSpleJK7K3TF0Q2jSd94uSZ60kK1e3qyVpQK6PVWXp2/FC3mp6jBhKKOiY2h3gtUV64TWM6wDETRPLDfSakXmH3w8g9Jlug8ZtTt4kVF0kLUYYmCCtD/DrQ5YhMGbA9L3ucdjh0y8kOHW5gU/VEEmJTcL4Pz/f7mgoAbYkAAAAAElFTkSuQmCC"] -}' -``` - -#### Response - -```json -{ - "model": "llava", - "created_at": "2023-11-03T15:36:02.583064Z", - "response": "A happy cartoon character, which is cute and cheerful.", - "done": true, - "context": [1, 2, 3], - "total_duration": 2938432250, - "load_duration": 2559292, - "prompt_eval_count": 1, - "prompt_eval_duration": 2195557000, - "eval_count": 44, - "eval_duration": 736432000 -} -``` - -#### Request (Raw Mode) - -In some cases, you may wish to bypass the templating system and provide a full prompt. In this case, you can use the `raw` parameter to disable templating. Also note that raw mode will not return a context. - -##### Request - -```shell -curl http://localhost:11434/api/generate -d '{ - "model": "mistral", - "prompt": "[INST] why is the sky blue? [/INST]", - "raw": true, - "stream": false -}' -``` - -#### Request (Reproducible outputs) - -For reproducible outputs, set `seed` to a number: - -##### Request - -```shell -curl http://localhost:11434/api/generate -d '{ - "model": "mistral", - "prompt": "Why is the sky blue?", - "options": { - "seed": 123 - } -}' -``` - -##### Response - -```json -{ - "model": "mistral", - "created_at": "2023-11-03T15:36:02.583064Z", - "response": " The sky appears blue because of a phenomenon called Rayleigh scattering.", - "done": true, - "total_duration": 8493852375, - "load_duration": 6589624375, - "prompt_eval_count": 14, - "prompt_eval_duration": 119039000, - "eval_count": 110, - "eval_duration": 1779061000 -} -``` - -#### Generate request (With options) - -If you want to set custom options for the model at runtime rather than in the Modelfile, you can do so with the `options` parameter. This example sets every available option, but you can set any of them individually and omit the ones you do not want to override. - -##### Request - -```shell -curl http://localhost:11434/api/generate -d '{ - "model": "llama3.2", - "prompt": "Why is the sky blue?", - "stream": false, - "options": { - "num_keep": 5, - "seed": 42, - "num_predict": 100, - "top_k": 20, - "top_p": 0.9, - "min_p": 0.0, - "typical_p": 0.7, - "repeat_last_n": 33, - "temperature": 0.8, - "repeat_penalty": 1.2, - "presence_penalty": 1.5, - "frequency_penalty": 1.0, - "mirostat": 1, - "mirostat_tau": 0.8, - "mirostat_eta": 0.6, - "penalize_newline": true, - "stop": ["\n", "user:"], - "numa": false, - "num_ctx": 1024, - "num_batch": 2, - "num_gpu": 1, - "main_gpu": 0, - "low_vram": false, - "vocab_only": false, - "use_mmap": true, - "use_mlock": false, - "num_thread": 8 - } -}' -``` - -##### Response - -```json -{ - "model": "llama3.2", - "created_at": "2023-08-04T19:22:45.499127Z", - "response": "The sky is blue because it is the color of the sky.", - "done": true, - "context": [1, 2, 3], - "total_duration": 4935886791, - "load_duration": 534986708, - "prompt_eval_count": 26, - "prompt_eval_duration": 107345000, - "eval_count": 237, - "eval_duration": 4289432000 -} -``` - -#### Load a model - -If an empty prompt is provided, the model will be loaded into memory. - -##### Request - -```shell -curl http://localhost:11434/api/generate -d '{ - "model": "llama3.2" -}' -``` - -##### Response - -A single JSON object is returned: - -```json -{ - "model": "llama3.2", - "created_at": "2023-12-18T19:52:07.071755Z", - "response": "", - "done": true -} -``` - -#### Unload a model - -If an empty prompt is provided and the `keep_alive` parameter is set to `0`, a model will be unloaded from memory. - -##### Request - -```shell -curl http://localhost:11434/api/generate -d '{ - "model": "llama3.2", - "keep_alive": 0 -}' -``` - -##### Response - -A single JSON object is returned: - -```json -{ - "model": "llama3.2", - "created_at": "2024-09-12T03:54:03.516566Z", - "response": "", - "done": true, - "done_reason": "unload" -} -``` - -## Generate a chat completion - -``` -POST /api/chat -``` - -Generate the next message in a chat with a provided model. This is a streaming endpoint, so there will be a series of responses. Streaming can be disabled using `"stream": false`. The final response object will include statistics and additional data from the request. - -### Parameters - -- `model`: (required) the [model name](#model-names) -- `messages`: the messages of the chat, this can be used to keep a chat memory -- `tools`: list of tools in JSON for the model to use if supported - -The `message` object has the following fields: - -- `role`: the role of the message, either `system`, `user`, `assistant`, or `tool` -- `content`: the content of the message -- `images` (optional): a list of images to include in the message (for multimodal models such as `llava`) -- `tool_calls` (optional): a list of tools in JSON that the model wants to use - -Advanced parameters (optional): - -- `format`: the format to return a response in. Format can be `json` or a JSON schema. -- `options`: additional model parameters listed in the documentation for the [Modelfile](./modelfile.md#valid-parameters-and-values) such as `temperature` -- `stream`: if `false` the response will be returned as a single response object, rather than a stream of objects -- `keep_alive`: controls how long the model will stay loaded into memory following the request (default: `5m`) - -### Structured outputs - -Structured outputs are supported by providing a JSON schema in the `format` parameter. The model will generate a response that matches the schema. See the [Chat request (Structured outputs)](#chat-request-structured-outputs) example below. - -### Examples - -#### Chat Request (Streaming) - -##### Request - -Send a chat message with a streaming response. - -```shell -curl http://localhost:11434/api/chat -d '{ - "model": "llama3.2", - "messages": [ - { - "role": "user", - "content": "why is the sky blue?" - } - ] -}' -``` - -##### Response - -A stream of JSON objects is returned: - -```json -{ - "model": "llama3.2", - "created_at": "2023-08-04T08:52:19.385406455-07:00", - "message": { - "role": "assistant", - "content": "The", - "images": null - }, - "done": false -} -``` - -Final response: - -```json -{ - "model": "llama3.2", - "created_at": "2023-08-04T19:22:45.499127Z", - "done": true, - "total_duration": 4883583458, - "load_duration": 1334875, - "prompt_eval_count": 26, - "prompt_eval_duration": 342546000, - "eval_count": 282, - "eval_duration": 4535599000 -} -``` - -#### Chat request (No streaming) - -##### Request - -```shell -curl http://localhost:11434/api/chat -d '{ - "model": "llama3.2", - "messages": [ - { - "role": "user", - "content": "why is the sky blue?" - } - ], - "stream": false -}' -``` - -##### Response - -```json -{ - "model": "llama3.2", - "created_at": "2023-12-12T14:13:43.416799Z", - "message": { - "role": "assistant", - "content": "Hello! How are you today?" - }, - "done": true, - "total_duration": 5191566416, - "load_duration": 2154458, - "prompt_eval_count": 26, - "prompt_eval_duration": 383809000, - "eval_count": 298, - "eval_duration": 4799921000 -} -``` - -#### Chat request (Structured outputs) - -##### Request - -```shell -curl -X POST http://localhost:11434/api/chat -H "Content-Type: application/json" -d '{ - "model": "llama3.1", - "messages": [{"role": "user", "content": "Ollama is 22 years old and busy saving the world. Return a JSON object with the age and availability."}], - "stream": false, - "format": { - "type": "object", - "properties": { - "age": { - "type": "integer" - }, - "available": { - "type": "boolean" - } - }, - "required": [ - "age", - "available" - ] - }, - "options": { - "temperature": 0 - } -}' -``` - -##### Response - -```json -{ - "model": "llama3.1", - "created_at": "2024-12-06T00:46:58.265747Z", - "message": { "role": "assistant", "content": "{\"age\": 22, \"available\": false}" }, - "done_reason": "stop", - "done": true, - "total_duration": 2254970291, - "load_duration": 574751416, - "prompt_eval_count": 34, - "prompt_eval_duration": 1502000000, - "eval_count": 12, - "eval_duration": 175000000 -} -``` - -#### Chat request (With History) - -Send a chat message with a conversation history. You can use this same approach to start the conversation using multi-shot or chain-of-thought prompting. - -##### Request - -```shell -curl http://localhost:11434/api/chat -d '{ - "model": "llama3.2", - "messages": [ - { - "role": "user", - "content": "why is the sky blue?" - }, - { - "role": "assistant", - "content": "due to rayleigh scattering." - }, - { - "role": "user", - "content": "how is that different than mie scattering?" - } - ] -}' -``` - -##### Response - -A stream of JSON objects is returned: - -```json -{ - "model": "llama3.2", - "created_at": "2023-08-04T08:52:19.385406455-07:00", - "message": { - "role": "assistant", - "content": "The" - }, - "done": false -} -``` - -Final response: - -```json -{ - "model": "llama3.2", - "created_at": "2023-08-04T19:22:45.499127Z", - "done": true, - "total_duration": 8113331500, - "load_duration": 6396458, - "prompt_eval_count": 61, - "prompt_eval_duration": 398801000, - "eval_count": 468, - "eval_duration": 7701267000 -} -``` - -#### Chat request (with images) - -##### Request - -Send a chat message with images. The images should be provided as an array, with the individual images encoded in Base64. - -```shell -curl http://localhost:11434/api/chat -d '{ - "model": "llava", - "messages": [ - { - "role": "user", - "content": "what is in this image?", - "images": ["iVBORw0KGgoAAAANSUhEUgAAAG0AAABmCAYAAADBPx+VAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAA3VSURBVHgB7Z27r0zdG8fX743i1bi1ikMoFMQloXRpKFFIqI7LH4BEQ+NWIkjQuSWCRIEoULk0gsK1kCBI0IhrQVT7tz/7zZo888yz1r7MnDl7z5xvsjkzs2fP3uu71nNfa7lkAsm7d++Sffv2JbNmzUqcc8m0adOSzZs3Z+/XES4ZckAWJEGWPiCxjsQNLWmQsWjRIpMseaxcuTKpG/7HP27I8P79e7dq1ars/yL4/v27S0ejqwv+cUOGEGGpKHR37tzJCEpHV9tnT58+dXXCJDdECBE2Ojrqjh071hpNECjx4cMHVycM1Uhbv359B2F79+51586daxN/+pyRkRFXKyRDAqxEp4yMlDDzXG1NPnnyJKkThoK0VFd1ELZu3TrzXKxKfW7dMBQ6bcuWLW2v0VlHjx41z717927ba22U9APcw7Nnz1oGEPeL3m3p2mTAYYnFmMOMXybPPXv2bNIPpFZr1NHn4HMw0KRBjg9NuRw95s8PEcz/6DZELQd/09C9QGq5RsmSRybqkwHGjh07OsJSsYYm3ijPpyHzoiacg35MLdDSIS/O1yM778jOTwYUkKNHWUzUWaOsylE00MyI0fcnOwIdjvtNdW/HZwNLGg+sR1kMepSNJXmIwxBZiG8tDTpEZzKg0GItNsosY8USkxDhD0Rinuiko2gfL/RbiD2LZAjU9zKQJj8RDR0vJBR1/Phx9+PHj9Z7REF4nTZkxzX4LCXHrV271qXkBAPGfP/atWvu/PnzHe4C97F48eIsRLZ9+3a3f/9+87dwP1JxaF7/3r17ba+5l4EcaVo0lj3SBq5kGTJSQmLWMjgYNei2GPT1MuMqGTDEFHzeQSP2wi/jGnkmPJ/nhccs44jvDAxpVcxnq0F6eT8h4ni/iIWpR5lPyA6ETkNXoSukvpJAD3AsXLiwpZs49+fPn5ke4j10TqYvegSfn0OnafC+Tv9ooA/JPkgQysqQNBzagXY55nO/oa1F7qvIPWkRL12WRpMWUvpVDYmxAPehxWSe8ZEXL20sadYIozfmNch4QJPAfeJgW3rNsnzphBKNJM2KKODo1rVOMRYik5ETy3ix4qWNI81qAAirizgMIc+yhTytx0JWZuNI03qsrgWlGtwjoS9XwgUhWGyhUaRZZQNNIEwCiXD16tXcAHUs79co0vSD8rrJCIW98pzvxpAWyyo3HYwqS0+H0BjStClcZJT5coMm6D2LOF8TolGJtK9fvyZpyiC5ePFi9nc/oJU4eiEP0jVoAnHa9wyJycITMP78+eMeP37sXrx44d6+fdt6f82aNdkx1pg9e3Zb5W+RSRE+n+VjksQWifvVaTKFhn5O8my63K8Qabdv33b379/PiAP//vuvW7BggZszZ072/+TJk91YgkafPn166zXB1rQHFvouAWHq9z3SEevSUerqCn2/dDCeta2jxYbr69evk4MHDyY7d+7MjhMnTiTPnz9Pfv/+nfQT2ggpO2dMF8cghuoM7Ygj5iWCqRlGFml0QC/ftGmTmzt3rmsaKDsgBSPh0/8yPeLLBihLkOKJc0jp8H8vUzcxIA1k6QJ/c78tWEyj5P3o4u9+jywNPdJi5rAH9x0KHcl4Hg570eQp3+vHXGyrmEeigzQsQsjavXt38ujRo44LQuDDhw+TW7duRS1HGgMxhNXHgflaNTOsHyKvHK5Ijo2jbFjJBQK9YwFd6RVMzfgRBmEfP37suBBm/p49e1qjEP2mwTViNRo0VJWH1deMXcNK08uUjVUu7s/zRaL+oLNxz1bpANco4npUgX4G2eFbpDFyQoQxojBCpEGSytmOH8qrH5Q9vuzD6ofQylkCUmh8DBAr+q8JCyVNtWQIidKQE9wNtLSQnS4jDSsxNHogzFuQBw4cyM61UKVsjfr3ooBkPSqqQHesUPWVtzi9/vQi1T+rJj7WiTz4Pt/l3LxUkr5P2VYZaZ4URpsE+st/dujQoaBBYokbrz/8TJNQYLSonrPS9kUaSkPeZyj1AWSj+d+VBoy1pIWVNed8P0Ll/ee5HdGRhrHhR5GGN0r4LGZBaj8oFDJitBTJzIZgFcmU0Y8ytWMZMzJOaXUSrUs5RxKnrxmbb5YXO9VGUhtpXldhEUogFr3IzIsvlpmdosVcGVGXFWp2oU9kLFL3dEkSz6NHEY1sjSRdIuDFWEhd8KxFqsRi1uM/nz9/zpxnwlESONdg6dKlbsaMGS4EHFHtjFIDHwKOo46l4TxSuxgDzi+rE2jg+BaFruOX4HXa0Nnf1lwAPufZeF8/r6zD97WK2qFnGjBxTw5qNGPxT+5T/r7/7RawFC3j4vTp09koCxkeHjqbHJqArmH5UrFKKksnxrK7FuRIs8STfBZv+luugXZ2pR/pP9Ois4z+TiMzUUkUjD0iEi1fzX8GmXyuxUBRcaUfykV0YZnlJGKQpOiGB76x5GeWkWWJc3mOrK6S7xdND+W5N6XyaRgtWJFe13GkaZnKOsYqGdOVVVbGupsyA/l7emTLHi7vwTdirNEt0qxnzAvBFcnQF16xh/TMpUuXHDowhlA9vQVraQhkudRdzOnK+04ZSP3DUhVSP61YsaLtd/ks7ZgtPcXqPqEafHkdqa84X6aCeL7YWlv6edGFHb+ZFICPlljHhg0bKuk0CSvVznWsotRu433alNdFrqG45ejoaPCaUkWERpLXjzFL2Rpllp7PJU2a/v7Ab8N05/9t27Z16KUqoFGsxnI9EosS2niSYg9SpU6B4JgTrvVW1flt1sT+0ADIJU2maXzcUTraGCRaL1Wp9rUMk16PMom8QhruxzvZIegJjFU7LLCePfS8uaQdPny4jTTL0dbee5mYokQsXTIWNY46kuMbnt8Kmec+LGWtOVIl9cT1rCB0V8WqkjAsRwta93TbwNYoGKsUSChN44lgBNCoHLHzquYKrU6qZ8lolCIN0Rh6cP0Q3U6I6IXILYOQI513hJaSKAorFpuHXJNfVlpRtmYBk1Su1obZr5dnKAO+L10Hrj3WZW+E3qh6IszE37F6EB+68mGpvKm4eb9bFrlzrok7fvr0Kfv727dvWRmdVTJHw0qiiCUSZ6wCK+7XL/AcsgNyL74DQQ730sv78Su7+t/A36MdY0sW5o40ahslXr58aZ5HtZB8GH64m9EmMZ7FpYw4T6QnrZfgenrhFxaSiSGXtPnz57e9TkNZLvTjeqhr734CNtrK41L40sUQckmj1lGKQ0rC37x544r8eNXRpnVE3ZZY7zXo8NomiO0ZUCj2uHz58rbXoZ6gc0uA+F6ZeKS/jhRDUq8MKrTho9fEkihMmhxtBI1DxKFY9XLpVcSkfoi8JGnToZO5sU5aiDQIW716ddt7ZLYtMQlhECdBGXZZMWldY5BHm5xgAroWj4C0hbYkSc/jBmggIrXJWlZM6pSETsEPGqZOndr2uuuR5rF169a2HoHPdurUKZM4CO1WTPqaDaAd+GFGKdIQkxAn9RuEWcTRyN2KSUgiSgF5aWzPTeA/lN5rZubMmR2bE4SIC4nJoltgAV/dVefZm72AtctUCJU2CMJ327hxY9t7EHbkyJFseq+EJSY16RPo3Dkq1kkr7+q0bNmyDuLQcZBEPYmHVdOBiJyIlrRDq41YPWfXOxUysi5fvtyaj+2BpcnsUV/oSoEMOk2CQGlr4ckhBwaetBhjCwH0ZHtJROPJkyc7UjcYLDjmrH7ADTEBXFfOYmB0k9oYBOjJ8b4aOYSe7QkKcYhFlq3QYLQhSidNmtS2RATwy8YOM3EQJsUjKiaWZ+vZToUQgzhkHXudb/PW5YMHD9yZM2faPsMwoc7RciYJXbGuBqJ1UIGKKLv915jsvgtJxCZDubdXr165mzdvtr1Hz5LONA8jrUwKPqsmVesKa49S3Q4WxmRPUEYdTjgiUcfUwLx589ySJUva3oMkP6IYddq6HMS4o55xBJBUeRjzfa4Zdeg56QZ43LhxoyPo7Lf1kNt7oO8wWAbNwaYjIv5lhyS7kRf96dvm5Jah8vfvX3flyhX35cuX6HfzFHOToS1H4BenCaHvO8pr8iDuwoUL7tevX+b5ZdbBair0xkFIlFDlW4ZknEClsp/TzXyAKVOmmHWFVSbDNw1l1+4f90U6IY/q4V27dpnE9bJ+v87QEydjqx/UamVVPRG+mwkNTYN+9tjkwzEx+atCm/X9WvWtDtAb68Wy9LXa1UmvCDDIpPkyOQ5ZwSzJ4jMrvFcr0rSjOUh+GcT4LSg5ugkW1Io0/SCDQBojh0hPlaJdah+tkVYrnTZowP8iq1F1TgMBBauufyB33x1v+NWFYmT5KmppgHC+NkAgbmRkpD3yn9QIseXymoTQFGQmIOKTxiZIWpvAatenVqRVXf2nTrAWMsPnKrMZHz6bJq5jvce6QK8J1cQNgKxlJapMPdZSR64/UivS9NztpkVEdKcrs5alhhWP9NeqlfWopzhZScI6QxseegZRGeg5a8C3Re1Mfl1ScP36ddcUaMuv24iOJtz7sbUjTS4qBvKmstYJoUauiuD3k5qhyr7QdUHMeCgLa1Ear9NquemdXgmum4fvJ6w1lqsuDhNrg1qSpleJK7K3TF0Q2jSd94uSZ60kK1e3qyVpQK6PVWXp2/FC3mp6jBhKKOiY2h3gtUV64TWM6wDETRPLDfSakXmH3w8g9Jlug8ZtTt4kVF0kLUYYmCCtD/DrQ5YhMGbA9L3ucdjh0y8kOHW5gU/VEEmJTcL4Pz/f7mgoAbYkAAAAAElFTkSuQmCC"] - } - ] -}' -``` - -##### Response - -```json -{ - "model": "llava", - "created_at": "2023-12-13T22:42:50.203334Z", - "message": { - "role": "assistant", - "content": " The image features a cute, little pig with an angry facial expression. It's wearing a heart on its shirt and is waving in the air. This scene appears to be part of a drawing or sketching project.", - "images": null - }, - "done": true, - "total_duration": 1668506709, - "load_duration": 1986209, - "prompt_eval_count": 26, - "prompt_eval_duration": 359682000, - "eval_count": 83, - "eval_duration": 1303285000 -} -``` - -#### Chat request (Reproducible outputs) - -##### Request - -```shell -curl http://localhost:11434/api/chat -d '{ - "model": "llama3.2", - "messages": [ - { - "role": "user", - "content": "Hello!" - } - ], - "options": { - "seed": 101, - "temperature": 0 - } -}' -``` - -##### Response - -```json -{ - "model": "llama3.2", - "created_at": "2023-12-12T14:13:43.416799Z", - "message": { - "role": "assistant", - "content": "Hello! How are you today?" - }, - "done": true, - "total_duration": 5191566416, - "load_duration": 2154458, - "prompt_eval_count": 26, - "prompt_eval_duration": 383809000, - "eval_count": 298, - "eval_duration": 4799921000 -} -``` - -#### Chat request (with tools) - -##### Request - -```shell -curl http://localhost:11434/api/chat -d '{ - "model": "llama3.2", - "messages": [ - { - "role": "user", - "content": "What is the weather today in Paris?" - } - ], - "stream": false, - "tools": [ - { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather for a location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The location to get the weather for, e.g. San Francisco, CA" - }, - "format": { - "type": "string", - "description": "The format to return the weather in, e.g. 'celsius' or 'fahrenheit'", - "enum": ["celsius", "fahrenheit"] - } - }, - "required": ["location", "format"] - } - } - } - ] -}' -``` - -##### Response - -```json -{ - "model": "llama3.2", - "created_at": "2024-07-22T20:33:28.123648Z", - "message": { - "role": "assistant", - "content": "", - "tool_calls": [ - { - "function": { - "name": "get_current_weather", - "arguments": { - "format": "celsius", - "location": "Paris, FR" - } - } - } - ] - }, - "done_reason": "stop", - "done": true, - "total_duration": 885095291, - "load_duration": 3753500, - "prompt_eval_count": 122, - "prompt_eval_duration": 328493000, - "eval_count": 33, - "eval_duration": 552222000 -} -``` - -#### Load a model - -If the messages array is empty, the model will be loaded into memory. - -##### Request - -```shell -curl http://localhost:11434/api/chat -d '{ - "model": "llama3.2", - "messages": [] -}' -``` - -##### Response - -```json -{ - "model": "llama3.2", - "created_at":"2024-09-12T21:17:29.110811Z", - "message": { - "role": "assistant", - "content": "" - }, - "done_reason": "load", - "done": true -} -``` - -#### Unload a model - -If the messages array is empty and the `keep_alive` parameter is set to `0`, a model will be unloaded from memory. - -##### Request - -```shell -curl http://localhost:11434/api/chat -d '{ - "model": "llama3.2", - "messages": [], - "keep_alive": 0 -}' -``` - -##### Response - -A single JSON object is returned: - -```json -{ - "model": "llama3.2", - "created_at":"2024-09-12T21:33:17.547535Z", - "message": { - "role": "assistant", - "content": "" - }, - "done_reason": "unload", - "done": true -} -``` - -## Create a Model - -``` -POST /api/create -``` - -Create a model from: - * another model; - * a safetensors directory; or - * a GGUF file. - -If you are creating a model from a safetensors directory or from a GGUF file, you must [create a blob](#create-a-blob) for each of the files and then use the file name and SHA256 digest associated with each blob in the `files` field. - -### Parameters - -- `model`: name of the model to create -- `from`: (optional) name of an existing model to create the new model from -- `files`: (optional) a dictionary of file names to SHA256 digests of blobs to create the model from -- `adapters`: (optional) a dictionary of file names to SHA256 digests of blobs for LORA adapters -- `template`: (optional) the prompt template for the model -- `license`: (optional) a string or list of strings containing the license or licenses for the model -- `system`: (optional) a string containing the system prompt for the model -- `parameters`: (optional) a dictionary of parameters for the model (see [Modelfile](./modelfile.md#valid-parameters-and-values) for a list of parameters) -- `messages`: (optional) a list of message objects used to create a conversation -- `stream`: (optional) if `false` the response will be returned as a single response object, rather than a stream of objects -- `quantize` (optional): quantize a non-quantized (e.g. float16) model - -#### Quantization types - -| Type | Recommended | -| --- | :-: | -| q2_K | | -| q3_K_L | | -| q3_K_M | | -| q3_K_S | | -| q4_0 | | -| q4_1 | | -| q4_K_M | * | -| q4_K_S | | -| q5_0 | | -| q5_1 | | -| q5_K_M | | -| q5_K_S | | -| q6_K | | -| q8_0 | * | - -### Examples - -#### Create a new model - -Create a new model from an existing model. - -##### Request - -```shell -curl http://localhost:11434/api/create -d '{ - "model": "mario", - "from": "llama3.2", - "system": "You are Mario from Super Mario Bros." -}' -``` - -##### Response - -A stream of JSON objects is returned: - -```json -{"status":"reading model metadata"} -{"status":"creating system layer"} -{"status":"using already created layer sha256:22f7f8ef5f4c791c1b03d7eb414399294764d7cc82c7e94aa81a1feb80a983a2"} -{"status":"using already created layer sha256:8c17c2ebb0ea011be9981cc3922db8ca8fa61e828c5d3f44cb6ae342bf80460b"} -{"status":"using already created layer sha256:7c23fb36d80141c4ab8cdbb61ee4790102ebd2bf7aeff414453177d4f2110e5d"} -{"status":"using already created layer sha256:2e0493f67d0c8c9c68a8aeacdf6a38a2151cb3c4c1d42accf296e19810527988"} -{"status":"using already created layer sha256:2759286baa875dc22de5394b4a925701b1896a7e3f8e53275c36f75a877a82c9"} -{"status":"writing layer sha256:df30045fe90f0d750db82a058109cecd6d4de9c90a3d75b19c09e5f64580bb42"} -{"status":"writing layer sha256:f18a68eb09bf925bb1b669490407c1b1251c5db98dc4d3d81f3088498ea55690"} -{"status":"writing manifest"} -{"status":"success"} -``` - -#### Quantize a model - -Quantize a non-quantized model. - -##### Request - -```shell -curl http://localhost:11434/api/create -d '{ - "model": "llama3.1:quantized", - "from": "llama3.1:8b-instruct-fp16", - "quantize": "q4_K_M" -}' -``` - -##### Response - -A stream of JSON objects is returned: - -```json -{"status":"quantizing F16 model to Q4_K_M"} -{"status":"creating new layer sha256:667b0c1932bc6ffc593ed1d03f895bf2dc8dc6df21db3042284a6f4416b06a29"} -{"status":"using existing layer sha256:11ce4ee3e170f6adebac9a991c22e22ab3f8530e154ee669954c4bc73061c258"} -{"status":"using existing layer sha256:0ba8f0e314b4264dfd19df045cde9d4c394a52474bf92ed6a3de22a4ca31a177"} -{"status":"using existing layer sha256:56bb8bd477a519ffa694fc449c2413c6f0e1d3b1c88fa7e3c9d88d3ae49d4dcb"} -{"status":"creating new layer sha256:455f34728c9b5dd3376378bfb809ee166c145b0b4c1f1a6feca069055066ef9a"} -{"status":"writing manifest"} -{"status":"success"} -``` - -#### Create a model from GGUF - -Create a model from a GGUF file. The `files` parameter should be filled out with the file name and SHA256 digest of the GGUF file you wish to use. Use [/api/blobs/:digest](#push-a-blob) to push the GGUF file to the server before calling this API. - - -##### Request - -```shell -curl http://localhost:11434/api/create -d '{ - "model": "my-gguf-model", - "files": { - "test.gguf": "sha256:432f310a77f4650a88d0fd59ecdd7cebed8d684bafea53cbff0473542964f0c3" - } -}' -``` - -##### Response - -A stream of JSON objects is returned: - -```json -{"status":"parsing GGUF"} -{"status":"using existing layer sha256:432f310a77f4650a88d0fd59ecdd7cebed8d684bafea53cbff0473542964f0c3"} -{"status":"writing manifest"} -{"status":"success"} -``` - - -#### Create a model from a Safetensors directory - -The `files` parameter should include a dictionary of files for the safetensors model which includes the file names and SHA256 digest of each file. Use [/api/blobs/:digest](#push-a-blob) to first push each of the files to the server before calling this API. Files will remain in the cache until the Ollama server is restarted. - -##### Request - -```shell -curl http://localhost:11434/api/create -d '{ - "model": "fred", - "files": { - "config.json": "sha256:dd3443e529fb2290423a0c65c2d633e67b419d273f170259e27297219828e389", - "generation_config.json": "sha256:88effbb63300dbbc7390143fbbdd9d9fa50587b37e8bfd16c8c90d4970a74a36", - "special_tokens_map.json": "sha256:b7455f0e8f00539108837bfa586c4fbf424e31f8717819a6798be74bef813d05", - "tokenizer.json": "sha256:bbc1904d35169c542dffbe1f7589a5994ec7426d9e5b609d07bab876f32e97ab", - "tokenizer_config.json": "sha256:24e8a6dc2547164b7002e3125f10b415105644fcf02bf9ad8b674c87b1eaaed6", - "model.safetensors": "sha256:1ff795ff6a07e6a68085d206fb84417da2f083f68391c2843cd2b8ac6df8538f" - } -}' -``` - -##### Response - -A stream of JSON objects is returned: - -```shell -{"status":"converting model"} -{"status":"creating new layer sha256:05ca5b813af4a53d2c2922933936e398958855c44ee534858fcfd830940618b6"} -{"status":"using autodetected template llama3-instruct"} -{"status":"using existing layer sha256:56bb8bd477a519ffa694fc449c2413c6f0e1d3b1c88fa7e3c9d88d3ae49d4dcb"} -{"status":"writing manifest"} -{"status":"success"} -``` - -## Check if a Blob Exists - -```shell -HEAD /api/blobs/:digest -``` - -Ensures that the file blob (Binary Large Object) used with create a model exists on the server. This checks your Ollama server and not ollama.com. - -### Query Parameters - -- `digest`: the SHA256 digest of the blob - -### Examples - -#### Request - -```shell -curl -I http://localhost:11434/api/blobs/sha256:29fdb92e57cf0827ded04ae6461b5931d01fa595843f55d36f5b275a52087dd2 -``` - -#### Response - -Return 200 OK if the blob exists, 404 Not Found if it does not. - -## Push a Blob - -``` -POST /api/blobs/:digest -``` - -Push a file to the Ollama server to create a "blob" (Binary Large Object). - -### Query Parameters - -- `digest`: the expected SHA256 digest of the file - -### Examples - -#### Request - -```shell -curl -T model.gguf -X POST http://localhost:11434/api/blobs/sha256:29fdb92e57cf0827ded04ae6461b5931d01fa595843f55d36f5b275a52087dd2 -``` - -#### Response - -Return 201 Created if the blob was successfully created, 400 Bad Request if the digest used is not expected. - -## List Local Models - -``` -GET /api/tags -``` - -List models that are available locally. - -### Examples - -#### Request - -```shell -curl http://localhost:11434/api/tags -``` - -#### Response - -A single JSON object will be returned. - -```json -{ - "models": [ - { - "name": "codellama:13b", - "modified_at": "2023-11-04T14:56:49.277302595-07:00", - "size": 7365960935, - "digest": "9f438cb9cd581fc025612d27f7c1a6669ff83a8bb0ed86c94fcf4c5440555697", - "details": { - "format": "gguf", - "family": "llama", - "families": null, - "parameter_size": "13B", - "quantization_level": "Q4_0" - } - }, - { - "name": "llama3:latest", - "modified_at": "2023-12-07T09:32:18.757212583-08:00", - "size": 3825819519, - "digest": "fe938a131f40e6f6d40083c9f0f430a515233eb2edaa6d72eb85c50d64f2300e", - "details": { - "format": "gguf", - "family": "llama", - "families": null, - "parameter_size": "7B", - "quantization_level": "Q4_0" - } - } - ] -} -``` - -## Show Model Information - -``` -POST /api/show -``` - -Show information about a model including details, modelfile, template, parameters, license, system prompt. - -### Parameters - -- `model`: name of the model to show -- `verbose`: (optional) if set to `true`, returns full data for verbose response fields - -### Examples - -#### Request - -```shell -curl http://localhost:11434/api/show -d '{ - "model": "llama3.2" -}' -``` - -#### Response - -```json -{ - "modelfile": "# Modelfile generated by \"ollama show\"\n# To build a new Modelfile based on this one, replace the FROM line with:\n# FROM llava:latest\n\nFROM /Users/matt/.ollama/models/blobs/sha256:200765e1283640ffbd013184bf496e261032fa75b99498a9613be4e94d63ad52\nTEMPLATE \"\"\"{{ .System }}\nUSER: {{ .Prompt }}\nASSISTANT: \"\"\"\nPARAMETER num_ctx 4096\nPARAMETER stop \"\u003c/s\u003e\"\nPARAMETER stop \"USER:\"\nPARAMETER stop \"ASSISTANT:\"", - "parameters": "num_keep 24\nstop \"<|start_header_id|>\"\nstop \"<|end_header_id|>\"\nstop \"<|eot_id|>\"", - "template": "{{ if .System }}<|start_header_id|>system<|end_header_id|>\n\n{{ .System }}<|eot_id|>{{ end }}{{ if .Prompt }}<|start_header_id|>user<|end_header_id|>\n\n{{ .Prompt }}<|eot_id|>{{ end }}<|start_header_id|>assistant<|end_header_id|>\n\n{{ .Response }}<|eot_id|>", - "details": { - "parent_model": "", - "format": "gguf", - "family": "llama", - "families": [ - "llama" - ], - "parameter_size": "8.0B", - "quantization_level": "Q4_0" - }, - "model_info": { - "general.architecture": "llama", - "general.file_type": 2, - "general.parameter_count": 8030261248, - "general.quantization_version": 2, - "llama.attention.head_count": 32, - "llama.attention.head_count_kv": 8, - "llama.attention.layer_norm_rms_epsilon": 0.00001, - "llama.block_count": 32, - "llama.context_length": 8192, - "llama.embedding_length": 4096, - "llama.feed_forward_length": 14336, - "llama.rope.dimension_count": 128, - "llama.rope.freq_base": 500000, - "llama.vocab_size": 128256, - "tokenizer.ggml.bos_token_id": 128000, - "tokenizer.ggml.eos_token_id": 128009, - "tokenizer.ggml.merges": [], // populates if `verbose=true` - "tokenizer.ggml.model": "gpt2", - "tokenizer.ggml.pre": "llama-bpe", - "tokenizer.ggml.token_type": [], // populates if `verbose=true` - "tokenizer.ggml.tokens": [] // populates if `verbose=true` - } -} -``` - -## Copy a Model - -``` -POST /api/copy -``` - -Copy a model. Creates a model with another name from an existing model. - -### Examples - -#### Request - -```shell -curl http://localhost:11434/api/copy -d '{ - "source": "llama3.2", - "destination": "llama3-backup" -}' -``` - -#### Response - -Returns a 200 OK if successful, or a 404 Not Found if the source model doesn't exist. - -## Delete a Model - -``` -DELETE /api/delete -``` - -Delete a model and its data. - -### Parameters - -- `model`: model name to delete - -### Examples - -#### Request - -```shell -curl -X DELETE http://localhost:11434/api/delete -d '{ - "model": "llama3:13b" -}' -``` - -#### Response - -Returns a 200 OK if successful, 404 Not Found if the model to be deleted doesn't exist. - -## Pull a Model - -``` -POST /api/pull -``` - -Download a model from the ollama library. Cancelled pulls are resumed from where they left off, and multiple calls will share the same download progress. - -### Parameters - -- `model`: name of the model to pull -- `insecure`: (optional) allow insecure connections to the library. Only use this if you are pulling from your own library during development. -- `stream`: (optional) if `false` the response will be returned as a single response object, rather than a stream of objects - -### Examples - -#### Request - -```shell -curl http://localhost:11434/api/pull -d '{ - "model": "llama3.2" -}' -``` - -#### Response - -If `stream` is not specified, or set to `true`, a stream of JSON objects is returned: - -The first object is the manifest: - -```json -{ - "status": "pulling manifest" -} -``` - -Then there is a series of downloading responses. Until any of the download is completed, the `completed` key may not be included. The number of files to be downloaded depends on the number of layers specified in the manifest. - -```json -{ - "status": "downloading digestname", - "digest": "digestname", - "total": 2142590208, - "completed": 241970 -} -``` - -After all the files are downloaded, the final responses are: - -```json -{ - "status": "verifying sha256 digest" -} -{ - "status": "writing manifest" -} -{ - "status": "removing any unused layers" -} -{ - "status": "success" -} -``` - -if `stream` is set to false, then the response is a single JSON object: - -```json -{ - "status": "success" -} -``` - -## Push a Model - -``` -POST /api/push -``` - -Upload a model to a model library. Requires registering for ollama.ai and adding a public key first. - -### Parameters - -- `model`: name of the model to push in the form of `/:` -- `insecure`: (optional) allow insecure connections to the library. Only use this if you are pushing to your library during development. -- `stream`: (optional) if `false` the response will be returned as a single response object, rather than a stream of objects - -### Examples - -#### Request - -```shell -curl http://localhost:11434/api/push -d '{ - "model": "mattw/pygmalion:latest" -}' -``` - -#### Response - -If `stream` is not specified, or set to `true`, a stream of JSON objects is returned: - -```json -{ "status": "retrieving manifest" } -``` - -and then: - -```json -{ - "status": "starting upload", - "digest": "sha256:bc07c81de745696fdf5afca05e065818a8149fb0c77266fb584d9b2cba3711ab", - "total": 1928429856 -} -``` - -Then there is a series of uploading responses: - -```json -{ - "status": "starting upload", - "digest": "sha256:bc07c81de745696fdf5afca05e065818a8149fb0c77266fb584d9b2cba3711ab", - "total": 1928429856 -} -``` - -Finally, when the upload is complete: - -```json -{"status":"pushing manifest"} -{"status":"success"} -``` - -If `stream` is set to `false`, then the response is a single JSON object: - -```json -{ "status": "success" } -``` - -## Generate Embeddings - -``` -POST /api/embed -``` - -Generate embeddings from a model - -### Parameters - -- `model`: name of model to generate embeddings from -- `input`: text or list of text to generate embeddings for - -Advanced parameters: - -- `truncate`: truncates the end of each input to fit within context length. Returns error if `false` and context length is exceeded. Defaults to `true` -- `options`: additional model parameters listed in the documentation for the [Modelfile](./modelfile.md#valid-parameters-and-values) such as `temperature` -- `keep_alive`: controls how long the model will stay loaded into memory following the request (default: `5m`) - -### Examples - -#### Request - -```shell -curl http://localhost:11434/api/embed -d '{ - "model": "all-minilm", - "input": "Why is the sky blue?" -}' -``` - -#### Response - -```json -{ - "model": "all-minilm", - "embeddings": [[ - 0.010071029, -0.0017594862, 0.05007221, 0.04692972, 0.054916814, - 0.008599704, 0.105441414, -0.025878139, 0.12958129, 0.031952348 - ]], - "total_duration": 14143917, - "load_duration": 1019500, - "prompt_eval_count": 8 -} -``` - -#### Request (Multiple input) - -```shell -curl http://localhost:11434/api/embed -d '{ - "model": "all-minilm", - "input": ["Why is the sky blue?", "Why is the grass green?"] -}' -``` - -#### Response - -```json -{ - "model": "all-minilm", - "embeddings": [[ - 0.010071029, -0.0017594862, 0.05007221, 0.04692972, 0.054916814, - 0.008599704, 0.105441414, -0.025878139, 0.12958129, 0.031952348 - ],[ - -0.0098027075, 0.06042469, 0.025257962, -0.006364387, 0.07272725, - 0.017194884, 0.09032035, -0.051705178, 0.09951512, 0.09072481 - ]] -} -``` - -## List Running Models -``` -GET /api/ps -``` - -List models that are currently loaded into memory. - -#### Examples - -### Request - -```shell -curl http://localhost:11434/api/ps -``` - -#### Response - -A single JSON object will be returned. - -```json -{ - "models": [ - { - "name": "mistral:latest", - "model": "mistral:latest", - "size": 5137025024, - "digest": "2ae6f6dd7a3dd734790bbbf58b8909a606e0e7e97e94b7604e0aa7ae4490e6d8", - "details": { - "parent_model": "", - "format": "gguf", - "family": "llama", - "families": [ - "llama" - ], - "parameter_size": "7.2B", - "quantization_level": "Q4_0" - }, - "expires_at": "2024-06-04T14:38:31.83753-07:00", - "size_vram": 5137025024 - } - ] -} -``` - -## Generate Embedding - -> Note: this endpoint has been superseded by `/api/embed` - -``` -POST /api/embeddings -``` - -Generate embeddings from a model - -### Parameters - -- `model`: name of model to generate embeddings from -- `prompt`: text to generate embeddings for - -Advanced parameters: - -- `options`: additional model parameters listed in the documentation for the [Modelfile](./modelfile.md#valid-parameters-and-values) such as `temperature` -- `keep_alive`: controls how long the model will stay loaded into memory following the request (default: `5m`) - -### Examples - -#### Request - -```shell -curl http://localhost:11434/api/embeddings -d '{ - "model": "all-minilm", - "prompt": "Here is an article about llamas..." -}' -``` - -#### Response - -```json -{ - "embedding": [ - 0.5670403838157654, 0.009260174818336964, 0.23178744316101074, -0.2916173040866852, -0.8924556970596313, - 0.8785552978515625, -0.34576427936553955, 0.5742510557174683, -0.04222835972905159, -0.137906014919281 - ] -} -``` - -## Version - -``` -GET /api/version -``` - -Retrieve the Ollama version - -### Examples - -#### Request - -```shell -curl http://localhost:11434/api/version -``` - -#### Response - -```json -{ - "version": "0.5.1" -} -``` - diff --git a/ai_integration_ollama_api/migrations/1.0.0/post-migration.py b/ai_integration_ollama_api/migrations/1.0.0/post-migration.py deleted file mode 100644 index 0998710..0000000 --- a/ai_integration_ollama_api/migrations/1.0.0/post-migration.py +++ /dev/null @@ -1,17 +0,0 @@ -def migrate(cr, version): - # Add num_predict column if it doesn't exist - cr.execute(""" - DO $$ - BEGIN - IF NOT EXISTS ( - SELECT 1 - FROM information_schema.columns - WHERE table_name='ai_provider_instance' - AND column_name='num_predict' - ) THEN - ALTER TABLE ai_provider_instance - ADD COLUMN num_predict integer DEFAULT 1024; - END IF; - END - $$; - """) diff --git a/ai_integration_ollama_api/models/__init__.py b/ai_integration_ollama_api/models/__init__.py deleted file mode 100644 index abd67f0..0000000 --- a/ai_integration_ollama_api/models/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Ollama AI Integration Models Package. - -This package contains all the model definitions required for integrating -Ollama AI with Odoo's AI framework. The models are loaded in a specific -order to handle dependencies correctly. - -Module Structure: -1. ollama_provider_mixin - Base configuration and parameter definitions -2. ollama_provider - Core Ollama API integration implementation -3. ollama_model_stats - Usage statistics and performance tracking -4. ai_provider_instance - Instance-specific configuration and management - -Note: The import order is important to avoid circular dependencies. -""" - -# Base Configuration -from . import ollama_provider_mixin - -# Core Implementation -from . import ollama_provider -from . import ai_provider_instance - -# Statistics and Monitoring -from . import ollama_model_stats - -# Instance Management -from . import ai_provider_instance diff --git a/ai_integration_ollama_api/models/ai_provider_instance.py b/ai_integration_ollama_api/models/ai_provider_instance.py deleted file mode 100644 index 466ceb3..0000000 --- a/ai_integration_ollama_api/models/ai_provider_instance.py +++ /dev/null @@ -1,153 +0,0 @@ -from odoo import models, fields, api, _ -from odoo.exceptions import UserError -import requests - -class OllamaAIProviderInstance(models.Model): - """Extends the AI Provider Instance model to support Ollama-specific configuration. - - This model inherits from both ai.provider.instance and ollama.provider.mixin to: - 1. Add Ollama-specific fields (num_ctx, temperature, etc.) - 2. Handle field visibility based on provider_type - 3. Manage field cleanup when switching providers - """ - _inherit = ['ai.provider.instance', 'ollama.provider.mixin'] - _name = 'ai.provider.instance' - _description = 'Ollama AI Provider Instance' - - # Override provider_type to add Ollama option - provider_type = fields.Selection( - selection_add=[('ollama', 'Ollama')], - ondelete={'ollama': lambda r: r.write({'provider_type': 'none'})} - ) - - @api.onchange('provider_type') - def _onchange_provider_type(self): - """Handle provider type changes. - - When switching to 'ollama': - - Set default host if empty - - When switching away from 'ollama': - - Clear Ollama-specific fields - """ - if self.provider_type == 'ollama': - if not self.host: - self.host = 'http://localhost:11434' - else: - # Clear Ollama-specific fields - self.update({ - 'num_ctx': False, # Context length - 'temperature': False, # Sampling temperature - 'top_p': False, # Nucleus sampling threshold - 'top_k': False, # Top-k sampling threshold - 'repeat_penalty': False, # Penalty for repeated tokens - 'repeat_last_n': False, # Number of tokens to consider for repeat penalty - 'num_thread': False, # Number of CPU threads to use - 'num_gpu': False, # Number of GPUs to use - 'num_batch': False, # Batch size for inference - 'model_name': False, # Model name/path - }) - - # Override default host for Ollama - host = fields.Char( - default='http://localhost:11434', - help='Ollama server host URL') - - def test_connection(self): - """Test the connection to the Ollama server. - - This method attempts to connect to the Ollama server and verify - that it is responding correctly. It will raise a user-friendly - error if the connection fails. - - Returns: - dict: Action to display success message - """ - self.ensure_one() - if self.provider_type != 'ollama': - return - - try: - # Try to list models as a basic connectivity test - response = requests.get(f'{self.host}/api/tags') - response.raise_for_status() - return { - 'type': 'ir.actions.client', - 'tag': 'display_notification', - 'params': { - 'title': _('Success'), - 'message': _('Successfully connected to Ollama server'), - 'sticky': False, - 'type': 'success', - } - } - except Exception as e: - raise UserError(_('Connection test failed: %s', str(e))) - - def sync_models(self): - """Synchronize available models from the Ollama server. - - This method fetches the list of available models from the Ollama - server and creates or updates the corresponding AI model records - in Odoo. - - Returns: - dict: Action to display success message - """ - self.ensure_one() - if self.provider_type != 'ollama': - return - - try: - # Get models from Ollama API - response = requests.get(f'{self.host}/api/tags') - response.raise_for_status() - - # Parse response - models = [{ - 'name': model['name'], - 'id': model['name'], - } for model in response.json()['models']] - - for model_data in models: - # Create or update AI model record - vals = { - 'name': model_data['name'], - 'identifier': model_data['id'], - 'provider_instance_id': self.id, - 'active': True, - } - # Search for existing model - existing = self.env['ai.model'].search([ - ('identifier', '=', model_data['id']), - ('provider_instance_id', '=', self.id) - ], limit=1) - - if existing: - existing.write(vals) - else: - self.env['ai.model'].create(vals) - - # Invalidate the cache to force reload of related records - self.invalidate_recordset(['model_ids']) - - # Return action to reload the view completely - return { - 'type': 'ir.actions.act_window', - 'res_model': 'ai.provider.instance', - 'res_id': self.id, - 'view_mode': 'form', - 'target': 'current', - 'flags': { - 'mode': 'readonly', - 'reload': True, # Force reload - }, - 'context': {'notification': { - 'type': 'success', - 'title': _('Success'), - 'message': _('Successfully synchronized %d models', len(models)), - 'sticky': False, - }} - } - except Exception as e: - raise UserError(_('Model synchronization failed: %s', str(e))) diff --git a/ai_integration_ollama_api/models/ai_provider_ollama.py.bak b/ai_integration_ollama_api/models/ai_provider_ollama.py.bak deleted file mode 100644 index 6d6a39f..0000000 --- a/ai_integration_ollama_api/models/ai_provider_ollama.py.bak +++ /dev/null @@ -1,35 +0,0 @@ -from odoo import models, fields, api, _ -from .ollama_provider_mixin import OllamaProviderMixin - -class OllamaAIProvider(models.Model, OllamaProviderMixin): - _name = 'ai.provider.ollama' - _description = 'Ollama AI Provider' - _inherit = ['ai.provider.interface'] - - provider_type = fields.Selection( - selection=[('ollama', 'Ollama')], - default='ollama', - required=True, - help='Type of AI provider') - - # Ollama-specific Parameters - host = fields.Char( - string='Host', - default='http://localhost:11434', - required=True, - help='Ollama server host URL') - - def _get_available_models(self): - """Get list of available models from Ollama server.""" - # TODO: Implement model discovery - return [] - - def _generate_text(self, prompt, **kwargs): - """Generate text using Ollama model.""" - # TODO: Implement text generation - return "" - - def _embed_text(self, text, **kwargs): - """Generate embeddings for text using Ollama model.""" - # TODO: Implement text embedding - return [] diff --git a/ai_integration_ollama_api/models/ollama_model_stats.py b/ai_integration_ollama_api/models/ollama_model_stats.py deleted file mode 100644 index 996da76..0000000 --- a/ai_integration_ollama_api/models/ollama_model_stats.py +++ /dev/null @@ -1,116 +0,0 @@ -from odoo import models, fields, api -from datetime import datetime, timedelta - -class OllamaModelStats(models.Model): - """Tracks and stores daily usage statistics for Ollama AI models. - - This model maintains detailed daily statistics for each Ollama model, - including request counts, token usage, response times, and error rates. - It inherits from ai.model.stats for base statistics functionality. - - Key Features: - - Daily usage tracking per model - - Performance metrics collection - - Error rate monitoring - - Version tracking for model updates - - Technical Details: - - One stat entry per model per day (enforced by SQL constraint) - - Automatic version tracking from Ollama API - - Aggregated statistics calculation - - Ordered by date for easy historical analysis - """ - _name = 'ollama.model.stats' - _description = 'Ollama Model Usage Statistics' - _inherit = ['ai.model.stats'] - _order = 'date desc' # Most recent stats first - - model_id = fields.Many2one('ai.model', string='Model', required=True, ondelete='cascade') - date = fields.Date(string='Date', required=True, default=fields.Date.context_today) - request_count = fields.Integer(string='Number of Requests', default=0) - token_count = fields.Integer(string='Total Tokens', default=0) - avg_response_time = fields.Float(string='Average Response Time (ms)', digits=(10, 2), default=0) - error_count = fields.Integer(string='Number of Errors', default=0) - version = fields.Char(string='Model Version', help='Version of the model when stats were recorded') - - _sql_constraints = [ - ('unique_model_date', 'unique(model_id, date)', 'Only one stat entry per model per day is allowed.') - ] - - def _update_stats(self, model, tokens, response_time, error=False): - """Update daily statistics for a specific model. - - This method handles the creation or update of daily statistics entries. - It maintains running averages and cumulative counts for various metrics. - - Args: - model (ai.model): The model record being tracked - tokens (int): Number of tokens in the current request - response_time (float): Response time in milliseconds - error (bool): Whether this request resulted in an error - - Technical Notes: - - Creates new stat entry if none exists for today - - Updates running averages for response time - - Fetches and stores model version from Ollama API - - Maintains cumulative counts for requests and errors - """ - today = fields.Date.context_today(self) - stats = self.search([ - ('model_id', '=', model.id), - ('date', '=', today) - ]) - - if not stats: - # Get model version - version = self.env['ai.provider.ollama']._get_model_info( - model.provider_instance_id, - model.identifier - ).get('details', {}).get('sha256', '')[:8] # First 8 chars of SHA - - stats = self.create({ - 'model_id': model.id, - 'date': today, - 'version': version - }) - - # Update statistics - new_count = stats.request_count + 1 - new_tokens = stats.token_count + tokens - new_time = ((stats.avg_response_time * stats.request_count) + response_time) / new_count - new_errors = stats.error_count + (1 if error else 0) - - stats.write({ - 'request_count': new_count, - 'token_count': new_tokens, - 'avg_response_time': new_time, - 'error_count': new_errors - }) - - @api.model - def get_model_stats(self, model_id, days=30): - """Get statistics for a model over the specified number of days.""" - start_date = fields.Date.today() - timedelta(days=days) - stats = self.search([ - ('model_id', '=', model_id), - ('date', '>=', start_date) - ]) - - return { - 'daily_stats': [{ - 'date': stat.date, - 'requests': stat.request_count, - 'tokens': stat.token_count, - 'response_time': stat.avg_response_time, - 'errors': stat.error_count, - 'version': stat.version - } for stat in stats], - 'summary': { - 'total_requests': sum(stat.request_count for stat in stats), - 'total_tokens': sum(stat.token_count for stat in stats), - 'avg_response_time': sum(stat.avg_response_time * stat.request_count for stat in stats) / - (sum(stat.request_count for stat in stats) if stats else 1), - 'total_errors': sum(stat.error_count for stat in stats), - 'versions_used': list(set(stat.version for stat in stats if stat.version)) - } - } diff --git a/ai_integration_ollama_api/models/ollama_provider.py b/ai_integration_ollama_api/models/ollama_provider.py deleted file mode 100644 index 6abf869..0000000 --- a/ai_integration_ollama_api/models/ollama_provider.py +++ /dev/null @@ -1,324 +0,0 @@ -import json -import logging -import requests -from odoo import models, fields, api, _ -from odoo.exceptions import UserError - -_logger = logging.getLogger(__name__) - -class OllamaProvider(models.Model): - """Main Ollama AI Provider implementation. - - This model implements the core functionality for interacting with Ollama's API, - including model management, text generation, and error handling. - - Key Responsibilities: - - Model discovery and validation - - API communication and error handling - - Request formatting and response parsing - - Resource management and cleanup - - Technical Details: - - Implements the ai.provider.interface for standardized AI provider integration - - Uses Ollama's HTTP API for all operations - - Handles both synchronous and asynchronous requests - - Provides detailed error messages for troubleshooting - """ - _name = 'ai.provider.ollama' - _description = 'Ollama AI Provider' - _inherit = ['ai.provider.interface'] - - @api.model - def _get_models(self, instance): - """Get list of available models from Ollama server. - - Args: - instance (ai.provider.instance): Provider instance to get models for - - Returns: - list: List of model dictionaries with keys: - - name: Model name - - id: Model identifier - - details: Additional model metadata - - Raises: - UserError: If unable to connect or retrieve models - """ - try: - response = requests.get(f"{instance.host}/api/tags") - response.raise_for_status() - - models_data = response.json().get('models', []) - return [{ - 'name': model['name'], - 'id': model['name'], - 'details': model - } for model in models_data] - - except requests.exceptions.RequestException as e: - raise UserError(_('Failed to connect to Ollama server: %s', str(e))) - except (KeyError, ValueError) as e: - raise UserError(_('Invalid response from Ollama server: %s', str(e))) - - # API Configuration - timeout = fields.Integer( - string='Timeout', - default=30, - help='API request timeout in seconds') - - def _get_provider_type(self): - return 'ollama' - - def _get_model_info(self, instance, model_name): - """Get detailed information about a specific model.""" - try: - response = requests.post( - f"{instance.host}/api/show", - json={'name': model_name} - ) - if response.status_code == 200: - return response.json() - else: - _logger.error( - "Failed to get model info for %s. Status: %s, Error: %s", - model_name, response.status_code, response.text - ) - return None - except requests.exceptions.RequestException as e: - _logger.error("Error getting model info: %s", str(e)) - return None - - def pull_model(self, instance, model_name): - """Pull a model from Ollama.""" - try: - # Start the pull - response = requests.post( - f"{instance.host}/api/pull", - json={'name': model_name}, - stream=True # Enable streaming for progress updates - ) - - if response.status_code != 200: - raise UserError(_("Failed to pull model %s: %s") % - (model_name, response.text)) - - # Process the streaming response - for line in response.iter_lines(): - if line: - try: - progress = json.loads(line) - status = progress.get('status') - if status: - _logger.info( - "Pulling model %s: %s", - model_name, status - ) - except json.JSONDecodeError: - continue - - return True - - except requests.exceptions.RequestException as e: - raise UserError(_("Error pulling model %s: %s") % - (model_name, str(e))) - - def delete_model(self, instance, model_name): - """Delete a model from Ollama.""" - try: - response = requests.delete( - f"{instance.host}/api/delete", - json={'name': model_name} - ) - - if response.status_code != 200: - raise UserError(_("Failed to delete model %s: %s") % - (model_name, response.text)) - - return True - - except requests.exceptions.RequestException as e: - raise UserError(_("Error deleting model %s: %s") % - (model_name, str(e))) - - def test_connection(self, instance): - """Test the connection to the Ollama server.""" - try: - response = requests.get(f"{instance.host}/api/tags") - if response.status_code != 200: - raise UserError(_( - "Failed to connect to Ollama server. Status code: %s. Error: %s", - response.status_code, response.text - )) - return True - except requests.exceptions.RequestException as e: - raise UserError(_( - "Failed to connect to Ollama server: %s", str(e) - )) - - def _format_chat_messages(self, messages): - """Format chat messages for Ollama API.""" - formatted_prompt = "" - for message in messages: - role = message.get('role', 'user') - content = message.get('content', '') - - if role == 'system': - formatted_prompt += f"{content}\n" - elif role == 'assistant': - formatted_prompt += f"Assistant: {content}\n" - else: # user - formatted_prompt += f"Human: {content}\n" - - return formatted_prompt.strip() - - def generate_response(self, instance, model, messages, **kwargs): - """Generate a response using the chat completion API.""" - try: - # Format messages into Ollama's expected format - prompt = self._format_chat_messages(messages) - - # Get model options from instance - options = instance._get_provider_options() - - # Prepare the request payload - payload = { - 'model': model.identifier, - 'prompt': prompt, - 'stream': False, - **options - } - - # Make the API call - response = requests.post( - f"{instance.host}/api/generate", - json=payload - ) - - if response.status_code != 200: - raise UserError(_("Failed to generate response: %s") % response.text) - - response_data = response.json() - generated_text = response_data.get('response', '') - - # Update statistics - total_tokens = response_data.get('eval_count', 0) - response_time = response_data.get('total_duration', 0) - version = self._get_model_info(instance, model.identifier)\ - .get('details', {}).get('sha256', '')[:8] - self._track_model_usage( - model, total_tokens, response_time, version=version - ) - - # Return the response in a standardized format - return { - 'content': generated_text, - 'role': 'assistant', - 'metadata': { - 'eval_count': response_data.get('eval_count'), - 'eval_duration': response_data.get('eval_duration'), - 'total_duration': response_data.get('total_duration'), - 'load_duration': response_data.get('load_duration'), - } - } - - except requests.exceptions.RequestException as e: - # Log error in statistics - if model: - self._track_model_usage(model, error=True) - raise UserError(_("Error generating response: %s") % str(e)) - - def sync_models(self, instance): - """Synchronize available models from the Ollama server.""" - self.test_connection(instance) - - try: - response = requests.get(f"{instance.host}/api/tags") - models_data = response.json().get('models', []) - - # Get existing models for this instance - existing_models = self.env['ai.model'].search([ - ('provider_instance_id', '=', instance.id) - ]) - existing_identifiers = {m.identifier: m for m in existing_models} - - for model_data in models_data: - identifier = model_data.get('name') - if not identifier: - continue - - # Get model details - model_info = self._get_model_info(instance, identifier) - model_details = model_info.get('details', {}) - - model_values = { - 'name': identifier.title(), - 'identifier': identifier, - 'provider_instance_id': instance.id, - 'company_id': instance.company_id.id, - 'active': True, - 'description': f"Ollama model: {identifier}\\nSize: {model_data.get('size', 'Unknown')}\\nModified: {model_data.get('modified', 'Unknown')}", - } - - if identifier in existing_identifiers: - # Update existing model - existing_identifiers[identifier].write(model_values) - del existing_identifiers[identifier] - else: - # Create new model - self.env['ai.model'].create(model_values) - - # Deactivate models that no longer exist - for model in existing_identifiers.values(): - model.active = False - - return True - - except requests.exceptions.RequestException as e: - raise UserError(_( - "Failed to sync models from Ollama server: %s", str(e) - )) - - def send_message(self, message, model, **kwargs): - """Send a message to the Ollama server.""" - instance = model.provider_instance_id - - try: - # Prepare the request payload - payload = { - 'model': model.identifier, - 'prompt': message.get('content', ''), - 'stream': False, - 'options': kwargs.get('options', {}), - } - - # Add system message if provided - if message.get('role') == 'system': - payload['system'] = message['content'] - - # Send the request - response = requests.post( - f"{instance.host}/api/generate", - json=payload, - timeout=(instance.timeout or 30) - ) - - if response.status_code != 200: - raise UserError(_( - "Ollama server error. Status code: %s. Error: %s", - response.status_code, response.text - )) - - result = response.json() - return result.get('response', '') - - except requests.exceptions.Timeout: - raise UserError(_("Request to Ollama server timed out")) - except requests.exceptions.RequestException as e: - raise UserError(_( - "Error communicating with Ollama server: %s", str(e) - )) - except Exception as e: - _logger.error("Unexpected error in Ollama provider: %s", str(e)) - raise UserError(_( - "Unexpected error in Ollama provider: %s", str(e) - )) diff --git a/ai_integration_ollama_api/models/ollama_provider_mixin.py b/ai_integration_ollama_api/models/ollama_provider_mixin.py deleted file mode 100644 index c50a4fe..0000000 --- a/ai_integration_ollama_api/models/ollama_provider_mixin.py +++ /dev/null @@ -1,274 +0,0 @@ -from odoo import models, fields, api, _ -from odoo.exceptions import UserError -import requests -import logging -import json - -_logger = logging.getLogger(__name__) - -class OllamaProviderMixin(models.AbstractModel): - """Mixin model that provides Ollama-specific configuration parameters. - - This mixin is designed to be inherited by models that need to interact with - the Ollama AI provider. It provides all the necessary fields and methods - for configuring and interacting with Ollama's API. - - Key Features: - - Provider type selection and validation - - Context window configuration - - Advanced sampling parameters (temperature, top-k, top-p) - - Token generation controls - - Technical Details: - - Inherits from ai.generation.params for base AI generation parameters - - Implements Ollama-specific API parameters - - Provides default values optimized for general use cases - """ - _name = 'ollama.provider.mixin' - _description = 'Ollama Provider Configuration Mixin' - _inherit = ['ai.generation.params'] - - # Model Parameters - model_name = fields.Char( - string='Model Name', - help='Name of the Ollama model to use (e.g. llama2, mistral, codellama)', - required=True, - default='deepseek-r1:32b') - - # Context Window Configuration - num_ctx = fields.Integer( - string='Context Length', - help='Maximum number of tokens to consider for context. A larger context window allows ' - 'the model to access more historical information but requires more memory. ' - 'Range: [0 - 32768].', - default=8192) - - # Generation Parameters - temperature = fields.Float( - string='Temperature', - help='Controls randomness in the output. Higher values make the output more random, ' - 'while lower values make it more focused and deterministic. ' - 'Range: [0.0 - 2.0]', - default=0.7) - - top_p = fields.Float( - string='Top P (Nucleus Sampling)', - help='Limits the cumulative probability of tokens to sample from. Only the most likely ' - 'tokens with total probability mass of top_p are considered. ' - 'Range: [0.0 - 1.0].', - default=0.9) - - top_k = fields.Integer( - string='Top K', - help='Limits the cumulative probability of tokens to sample from. Only the top K ' - 'most likely tokens are considered for sampling at each step. ' - 'Range: [1 - 100].', - default=40) - - min_p = fields.Float( - string='Min P', - help='Sets a minimum probability threshold for token selection. Range: [0.0 - 1.0].', - default=0.05, - digits=(3, 2)) - - repeat_penalty = fields.Float( - string='Repeat Penalty', - help='Penalty for repeating tokens. Range: [1.0 - 2.0]. Higher values make repetition less likely.', - default=1.1, - digits=(3, 2)) - - # Advanced Configuration - stop_sequences = fields.Char( - string='Stop Sequences', - help='Comma-separated list of sequences where the model should stop generating further tokens.') - - num_predict = fields.Integer( - string='Maximum Tokens', - help='Maximum number of tokens to predict. Set to -1 for unlimited.', - default=2048) - - repeat_last_n = fields.Integer( - string='Repeat Last N', - help='Sets the context window for repeat penalty. Range: [0 - 4096]. Default is 64, 0 disables.', - default=64 - ) - - def generate_text(self, prompt, **kwargs): - """Generate text using the Ollama API. - - Args: - prompt (str): The prompt to generate text from - **kwargs: Additional parameters to pass to the API - - Returns: - str: The generated text - """ - self.ensure_one() - - # Prepare the request - url = f"{self.host}/api/generate" - - # Build the request data - data = { - 'model': self.model_name, - 'prompt': prompt, - 'stream': False, - 'num_ctx': self.num_ctx, - 'temperature': self.temperature, - 'top_k': self.top_k, - 'top_p': self.top_p, - 'repeat_penalty': self.repeat_penalty, - 'repeat_last_n': self.repeat_last_n, - 'num_predict': self.num_predict, - 'min_p': self.min_p, - 'seed': self.seed, - 'num_gpu': self.num_gpu, - 'num_thread': self.num_thread, - 'mirostat': int(self.mirostat), - 'mirostat_tau': self.mirostat_tau, - 'mirostat_eta': self.mirostat_eta, - 'num_batch': self.num_batch, - 'num_keep': self.num_keep, - 'tfs_z': self.tfs_z, - 'skip_special_tokens': self.skip_special_tokens - } - - # Add any additional parameters - if kwargs: - data.update(kwargs) - - # Make the request - try: - _logger = logging.getLogger(__name__) - _logger.info("Sending request to Ollama API with data: %s", data) - - response = requests.post(url, json=data, timeout=self.timeout) - response.raise_for_status() - - # Log the raw response - _logger.info("Raw API response: %s", response.text) - - # Parse the response - result = response.json() - response_text = result.get('response', '') - - # Si la réponse est une chaîne JSON, la parser - try: - if isinstance(response_text, str): - parsed_response = json.loads(response_text) - _logger.info("Parsed nested JSON response: %s", parsed_response) - return parsed_response - else: - _logger.info("Direct response: %s", response_text) - return response_text - except json.JSONDecodeError: - # Si ce n'est pas du JSON valide, retourner le texte tel quel - _logger.info("Non-JSON response: %s", response_text) - return response_text - - except requests.exceptions.RequestException as e: - raise UserError(_('Failed to generate text: %s') % str(e)) - - # Advanced Generation Parameters - seed = fields.Integer( - string='Random Seed', - help='Sets the random seed for generation. Range: [0 - 2147483647]. Use 0 for random.', - default=0) - - num_gpu = fields.Integer( - string='Number of GPUs', - help='Number of GPUs to use for generation. Range: [0 - 8]. 0 means CPU only.', - default=1) - - num_thread = fields.Integer( - string='Number of Threads', - help='Number of CPU threads to use for generation. Range: [1 - 32].', - default=8) - - mirostat = fields.Selection([ - ('0', 'Disabled'), - ('1', 'Mirostat'), - ('2', 'Mirostat 2.0')], - string='Mirostat Mode', - help='Enable Mirostat sampling for controlling perplexity', - default='0') - - mirostat_tau = fields.Float( - string='Mirostat Tau', - help='Mirostat target entropy. Range: [0.0 - 10.0].', - default=5.0, - digits=(3, 2)) - - mirostat_eta = fields.Float( - string='Mirostat Eta', - help='Mirostat learning rate. Range: [0.0 - 1.0].', - default=0.1, - digits=(3, 2)) - - # Ollama-specific Response Control - - tfs_z = fields.Float( - string='Tail Free Sampling Z', - help='Tail free sampling parameter. Range: [0.0 - 2.0]. Higher value = more focused.', - default=1.0, - digits=(3, 2)) - - # System Settings - num_batch = fields.Integer( - string='Batch Size', - help='Number of prompts to batch together', - default=8) - - num_keep = fields.Integer( - string='Keep Last N Tokens', - help='Number of tokens to keep from initial prompt', - default=0) - - skip_special_tokens = fields.Boolean( - string='Skip Special Tokens', - help='Skip special tokens in generation', - default=True) - - @api.model - def default_get(self, fields_list): - defaults = super().default_get(fields_list) - if 'provider_type' in fields_list: - defaults['provider_type'] = 'ollama' - if 'host' in fields_list and not defaults.get('host'): - defaults['host'] = 'http://localhost:11434' - return defaults - - def _get_provider_options(self): - """Get Ollama-specific options for API calls.""" - self.ensure_one() - options = { - 'model': self.model_name, - 'temperature': self.temperature, - 'num_ctx': self.num_ctx, - 'num_predict': self.num_predict, - 'top_k': self.top_k, - 'top_p': self.top_p, - 'min_p': self.min_p, - 'repeat_penalty': self.repeat_penalty, - 'repeat_last_n': self.repeat_last_n, - 'seed': self.seed, - 'num_gpu': self.num_gpu, - 'num_thread': self.num_thread, - 'mirostat': int(self.mirostat), - 'mirostat_tau': self.mirostat_tau, - 'mirostat_eta': self.mirostat_eta, - 'num_batch': self.num_batch, - 'num_keep': self.num_keep, - 'tfs_z': self.tfs_z, - 'skip_special_tokens': self.skip_special_tokens, - 'stream': False - } - - if self.stop_sequences: - options['stop'] = [ - seq.strip() - for seq in self.stop_sequences.split(',') - if seq.strip() - ] - - return options diff --git a/ai_integration_ollama_api/security/ir.model.access.csv b/ai_integration_ollama_api/security/ir.model.access.csv deleted file mode 100644 index 1cebd2d..0000000 --- a/ai_integration_ollama_api/security/ir.model.access.csv +++ /dev/null @@ -1,5 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_ollama_model_stats_user,ollama.model.stats.user,model_ollama_model_stats,base.group_user,1,0,0,0 -access_ollama_model_stats_manager,ollama.model.stats.manager,model_ollama_model_stats,base.group_system,1,1,1,1 -access_ai_provider_ollama_user,ai.provider.ollama.user,model_ai_provider_ollama,base.group_user,1,0,0,0 -access_ai_provider_ollama_manager,ai.provider.ollama.manager,model_ai_provider_ollama,base.group_system,1,1,1,1 diff --git a/ai_integration_ollama_api/views/ai_provider_instance_views.xml b/ai_integration_ollama_api/views/ai_provider_instance_views.xml deleted file mode 100644 index 9375f4e..0000000 --- a/ai_integration_ollama_api/views/ai_provider_instance_views.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - ai.provider.instance.list.ollama - ai.provider.instance - - primary - - - true - - - - diff --git a/ai_integration_ollama_api/views/ollama_stats_views.xml b/ai_integration_ollama_api/views/ollama_stats_views.xml deleted file mode 100644 index cecf64c..0000000 --- a/ai_integration_ollama_api/views/ollama_stats_views.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - - - ollama.model.stats.list - ollama.model.stats - - - - - - - - - - - - - - - - ollama.model.stats.form - ollama.model.stats - -
- - - - - - - - - - - - - - - -
-
-
- - - - ollama.model.stats.search - ollama.model.stats - - - - - - - - - - - - - - - - - - - - ollama.model.stats.graph - ollama.model.stats - - - - - - - - - - - - - ollama.model.stats.pivot - ollama.model.stats - - - - - - - - - - - - - - - Model Statistics - ollama.model.stats - list,form,graph,pivot - {'search_default_last_month': 1} - -

- No statistics recorded yet -

-

- Statistics will be automatically recorded as you use your AI models. -

-
-
- - - -
diff --git a/ai_integration_ollama_api/views/ollama_views.xml b/ai_integration_ollama_api/views/ollama_views.xml deleted file mode 100644 index c459b12..0000000 --- a/ai_integration_ollama_api/views/ollama_views.xml +++ /dev/null @@ -1,108 +0,0 @@ - - - - - ollama.instance.form - ai.provider.instance - form - primary - - - -
- -
-
- - - - - - - - - - - - - - - - - - - - -
-
- - - - ollama.instance.list - ai.provider.instance - list - - - - - - - - - - - - - - - ollama.instance.search - ai.provider.instance - primary - - - - - - - - - - - Ollama Instances - ai.provider.instance - list,form - [('provider_type', '=', 'ollama')] - {'default_provider_type': 'ollama'} - -

- Create your first Ollama instance -

-

- Configure Ollama instances to use local AI models in your Odoo instance. - Make sure you have Ollama installed and running on your server. -

-
-
- - - -
diff --git a/ai_integration_openai_api/__init__.py b/ai_integration_openai_api/__init__.py deleted file mode 100644 index 0650744..0000000 --- a/ai_integration_openai_api/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import models diff --git a/ai_integration_openai_api/__manifest__.py b/ai_integration_openai_api/__manifest__.py deleted file mode 100644 index f397818..0000000 --- a/ai_integration_openai_api/__manifest__.py +++ /dev/null @@ -1,35 +0,0 @@ -{ - 'name': 'ChatGPT-Compatible AI Integration', - 'version': '1.0', - 'category': 'Technical', - 'summary': 'Integration for ChatGPT-compatible AI providers', - 'description': """ -ChatGPT-Compatible AI Integration -================================ -This module provides integration with ChatGPT-compatible AI providers (OpenWebUI, ChatGPT, etc), offering: - -* ChatGPT-compatible provider implementation -* Model synchronization -* Advanced parameter configuration -* Usage statistics tracking -* Support for multiple providers using the ChatGPT API format -""", - 'author': 'Bemade', - 'website': 'https://www.bemade.org', - 'depends': [ - 'ai_integration', - 'openwebui_integration' - ], - 'data': [ - 'security/ir.model.access.csv', - 'views/chatgpt_instance_views.xml', - 'data/chatgpt_provider.xml', - ], - 'external_dependencies': { - 'python': ['requests'], - }, - 'installable': True, - 'application': False, - 'auto_install': False, - 'license': 'LGPL-3', -} diff --git a/ai_integration_openai_api/data/chatgpt_provider.xml b/ai_integration_openai_api/data/chatgpt_provider.xml deleted file mode 100644 index 061810b..0000000 --- a/ai_integration_openai_api/data/chatgpt_provider.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - ChatGPT-Compatible - chatgpt - chatgpt.ai.instance - ai.provider.chatgpt - Integration with ChatGPT-compatible AI providers (OpenWebUI, ChatGPT, etc). - https://platform.openai.com/docs/api-reference/chat - - - diff --git a/ai_integration_openai_api/models/__init__.py b/ai_integration_openai_api/models/__init__.py deleted file mode 100644 index 9ae9743..0000000 --- a/ai_integration_openai_api/models/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from . import chatgpt_provider -from . import chatgpt_instance diff --git a/ai_integration_openai_api/models/chatgpt_instance.py b/ai_integration_openai_api/models/chatgpt_instance.py deleted file mode 100644 index 9c1b15a..0000000 --- a/ai_integration_openai_api/models/chatgpt_instance.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -from odoo import models, fields, api, _ - -class ChatGPTInstance(models.Model): - _name = 'chatgpt.ai.instance' - _description = 'ChatGPT-Compatible Instance Configuration' - _inherit = ['ai.provider.instance', 'ai.generation.params'] - - provider_type = fields.Selection( - selection_add=[('chatgpt', 'ChatGPT-Compatible')], - ondelete={'chatgpt': 'cascade'}) - - # ChatGPT API Parameters - - presence_penalty = fields.Float( - string='Presence Penalty', - help='Penalty for new tokens based on their presence in text. Range: [-2.0 - 2.0].', - default=0.0, - digits=(3, 2)) - - frequency_penalty = fields.Float( - string='Frequency Penalty', - help='Penalty for new tokens based on their frequency in text. Range: [-2.0 - 2.0].', - default=0.0, - digits=(3, 2)) - - # Provider Settings - - def _get_provider_options(self): - """Get ChatGPT-compatible options for API calls.""" - self.ensure_one() - - options = { - 'temperature': self.temperature, - 'top_p': self.top_p, - 'max_tokens': self.max_tokens, - 'presence_penalty': self.presence_penalty, - 'frequency_penalty': self.frequency_penalty, - 'stream': self.stream_response, - } - - if self.stop_sequences: - options['stop'] = [ - seq.strip() - for seq in self.stop_sequences.split(',') - ] - - return options diff --git a/ai_integration_openai_api/models/chatgpt_provider.py b/ai_integration_openai_api/models/chatgpt_provider.py deleted file mode 100644 index 8dd2201..0000000 --- a/ai_integration_openai_api/models/chatgpt_provider.py +++ /dev/null @@ -1,163 +0,0 @@ -# -*- coding: utf-8 -*- -import json -import logging -import requests -from odoo import models, fields, api, _ -from odoo.exceptions import UserError - -_logger = logging.getLogger(__name__) - -class ChatGPTProvider(models.AbstractModel): - _name = 'ai.provider.chatgpt' - _description = 'ChatGPT-Compatible AI Provider' - _inherit = ['ai.provider'] - - def _get_provider_type(self): - return 'chatgpt' - - def test_connection(self, instance): - """Test the connection to the OpenWebUI server.""" - try: - response = requests.get(f"{instance.host}/api/v1/models") - if response.status_code != 200: - raise UserError(_( - "Failed to connect to AI server. Status code: %s. Error: %s", - response.status_code, response.text - )) - return True - except requests.exceptions.RequestException as e: - raise UserError(_( - "Failed to connect to AI server: %s", str(e) - )) - - def sync_models(self, instance): - """Synchronize available models from the OpenWebUI server.""" - self.test_connection(instance) - - try: - # Get models from provider - response = requests.get(f"{instance.host}/api/v1/models") - models_data = response.json() - - # Get existing models for this instance - existing_models = self.env['ai.model'].search([ - ('provider_instance_id', '=', instance.id) - ]) - existing_identifiers = {m.identifier: m for m in existing_models} - - for model_data in models_data: - identifier = model_data.get('id') - if not identifier: - continue - - # Get model details - model_info = self._get_model_info(instance, identifier) - model_details = model_info.get('details', {}) - - model_values = { - 'name': model_data.get('name', identifier), - 'identifier': identifier, - 'description': model_details.get('description', ''), - 'version': model_details.get('version', ''), - 'provider_instance_id': instance.id, - } - - if identifier in existing_identifiers: - # Update existing model - existing_identifiers[identifier].write(model_values) - else: - # Create new model - self.env['ai.model'].create(model_values) - - return True - - except requests.exceptions.RequestException as e: - raise UserError(_("Error synchronizing models: %s") % str(e)) - - def _get_model_info(self, instance, model_name): - """Get detailed information about a specific model.""" - try: - response = requests.get( - f"{instance.host}/api/v1/models/{model_name}/info" - ) - if response.status_code == 200: - return response.json() - else: - _logger.error( - "Failed to get model info for %s. Status: %s, Error: %s", - model_name, response.status_code, response.text - ) - return {} - except requests.exceptions.RequestException as e: - _logger.error("Error getting model info: %s", str(e)) - return {} - - def _format_chat_messages(self, messages): - """Format chat messages for OpenWebUI API.""" - formatted_messages = [] - for message in messages: - role = message.get('role', 'user') - content = message.get('content', '') - - formatted_messages.append({ - 'role': role, - 'content': content - }) - - return formatted_messages - - def generate_response(self, instance, model, messages, **kwargs): - """Generate a response using the chat completion API.""" - try: - # Format messages for OpenWebUI - formatted_messages = self._format_chat_messages(messages) - - # Get model options from instance - options = instance._get_provider_options() - - # Prepare the request payload - payload = { - 'model': model.identifier, - 'messages': formatted_messages, - **options - } - - # Make the API call - response = requests.post( - f"{instance.host}/api/v1/chat/completions", - json=payload - ) - - if response.status_code != 200: - raise UserError(_("Failed to generate response: %s") % response.text) - - response_data = response.json() - generated_text = response_data.get('choices', [{}])[0].get('message', {}).get('content', '') - - # Update statistics - total_tokens = response_data.get('usage', {}).get('total_tokens', 0) - response_time = response_data.get('response_ms', 0) - version = self._get_model_info(instance, model.identifier)\ - .get('details', {}).get('version', '') - - self._track_model_usage( - model, total_tokens, response_time, version=version - ) - - # Return the response in a standardized format - return { - 'content': generated_text, - 'role': 'assistant', - 'metadata': { - 'total_tokens': total_tokens, - 'response_time': response_time, - 'model_version': version, - 'usage': response_data.get('usage', {}) - } - } - - except requests.exceptions.RequestException as e: - # Log error in statistics - if model: - self._track_model_usage(model, error=True) - raise UserError(_("Error generating response: %s") % str(e)) diff --git a/ai_integration_openai_api/security/ir.model.access.csv b/ai_integration_openai_api/security/ir.model.access.csv deleted file mode 100644 index ca4dd20..0000000 --- a/ai_integration_openai_api/security/ir.model.access.csv +++ /dev/null @@ -1,3 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_openwebui_ai_instance_user,openwebui.ai.instance user,model_openwebui_ai_instance,base.group_user,1,0,0,0 -access_openwebui_ai_instance_system,openwebui.ai.instance system,model_openwebui_ai_instance,base.group_system,1,1,1,1 diff --git a/ai_integration_openai_api/views/chatgpt_instance_views.xml b/ai_integration_openai_api/views/chatgpt_instance_views.xml deleted file mode 100644 index cd547bb..0000000 --- a/ai_integration_openai_api/views/chatgpt_instance_views.xml +++ /dev/null @@ -1,106 +0,0 @@ - - - - - chatgpt.ai.instance.form - chatgpt.ai.instance - -
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
- - - - chatgpt.ai.instance.tree - chatgpt.ai.instance - - - - - - - - - - - - - chatgpt.ai.instance.search - chatgpt.ai.instance - - - - - - - - - - - - - - - - ChatGPT-Compatible Instances - chatgpt.ai.instance - tree,form - -

- Create your first ChatGPT-compatible instance -

-

- Configure instances to connect to ChatGPT-compatible servers (OpenWebUI, ChatGPT, etc). -

-
-
- - - -
diff --git a/bemade_add_follower_no_sendmail_default/__init__.py b/bemade_add_follower_no_sendmail_default/__init__.py deleted file mode 100644 index 02565c9..0000000 --- a/bemade_add_follower_no_sendmail_default/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# -*- coding: utf-8 -*- -from . import models - - - diff --git a/bemade_add_follower_no_sendmail_default/__manifest__.py b/bemade_add_follower_no_sendmail_default/__manifest__.py deleted file mode 100644 index 68ec78f..0000000 --- a/bemade_add_follower_no_sendmail_default/__manifest__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -{ - "name": "Change default when adding follower", - "version": "17.0.0.0.1", - "category": "Extra Tools", - 'summary': 'Change default when adding follower', - "description": """ - Change default when adding follower - Send mail false by default - """, - "author": "Bemade", - 'website': 'https://www.bemade.org', - "depends": [ - 'mail', - ], - "data": [ - ], - "auto_install": False, - "installable": True, - 'license': 'OPL-1' -} diff --git a/bemade_add_follower_no_sendmail_default/migration18.md b/bemade_add_follower_no_sendmail_default/migration18.md deleted file mode 100644 index 9e3e516..0000000 --- a/bemade_add_follower_no_sendmail_default/migration18.md +++ /dev/null @@ -1,87 +0,0 @@ -# Migration vers Odoo 18.0 - bemade_add_follower_no_sendmail_default - -## Description du module -Ce module modifie le comportement par défaut du wizard d'ajout de followers pour que l'option "Envoyer un email" soit désactivée par défaut. - -## Analyse technique -- Dépendances : mail -- Modèles modifiés : - - mail.wizard.invite : Modification de la valeur par défaut du champ send_mail à False -- Implémentation actuelle : - - Hérite de mail.wizard.invite - - Redéfinit uniquement le champ send_mail avec default=False - -## Alternatives Natives - -### Configuration Système -1. Vérifier dans Odoo 18.0 : - - Paramètres de configuration du module mail - - Paramètres système (ir.config_parameter) - - Préférences utilisateur - -### Approches Alternatives -1. Configuration par utilisateur : - - Ajouter une préférence utilisateur dans res.users - - Utiliser cette préférence comme valeur par défaut - -2. Configuration par type de document : - - Ajouter un paramètre dans les paramètres de notification par modèle - - Permettre une configuration plus granulaire - -## Recommandations pour la Migration - -### Approche "Vanilla First" -1. Évaluer les alternatives natives : - - [X] Vérifier si Odoo 18.0 a ajouté une configuration similaire - - [ ] Explorer les nouvelles fonctionnalités de notification - - [ ] Vérifier les paramètres de notification par défaut - -2. Si aucune alternative native n'existe : - - [ ] Considérer l'ajout d'une configuration système - - [ ] Implémenter une solution plus flexible (par utilisateur ou par type de document) - -### Modifications Techniques -1. Si le module est conservé : - - [ ] Mettre à jour la version dans __manifest__.py - - [ ] Vérifier la compatibilité de l'héritage du wizard - - [ ] Vérifier si le champ send_mail existe toujours et a le même comportement - - [ ] Adapter le code aux nouvelles conventions Odoo 18.0 - -2. Si migration vers une solution native : - - [ ] Créer un module de migration pour la transition - - [ ] Migrer les configurations existantes - - [ ] Prévoir un plan de désactivation du module - -## Fonctionnalité Native dans Odoo 18.0 -✅ La fonctionnalité existe nativement dans Odoo 18.0 ! - -Dans le modèle `mail.wizard.invite` (`mail/wizard/mail_wizard_invite.py`), le champ `notify` est déjà défini avec `default=False` : -```python -notify = fields.Boolean('Notify Recipients', default=False) -``` - -## Plan de Migration - -### Actions Requises -1. **Désactivation du Module** : - - [ ] Désactiver le module avant la migration vers Odoo 18.0 - - [ ] Vérifier qu'aucun autre module ne dépend de celui-ci - - [ ] Informer les utilisateurs que le comportement est maintenant natif - -2. **Vérification** : - - [ ] Tester le comportement natif dans Odoo 18.0 - - [ ] Confirmer que le comportement par défaut est identique - - [ ] Documenter tout changement d'interface utilisateur - -## État de la Migration -🟢 Pas de migration nécessaire - Utiliser la fonctionnalité native - -## Notes Importantes -- Le comportement souhaité (notification désactivée par défaut) est maintenant le comportement standard d'Odoo 18.0 -- L'interface utilisateur est similaire, utilisant un widget boolean_toggle -- Aucune personnalisation supplémentaire n'est nécessaire - -## Prochaines Étapes -1. Planifier la désactivation du module -2. Informer les utilisateurs du changement -3. Retirer le module de la liste des dépendances des autres modules si nécessaire \ No newline at end of file diff --git a/bemade_add_follower_no_sendmail_default/models/__init__.py b/bemade_add_follower_no_sendmail_default/models/__init__.py deleted file mode 100644 index cd332dd..0000000 --- a/bemade_add_follower_no_sendmail_default/models/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# -*- coding: utf-8 -*- -from . import mail_wizard_invite diff --git a/bemade_add_follower_no_sendmail_default/models/mail_wizard_invite.py b/bemade_add_follower_no_sendmail_default/models/mail_wizard_invite.py deleted file mode 100644 index fb352d8..0000000 --- a/bemade_add_follower_no_sendmail_default/models/mail_wizard_invite.py +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright Bemade.org -from odoo import models, fields, api - - -class MailWizardInviteDefault(models.TransientModel): - _inherit = 'mail.wizard.invite' - - send_mail = fields.Boolean( - default=False, - help="If true, an invitation email will be sent to the recipient" - ) diff --git a/bemade_attachments_cleanup/__init__.py b/bemade_attachments_cleanup/__init__.py deleted file mode 100644 index 4027237..0000000 --- a/bemade_attachments_cleanup/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import wizard diff --git a/bemade_attachments_cleanup/__manifest__.py b/bemade_attachments_cleanup/__manifest__.py deleted file mode 100644 index 2d18b49..0000000 --- a/bemade_attachments_cleanup/__manifest__.py +++ /dev/null @@ -1,22 +0,0 @@ -{ - 'name': "Attachment Cleanup", - 'version': '1.0.1', - 'author': "Bemade", - 'website': "http://www.bemade.org", - 'category': 'Tools', - 'license': 'OPL-1', - 'summary': "Find and delete missing attachments", - 'description': """ - This module adds a wizard in the settings menu to find and delete missing attachments. - The wizard lists all attachments that are not found in the filestore, and allows the user to select and delete them. - Please use this tool with caution, as deleting attachments cannot be undone. - """, - 'depends': ['base'], - 'data': [ - 'wizard/attachment_cleanup_wizard_view.xml', - 'security/ir.model.access.csv', - - ], - 'installable': True, - 'application': False, -} diff --git a/bemade_attachments_cleanup/i18n/fr_CA.po b/bemade_attachments_cleanup/i18n/fr_CA.po deleted file mode 100644 index 5b3b39b..0000000 --- a/bemade_attachments_cleanup/i18n/fr_CA.po +++ /dev/null @@ -1,37 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * attachment_cleanup -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 15.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-08 12:00+0000\n" -"PO-Revision-Date: 2023-06-08 12:00+0000\n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: fr_CA\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: \n" - -#. module: attachment_cleanup -#: model:ir.actions.act_window,name:attachment_cleanup.action_open_attachment_cleanup_wizard -msgid "Cleanup Attachments" -msgstr "Nettoyer les pièces jointes" - -#. module: attachment_cleanup -#: model:ir.ui.view,arch_db:attachment_cleanup.view_attachment_cleanup_wizard -msgid "Delete" -msgstr "Supprimer" - -#. module: attachment_cleanup -#: model:ir.ui.view,arch_db:attachment_cleanup.view_attachment_cleanup_wizard -msgid "Cancel" -msgstr "Annuler" - -#. module: attachment_cleanup -#: model:ir.model.fields,field_description:attachment_cleanup.field_attachment_cleanup_wizard_attachment_ids -msgid "Missing Attachments" -msgstr "Pièces jointes manquantes" diff --git a/bemade_attachments_cleanup/migration18.md b/bemade_attachments_cleanup/migration18.md deleted file mode 100644 index 9eeb92b..0000000 --- a/bemade_attachments_cleanup/migration18.md +++ /dev/null @@ -1,31 +0,0 @@ -# Migration vers Odoo 18.0 - bemade_attachments_cleanup - -## Description -Module de nettoyage des pièces jointes obsolètes - -## Fonctionnalités Ajoutées -- Suppression automatique des pièces jointes non utilisées -- Configuration des règles de nettoyage -- Historique des suppressions - -## Modèles et Champs Modifiés -- ir.attachment - - Ajout du champ cleanup_date (date) - - Ajout du champ cleanup_reason (text) - -## Statut Migration -- [ ] A migrer -- [ ] En cours -- [ ] Migré - -## Détails Migration -- Vérifier si la fonctionnalité existe déjà dans Odoo 18.0 -- Analyser les impacts sur les workflows existants - -## Actions Requises -- [ ] Vérifier la compatibilité avec Odoo 18.0 -- [ ] Tester les fonctionnalités -- [ ] Mettre à jour la documentation - -## Notes -- Ce module pourrait être remplacé par une configuration native dans Odoo 18.0 \ No newline at end of file diff --git a/bemade_attachments_cleanup/security/ir.model.access.csv b/bemade_attachments_cleanup/security/ir.model.access.csv deleted file mode 100644 index 735f299..0000000 --- a/bemade_attachments_cleanup/security/ir.model.access.csv +++ /dev/null @@ -1,2 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_attachment_cleanup_wizard,access.attachment.cleanup.wizard,model_attachment_cleanup_wizard,base.group_system,1,1,1,1 diff --git a/bemade_attachments_cleanup/wizard/__init__.py b/bemade_attachments_cleanup/wizard/__init__.py deleted file mode 100644 index c5856e0..0000000 --- a/bemade_attachments_cleanup/wizard/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import attachment_cleanup_wizard diff --git a/bemade_attachments_cleanup/wizard/attachment_cleanup_wizard.py b/bemade_attachments_cleanup/wizard/attachment_cleanup_wizard.py deleted file mode 100644 index f2446a3..0000000 --- a/bemade_attachments_cleanup/wizard/attachment_cleanup_wizard.py +++ /dev/null @@ -1,45 +0,0 @@ -from odoo import api, fields, models -import os - - -class AttachmentCleanupWizard(models.TransientModel): - _name = 'attachment.cleanup.wizard' - _description = 'Attachment Cleanup Wizard' - - attachment_ids = fields.Many2many( - 'ir.attachment', - string='Missing Attachments', - readonly=True, - help='Attachments that are not found in the filestore' - ) - - @api.model - def default_get(self, fields_list): - res = super(AttachmentCleanupWizard, self).default_get(fields_list) - - attachments_1 = self.sudo().env['ir.attachment'].search([]) - - self._cr.execute("SELECT id FROM ir_attachment WHERE company_id = %s", (self.env.company.id,)) - - attachments = self._cr.fetchall() - - filestore_location = self.env['ir.attachment']._filestore() - - missing_attachments = [] - for attachment_id in attachments: - # if attachment.id == 47984: - # print(attachment.store_fname) - attachment = self.env['ir.attachment'].browse(attachment_id) - - if attachment.store_fname: - file_path = os.path.join(filestore_location, attachment.store_fname) - if not os.path.exists(file_path): - missing_attachments.append(attachment.id) - - if missing_attachments: - res.update({'attachment_ids': [(6, 0, missing_attachments)]}) - return res - - def action_cleanup_attachments(self): - self.ensure_one() - self.attachment_ids.unlink() diff --git a/bemade_attachments_cleanup/wizard/attachment_cleanup_wizard_view.xml b/bemade_attachments_cleanup/wizard/attachment_cleanup_wizard_view.xml deleted file mode 100644 index b652785..0000000 --- a/bemade_attachments_cleanup/wizard/attachment_cleanup_wizard_view.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - attachment.cleanup.wizard.view - attachment.cleanup.wizard - -
- - - - - - - - -