19 Commits
Author SHA1 Message Date
root eed2959ec1 Juiste go versie 2026-07-29 06:41:35 +00:00
root 880106128a Geen publieke attachments 2026-07-15 05:25:37 +00:00
root 1a39a5a68c Cron base.autovacuum_job verwijdert de files daadwerkelijk op het systeem 2026-07-15 05:20:48 +00:00
root fe6b724bb5 sign modellen uitsluiten geven errors en per 5000 actie werkt snel 2026-07-15 05:15:42 +00:00
dochse 1983913340 typo 2026-07-13 15:11:33 +02:00
dochse 833d5e0298 Odoo 19 syntaxing 2026-07-13 15:00:04 +02:00
dochse bf4049382e Odoo 19 syntaxing 2026-07-13 14:58:34 +02:00
dochse f2d4064c5e File cleanup 2026-07-13 14:52:53 +02:00
Thomas Pot 4f9b0e7907 Merge remote-tracking branch 'origin/19.0' into 19.0 2026-06-03 15:51:35 +02:00
Thomas Pot 71908a3a47 [NEW] Automatic install mailhog. Mailhog integration in Odoo 2026-06-03 15:51:00 +02:00
tpot 2706479d9f Merge pull request '19.0_mailhog_install' (#2) from 19.0_mailhog_install into 19.0
Reviewed-on: open2bizz/testserver#2
2026-06-03 13:34:55 +00:00
Thomas Pot fe8680941a [NEW] Automatic install mailhog. Mailhog integration in Odoo 2026-06-03 15:32:18 +02:00
Thomas Pot 3da7ae2cb8 [NEW] Automatic install mailhog. Mailhog integration in Odoo 2026-06-03 14:02:37 +02:00
Thomas Pot 01c79fcfff NEW] Add methods to disable web push notifications 2026-04-28 19:40:03 +02:00
Thomas Pot 253be2ed71 NEW] Add methods to disable web push notifications 2026-04-28 19:27:51 +02:00
Thomas Pot 272b34e061 [FIX] Licence and category 2026-04-01 19:12:49 +02:00
Thomas Pot 3a233406dc [NEW] Test script update and extra cron job for setting database parameter expiration date 2026-03-15 16:42:26 +01:00
mreul 4bedb33244 Normaliseren ADDONS_PATH 2026-01-23 11:10:22 +00:00
mreul 73773b754d migrated to 19.0 2026-01-23 11:49:05 +01:00
11 changed files with 290 additions and 63 deletions
+6
View File
@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/testserver.iml" filepath="$PROJECT_DIR$/.idea/testserver.iml" />
</modules>
</component>
</project>
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
</module>
Generated
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+68
View File
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="417d3a9a-dab7-4fec-b2a8-da7eae112104" name="Changes" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="EmbeddingIndexingInfo">
<option name="cachedIndexableFilesCount" value="36" />
<option name="fileBasedEmbeddingIndicesEnabled" value="true" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="McpProjectServerCommands">
<commands />
<urls />
</component>
<component name="ProjectColorInfo"><![CDATA[{
"associatedIndex": 7,
"fromUser": false
}]]></component>
<component name="ProjectId" id="3GRtXrhb1Z1wz5HO20Plf2KjZjN" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RunOnceActivity.MCP Project settings loaded": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.git.unshallow": "true",
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
"codeWithMe.voiceChat.enabledByDefault": "false",
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
"git-widget-placeholder": "19.0",
"junie.onboarding.icon.badge.shown": "true",
"last_opened_file_path": "/home/dochse/development/testserver",
"nodejs_package_manager_path": "npm",
"to.speed.mode.migration.done": "true",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-python-sdk-50341a9f1f9c-c2ffad84badb-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-261.26222.68" />
</set>
</attachedChunks>
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="417d3a9a-dab7-4fec-b2a8-da7eae112104" name="Changes" comment="" />
<created>1783946253712</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1783946253712</updated>
<workItem from="1783946254947" duration="22000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
</project>
Regular → Executable
View File
+1 -1
View File
@@ -13,7 +13,7 @@
'website': "http://www.open2bizz.tech", 'website': "http://www.open2bizz.tech",
'category': 'Tools', 'category': 'Tools',
'license': "AGPL-3", 'license': "AGPL-3",
'version': '18.0.1.0.0', 'version': '19.0.1.0.0',
'module_type': 'official', 'module_type': 'official',
'depends': ['mail','base',], 'depends': ['mail','base',],
'data': [ 'data': [
@@ -18,7 +18,7 @@ echo ""
echo "===================================" echo "==================================="
echo "Install Go 1.24.3..." echo "Install Go 1.24.3..."
echo "===================================" echo "==================================="
GO_VERSION=1.26.0 GO_VERSION=1.24.3
wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz
sudo rm -rf /usr/local/go sudo rm -rf /usr/local/go
+2 -2
View File
@@ -10,8 +10,8 @@
'website': "http://www.open2bizz.tech", 'website': "http://www.open2bizz.tech",
'category': 'Tools', 'category': 'Tools',
'license': "AGPL-3", 'license': "AGPL-3",
'version': '18.0.1.0.0', 'version': '19.0.1.0.0',
'depends': ['mail','base','mailcatcher_menu',], 'depends': ['mail', 'base', 'mailcatcher_menu'],
'data': [ 'data': [
'views/templates.xml', 'views/templates.xml',
'data/ir_cron.xml', 'data/ir_cron.xml',
+183 -57
View File
@@ -1,74 +1,86 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from odoo import tools from odoo import tools
from odoo import api, fields, models from odoo import api, fields, models
from collections.abc import Mapping from datetime import datetime, timedelta
import logging
_logger = logging.getLogger(__name__)
import os import os
import uuid import uuid
import odoo import odoo
import logging
_logger = logging.getLogger(__name__)
class IrLogging(models.Model): class IrLogging(models.Model):
_inherit = 'ir.logging' _inherit = 'ir.logging'
def init(self): MAIL_SERVERS = (
db_id = uuid.uuid1() ('127.0.0.1', '1025', 'Lokale mailcatcher', 'login', 'name', 't'),
_logger.error(db_id) ('192.168.78.199', '1025', 'Algemene mailcatcher', 'login', 'name', 'f'),
self.env.cr.execute(""" ('hnode6.openworx.nl', '1025', 'Algemene mailcatcher vanaf hnode4', 'login', 'name', 'f'),
UPDATE ir_mail_server set active = 'f'; )
UPDATE fetchmail_server set active = 'f'; EXPECTED_IP_PREFIX = '192.168.78.'
UPDATE ir_cron set active = 'f'; REPORT_URL = 'http://127.0.0.1:8069'
DELETE FROM mail_mail; ENTERPRISE_CODE = 'M160129258730'
UPDATE ir_config_parameter set value = 'M160129258730' where key = 'database.enterprise_code'; FILESTORE_CLEANUP_BATCH_LIMIT = 100
UPDATE ir_config_parameter set value = (NOW() + INTERVAL '30 DAY') where key = 'database.expiration_date';
UPDATE ir_config_parameter set value = '%s' where key = 'database.uuid';
INSERT INTO ir_mail_server(smtp_host,smtp_port,name,smtp_authentication,smtp_encryption,active) VALUES ('127.0.0.1','1025','Lokale mailcatcher','login','name','t');
INSERT INTO ir_mail_server(smtp_host,smtp_port,name,smtp_authentication,smtp_encryption,active) VALUES ('192.168.78.199','1025','Algemene mailcatcher','login','name','t');
INSERT INTO ir_mail_server(smtp_host,smtp_port,name,smtp_authentication,smtp_encryption,active) VALUES ('hnode6.openworx.nl','1025','Algemene mailcatcher vanaf hnode4','login','name','t');
""" %(db_id))
if self.env['ir.config_parameter'].search([('key','=','web.base.url.freeze')]):
self.env.cr.execute("""DELETE FROM ir_config_parameter WHERE key = 'web.base.url.freeze';""")
if not self.env['ir.config_parameter'].search([('key','=','report.url')]):
self.env.cr.execute("""INSERT INTO ir_config_parameter(key,value) VALUES ('report.url','http://127.0.0.1:8069');""")
if self.env['ir.model'].search([('model','=','mail.partner.device')]):
self.env.cr.execute("""DELETE FROM mail_partner_device;""")
model = self.env['ir.model'].search([('model','=','delivery.carrier')])
if model:
field = self.env['ir.model.fields'].search([('name','=','prod_environment'),('model_id','=',model.id)])
if field:
self.env.cr.execute("""UPDATE delivery_carrier SET prod_environment = False WHERE id>0;""")
model = self.env['ir.model'].search([('model','=','payment.provider')])
if model:
field = self.env['ir.model.fields'].search([('name','=','state'),('model_id','=',model.id)])
if field:
self.env.cr.execute("""UPDATE payment_provider SET state = 'disabled' WHERE id>0;""")
model = self.env['ir.model'].search([('model','=','account.online.link')])
if model:
field = self.env['ir.model.fields'].search([('id','>',0),('model_id','=',model.id)])
if field:
self.env.cr.execute("""DELETE FROM account_online_link WHERE id > 0;""")
if self.env['ir.model'].search([('model','=','account.journal')]):
self.env.cr.execute("""UPDATE account_journal set bank_statements_source = 'undefined';""")
ip_ok = False
with os.popen("ip a") as f:
for x in f.readlines():
if float(x.find('192.168.78.')) > -1:
ip_ok = True
if not ip_ok:
self.env.cr.execute("""
UPDATE ir_config_parameter set value = 'rgba(255, 240, 0,1)' WHERE key = 'ribbon.background.color';
UPDATE ir_config_parameter set value = '#000000' WHERE key = 'ribbon.color';
UPDATE ir_config_parameter set value = '!!! IP WRONG !!!' WHERE key = 'ribbon.name';
""")
ADDONS_PATH = odoo.tools.config['addons_path']
_logger.error(ADDONS_PATH)
for ap in ADDONS_PATH.split(','):
if ap[-10:] == 'testserver':
_logger.error(os.system('./%s/testserver.sh' %(ap)))
def init(self):
database_uuid = str(uuid.uuid1())
_logger.debug(f"____ Database UID: {database_uuid}")
self._reset_base_configuration(database_uuid)
_logger.debug(f"_____ reset_base_configuration ____")
self._remove_param_if_exists('web.base.url.freeze')
_logger.debug(f"______ remove_param_if_exists web.base.url.freeze ____")
self._create_param_if_missing('report.url', self.REPORT_URL)
_logger.debug(f"_______ create_param_if_missing report.url ____")
self._disable_web_push_notifications() self._disable_web_push_notifications()
_logger.debug(f"_______ disable_web_push_notifications ____") _logger.debug(f"_______ disable_web_push_notifications ____")
self._disable_delivery_carrier_prod_environment()
_logger.debug(f"_______ disable_delivery_carrier_prod_environment ____")
self._disable_payment_providers()
_logger.debug(f"_______ disable_delivery_carrier_prod_environment ____")
self._clear_account_online_links()
_logger.debug(f"_______ _disable_payment_providers ____")
self._reset_bank_statement_source()
_logger.debug(f"_______ _reset_bank_statement_source ____")
self._set_warning_ribbon_if_ip_is_invalid()
_logger.debug(f"_______ _set_warning_ribbon_if_ip_is_invalid ____")
self._run_testserver_script()
_logger.debug(f"_______ _run_testserver_script ____")
def _reset_base_configuration(self, database_uuid):
self.env.cr.execute("""
UPDATE ir_mail_server SET active = 'f';
UPDATE fetchmail_server SET active = 'f';
UPDATE ir_cron SET active = 'f';
DELETE FROM mail_mail;
UPDATE ir_config_parameter
SET value = %s
WHERE key = 'database.enterprise_code';
UPDATE ir_config_parameter
SET value = (NOW() + INTERVAL '30 DAY')
WHERE key = 'database.expiration_date';
UPDATE ir_config_parameter
SET value = %s
WHERE key = 'database.uuid';
""", (self.ENTERPRISE_CODE, database_uuid))
for mail_server in self.MAIL_SERVERS:
self.env.cr.execute("""
INSERT INTO ir_mail_server(
smtp_host, smtp_port, name, smtp_authentication, smtp_encryption, active
) VALUES (%s, %s, %s, %s, %s, %s);
""", mail_server)
def _remove_param_if_exists(self, key):
if self.env['ir.config_parameter'].search([('key', '=', key)], limit=1):
self.env.cr.execute("DELETE FROM ir_config_parameter WHERE key = %s;", (key,))
def _create_param_if_missing(self, key, value):
if not self.env['ir.config_parameter'].search([('key', '=', key)], limit=1):
self.env.cr.execute(
"INSERT INTO ir_config_parameter(key, value) VALUES (%s, %s);",
(key, value),
)
def _disable_web_push_notifications(self): def _disable_web_push_notifications(self):
parameter = self.env['ir.config_parameter'].sudo() parameter = self.env['ir.config_parameter'].sudo()
@@ -78,3 +90,117 @@ class IrLogging(models.Model):
('key', 'in', ('mail.web_push_vapid_private_key', 'mail.web_push_vapid_public_key', 'mail.sfu_server_key'))]) ('key', 'in', ('mail.web_push_vapid_private_key', 'mail.web_push_vapid_public_key', 'mail.sfu_server_key'))])
for parameter in parameters: for parameter in parameters:
parameter.sudo().unlink() parameter.sudo().unlink()
if self.env['ir.model'].search([('model', '=', 'mail.partner.device')]):
self.env.cr.execute("""DELETE FROM mail_partner_device;""")
def _model_has_field(self, model_name, field_name=None):
model = self.env['ir.model'].search([('model', '=', model_name)], limit=1)
if not model:
return False
if field_name is None:
return True
return bool(
self.env['ir.model.fields'].search(
[('name', '=', field_name), ('model_id', '=', model.id)],
limit=1,
)
)
def _disable_delivery_carrier_prod_environment(self):
if self._model_has_field('delivery.carrier', 'prod_environment'):
self.env.cr.execute(
"UPDATE delivery_carrier SET prod_environment = False WHERE id > 0;"
)
def _disable_payment_providers(self):
if self._model_has_field('payment.provider', 'state'):
self.env.cr.execute(
"UPDATE payment_provider SET state = 'disabled' WHERE id > 0;"
)
def _clear_account_online_links(self):
model = self.env['ir.model'].search([('model', '=', 'account.online.link')], limit=1)
if not model:
return
has_any_field = self.env['ir.model.fields'].search(
[('id', '>', 0), ('model_id', '=', model.id)],
limit=1,
)
if has_any_field:
self.env.cr.execute("DELETE FROM account_online_link WHERE id > 0;")
def _reset_bank_statement_source(self):
if self.env['ir.model'].search([('model', '=', 'account.journal')], limit=1):
self.env.cr.execute(
"UPDATE account_journal SET bank_statements_source = 'undefined';"
)
def _has_expected_ip(self):
with os.popen("ip a") as command_output:
return any(self.EXPECTED_IP_PREFIX in line for line in command_output.readlines())
def _set_warning_ribbon_if_ip_is_invalid(self):
if self._has_expected_ip():
return
self.env.cr.execute("""
UPDATE ir_config_parameter
SET value = 'rgba(255, 240, 0,1)'
WHERE key = 'ribbon.background.color';
UPDATE ir_config_parameter
SET value = '#000000'
WHERE key = 'ribbon.color';
UPDATE ir_config_parameter
SET value = '!!! IP WRONG !!!'
WHERE key = 'ribbon.name';
""")
def _run_testserver_script(self):
addons_path = odoo.tools.config['addons_path']
_logger.error(addons_path)
addons_list = addons_path.split(',') if isinstance(addons_path, str) else list(addons_path)
for addon_path in addons_list:
if addon_path.endswith('testserver'):
_logger.error(os.system(f'./{addon_path}/testserver.sh'))
def _get_unneeded_filestore_attachment_ids(self, limit):
self.env.cr.execute(
"""
SELECT id
FROM ir_attachment
WHERE type = 'binary'
AND res_field IS NULL
AND store_fname IS NOT NULL
AND res_model not in ('sign.document','sign.request')
AND public = 'f'
ORDER BY COALESCE(file_size, 0) DESC, id ASC
LIMIT %s
""",
(limit,),
)
return [row[0] for row in self.env.cr.fetchall()]
def cleanup_unneeded_filestore_attachments(self, limit=FILESTORE_CLEANUP_BATCH_LIMIT):
limit = int(limit or 0)
if limit <= 0:
return 0
attachment_ids = self._get_unneeded_filestore_attachment_ids(limit)
if not attachment_ids:
return 0
self.env['ir.attachment'].sudo().browse(attachment_ids).unlink()
_logger.info('Deleted %s unneeded filestore attachments', len(attachment_ids))
return len(attachment_ids)
def set_db_param(self):
## Script to set database expiration date, when enterprise and test env.
parameter = self.env['ir.config_parameter'].search(
[('key', '=', 'database.expiration_date')],
limit=1,
)
if parameter:
new_date_time = datetime.now() + timedelta(days=30)
parameter.write({'value': str(new_date_time)[:19]})
+3 -2
View File
@@ -8,8 +8,9 @@
'author': "Open2bizz", 'author': "Open2bizz",
'website': "http://www.open2bizz.tech", 'website': "http://www.open2bizz.tech",
'category': 'Uncategorized', 'category': 'Tools',
'version': '18.0.1.0.0', 'license': "AGPL-3",
'version': '19.0.1.0.0',
'depends': ['testserver_o2b','website'], 'depends': ['testserver_o2b','website'],
'data': [ 'data': [
'views/templates.xml', 'views/templates.xml',