From b0dc2570d24726d471b74f795bcb1bae74ef22ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Br=C3=BCckl?= Date: Thu, 23 Nov 2017 18:11:23 +0100 Subject: [PATCH] multi-company setup --- setup/lib/__init__.py | 2 +- setup/lib/cli.py | 13 ++-- setup/lib/{config_at.py => config.py} | 93 +++------------------------ setup/lib/config_glaser.py | 81 +++++++++++++++++++++++ setup/lib/config_tza.py | 81 +++++++++++++++++++++++ setup/lib/environments.py | 10 ++- setup/lib/functions.py | 60 +++++++---------- 7 files changed, 210 insertions(+), 130 deletions(-) rename setup/lib/{config_at.py => config.py} (65%) create mode 100644 setup/lib/config_glaser.py create mode 100644 setup/lib/config_tza.py diff --git a/setup/lib/__init__.py b/setup/lib/__init__.py index 6354a6f1..1092d404 100644 --- a/setup/lib/__init__.py +++ b/setup/lib/__init__.py @@ -1,4 +1,4 @@ from . import cli -from . import config_at +from . import config from . import environments from . import functions diff --git a/setup/lib/cli.py b/setup/lib/cli.py index a5533353..dd1b11f3 100755 --- a/setup/lib/cli.py +++ b/setup/lib/cli.py @@ -3,7 +3,7 @@ import sys from urllib.parse import urlparse -from .config_at import Config +from .config import Config from .environments import ENVIRONMENTS, Environment from .functions import DatenpolFunctions @@ -31,7 +31,6 @@ def main(): sys.exit(3) argv = sys.argv[1:] - config = Config() if not argv: _usage() @@ -70,6 +69,10 @@ def main(): print('Unbekannte Umgebung') _usage() + if env.config: + config = env.config + else: + config = Config() instance = DatenpolFunctions(env, config) methods = None @@ -108,9 +111,9 @@ def main(): #'stock_set_cost_method', #'set_incoterms', 'set_company', - #'set_taxes', 'set_uom', - #'set_fiscal_position', + 'set_taxes', + 'set_fiscal_position', #'setup_journals', 'set_decimal_price', 'set_default_values', @@ -122,7 +125,7 @@ def main(): 'set_password_for_admin_users', 'set_sys_params', #'setup_reports', - 'consume_tours', + #'consume_tours', 'disable_planners', 'set_admin_rights', ] diff --git a/setup/lib/config_at.py b/setup/lib/config.py similarity index 65% rename from setup/lib/config_at.py rename to setup/lib/config.py index 03fd5eb4..d3c5b759 100644 --- a/setup/lib/config_at.py +++ b/setup/lib/config.py @@ -6,31 +6,11 @@ class Config(): self.module_name = None self.lang = 'de_DE' # de_DE, en_US - self.chart_of_accounts = 'l10n_at' - self.sales_tax = '20% MwSt' - self.purchase_tax = '20% VSt' - self.chart_template_id = 2 # Austrian Chart of Account + self.default_sales_tax = 'Mehrwertsteuer 20%' + self.default_supplier_tax = 'Vorsteuer 20%' self.price_decimals = 2 # Nachkommastellen Preis self.uom_decimals = 3 # Nachkommastellen Mengeneinheiten - self.company_data = { - 'name': 'TZ Tischlerzentrum GesmbH', - 'street': 'Neugasse 36', - 'street2': False, - 'city': 'Spannberg', - 'zip': '2244', - 'phone': '+43 2538/8628 – 0', - 'email': 'office@tzaustria.com', - 'website': 'https://www.tzaustria.com/', - 'company_registry': 'FN 224119m', - 'country_id': 'at', # 'de' für Deutschland - 'vat': 'ATU 54619104', - 'vat_check_vies': True, - 'logo': '../ext/custom-addons/dp_custom/static/src/img/logo.png', - #'favicon_backend': '../ext/custom-addons/dp_custom/static/src/img/favicon.ico', - #'favicon_backend_mimetype': 'image/x-icon' - } - self.mail_server = { 'name': 'test', 'sequence': 0, @@ -41,24 +21,12 @@ class Config(): 'smtp_pass': 'test', } - # Nur für Lager - # Wenn nicht gesetzt, dann wird der Firmenname genommen - self.warehouse_name = 'TZA' - self.warehouse_code = 'TZA' - # Anzahl der Schritte beim Ausliefern # [ship_only] Direkt vom Lager liefern # [pick_ship] Liefere vor Auslieferung zuerst in Versandlager (Pick + Ship) # [pick_pack_ship] Verpacken Sie die Produkte an einer Pack-Station bevor Sie den Versand vornehmen self.delivery_steps = 'ship_only' - self.valid_taxes = [ - '20% MwSt', - '10% MwSt', - '20% VSt', - '10% VSt', - ] - # Aktive Steuerzuordnungen self.valid_fiscal_positions = [ #'Lieferant EU (ohne Ust-ID)', @@ -86,7 +54,7 @@ class Config(): 'group_sale_delivery_address': True, # Verschiedene Adressen für Rechnung und Lieferung 'group_warning_sale': False, 'auto_done_setting': False, - 'module_delivery': False, + 'module_delivery': True, # Für Intrastat benötigt 'group_display_incoterm': True, 'module_sale_order_dates': False, 'group_route_so_lines': False, @@ -118,54 +86,6 @@ class Config(): self.removal_strategy = 'fifo' #[fifo], [lifo], [fefo] self.stock_cost_method = 'standard' # [standard], [average], [real] - self.sequences = { - 'sale.order': { - # 'number_next_actual': 1, - 'prefix': '%(y)s', - 'padding': 4, - 'use_date_range': True, - 'monthly_date_range': False - }, - 'account.invoice': { - # 'number_next_actual': 0001, - 'prefix': '%(y)s%(month)s', - 'padding': 4, - 'use_date_range': True, - 'monthly_date_range': False - }, - # Wenn 'account.invoice_refund' auskommentiert ist, dann wird - # für die Gutschrift der selbe Nummernkreis verwendet - 'account.invoice_refund': { - # 'number_next_actual': 0001, - 'name': 'Gutschriften', - 'implementation': 'no_gap', - 'prefix': '%(y)s', - 'padding': 4, - 'use_date_range': True, - 'monthly_date_range': False - }, - # 'picking.out': { - # # 'number_next_actual': 1, - # 'prefix': 'LS-', - # 'padding': 5, - # }, - # 'picking.in': { - # #'number_next_actual': 1, - # 'prefix': 'LS/IN/', - # 'padding': 4, - # }, - # 'picking.int': { - # #'number_next_actual': 1, - # 'prefix': 'LS/INT/', - # 'padding': 4, - # }, - # 'purchase.order': { - # 'number_next_actual': 1, - # 'prefix': 'B-', - # 'padding': 5, - # }, - } - self.active_uoms = { 'product.product_uom_unit': 'Stk.', 'product.product_uom_kgm': 'kg', @@ -198,7 +118,12 @@ class Config(): # 'dp_reports_stock', 'account_cancel', 'stock', - 'dp_changelogs' + 'dp_changelogs', + 'web_responsive', + 'web_environment_ribbon', + 'web_no_bubble', + 'report_intrastat', + ] # Setze das Feld "Attachment" im Report (wenn gesetzt wird das PDF in den Anhängen gespeichert) diff --git a/setup/lib/config_glaser.py b/setup/lib/config_glaser.py new file mode 100644 index 00000000..274229bf --- /dev/null +++ b/setup/lib/config_glaser.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +from .config import Config + +class ConfigGlaser(Config): + def __init__(self): + super(ConfigGlaser, self).__init__() + + self.company_xmlid = 'dp_custom.glaser_and_co_company' + + self.company_data = { + 'name': 'Glaser & Co.', + 'street': 'Neugasse 36', + 'street2': False, + 'city': 'Spannberg', + 'zip': '2244', + 'phone': '+43 2538/8628 – 0', + 'email': 'office@tzaustria.com', + 'website': 'https://www.glaser-co.at', + 'company_registry': 'FN 61793 y', + 'country_id': 'at', # 'de' für Deutschland + 'vat': 'ATU17860303', + 'vat_check_vies': True, + 'logo': '../ext/custom-addons/dp_custom/static/src/img/logo_glaser.png', + #'favicon_backend': '../ext/custom-addons/dp_custom/static/src/img/favicon.ico', + #'favicon_backend_mimetype': 'image/x-icon' + } + + # Nur für Lager + # Wenn nicht gesetzt, dann wird der Firmenname genommen + self.warehouse_name = 'Glaser' + self.warehouse_code = 'Glaser' + + self.sequences = { + 'sale.order': { + # 'number_next_actual': 1, + 'prefix': 'GL%(y)s', + 'padding': 4, + 'use_date_range': True, + 'monthly_date_range': False + }, + 'account.invoice': { + # 'number_next_actual': 0001, + 'prefix': 'GL%(y)s%(month)s', + 'padding': 4, + 'use_date_range': True, + 'monthly_date_range': False + }, + # Wenn 'account.invoice_refund' auskommentiert ist, dann wird + # für die Gutschrift der selbe Nummernkreis verwendet + 'account.invoice_refund': { + # 'number_next_actual': 0001, + 'name': 'Gutschriften', + 'implementation': 'no_gap', + 'prefix': 'GL%(y)s', + 'padding': 4, + 'use_date_range': True, + 'monthly_date_range': False + }, + # 'picking.out': { + # # 'number_next_actual': 1, + # 'prefix': 'LS-', + # 'padding': 5, + # }, + # 'picking.in': { + # #'number_next_actual': 1, + # 'prefix': 'LS/IN/', + # 'padding': 4, + # }, + # 'picking.int': { + # #'number_next_actual': 1, + # 'prefix': 'LS/INT/', + # 'padding': 4, + # }, + # 'purchase.order': { + # 'number_next_actual': 1, + # 'prefix': 'B-', + # 'padding': 5, + # }, + } + diff --git a/setup/lib/config_tza.py b/setup/lib/config_tza.py new file mode 100644 index 00000000..9e447cc1 --- /dev/null +++ b/setup/lib/config_tza.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +from .config import Config + +class ConfigTZA(Config): + def __init__(self): + super(ConfigTZA, self).__init__() + + self.company_xmlid = 'base.main_company' + + self.company_data = { + 'name': 'TZ Tischlerzentrum GesmbH', + 'street': 'Neugasse 36', + 'street2': False, + 'city': 'Spannberg', + 'zip': '2244', + 'phone': '+43 2538/8628 – 0', + 'email': 'office@tzaustria.com', + 'website': 'https://www.tzaustria.com/', + 'company_registry': 'FN 224119m', + 'country_id': 'at', # 'de' für Deutschland + 'vat': 'ATU 54619104', + 'vat_check_vies': True, + 'logo': '../ext/custom-addons/dp_custom/static/src/img/logo.png', + #'favicon_backend': '../ext/custom-addons/dp_custom/static/src/img/favicon.ico', + #'favicon_backend_mimetype': 'image/x-icon' + } + + # Nur für Lager + # Wenn nicht gesetzt, dann wird der Firmenname genommen + self.warehouse_name = 'TZA' + self.warehouse_code = 'TZA' + + self.sequences = { + 'sale.order': { + # 'number_next_actual': 1, + 'prefix': '%(y)s', + 'padding': 4, + 'use_date_range': True, + 'monthly_date_range': False + }, + 'account.invoice': { + # 'number_next_actual': 0001, + 'prefix': '%(y)s%(month)s', + 'padding': 4, + 'use_date_range': True, + 'monthly_date_range': False + }, + # Wenn 'account.invoice_refund' auskommentiert ist, dann wird + # für die Gutschrift der selbe Nummernkreis verwendet + 'account.invoice_refund': { + # 'number_next_actual': 0001, + 'name': 'Gutschriften', + 'implementation': 'no_gap', + 'prefix': '%(y)s', + 'padding': 4, + 'use_date_range': True, + 'monthly_date_range': False + }, + # 'picking.out': { + # # 'number_next_actual': 1, + # 'prefix': 'LS-', + # 'padding': 5, + # }, + # 'picking.in': { + # #'number_next_actual': 1, + # 'prefix': 'LS/IN/', + # 'padding': 4, + # }, + # 'picking.int': { + # #'number_next_actual': 1, + # 'prefix': 'LS/INT/', + # 'padding': 4, + # }, + # 'purchase.order': { + # 'number_next_actual': 1, + # 'prefix': 'B-', + # 'padding': 5, + # }, + } + diff --git a/setup/lib/environments.py b/setup/lib/environments.py index d1b688fe..b8b057b2 100644 --- a/setup/lib/environments.py +++ b/setup/lib/environments.py @@ -1,7 +1,10 @@ # -*- coding: utf-8 -*- +from .config_tza import ConfigTZA +from .config_glaser import ConfigGlaser + class Environment(): - def __init__(self, host, port, dbname, username, pwd=None, super_admin_pw=None, demo=False): + def __init__(self, host, port, dbname, username, pwd=None, super_admin_pw=None, demo=False, config=False): self.host = host self.port = port self.dbname = dbname @@ -12,6 +15,7 @@ class Environment(): self.pwd = pwd self.super_admin_pw = super_admin_pw self.demo = demo + self.config = config def __str__(self): return """============================== @@ -24,7 +28,9 @@ Port: %s ENVIRONMENTS = { # Local environments are listed with passwords - 'br': Environment('http://localhost', '8080', 'tz-austria_1', 'admin', 'x', 'admin'), + 'br': Environment('http://localhost', '8080', 'tz-austria_1', 'tz-admin', 'x', 'admin', config=ConfigTZA()), + 'br-glaser': Environment('http://localhost', '8080', 'tz-austria_1', 'glaser-admin', 'x', 'admin', config=ConfigTZA()), + 'aa': Environment('http://localhost', '8080', 'tz-austria_1', 'admin', 'x', 'admin'), 'oa': Environment('http://localhost', '8080', 'tz-austria_1', 'admin', 'x', 'admin'), diff --git a/setup/lib/functions.py b/setup/lib/functions.py index 285af674..d041138c 100644 --- a/setup/lib/functions.py +++ b/setup/lib/functions.py @@ -54,6 +54,7 @@ class DatenpolFunctions: """Login""" self.odoo.login(self.env.dbname, self.env.username, self.env.pwd) + self.company_id = self.odoo.env.user.company_id return True def set_default_settings(self): @@ -90,13 +91,21 @@ class DatenpolFunctions: vals['favicon_backend'] = self._readAndReturnFile(vals['favicon_backend'], encode='base64') vals['country_id'] = country_id - return self.odoo.env.ref('base.main_company').write(vals) + return self.odoo.env.ref(self.config.company_xmlid).write(vals) def set_taxes(self): - """Setze nicht benötigte Steuern auf inaktiv""" + """Setze Standard-Steuersätze""" - 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}) + c = self.config + # Standard Sales Tax + sales_tax_ids = self.odoo.env['account.tax'].search( + [('name', '=', c.default_sales_tax)]) + self.odoo.env['ir.default'].set('product.template', 'taxes_id', sales_tax_ids, company_id=self.company_id.id) + # Standard Purchase Tax + supplier_tax_ids = self.odoo.env['account.tax'].search( + [('name', '=', c.default_supplier_tax)]) + self.odoo.env['ir.default'].set('product.template', 'supplier_taxes_id', supplier_tax_ids, company_id=self.company_id.id) + return True def set_incoterms(self): """Lieferbedingungen setzen""" @@ -134,8 +143,7 @@ class DatenpolFunctions: 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) + self.odoo.env['ir.module.module'].button_immediate_install(mod_ids) return True def _set_picking_sequence_prefix(self, code, value): @@ -230,7 +238,7 @@ class DatenpolFunctions: """Setze Administrator Rechte""" groups = [] - user_id = self.odoo.env.ref('base.user_root').id + user_id = self.odoo.env._uid # Technische Eigenschaften groups.append((4, self.odoo.env.ref('base.group_no_one').id)) @@ -244,31 +252,6 @@ class DatenpolFunctions: } 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""" @@ -314,13 +297,14 @@ class DatenpolFunctions: # 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)]) + #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) +# 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) + return True def update_module(self): """Aktualisiere Modul"""