547 lines
22 KiB
Python
Executable File
547 lines
22 KiB
Python
Executable File
# -*- coding: utf-8 -*-
|
|
|
|
import xmlrpclib
|
|
import base64
|
|
import os
|
|
import sys
|
|
import datetime
|
|
import json
|
|
import requests
|
|
from config_at import Config
|
|
from environments import ENVIRONMENTS
|
|
|
|
class CamadeusFunctions():
|
|
|
|
def __init__(self, environment, config):
|
|
self.env = environment
|
|
self.config = config
|
|
|
|
def create_db(self):
|
|
"""Neue Datenbank erstellen"""
|
|
|
|
payload = {'fields': [ {'name': 'super_admin_pwd', 'value': self.env.admin_pw},
|
|
{'name': 'db_name', 'value': self.env.dbname},
|
|
{'name': 'demo_data', 'value': False},
|
|
{'name': 'db_lang', 'value': self.env.lang},
|
|
{'name': 'create_admin_pwd', 'value': self.env.pwd},
|
|
]
|
|
}
|
|
payload = {'params': payload}
|
|
json_data = json.dumps(payload)
|
|
headers = {'content-type': 'application/json'}
|
|
r = requests.post('%s:%s/web/database/create' % (self.env.host,self.env.port), data=json_data, headers=headers, auth=self.env.basic_auth, verify=False)
|
|
if r and r.json().get('result',False):
|
|
return True
|
|
else:
|
|
print "Error occured: %s" % r.json().get('error', '????')
|
|
return False
|
|
|
|
def login(self):
|
|
"""Login"""
|
|
|
|
# Get the uid
|
|
sock_common = xmlrpclib.ServerProxy ('%s:%s/xmlrpc/common' % (self.env.host,self.env.port))
|
|
self.uid = sock_common.login(self.env.dbname, self.env.username, self.env.pwd)
|
|
if not self.uid:
|
|
raise "Authentication Error"
|
|
self.sock = xmlrpclib.ServerProxy('%s:%s/xmlrpc/object' % (self.env.host,self.env.port))
|
|
return True
|
|
|
|
def _execute(self, *args):
|
|
return self.sock.execute(self.env.dbname, self.uid, self.env.pwd, *args)
|
|
|
|
def _readAndReturnFile(self, filename, encode = ''):
|
|
fi = open (filename, 'r')
|
|
content = ''
|
|
if encode=='':
|
|
content = fi.read()
|
|
elif encode=='base64':
|
|
content = base64.b64encode(fi.read())
|
|
else:
|
|
sys.exit(-1)
|
|
fi.close()
|
|
return content
|
|
|
|
def set_company(self):
|
|
"""Setze Unternehmensdaten (Allgemein, RML, Logo)"""
|
|
|
|
vals = self.config.company_data
|
|
dummy,country_id = self._execute('ir.model.data', 'get_object_reference', 'base',vals['country_id'])
|
|
|
|
# RML-Header ist nun ein function-Feld
|
|
#if vals.get('rml_header',False):
|
|
# vals['rml_header'] = self._readAndReturnFile(vals['rml_header'])
|
|
|
|
if vals.get('logo',False):
|
|
vals['logo'] = self._readAndReturnFile(vals['logo'], encode = 'base64')
|
|
vals['country_id'] = country_id
|
|
c_ids = self._execute('res.company', 'search', [], )
|
|
return self._execute('res.company', 'write', c_ids, vals)
|
|
|
|
def set_taxes(self):
|
|
"""Setze nicht benötigte Steuern auf inaktiv"""
|
|
|
|
tax_ids = self._execute('account.tax', 'search', [('description','not in', self.config.valid_taxes)])
|
|
return self._execute('account.tax', 'write', tax_ids, {'active': False})
|
|
|
|
def set_date_format(self):
|
|
"""Setzen des Datumsformats """
|
|
|
|
lang_ids = self._execute('res.lang', 'search', [('code','=','de_DE')])
|
|
if lang_ids:
|
|
vals = {
|
|
'date_format': '%d.%m.%Y',
|
|
'time_format': '%H:%M:%S',
|
|
'grouping': '[3,3]',
|
|
'thousands_sep': '.',
|
|
'decimal_point': ',',
|
|
}
|
|
self._execute('res.lang', 'write', lang_ids, vals)
|
|
else:
|
|
return False
|
|
|
|
lang_ids = self._execute('res.lang', 'search', [('code','=','en_US')])
|
|
if lang_ids:
|
|
vals = {
|
|
'grouping': '[3,3]',
|
|
}
|
|
self._execute('res.lang', 'write', lang_ids, vals)
|
|
else:
|
|
return False
|
|
|
|
return True
|
|
|
|
# def set_report_types(self):
|
|
# """Setzen der Report Types auf RML (PDF)"""
|
|
#
|
|
# report_names = ['purchase.report_purchaseorder',
|
|
# 'purchase.report_purchasequotation',
|
|
# 'account.report_invoice',
|
|
# 'sale.report_saleorder',
|
|
# 'stock.report_picking']
|
|
# report_ids = self._execute('ir.actions.report.xml', 'search', [('report_name','in',report_names)])
|
|
# return self._execute('ir.actions.report.xml', 'write', report_ids, {'report_type': 'pdf'})
|
|
|
|
def purchase_config(self):
|
|
"""Basiskonfiguration für Einkauf laden"""
|
|
|
|
if hasattr(self.config, 'purchase_config'):
|
|
vals = self._execute('purchase.config.settings', 'default_get', [])
|
|
vals.update(self.config.purchase_config)
|
|
wizard_id = self._execute('purchase.config.settings', 'create', vals)
|
|
return self._execute('purchase.config.settings', 'execute', [wizard_id])
|
|
return True
|
|
|
|
def sale_config(self):
|
|
"""Basiskonfiguration für Verkauf laden"""
|
|
|
|
vals = self._execute('sale.config.settings', 'default_get', [])
|
|
vals.update(self.config.sale_config)
|
|
wizard_id = self._execute('sale.config.settings', 'create', vals)
|
|
return self._execute('sale.config.settings', 'execute', [wizard_id])
|
|
|
|
def stock_config(self):
|
|
"""Basiskonfiguration für Lager laden"""
|
|
|
|
if hasattr(self.config, 'stock_config'):
|
|
vals = self._execute('stock.config.settings', 'default_get', [])
|
|
vals.update(self.config.stock_config)
|
|
wizard_id = self._execute('stock.config.settings', 'create', vals)
|
|
return self._execute('stock.config.settings', 'execute', [wizard_id])
|
|
return True
|
|
|
|
def set_incoterms(self):
|
|
"""Lieferbedingungen setzen"""
|
|
|
|
if hasattr(self.config, 'incoterms'):
|
|
terms = self.config.incoterms
|
|
|
|
|
|
for name,code in terms:
|
|
existing_ids = self._execute('stock.incoterms', 'search', ['|',('active','=',True),('active','=',False),('code','=',code)])
|
|
if existing_ids:
|
|
vals = {
|
|
'active': True,
|
|
'name': name,
|
|
}
|
|
self._execute('stock.incoterms', 'write', existing_ids, vals)
|
|
else:
|
|
vals = {
|
|
'name': name,
|
|
'code': code,
|
|
}
|
|
self._execute('stock.incoterms', 'create', vals)
|
|
|
|
codes = [code for name,code in terms]
|
|
inactive_ids = self._execute('stock.incoterms', 'search', [('code','not in',codes)])
|
|
self._execute('stock.incoterms', 'write', inactive_ids, {'active': False})
|
|
|
|
|
|
return True
|
|
|
|
def base_config(self):
|
|
"""Allgemeine Konfiguration laden"""
|
|
|
|
vals = self._execute('base.config.settings', 'default_get', [])
|
|
vals.update(self.config.base_config)
|
|
wizard_id = self._execute('base.config.settings', 'create', vals)
|
|
return self._execute('base.config.settings', 'execute', [wizard_id])
|
|
|
|
def install_module_sale(self):
|
|
"""Modul 'Sale' installieren"""
|
|
|
|
modules_to_install = self._execute('ir.module.module', 'search', [('name','=','sale'),('state','!=','installed')])
|
|
res = self._execute('ir.module.module', 'button_install', modules_to_install)
|
|
res = self._execute('base.module.upgrade', 'upgrade_module', modules_to_install)
|
|
return True
|
|
|
|
def install_modules(self):
|
|
"""Module installieren"""
|
|
|
|
modules_to_install = self._execute('ir.module.module', 'search', [('name','in',self.config.modules),('state','!=','installed')])
|
|
res = self._execute('ir.module.module', 'button_install', modules_to_install)
|
|
res = self._execute('base.module.upgrade', 'upgrade_module', modules_to_install)
|
|
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._execute('stock.picking.type', 'search', [('code','=',code)], 0, 1, 'id')[0]
|
|
picking_type = self._execute('stock.picking.type', 'read', picking_type_id, ['sequence_id'])
|
|
s_id = picking_type['sequence_id'][0]
|
|
if not self._execute('ir.sequence', 'write', s_id, seq_dict.get(value)):
|
|
return False
|
|
|
|
#Allen Picking Types mit diesem code die Haupsequenz geben
|
|
picking_type_ids = self._execute('stock.picking.type', 'search', [('code','=',code)])
|
|
if not self._execute('stock.picking.type', 'write', picking_type_ids, {'sequence_id': s_id}):
|
|
return False
|
|
|
|
def set_dokumentennummern(self):
|
|
"""Dokumentennummern setzen"""
|
|
|
|
seq_dict = self.config.sequences
|
|
|
|
# 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 = self._execute('ir.sequence', 'search', [('code','=','sale.order')])
|
|
if len(s_ids) != 1:
|
|
return False
|
|
if not self._execute('ir.sequence', 'write', s_ids, seq_dict.get('sale.order')):
|
|
return False
|
|
|
|
# Arbeitsschein
|
|
if seq_dict.get('work.order',False):
|
|
s_ids = self._execute('ir.sequence', 'search', [('code','=','work.order')])
|
|
if len(s_ids) != 1:
|
|
return False
|
|
if not self._execute('ir.sequence', 'write', s_ids, seq_dict.get('work.order')):
|
|
return False
|
|
|
|
# EK-Angebot
|
|
if seq_dict.get('purchase.order',False):
|
|
s_ids = self._execute('ir.sequence', 'search', [('code','=','purchase.order')])
|
|
if len(s_ids) != 1:
|
|
return False
|
|
if not self._execute('ir.sequence', 'write', s_ids, seq_dict.get('purchase.order')):
|
|
return False
|
|
|
|
# Rechnungsnummer
|
|
if seq_dict.get('account.invoice',False):
|
|
j_ids = self._execute('account.journal', 'search', [('code','=','VK')])
|
|
if len(j_ids) != 1:
|
|
return False
|
|
journals = self._execute('account.journal', 'read', j_ids, ['sequence_id'])
|
|
s_id = journals[0]['sequence_id'][0]
|
|
if not self._execute('ir.sequence', 'write', [s_id], seq_dict.get('account.invoice')):
|
|
return False
|
|
|
|
# Setzen Gutschriftenkreis
|
|
if self.config.refund_invoice_sequence:
|
|
j_ids = self._execute('account.journal', 'search', [('code','=','VK')])
|
|
if len(j_ids) != 1:
|
|
return False
|
|
journals = self._execute('account.journal', 'read', j_ids, ['sequence_id'])
|
|
s_id = journals[0]['sequence_id'][0]
|
|
|
|
gj_ids = self._execute('account.journal', 'search', [('code','=','GSV')])
|
|
if len(gj_ids) != 1:
|
|
return False
|
|
vals = {
|
|
'sequence_id': s_id,
|
|
}
|
|
self._execute('account.journal', 'write', gj_ids,vals)
|
|
|
|
return True
|
|
|
|
def set_admin_rights(self):
|
|
"""Setze Administrator Rechte"""
|
|
|
|
dummy,user_id = self._execute('ir.model.data', 'get_object_reference', 'base', 'user_root')
|
|
groups = []
|
|
|
|
# Technische Eigenschaften
|
|
dummy,group_id = self._execute('ir.model.data', 'get_object_reference', 'base', 'group_no_one')
|
|
groups.append((4,group_id))
|
|
|
|
# Finanzmanager
|
|
dummy,group_id = self._execute('ir.model.data', 'get_object_reference', 'account', 'group_account_manager')
|
|
groups.append((4,group_id))
|
|
|
|
vals = {
|
|
'groups_id': groups,
|
|
'tz': 'Europe/Vienna',
|
|
}
|
|
|
|
return self._execute('res.users', 'write', [user_id], vals)
|
|
|
|
def setup_accounting(self):
|
|
"""Konfiguration Buchhaltung"""
|
|
|
|
vals = self._execute('account.installer', 'default_get', [])
|
|
vals['charts'] = self.config.chart_of_accounts
|
|
wizard_id = self._execute('account.installer', 'create', vals)
|
|
res = self._execute('account.installer', 'action_next', [wizard_id])
|
|
return True
|
|
|
|
def setup_accounting2(self):
|
|
"""Konfiguration Kontenplan"""
|
|
|
|
c = self.config
|
|
sales_tax_ids = self._execute('account.tax.template', 'search', [('description','=', c.sales_tax),('parent_id','=',False)])
|
|
if not sales_tax_ids:
|
|
return False
|
|
purchase_tax_ids = self._execute('account.tax.template', 'search', [('description','=', c.purchase_tax),('parent_id','=',False)])
|
|
if not purchase_tax_ids:
|
|
return False
|
|
|
|
#Set Your Accounting Options
|
|
dummy,currency_id = self._execute('ir.model.data', 'get_object_reference', 'base', 'EUR')
|
|
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._execute('wizard.multi.charts.accounts', 'create', vals)
|
|
res = self._execute('wizard.multi.charts.accounts', 'action_next', [wizard_id])
|
|
return True
|
|
|
|
def set_currencies(self):
|
|
"""Währungen setzen"""
|
|
|
|
c = self.config
|
|
|
|
# Set all currencies to active
|
|
ids = self._execute('res.currency', 'search', ['|',('active','=',True),('active','=',False)])
|
|
res = self._execute('res.currency', 'write', ids, {'active': True})
|
|
if not res:
|
|
return False
|
|
|
|
# Set all other UOMs to inactive
|
|
inactive_ids = self._execute('res.currency', 'search', [('name','not in',c.valid_currencies)])
|
|
res = self._execute('res.currency', 'write', inactive_ids, {'active': False})
|
|
if not res:
|
|
return False
|
|
|
|
return True
|
|
|
|
def uninstall_chat(self):
|
|
"""Chat-Modul deinstallieren """
|
|
|
|
modules = ['im_chat','im_odoo_support','bus']
|
|
modules_to_install = self._execute('ir.module.module', 'search', [('name','in',modules)])
|
|
res = self._execute('ir.module.module', 'button_uninstall', modules_to_install)
|
|
res = self._execute('base.module.upgrade', 'upgrade_module', modules_to_install)
|
|
return True
|
|
|
|
def set_uom(self):
|
|
"""Mengeneinheiten setzen"""
|
|
|
|
context = {'lang': 'de_DE'}
|
|
c = self.config
|
|
active_uoms = c.active_uoms.keys()
|
|
|
|
active_ids = []
|
|
for uom_xml_id in active_uoms:
|
|
uom_id = self._execute('ir.model.data', 'xmlid_to_res_id', uom_xml_id)
|
|
active_ids.append(uom_id)
|
|
|
|
# Set all UOMs to active
|
|
ids = self._execute('product.uom', 'search', ['|',('active','=',True),('active','=',False)])
|
|
res = self._execute('product.uom', 'write', ids, {'active': True})
|
|
if not res:
|
|
return False
|
|
|
|
# Set all other UOMs to inactive
|
|
inactive_ids = self._execute('product.uom', 'search', [('id','not in',active_ids)])
|
|
res = self._execute('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._execute('ir.model.data', 'xmlid_to_res_id', uom_xml_id)
|
|
res = self._execute('product.uom', 'write', [uom_id], {'name': name}, context)
|
|
if not res:
|
|
return False
|
|
return True
|
|
|
|
def set_steuerzuordnung(self):
|
|
"""Steuerzuordnungen setzen"""
|
|
|
|
c = self.config
|
|
|
|
# Ungültige Steuerzuordnungen auf inaktiv setzen
|
|
invalid_ids = self._execute('account.fiscal.position', 'search', [('name','not in',c.valid_fiscal_positions)])
|
|
self._execute('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._execute('account.fiscal.position', 'search', [('name','in',c.valid_fiscal_positions)])
|
|
valid_tax_ids = self._execute('account.tax', 'search', [('parent_id','=',False)])
|
|
|
|
position_tax_line_ids = self._execute('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._execute('account.fiscal.position.tax', 'write', position_tax_line_ids, vals)
|
|
|
|
def update_module(self):
|
|
"""Aktualisiere Modul"""
|
|
module_name = self.config.module_name
|
|
mod_ids = self._execute('ir.module.module', 'search', [('name','=',module_name),('state','=','installed')])
|
|
if not len(mod_ids) == 1:
|
|
raise "Module '%s' not found or ist not installed." % module_name
|
|
|
|
res = self._execute('ir.module.module', 'button_upgrade', mod_ids)
|
|
res = self._execute('base.module.upgrade', 'upgrade_module', [])
|
|
return True
|
|
|
|
def install_module(self):
|
|
"""Installiere Modul"""
|
|
module_name = self.config.module_name
|
|
mod_ids = self._execute('ir.module.module', 'search', [('name','=',module_name),('state','=','uninstalled')])
|
|
if not len(mod_ids) == 1:
|
|
raise "Module '%s' not found or is not in state 'uninstalled'." % module_name
|
|
|
|
res = self._execute('ir.module.module', 'button_install', mod_ids)
|
|
res = self._execute('base.module.upgrade', 'upgrade_module', [])
|
|
return True
|
|
|
|
def update_modules(self):
|
|
"""Verfügbare Module updaten"""
|
|
|
|
wizard_id = self._execute('base.module.update', 'create', {})
|
|
vals = self._execute('base.module.update', 'update_module', [wizard_id])
|
|
return True
|
|
|
|
def setup_journals(self):
|
|
"""Update journals"""
|
|
# Verkauf- und Gutschriftenjournal
|
|
j_ids = self._execute('account.journal', 'search', [('code','in',['VK','GSV','SAJ','SCNJ'])])
|
|
if len(j_ids) != 2:
|
|
return False
|
|
vals = {
|
|
'update_posted': self.config.allow_cancel_invoice
|
|
}
|
|
if not self._execute('account.journal', 'write', j_ids, vals):
|
|
return False
|
|
return True
|
|
|
|
def update_all(self):
|
|
"""Aktualisiere Modul"""
|
|
for module_name in self.config.modules:
|
|
mod_ids = self._execute('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)
|
|
res = self._execute('ir.module.module', 'button_upgrade', mod_ids)
|
|
|
|
res = self._execute('base.module.upgrade', 'upgrade_module', [])
|
|
return True
|
|
|
|
def set_warehouse(self):
|
|
"""Name des Zentrallagers setzen"""
|
|
|
|
is_installed = self._execute('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')
|
|
}
|
|
warehouse_ids = self._execute('stock.warehouse', 'search', [('id','=',1)])
|
|
return self._execute('stock.warehouse', 'write', warehouse_ids, vals)
|
|
else:
|
|
return True
|
|
|
|
def set_dmi_noupdate(self):
|
|
"""DMI: Einträge auf 'no update' setzen"""
|
|
|
|
domain = [('module','=','cam_dmi'),('noupdate','=',False)]
|
|
data_ids = self._execute('ir.model.data', 'search', domain)
|
|
|
|
vals = {'noupdate': True}
|
|
return self._execute('ir.model.data', 'write', data_ids, vals)
|
|
|
|
def dmi_confirm_inventory(self):
|
|
"""DMI: Lagerstand einbuchen"""
|
|
|
|
dummy,inventory_id = self._execute('ir.model.data', 'get_object_reference', 'cam_dmi','inv_init')
|
|
|
|
inventory = self._execute('stock.inventory', 'read', inventory_id, ['state'])
|
|
|
|
if inventory.get('state','') == 'confirm':
|
|
return self._execute('stock.inventory', 'action_done', [inventory_id])
|
|
|
|
return True
|
|
|
|
def set_decimal_price(self):
|
|
"""Dezimalstellen setzen"""
|
|
|
|
# UOM
|
|
decimal_id = self._execute('ir.model.data', 'xmlid_to_res_id', 'product.decimal_product_uom')
|
|
res = self._execute('decimal.precision', 'write', [decimal_id], {'digits': self.config.uom_decimals})
|
|
if not res:
|
|
return False
|
|
|
|
# Product Price
|
|
decimal_id = self._execute('ir.model.data', 'xmlid_to_res_id', 'product.decimal_price')
|
|
res = self._execute('decimal.precision', 'write', [decimal_id], {'digits': self.config.price_decimals})
|
|
if not res:
|
|
return False
|
|
|
|
# Product Price
|
|
ids = self._execute('decimal.precision', 'search', [('name','=','Product Price')])
|
|
res = self._execute('decimal.precision', 'write', ids, {'digits': self.config.price_decimals})
|
|
if not res:
|
|
return False
|
|
|
|
return True
|
|
|
|
def setup_mail_server(self):
|
|
"""Mailserver einrichten"""
|
|
|
|
if hasattr(self.config, 'mail_server'):
|
|
vals = self.config.mail_server
|
|
server_ids = self._execute('ir.mail_server', 'search', [('name','=',vals.get('name'))])
|
|
|
|
if server_ids:
|
|
return self._execute('ir.mail_server', 'write', server_ids, vals)
|
|
else:
|
|
return self._execute('ir.mail_server', 'create', vals)
|
|
return False
|
|
|
|
def stock_set_cost_method(self):
|
|
"""Kalkulationsverfahren für Lager setzen"""
|
|
|
|
if hasattr(self.config, 'stock_cost_method'):
|
|
method = self.config.stock_cost_method
|
|
self._execute('ir.values', 'set_default', 'product.template', 'cost_method', method)
|
|
return True
|
|
|
|
return True |