# -*- coding: utf-8 -*- import base64 import sys import odoorpc from urllib.parse import urlparse class DatenpolFunctions: def __init__(self, environment, config): self.env = environment self.config = config self._init_OdooRPC() def _init_OdooRPC(self): protocol = 'jsonrpc' if urlparse(self.env.host).scheme == 'https': protocol += '+ssl' host = urlparse(self.env.host).netloc self.odoo = odoorpc.ODOO(host, protocol=protocol, port=self.env.port) def create_db(self): """Neue Datenbank erstellen""" self.odoo.db.create(self.env.super_admin_pw, self.env.dbname, self.env.demo, self.config.lang, self.env.pwd) return True def create_dump(self): """ Erstelle Odoo-Dump""" dump = self.odoo.db.dump(self.env.super_admin_pw, self.env.dbname, 'zip') with open(self.config.dump_file, 'wb') as dump_file: dump_file.write(dump.read()) return True def create_db_from_dump(self): """ Neue Datenbank von Dump erstellen""" try: with open(self.config.dump_file, 'rb') as dump_file: self.odoo.db.restore(self.env.super_admin_pw, self.env.dbname, dump_file, True) except Exception: raise Exception("Wiederherstellen der Datenbank fehlgeschlagen. Eventuell wurde './dp [env] dump' nicht ausgeführt.") print("\nACHTUNG: Nicht vergessen './dp [env] anonym' auszuführen, sodass es zu keiner Kommunikation mit dem Produktivsystem kommt") return True def drop_db(self): """ Datenbank löschen""" self.odoo.db.drop(self.env.super_admin_pw, self.env.dbname) return True def login(self): """Login""" self.odoo.login(self.env.dbname, self.env.username, self.env.pwd) return True def set_default_settings(self): """Systemeinstellungen konfigurieren""" res_settings = self.odoo.env['res.config.settings'] vals = res_settings.default_get([]) vals.update(self.config.settings) wizard_id = res_settings.create(vals) return res_settings.execute(wizard_id) def _readAndReturnFile(self, filename, encode=''): fi = open(filename, 'rb') content = '' if encode == '': content = fi.read() elif encode == 'base64': content = base64.b64encode(fi.read()) content = content.decode() else: sys.exit(-1) fi.close() return content def set_company(self): """Setze Unternehmensdaten (Allgemein, RML, Logo)""" vals = self.config.company_data country_id = self.odoo.env.ref('base.' + vals['country_id']).id if vals.get('logo', False): vals['logo'] = self._readAndReturnFile(vals['logo'], encode='base64') if vals.get('favicon_backend', False): vals['favicon_backend'] = self._readAndReturnFile(vals['favicon_backend'], encode='base64') vals['country_id'] = country_id c_ids = self.odoo.env['res.company'].search([]) return self.odoo.env['res.company'].write(c_ids, vals) def set_taxes(self): """Setze nicht benötigte Steuern auf inaktiv""" tax_ids = self.odoo.env['account.tax'].search([('description', 'not in', self.config.valid_taxes)]) return self.odoo.env['account.tax'].write(tax_ids, {'active': False}) def set_incoterms(self): """Lieferbedingungen setzen""" if hasattr(self.config, 'incoterms'): terms = self.config.incoterms stock_incoterms = self.odoo.env['stock.incoterms'] for name, code in terms: existing_ids = stock_incoterms.search( ['|', ('active', '=', True), ('active', '=', False), ('code', '=', code)] ) if existing_ids: vals = { 'active': True, 'name': name, } stock_incoterms.write(existing_ids, vals) else: vals = { 'name': name, 'code': code, } stock_incoterms.create(vals) codes = [code for name, code in terms] inactive_ids = stock_incoterms.search([('code', 'not in', codes)]) stock_incoterms.write(inactive_ids, {'active': False}) return True def install_modules(self, module=False, raise_exception=False): """Module installieren""" module_to_install = [module] if module else self.config.modules mod_ids = self.odoo.env['ir.module.module'].search([('name', 'in', module_to_install), ('state', '!=', 'installed')]) if not len(mod_ids) == 1 and raise_exception: raise Exception('Module %s not found or is not in state "uninstalled".' % module_to_install) self.odoo.env['ir.module.module'].button_install(mod_ids) self.odoo.env['base.module.upgrade'].upgrade_module(mod_ids) return True def _set_picking_sequence_prefix(self, code, value): seq_dict = self.config.sequences # Hauptsequenz des Picking Types mit diesem code anpassen picking_type_id = self.odoo.env['stock.picking.type'].search([('code', '=', code)], 0, 1, 'id')[0] picking_type = self.odoo.env['stock.picking.type'].read(picking_type_id, ['sequence_id']) s_id = picking_type[0]['sequence_id'][0] if not self.odoo.env['ir.sequence'].write(s_id, seq_dict.get(value)): return False # Allen Picking Types mit diesem code die Haupsequenz geben picking_type_ids = self.odoo.env['stock.picking.type'].search([('code', '=', code)]) if not self.odoo.env['stock.picking.type'].write(picking_type_ids, {'sequence_id': s_id}): return False def set_sequences(self): """Dokumentennummern setzen""" seq_dict = self.config.sequences ir_seq = self.odoo.env['ir.sequence'] # Lieferschein if seq_dict.get('picking.out', False): self._set_picking_sequence_prefix('outgoing', 'picking.out') if seq_dict.get('picking.in', False): self._set_picking_sequence_prefix('incoming', 'picking.in') if seq_dict.get('picking.int', False): self._set_picking_sequence_prefix('internal', 'picking.int') # Angebot if seq_dict.get('sale.order', False): s_ids = ir_seq.search([('code', '=', 'sale.order')]) if len(s_ids) != 1: return False if not ir_seq.write(s_ids, seq_dict.get('sale.order')): return False # Arbeitsschein if seq_dict.get('work.order', False): s_ids = ir_seq.search([('code', '=', 'work.order')]) if len(s_ids) != 1: return False if not ir_seq.write(s_ids, seq_dict.get('work.order')): return False # EK-Angebot if seq_dict.get('purchase.order', False): s_ids = ir_seq.search([('code', '=', 'purchase.order')]) if len(s_ids) != 1: return False if not ir_seq.write(s_ids, seq_dict.get('purchase.order')): return False # Hole Journal für Ausgangsrechnungen j_ids = self.odoo.env['account.journal'].search([('code', '=', 'Re.:')]) if len(j_ids) != 1: return False journals = self.odoo.env['account.journal'].read(j_ids, ['refund_sequence', 'sequence_id', 'refund_sequence_id']) # Rechnungsnummer if seq_dict.get('account.invoice', False): s_id = journals[0]['sequence_id'][0] if not ir_seq.write([s_id], seq_dict.get('account.invoice')): return False # Gutschriftennummer ref_seq_data = seq_dict.get('account.invoice_refund', False) if ref_seq_data: s_id = journals[0]['refund_sequence_id'] and journals[0]['refund_sequence_id'][0] or False if not s_id: s_id = ir_seq.create(ref_seq_data) else: ir_seq.write([s_id], ref_seq_data) # Wenn Checkbox nicht gesetzt ist, dann setzen vals = { 'refund_sequence_id': s_id, 'refund_sequence': True } self.odoo.env['account.journal'].write(j_ids, vals) else: vals = { 'refund_sequence': False } self.odoo.env['account.journal'].write(j_ids, vals) return True def set_admin_rights(self): """Setze Administrator Rechte""" groups = [] user_id = self.odoo.env.ref('base.user_root').id # Technische Eigenschaften groups.append((4, self.odoo.env.ref('base.group_no_one').id)) # Finanzmanager groups.append((4, self.odoo.env.ref('account.group_account_manager').id)) vals = { 'groups_id': groups, 'tz': 'Europe/Vienna', } return self.odoo.env['res.users'].write([user_id], vals) def setup_accounting(self): """Konfiguration Kontenplan""" c = self.config sales_tax_ids = self.odoo.env['account.tax.template'].search( [('description', '=', c.sales_tax), ('parent_id', '=', False)]) if not sales_tax_ids: return False purchase_tax_ids = self.odoo.env['account.tax.template'].search( [('description', '=', c.purchase_tax), ('parent_id', '=', False)]) if not purchase_tax_ids: return False # Set Your Accounting Options currency_id = self.odoo.env.ref('base.EUR').id vals = {} vals['chart_template_id'] = c.chart_template_id vals['sale_tax'] = sales_tax_ids[0] vals['purchase_tax'] = purchase_tax_ids[0] vals['company_id'] = 1 # Default vals['currency_id'] = currency_id wizard_id = self.odoo.env['wizard.multi.charts.accounts'].create(vals) self.odoo.env['wizard.multi.charts.accounts'].action_next([wizard_id]) return True def set_uom(self): """Mengeneinheiten setzen""" self.odoo.env.context['lang'] = self.config.lang c = self.config active_uoms = c.active_uoms.keys() product_uom = self.odoo.env['product.uom'] active_ids = [] for uom_xml_id in active_uoms: uom_id = self.odoo.env.ref(uom_xml_id).id active_ids.append(uom_id) # Set all UOMs to active ids = product_uom.search(['|', ('active', '=', True), ('active', '=', False)]) res = product_uom.write(ids, {'active': True}) if not res: return False # Set all other UOMs to inactive inactive_ids = product_uom.search([('id', 'not in', active_ids)]) res = product_uom.write(inactive_ids, {'active': False}) if not res: return False # Update names for uom_xml_id, name in c.active_uoms.items(): uom_id = self.odoo.env.ref(uom_xml_id).id res = product_uom.write([uom_id], {'name': name}) if not res: return False return True def set_fiscal_position(self): """Steuerzuordnungen setzen""" c = self.config # Ungültige Steuerzuordnungen auf inaktiv setzen invalid_ids = self.odoo.env['account.fiscal.position'].search([('name', 'not in', c.valid_fiscal_positions)]) self.odoo.env['account.fiscal.position'].write(invalid_ids, {'active': False}) # Mappings inaktiver Steuern löschen (also wenn rechte Seite eine inaktive Steuer ist, wie z. B "strf. i.g.L")) valid_position_ids = self.odoo.env['account.fiscal.position'].search( [('name', 'in', c.valid_fiscal_positions)]) valid_tax_ids = self.odoo.env['account.tax'].search([('parent_id', '=', False)]) position_tax_line_ids = self.odoo.env['account.fiscal.position.tax'].search( [('position_id', 'in', valid_position_ids), ('tax_dest_id', 'not in', valid_tax_ids)]) vals = {'tax_dest_id': False} return self.odoo.env['account.fiscal.position.tax'].write(position_tax_line_ids, vals) def update_module(self): """Aktualisiere Modul""" module_names = self.config.module_name mod_ids = [] for module_name in module_names: mod_id = self.odoo.env['ir.module.module'].search([('name', '=', module_name), ('state', '=', 'installed')]) if not len(mod_id) == 1: raise Exception('Module "%s" not found or not installed.' % module_name) mod_ids += mod_id self.odoo.env['ir.module.module'].button_upgrade(mod_ids) self.odoo.env['base.module.upgrade'].upgrade_module([]) return True def install_module(self): """Installiere Modul""" self.install_modules(self.config.module_name, raise_exception=True) return True def update_modules(self): """Verfügbare Module updaten""" wizard_id = self.odoo.env['base.module.update'].create({}) self.odoo.env['base.module.update'].update_module([wizard_id]) return True def uninstall_module(self): """Deinstalliere Modul""" module_name = self.config.module_name mod_ids = self.odoo.env['ir.module.module'].search([('name', '=', module_name), ('state', '=', 'installed')]) if not len(mod_ids) == 1: raise Exception("Module '%s' not found or is not installed." % module_name) self.odoo.env['ir.module.module'].button_uninstall(mod_ids) self.odoo.env['base.module.upgrade'].upgrade_module([]) return True def cancel_upgrade_module(self): """Modul Upgrade abbrechen""" module_name = self.config.module_name mod_ids = self.odoo.env['ir.module.module'].search( [('name', '=', module_name), ('state', '=', 'to upgrade')]) if not len(mod_ids) == 1: raise Exception("Module '%s' not found or is not installed." % module_name) self.odoo.env['ir.module.module'].button_upgrade_cancel(mod_ids) return True def setup_journals(self): """Update journals""" if self.config.allow_cancel_invoice: self.install_modules('account_cancel') # Verkauf- und Gutschriftenjournal j_ids = self.odoo.env['account.journal'].search([('type', 'in', ['sale', 'purchase'])]) if len(j_ids) != 2: return False vals = { 'update_posted': self.config.allow_cancel_invoice } return self.odoo.env['account.journal'].write(j_ids, vals) def update_all(self): """Aktualisiere Modul""" for module_name in self.config.modules: mod_ids = self.odoo.env['ir.module.module'].search( [('name', '=', module_name), ('state', '=', 'installed')]) if not len(mod_ids) == 1: raise Exception('Module "%s" not found or ist not installed.' % module_name) self.odoo.env['ir.module.module'].button_upgrade(mod_ids) self.odoo.env['base.module.upgrade'].upgrade_module([]) return True def set_warehouse(self): """Name des Zentrallagers setzen""" is_installed = self.odoo.env['ir.module.module'].search( [('name', '=', 'stock'), ('state', '=', 'installed')]) if is_installed: vals = { 'name': self.config.warehouse_name or self.config.company_data.get('name', 'Mein Unternehmen'), 'delivery_steps': self.config.delivery_steps, } if self.config.warehouse_code: vals.update({'code': self.config.warehouse_code}) warehouse_ids = self.odoo.env['stock.warehouse'].search([('id', '=', 1)]) return self.odoo.env['stock.warehouse'].write(warehouse_ids, vals) else: return True def set_dmi_noupdate(self): """DMI: Einträge auf 'no update' setzen""" domain = [('module', '=', 'dp_dmi'), ('noupdate', '=', False)] data_ids = self.odoo.env['ir.model.data'].search(domain) vals = {'noupdate': True} return self.odoo.env['ir.model.data'].write(data_ids, vals) def dmi_confirm_inventory(self): """DMI: Lagerstand einbuchen""" dummy, inventory_id = self.odoo.env.ref('dp_dmi.inv_init') inventory = self.odoo.env['stock.inventory'].read(inventory_id, ['state']) if inventory.get('state', '') == 'confirm': return self.odoo.env['stock.inventory'].action_done([inventory_id]) return True def set_decimal_price(self): """Dezimalstellen setzen""" decimal_precision = self.odoo.env['decimal.precision'] ir_data = self.odoo.env['ir.model.data'] # UOM decimal_id = self.odoo.env.ref('product.decimal_product_uom').id res = decimal_precision.write([decimal_id], {'digits': self.config.uom_decimals}) if not res: return False # # UOS # decimal_id = self.odoo.env.ref('product.decimal_product_uos').id # res = decimal_precision.write([decimal_id], {'digits': self.config.uom_decimals}) # if not res: # return False # Product Price decimal_id = self.odoo.env.ref('product.decimal_price').id res = decimal_precision.write([decimal_id], {'digits': self.config.price_decimals}) if not res: return False # Product Price ids = decimal_precision.search([('name', '=', 'Product Price')]) res = decimal_precision.write(ids, {'digits': self.config.price_decimals}) if not res: return False return True def setup_email(self): """Mailserver einrichten""" mail_server = self.odoo.env['ir.mail_server'] server_ids = mail_server.search([]) if server_ids: mail_server.unlink(server_ids) if mail_server.create(self.config.mail_server): return True return False def stock_set_cost_method(self): """Kalkulationsverfahren für Lager setzen""" if hasattr(self.config, 'stock_cost_method'): self.odoo.env['ir.default'].set('product.category', 'property_cost_method', self.config.stock_cost_method) return True def import_users(self): """User importieren""" if hasattr(self.config, 'users_file'): vals = {} vals['res_model'] = 'res.users' vals['file'] = self._readAndReturnFile(self.config.users_file) fields = [u'id', u'name', u'login', u'email', u'groups_id/id', False, u'tz', u'mobile', u'phone', u'function'] options = {u'headers': True, u'quoting': u'"', u'separator': u',', u'encoding': u'utf-8'} wizard_id = self.odoo.env['base_import.import'].create(vals) if wizard_id: messages = self.odoo.env['base_import.import'].do(wizard_id, fields, options) if messages: print(messages) return False return True return False def set_translations(self): """Übersetzungen aktualisieren """ if hasattr(self.config, 'translation_files') and self.config.lang != 'en_US': for file in self.config.translation_files: data = self._readAndReturnFile(file, encode='base64') vals = { 'name': 'test', 'code': self.config.lang, 'data': data, 'overwrite': True, } wizard_id = self.odoo.env['base.language.import'].create(vals) self.odoo.env['base.language.import'].import_lang([wizard_id]) return True return True def default_set_order_policy(self): """Setze Rechnung von Lieferschein""" if hasattr(self.config, 'order_policy'): self.odoo.env['ir.default'].set('sale.order', 'order_policy', self.config.order_policy) return True def set_default_removal_strategy(self): """Default Entnahmestrategie für Lager setzen""" if hasattr(self.config, 'removal_strategy'): method = self.config.removal_strategy strategy_ids = self.odoo.env['product.removal'].search([('method', '=', method)]) if not strategy_ids: return False stock_id = self.odoo.env.ref('stock.stock_location_stock').id if not stock_id: return False product_category_ids = self.odoo.env['product.category'].search([]) return self.odoo.env['product.category'].write(product_category_ids, {'removal_strategy_id': strategy_ids[0]}) return True def set_default_values(self): """Defaultwerte für Dokumente setzen""" for model, field, value in self.config.default_values: self.odoo.env['ir.default'].set(model, field, value) return True def update_special_values(self): """Spezialwerte setzen""" return True def update_values(self): """Existierende Daten aktualisieren""" for xml_id, vals in self.config.data_updates.items(): res = self.odoo.env.ref(xml_id) model = res._name self.odoo.env[model].write([res.id], vals) return True def set_sys_params(self): """Systemparameter setzen""" for key, value in self.config.system_parameters.items(): param_ids = self.odoo.env['ir.config_parameter'].search([('key', '=', key)]) vals = { 'key': key, 'value': value, } if param_ids: self.odoo.env['ir.config_parameter'].write(param_ids, vals) else: self.odoo.env['ir.config_parameter'].create(vals) return True def remove_sys_params(self): """Systemparameter entfernen""" for key, value in self.config.system_parameters_remove_on_rollout.items(): print(key) param_ids = self.odoo.env['ir.config_parameter'].search([('key', '=', key)]) print(param_ids) if param_ids: self.odoo.env['ir.config_parameter'].unlink(param_ids) return True def setup_reports(self): """Berichte konfigurieren""" for report, attachment in self.config.reports.items(): r_ids = self.odoo.env.ref(report) if r_ids: self.odoo.env['ir.actions.report'].write(r_ids.id, {'attachment': attachment}) else: return False return True def invalidate_email(self): """In E-Mail-Adressen @ durch # ersetzen, um unbeabsichtigen E-Mail-Versand zu vermeiden""" # E-Mail adressen von res_partner: @ -> # p_ids = self.odoo.env['res.partner'].search([('email', 'ilike', '%@%')]) partner = self.odoo.env['res.partner'].read(p_ids, ['email']) for p in partner: id = p['id'] email = p['email'] new_email = email.replace('@', '#') self.odoo.env['res.partner'].write([id], {'email': new_email}) return True def make_anonymous(self): """Anonymisieren der Daten""" res = True # res &= self.make_anonymous_one('make_anonymous_partner') # res &= self.make_anonymous_one('make_anonymous_project') # res &= self.make_anonymous_one('make_anonymous_employee') # res &= self.make_anonymous_one('make_anonymous_leads') res &= self.make_anonymous_one('make_anonymous_mailserver') res &= self.make_anonymous_one('make_anonymous_cron') return res def make_anonymous_one(self, func_name): """Anonymisieren der Daten ein Schritt""" try: getattr(self, func_name)() print('.............. ' + func_name + ': OK') except: print('.............. ' + func_name + ': ERROR!!!') return False return True def make_anonymous_partner(self): ids = self.odoo.env['res.partner'].search([]) for id in ids: vals = { 'name': 'Partner %s' % id, 'street': '----', 'email': 'test@example.com', } self.odoo.env['res.partner'].write([id], vals) def make_anonymous_project(self): if (self.odoo.env['ir.module.module'].search([('name', '=', 'project'), ('state', '=', 'installed')])): ids = self.odoo.env['project.project'].search([]) for id in ids: vals = { 'name': 'Projekt %s' % id, } self.odoo.env['project.project'].write([id], vals) # Tasks ids = self.odoo.env['project.task'].search([]) for id in ids: vals = { 'name': 'Aufgabe %s' % id, } self.odoo.env['project.task'].write([id], vals) def make_anonymous_employee(self): if (self.odoo.env['ir.module.module'].search([('name', '=', 'hr'), ('state', '=', 'installed')])): ids = self.odoo.env['hr.employee'].search([]) for id in ids: vals = { 'name': 'Mitarbeiter %s' % id, 'work_email': 'test@example.com', } self.odoo.env['hr.employee'].write([id], vals) def make_anonymous_leads(self): if (self.odoo.env['ir.module.module'].search([('name', '=', 'crm'), ('state', '=', 'installed')])): ids = self.odoo.env['crm.lead'].search([]) for id in ids: vals = { 'name': 'Lead %s' % id, 'email_from': 'test@example.com', 'description': '', } ids = self.odoo.env['crm.lead'].write([id], vals) def make_anonymous_mailserver(self): server_ids = self.odoo.env['ir.mail_server'].search([]) self.odoo.env['ir.mail_server'].write(server_ids, {'active': False}) server_ids = self.odoo.env['fetchmail.server'].search([]) self.odoo.env['fetchmail.server'].unlink(server_ids) def make_anonymous_cron(self): cron_ids = self.odoo.env['ir.cron'].search([]) if cron_ids: self.odoo.env['ir.cron'].write(cron_ids, {'active': False}) def set_ext_ids(self): """ExtIDs für Accounts und Types""" # # Konten Ext IDs # lst_accs = ['200000', '330000', '250000', '350000'] # odoo 9 nummern # for acc in lst_accs: # res_id = self._execute('account.account', 'search', [('code', '=', acc)]) # # print "---------------------------------------------" # # print acc # # print res_id # vals = { # 'name': 'cust_account_mapp_' + acc, # 'module': 'account', # 'model': 'account.account', # 'res_id': res_id[0], # } # try: # self._execute('ir.model.data', 'create', vals) # except: # print "Fehler Anlage ExtID " + 'cust_account_mapp_' + acc return True def consume_tours(self): """Odoo-Touren auf konsumiert setzen""" tours = [ 'crm_tour', 'mail_tour', 'sale_tour', 'rte', 'rte_inline', 'rte_translator', 'account_accountant_tour', 'banner', 'event', ] for uid in self.odoo.env['res.users'].search([]): for t in tours: vals = { 'name': t, 'user_id': uid, } self.odoo.env['web_tour.tour'].create(vals) return True def disable_planners(self): """Implementierungsplaner deaktivieren""" # The dashboard widget itself remains. It can be removed in the # module web_settings_dashboard in dashboard.xml and dashboard.js. planner_ids = self.odoo.env['web.planner'].search([]) return self.odoo.env['web.planner'].write(planner_ids, {'active': False}) def remove_standard_translations(self): """entferne standard odoo ueberseztungen""" res_ids = self.odoo.env['ir.translation'].search( [('name', '=', 'stock.location,name'), ('src', '=', 'Stock'), ('value', '=', 'Lager')]) if res_ids: return self.odoo.env['ir.translation'].unlink(res_ids) return True