# Table of Contents 1. [Configuración Etrivial de Tryton](#org3225ee4) 1. [Contexto](#org7f56056) 1. [imports necesarios](#orgaad26ae) 2. [datos de la empresa](#orgff293ae) 3. [Parametros de la configuración del Tryton](#org1e89720) 2. [Funciones](#orgfa74ab7) 3. [Main](#orge7c1f97) 4. [Manejo de argumentos](#org14b13c7) 5. [Script completo](#org60739d5) # Configuración Etrivial de Tryton Si se desea se puede agregar la información de la empresa en un archivo **empresa.py** junto a este script el cual debe contener una variable EMPRESA con los datos de la empresa. ## Contexto ### imports necesarios #!/usr/bin/env python import os import sys from decimal import Decimal from argparse import ArgumentParser from datetime import date, timedelta from dateutil.relativedelta import relativedelta try: from proteus import Model, config, Wizard from proteus.config import get_config from trytond.transaction import Transaction except ImportError: prog = os.path.basename(sys.argv[0]) sys.exit("proteus must be installed to use %s" % prog) ### datos de la empresa Importar informacion de la empresa de un archivo py try: from configuracion import EMPRESA except ImportError: EMPRESA = { 'nombre': "Nombre Empresa", 'telefonos': ['0000000'], 'celulares': ['0000000000'], 'identificador': '', 'calle': '', 'zona horaria': "America/Bogota", 'listas de precios': ['lista1', 'lista2'], 'tercero mostrador': 'Mostrador', 'moneda': 'COP' } ### Parametros de la configuración del Tryton 1. Módulos a activar MODULOS_NECESARIOS = set([ 'currency', 'country', 'party', 'company', 'account', 'trytonpsk_account_co_pyme', 'product', 'sale', 'purchase', 'sale_shop', 'sale_payment', 'sale_pos', 'account_stock_continental', 'one_click_for_sale', 'one_click_for_purchase', 'account_invoice_expenses', 'sale_payment_form', 'sale_w_tax', 'sale_pos_extras' ]) 2. Cuentas requeridas en la configuracion CUENTA_CAJA = "110505" CUENTA_BANCO = "11100501" CUENTA_A_COBRAR = "130505" CUENTA_A_PAGAR = "220505" CUENTA_COMPRAS_PADRE = "6135" CUENTA_COMPRAS = "613520" CUENTA_COMPRAS_NOMBRE = "Venta de productos en almacenes no especializados".upper() TIPO_CUENTA_COMPRAS = 'COSTO DE VENTAS Y OPERACIÓN' CUENTA_INGRESOS = "413520" CUENTA_PADRE_EXISTENCIAS = "1435" TIPO_PADRE_EXISTENCIAS = "UTILIDAD ANTES DE IMPUESTOS" CUENTA_EXISTENCIA = "143501" CUENTA_EXISTENCIA_COMPRAS = "143502" CUENTA_EXISTENCIA_COMPRAS_NOMBRE = "EXISTENCIAS COMPRAS" TIPO_CUENTA_EXISTENCIA_COMPRAS = "EXISTENCIAS COMPRAS" CUENTA_EXISTENCIA_VENTAS = "143503" CUENTA_EXISTENCIA_VENTAS_NOMBRE = "EXISTENCIAS VENTAS" TIPO_CUENTA_EXISTENCIA_VENTAS = "EXISTENCIAS VENTAS" CUENTA_EXISTENCIA_PERDIDO_NOMBRE = "EXISTENCIAS PERDIDO ENCONTRADO" CUENTA_EXISTENCIA_PERDIDO = "143504" TIPO_CUENTA_EXISTENCIA_PERDIDO = "EXISTENCIAS PERDIDO ENCONTRADO" CUENTA_PATRIMONIO_FACTURA_INICIAL = "311505" 3. Categorías contables CATEGORIA_CONTABLE_PRODUCTOS = "CACHARRO" CATEGORIA_CONTABLE_GASTOS = "GASTOS" 4. Preferencias de Empresa TIME_ZONE = EMPRESA.get('zona horaria', "America/Bogota") CURRENCY = EMPRESA.get('moneda', "COP") 5. Lista de precios LISTAS_PRECIOS = EMPRESA.get('listas de precios', []) 6. Tercero Genérico NOMBRE_TERCERO_MOSTRADOR = EMPRESA.get('tercero mostrador', 'Mostrador') 7. Ajuste de unidades de productos CIFRAS_KILOGRAMO = 4 ## Funciones Se deben de pasar a un archivo(modulo python) aparte y ser importadas en este script. También sería útil documentarlas. def get_cuenta_gastos(codigo, tipo): Cuenta = Model.get('account.account') CuentaTipo = Model.get('account.account.type') tipo_gasto, = CuentaTipo.find([('name', '=', tipo)]) cuenta, = Cuenta.find([('code', '=', codigo)]) cuenta.template_override = True cuenta.type = tipo_gasto cuenta.save() return cuenta def crear_tipo_cuenta(nombre, statement, nombre_padre, empresa=None, existencia=False, ingreso=False, gasto=False, asiento=False): CuentaTipo = Model.get('account.account.type') padre, = CuentaTipo.find([('name', '=', nombre_padre)]) cuentatipo = CuentaTipo(name=nombre, statement=statement, parent=padre, stock=existencia, revenue=ingreso, expense=gasto, assets=asiento) cuentatipo.save() return cuentatipo def crear_cuenta(nombre, codigo, tipo, padre, company, activa=True, cerrada=False, en_balance=True, reconcile=False): Cuenta = Model.get('account.account') parent, = Cuenta.find([('code', '=', padre)]) cuenta = Cuenta(name=nombre, code=codigo, type=tipo, active=activa, closed=cerrada, reconcile=reconcile, parent=parent, general_ledger_balance=en_balance) cuenta.save() return cuenta def activate_modules(modules): if isinstance(modules, str): modules = [modules] Module = Model.get('ir.module') records = Module.find([ ('name', 'in', modules), ]) assert len(records) == len(modules), f"faltan los modulos {set(modules).difference(set(r.name for r in records))}" Module.click(records, 'activate') Wizard('ir.module.activate_upgrade').execute('upgrade') def get_company(config=None): "Return the only company" Company = Model.get('company.company', config=config) company, = Company.find() return company def create_party(nombre, telefonos=None, celulares=None, identificador=None, calle=""): Party = Model.get('party.party') party = Party(name=nombre) if identificador: _ = party.identifiers.new(code=identificador) if telefonos: for tel in telefonos: _ = party.contact_mechanisms.new(type='phone', value=tel) if celulares: for celular in celulares: _ = party.contact_mechanisms.new(type='mobile', value=celular) party.save() if calle: adress, = party.addresses adress.street = calle adress.save() return party def create_company(party, currency, timezone=None, config=None): "Create the company using the proteus config" Party = Model.get('party.party', config=config) User = Model.get('res.user', config=config) company_config = Wizard('company.company.config') company_config.execute('company') company = company_config.form if not party: party = Party(name='Dunder Mifflin') party.save() company.party = party company.currency = currency company_config.execute('add') if not config: config = get_config() config._context = User.get_preferences(True, {}) return company_config def create_fiscalyear(company=None, today=None, config=None): "Create a fiscal year for the company on today" FiscalYear = Model.get('account.fiscalyear', config=config) Sequence = Model.get('ir.sequence', config=config) if not company: company = get_company() if not today: today = date.today() fiscalyear = FiscalYear(name=str(today.year)) fiscalyear.start_date = today + relativedelta(month=1, day=1) fiscalyear.end_date = today + relativedelta(month=12, day=31) fiscalyear.company = company post_move_sequence = Sequence( name=f"Asiento contabilizado {str(today.year)}", code='account.move', company=company) post_move_sequence.save() fiscalyear.post_move_sequence = post_move_sequence fiscalyear.account_stock_method = 'continental' return fiscalyear def create_chart( company=None, chart='account.account_template_root_en', config=None): "Create chart of accounts" AccountTemplate = Model.get('account.account.template', config=config) CuentaTipo = Model.get('account.account.type') ModelData = Model.get('ir.model.data') if not company: company = get_company() module, xml_id = chart.split('.') data, = ModelData.find([ ('module', '=', module), ('fs_id', '=', xml_id), ], limit=1) account_template = AccountTemplate(data.db_id) create_chart = Wizard('account.create_chart') create_chart.execute('account') create_chart.form.account_template = account_template create_chart.form.company = company create_chart.execute('create_account') Account = Model.get('account.account') receivable, = Account.find([('company', '=', company.id), ('code', '=', CUENTA_A_COBRAR)]) payable, = Account.find([('company', '=', company.id), ('code', '=', CUENTA_A_PAGAR)]) tipo_cuenta_compra, = CuentaTipo.find([('name', '=', TIPO_CUENTA_COMPRAS)]) cuenta_compras = crear_cuenta( CUENTA_COMPRAS_NOMBRE, CUENTA_COMPRAS, tipo_cuenta_compra, CUENTA_COMPRAS_PADRE, company, en_balance=True ) expense = cuenta_compras revenue, = Account.find([('company', '=', company.id), ('code', '=', CUENTA_INGRESOS)]) create_chart.form.account_receivable = receivable create_chart.form.account_payable = payable create_chart.form.category_account_expense = expense create_chart.form.category_account_revenue = revenue create_chart.execute('create_properties') return create_chart def set_fiscalyear_invoice_sequences(fiscalyear, config=None): "Set invoice sequences to fiscalyear" SequenceStrict = Model.get('ir.sequence.strict', config=config) in_invoice_seq = SequenceStrict( name=f"Factura Proveedor {fiscalyear.name}", code='account.invoice', company=fiscalyear.company) in_invoice_seq.save() in_credit_note_seq = SequenceStrict( name=f"Abono Proveedor {fiscalyear.name}", code='account.invoice', company=fiscalyear.company) in_credit_note_seq.save() out_invoice_seq = SequenceStrict( name=f"Factura Cliente {fiscalyear.name}", code='account.invoice', company=fiscalyear.company) out_invoice_seq.save() out_credit_note_seq = SequenceStrict( name=f"Abono Cliente {fiscalyear.name}", code='account.invoice', company=fiscalyear.company) out_credit_note_seq.save() seq, = fiscalyear.invoice_sequences seq.out_invoice_sequence = out_invoice_seq seq.in_invoice_sequence = in_invoice_seq seq.out_credit_note_sequence = out_credit_note_seq seq.in_credit_note_sequence = in_credit_note_seq return fiscalyear def crear_categoria_contable_producto( nombre, cuenta_gastos, cuenta_ingresos, cuenta_existencia, cuenta_existencia_cliente, cuenta_existencia_proveedor, cuenta_existencia_perdido_encontrado): CategoriaContable = Model.get('product.category') Account = Model.get('account.account') categoria_contable = CategoriaContable( name=nombre) categoria_contable.accounting = True categoria_contable.account_expense = cuenta_gastos categoria_contable.account_revenue = cuenta_ingresos categoria_contable.account_stock = cuenta_existencia categoria_contable.account_stock_lost_found = cuenta_existencia_perdido_encontrado categoria_contable.account_stock_customer = cuenta_existencia_cliente categoria_contable.account_stock_supplier = cuenta_existencia_proveedor categoria_contable.save() return categoria_contable def verificar_modulos_necesarios(): pass def instalar_modulos_necesarios(): pass def configurar_modulos(): pass ## Main def main(database, config_file=None): """ para correr desde ipyhton ejecutar: database = 'auto' config_file = '/home/yoloarreglo/trytond.conf' """ config.set_trytond(database, config_file=config_file) #activar modulos activate_modules(MODULOS_NECESARIOS) Party = Model.get('party.party') Account = Model.get('account.account') Currency = Model.get('currency.currency') CuentaTipo = Model.get('account.account.type') ListaPrecio = Model.get('product.price_list') Uom = Model.get('product.uom') Journal = Model.get('account.journal') PaymentMethod = Model.get('account.invoice.payment.method') Sequence = Model.get('ir.sequence') Tienda = Model.get('sale.shop') Almacen = Model.get('stock.location') Usuario = Model.get('res.user') today = date.today() start_date = today + relativedelta(month=1, day=1) end_date = today + relativedelta(month=12, day=31) # crear tercero de empresa party = create_party(EMPRESA['nombre'], EMPRESA['telefonos'], EMPRESA['celulares'], EMPRESA['identificador'], EMPRESA['calle']) # Moneda para empresa currency, = Currency.find([('code', '=', CURRENCY)]) # agregar cambio a moneda para reportes de ventas currency.rates.new(date=start_date - timedelta(days=1), rate=Decimal(1.00)) currency.save() # Configurar Empresa _ = create_company(party, currency) company = get_company() # Agregar zona horaria a empresa company.timezone = TIME_ZONE company.save() # Crear año Fiscal fiscalyear = set_fiscalyear_invoice_sequences( create_fiscalyear(company)) fiscalyear.click('create_period') # Crear plan de cuentas chart = create_chart(chart='trytonpsk_account_co_pyme.pc') # desactivar tercero requerido para cuenta caja general cuenta_caja, = Account.find([('code', '=', CUENTA_CAJA)]) cuenta_caja.template_override = True cuenta_caja.party_required = False cuenta_caja.save() # desactivar tercero requerido para cuenta existencias cuenta_existencia, = Account.find([('company', '=', company.id), ('code', '=', CUENTA_EXISTENCIA)]) cuenta_existencia.template_override = True cuenta_existencia.party_required = False cuenta_existencia.save() cuenta_compras, = Account.find([('code', '=', CUENTA_COMPRAS)]) # Ajustar kilo kilogram, = Uom.find([('name', 'in', ('Kilogram', 'Kilogramo'))]) kilogram.digits = CIFRAS_KILOGRAMO kilogram.rounding = 1.0 / (10 ** CIFRAS_KILOGRAMO) kilogram.save() # crear cuentas para inventario # tipo_existencia, = CuentaTipo.find( # [('name', '=', 'INVENTARIOS')]) tipo_existencia_perdido = crear_tipo_cuenta( nombre=TIPO_CUENTA_EXISTENCIA_PERDIDO, statement='income', nombre_padre=TIPO_PADRE_EXISTENCIAS, empresa=company, existencia=True) tipo_existencia_compra = crear_tipo_cuenta( nombre=TIPO_CUENTA_EXISTENCIA_COMPRAS, statement='income', nombre_padre=TIPO_PADRE_EXISTENCIAS, empresa=company, existencia=True) tipo_existencia_venta = crear_tipo_cuenta( nombre=TIPO_CUENTA_EXISTENCIA_VENTAS, statement='income', nombre_padre=TIPO_PADRE_EXISTENCIAS, empresa=company, existencia=True) cuenta_existencia_perdido = crear_cuenta( CUENTA_EXISTENCIA_PERDIDO_NOMBRE, CUENTA_EXISTENCIA_PERDIDO, tipo_existencia_perdido, CUENTA_PADRE_EXISTENCIAS, company, en_balance=True ) cuenta_existencia_venta = crear_cuenta( CUENTA_EXISTENCIA_VENTAS_NOMBRE, CUENTA_EXISTENCIA_VENTAS, tipo_existencia_venta, CUENTA_PADRE_EXISTENCIAS, company, en_balance=True ) cuenta_existencia_compra = crear_cuenta( CUENTA_EXISTENCIA_COMPRAS_NOMBRE, CUENTA_EXISTENCIA_COMPRAS, tipo_existencia_compra, CUENTA_PADRE_EXISTENCIAS, company, en_balance=True ) # crear categoria contable para producto categoria_contable_producto = crear_categoria_contable_producto( CATEGORIA_CONTABLE_PRODUCTOS, cuenta_compras, chart.form.category_account_revenue, cuenta_existencia, cuenta_existencia_venta, cuenta_existencia_compra, cuenta_existencia_perdido) # crear listas precios for lista in LISTAS_PRECIOS: ListaPrecio(name=lista).save() # crear Metodos de pago Efectivo journal_cash, = Journal.find([('type', '=', 'cash')]) payment_method = PaymentMethod() payment_method.name = 'Efectivo' payment_method.journal = journal_cash payment_method.credit_account = cuenta_caja payment_method.debit_account = cuenta_caja payment_method.save() # crear Metodos de pago Factura inicial cuenta_pago_patrimonio, = Account.find( [('code', '=', CUENTA_PATRIMONIO_FACTURA_INICIAL)]) journal_cash, = Journal.find([('type', '=', 'cash')]) payment_method = PaymentMethod() payment_method.name = 'Factura Inicial' payment_method.journal = journal_cash #@todo verificar si es este diario payment_method.credit_account = cuenta_pago_patrimonio payment_method.debit_account = cuenta_pago_patrimonio payment_method.save() # configurar almacen almacen, = Almacen.find([('name', 'in', ('Warehouse', 'Almacén'))]) almacen.input_location = almacen.storage_location almacen.output_location = almacen.storage_location almacen.save() # configurar tienda mostrador = Party(name=NOMBRE_TERCERO_MOSTRADOR) mostrador.save() admin, = Usuario.find([('login', '=', 'admin')]) tienda = Tienda(name="Principal", company=company, warehouse=almacen) tienda.users.append(admin) tienda.party = mostrador tienda.self_pick_up = True tienda.save() # secuencias necesarias Sequence = Model.get('ir.sequence') secuencia_libro_ingresos, = Sequence.find([('name', '=', 'Libro Ingresos')]) secuencia_libro_bancos, = Sequence.find([('name', '=', 'Libro Bancos')]) secuencia_de_compra, = Sequence.find([('name', '=', 'Purchase')]) # crear diarios tipo registros para diarios de pagos journal_pago_efectivo = Journal( name='Efectivo PTV', code='EPTV', active=True, type='statement', sequence=secuencia_libro_bancos) journal_pago_efectivo.save() journal_pago_banco = Journal( name='Banco PTV', code='BPTV', active=True, type='statement', sequence=secuencia_libro_bancos) journal_pago_banco.save() # cuenta banco cuenta_banco, = Account.find([('code', '=', CUENTA_BANCO)]) cuenta_banco.template_override = True cuenta_banco.party_required = False cuenta_banco.save() #crear diarios de pagos StatementJournal = Model.get('account.statement.journal') diario_de_pago_efectivo = StatementJournal( name="Efectivo", journal=journal_pago_efectivo, account=cuenta_caja, validation='balance') diario_de_pago_efectivo.save() diario_de_pago_banco = StatementJournal( name="Banco", journal=journal_pago_banco, account=cuenta_banco, validation='balance') diario_de_pago_banco.save() #configurar ptv Device = Model.get('sale.device') device = Device(name='Principal') device.change_unit_price = True # error cuando agrega la tienda por primera vez try: device.shop = tienda except: pass device.shop = tienda device.journals.extend([diario_de_pago_banco, diario_de_pago_efectivo]) device.journal = diario_de_pago_efectivo device.save() #configurar ptv a usuario administrador admin.shop = tienda admin.sale_device = device #ajustar idioma español al administrador Lang = Model.get('ir.lang') es, = Lang.find([('code', '=', 'es')]) admin.language = es admin.save() # configurando destino de compras por defecto ConfPurchase = Model.get('purchase.configuration') conf_compra = ConfPurchase(1) conf_compra.purchase_sequence = secuencia_de_compra conf_compra.one_click_to_location = almacen.storage_location conf_compra.save() # configurando metodo de coste por defecto de productos ProductConf = Model.get('product.configuration') conf_producto = ProductConf(1) conf_producto.default_cost_price_method = 'average' conf_producto.save() ## Manejo de argumentos def run(): print("#################################") print("Recuerde Iniciar la base de datos") print("createdb base_datos") print("trytond-admin -c trytond.conf --all -d base_datos -l es") print("trytond-admin -c trytond.conf -d base_datos -u country") print("python enlace_a_modules/country/scripts/import_countries.py -c trytond.conf -d base_datos") print("trytond-admin -c trytond.conf -d auto -u currency") print("python enlace_a_modules/currency/scripts/import_currencies.py -c trytond.conf -d base_datos") print("#################################") parser = ArgumentParser() parser.add_argument('-d', '--database', dest='database') parser.add_argument('-c', '--config', dest='config_file', help='the trytond config file') args = parser.parse_args() if not args.database: parser.error('Missing database') main(args.database, args.config_file) if __name__ == '__main__': run() ## Script completo #!/usr/bin/env python import os import sys from decimal import Decimal from argparse import ArgumentParser from datetime import date, timedelta from dateutil.relativedelta import relativedelta try: from proteus import Model, config, Wizard from proteus.config import get_config from trytond.transaction import Transaction except ImportError: prog = os.path.basename(sys.argv[0]) sys.exit("proteus must be installed to use %s" % prog) try: from configuracion import EMPRESA except ImportError: EMPRESA = { 'nombre': "Nombre Empresa", 'telefonos': ['0000000'], 'celulares': ['0000000000'], 'identificador': '', 'calle': '', 'zona horaria': "America/Bogota", 'listas de precios': ['lista1', 'lista2'], 'tercero mostrador': 'Mostrador', 'moneda': 'COP' } MODULOS_NECESARIOS = set([ 'currency', 'country', 'party', 'company', 'account', 'trytonpsk_account_co_pyme', 'product', 'sale', 'purchase', 'sale_shop', 'sale_payment', 'sale_pos', 'account_stock_continental', 'one_click_for_sale', 'one_click_for_purchase', 'account_invoice_expenses', 'sale_payment_form', 'sale_w_tax', 'sale_pos_extras' ]) CUENTA_CAJA = "110505" CUENTA_BANCO = "11100501" CUENTA_A_COBRAR = "130505" CUENTA_A_PAGAR = "220505" CUENTA_COMPRAS_PADRE = "6135" CUENTA_COMPRAS = "613520" CUENTA_COMPRAS_NOMBRE = "Venta de productos en almacenes no especializados".upper() TIPO_CUENTA_COMPRAS = 'COSTO DE VENTAS Y OPERACIÓN' CUENTA_INGRESOS = "413520" CUENTA_PADRE_EXISTENCIAS = "1435" TIPO_PADRE_EXISTENCIAS = "UTILIDAD ANTES DE IMPUESTOS" CUENTA_EXISTENCIA = "143501" CUENTA_EXISTENCIA_COMPRAS = "143502" CUENTA_EXISTENCIA_COMPRAS_NOMBRE = "EXISTENCIAS COMPRAS" TIPO_CUENTA_EXISTENCIA_COMPRAS = "EXISTENCIAS COMPRAS" CUENTA_EXISTENCIA_VENTAS = "143503" CUENTA_EXISTENCIA_VENTAS_NOMBRE = "EXISTENCIAS VENTAS" TIPO_CUENTA_EXISTENCIA_VENTAS = "EXISTENCIAS VENTAS" CUENTA_EXISTENCIA_PERDIDO_NOMBRE = "EXISTENCIAS PERDIDO ENCONTRADO" CUENTA_EXISTENCIA_PERDIDO = "143504" TIPO_CUENTA_EXISTENCIA_PERDIDO = "EXISTENCIAS PERDIDO ENCONTRADO" CUENTA_PATRIMONIO_FACTURA_INICIAL = "311505" CATEGORIA_CONTABLE_PRODUCTOS = "CACHARRO" CATEGORIA_CONTABLE_GASTOS = "GASTOS" TIME_ZONE = EMPRESA.get('zona horaria', "America/Bogota") CURRENCY = EMPRESA.get('moneda', "COP") LISTAS_PRECIOS = EMPRESA.get('listas de precios', []) NOMBRE_TERCERO_MOSTRADOR = EMPRESA.get('tercero mostrador', 'Mostrador') CIFRAS_KILOGRAMO = 4 def get_cuenta_gastos(codigo, tipo): Cuenta = Model.get('account.account') CuentaTipo = Model.get('account.account.type') tipo_gasto, = CuentaTipo.find([('name', '=', tipo)]) cuenta, = Cuenta.find([('code', '=', codigo)]) cuenta.template_override = True cuenta.type = tipo_gasto cuenta.save() return cuenta def crear_tipo_cuenta(nombre, statement, nombre_padre, empresa=None, existencia=False, ingreso=False, gasto=False, asiento=False): CuentaTipo = Model.get('account.account.type') padre, = CuentaTipo.find([('name', '=', nombre_padre)]) cuentatipo = CuentaTipo(name=nombre, statement=statement, parent=padre, stock=existencia, revenue=ingreso, expense=gasto, assets=asiento) cuentatipo.save() return cuentatipo def crear_cuenta(nombre, codigo, tipo, padre, company, activa=True, cerrada=False, en_balance=True, reconcile=False): Cuenta = Model.get('account.account') parent, = Cuenta.find([('code', '=', padre)]) cuenta = Cuenta(name=nombre, code=codigo, type=tipo, active=activa, closed=cerrada, reconcile=reconcile, parent=parent, general_ledger_balance=en_balance) cuenta.save() return cuenta def activate_modules(modules): if isinstance(modules, str): modules = [modules] Module = Model.get('ir.module') records = Module.find([ ('name', 'in', modules), ]) assert len(records) == len(modules), f"faltan los modulos {set(modules).difference(set(r.name for r in records))}" Module.click(records, 'activate') Wizard('ir.module.activate_upgrade').execute('upgrade') def get_company(config=None): "Return the only company" Company = Model.get('company.company', config=config) company, = Company.find() return company def create_party(nombre, telefonos=None, celulares=None, identificador=None, calle=""): Party = Model.get('party.party') party = Party(name=nombre) if identificador: _ = party.identifiers.new(code=identificador) if telefonos: for tel in telefonos: _ = party.contact_mechanisms.new(type='phone', value=tel) if celulares: for celular in celulares: _ = party.contact_mechanisms.new(type='mobile', value=celular) party.save() if calle: adress, = party.addresses adress.street = calle adress.save() return party def create_company(party, currency, timezone=None, config=None): "Create the company using the proteus config" Party = Model.get('party.party', config=config) User = Model.get('res.user', config=config) company_config = Wizard('company.company.config') company_config.execute('company') company = company_config.form if not party: party = Party(name='Dunder Mifflin') party.save() company.party = party company.currency = currency company_config.execute('add') if not config: config = get_config() config._context = User.get_preferences(True, {}) return company_config def create_fiscalyear(company=None, today=None, config=None): "Create a fiscal year for the company on today" FiscalYear = Model.get('account.fiscalyear', config=config) Sequence = Model.get('ir.sequence', config=config) if not company: company = get_company() if not today: today = date.today() fiscalyear = FiscalYear(name=str(today.year)) fiscalyear.start_date = today + relativedelta(month=1, day=1) fiscalyear.end_date = today + relativedelta(month=12, day=31) fiscalyear.company = company post_move_sequence = Sequence( name=f"Asiento contabilizado {str(today.year)}", code='account.move', company=company) post_move_sequence.save() fiscalyear.post_move_sequence = post_move_sequence fiscalyear.account_stock_method = 'continental' return fiscalyear def create_chart( company=None, chart='account.account_template_root_en', config=None): "Create chart of accounts" AccountTemplate = Model.get('account.account.template', config=config) CuentaTipo = Model.get('account.account.type') ModelData = Model.get('ir.model.data') if not company: company = get_company() module, xml_id = chart.split('.') data, = ModelData.find([ ('module', '=', module), ('fs_id', '=', xml_id), ], limit=1) account_template = AccountTemplate(data.db_id) create_chart = Wizard('account.create_chart') create_chart.execute('account') create_chart.form.account_template = account_template create_chart.form.company = company create_chart.execute('create_account') Account = Model.get('account.account') receivable, = Account.find([('company', '=', company.id), ('code', '=', CUENTA_A_COBRAR)]) payable, = Account.find([('company', '=', company.id), ('code', '=', CUENTA_A_PAGAR)]) tipo_cuenta_compra, = CuentaTipo.find([('name', '=', TIPO_CUENTA_COMPRAS)]) cuenta_compras = crear_cuenta( CUENTA_COMPRAS_NOMBRE, CUENTA_COMPRAS, tipo_cuenta_compra, CUENTA_COMPRAS_PADRE, company, en_balance=True ) expense = cuenta_compras revenue, = Account.find([('company', '=', company.id), ('code', '=', CUENTA_INGRESOS)]) create_chart.form.account_receivable = receivable create_chart.form.account_payable = payable create_chart.form.category_account_expense = expense create_chart.form.category_account_revenue = revenue create_chart.execute('create_properties') return create_chart def set_fiscalyear_invoice_sequences(fiscalyear, config=None): "Set invoice sequences to fiscalyear" SequenceStrict = Model.get('ir.sequence.strict', config=config) in_invoice_seq = SequenceStrict( name=f"Factura Proveedor {fiscalyear.name}", code='account.invoice', company=fiscalyear.company) in_invoice_seq.save() in_credit_note_seq = SequenceStrict( name=f"Abono Proveedor {fiscalyear.name}", code='account.invoice', company=fiscalyear.company) in_credit_note_seq.save() out_invoice_seq = SequenceStrict( name=f"Factura Cliente {fiscalyear.name}", code='account.invoice', company=fiscalyear.company) out_invoice_seq.save() out_credit_note_seq = SequenceStrict( name=f"Abono Cliente {fiscalyear.name}", code='account.invoice', company=fiscalyear.company) out_credit_note_seq.save() seq, = fiscalyear.invoice_sequences seq.out_invoice_sequence = out_invoice_seq seq.in_invoice_sequence = in_invoice_seq seq.out_credit_note_sequence = out_credit_note_seq seq.in_credit_note_sequence = in_credit_note_seq return fiscalyear def crear_categoria_contable_producto( nombre, cuenta_gastos, cuenta_ingresos, cuenta_existencia, cuenta_existencia_cliente, cuenta_existencia_proveedor, cuenta_existencia_perdido_encontrado): CategoriaContable = Model.get('product.category') Account = Model.get('account.account') categoria_contable = CategoriaContable( name=nombre) categoria_contable.accounting = True categoria_contable.account_expense = cuenta_gastos categoria_contable.account_revenue = cuenta_ingresos categoria_contable.account_stock = cuenta_existencia categoria_contable.account_stock_lost_found = cuenta_existencia_perdido_encontrado categoria_contable.account_stock_customer = cuenta_existencia_cliente categoria_contable.account_stock_supplier = cuenta_existencia_proveedor categoria_contable.save() return categoria_contable def verificar_modulos_necesarios(): pass def instalar_modulos_necesarios(): pass def configurar_modulos(): pass def main(database, config_file=None): """ para correr desde ipyhton ejecutar: database = 'auto' config_file = '/home/yoloarreglo/trytond.conf' """ config.set_trytond(database, config_file=config_file) #activar modulos activate_modules(MODULOS_NECESARIOS) Party = Model.get('party.party') Account = Model.get('account.account') Currency = Model.get('currency.currency') CuentaTipo = Model.get('account.account.type') ListaPrecio = Model.get('product.price_list') Uom = Model.get('product.uom') Journal = Model.get('account.journal') PaymentMethod = Model.get('account.invoice.payment.method') Sequence = Model.get('ir.sequence') Tienda = Model.get('sale.shop') Almacen = Model.get('stock.location') Usuario = Model.get('res.user') today = date.today() start_date = today + relativedelta(month=1, day=1) end_date = today + relativedelta(month=12, day=31) # crear tercero de empresa party = create_party(EMPRESA['nombre'], EMPRESA['telefonos'], EMPRESA['celulares'], EMPRESA['identificador'], EMPRESA['calle']) # Moneda para empresa currency, = Currency.find([('code', '=', CURRENCY)]) # agregar cambio a moneda para reportes de ventas currency.rates.new(date=start_date - timedelta(days=1), rate=Decimal(1.00)) currency.save() # Configurar Empresa _ = create_company(party, currency) company = get_company() # Agregar zona horaria a empresa company.timezone = TIME_ZONE company.save() # Crear año Fiscal fiscalyear = set_fiscalyear_invoice_sequences( create_fiscalyear(company)) fiscalyear.click('create_period') # Crear plan de cuentas chart = create_chart(chart='trytonpsk_account_co_pyme.pc') # desactivar tercero requerido para cuenta caja general cuenta_caja, = Account.find([('code', '=', CUENTA_CAJA)]) cuenta_caja.template_override = True cuenta_caja.party_required = False cuenta_caja.save() # desactivar tercero requerido para cuenta existencias cuenta_existencia, = Account.find([('company', '=', company.id), ('code', '=', CUENTA_EXISTENCIA)]) cuenta_existencia.template_override = True cuenta_existencia.party_required = False cuenta_existencia.save() cuenta_compras, = Account.find([('code', '=', CUENTA_COMPRAS)]) # Ajustar kilo kilogram, = Uom.find([('name', 'in', ('Kilogram', 'Kilogramo'))]) kilogram.digits = CIFRAS_KILOGRAMO kilogram.rounding = 1.0 / (10 ** CIFRAS_KILOGRAMO) kilogram.save() # crear cuentas para inventario # tipo_existencia, = CuentaTipo.find( # [('name', '=', 'INVENTARIOS')]) tipo_existencia_perdido = crear_tipo_cuenta( nombre=TIPO_CUENTA_EXISTENCIA_PERDIDO, statement='income', nombre_padre=TIPO_PADRE_EXISTENCIAS, empresa=company, existencia=True) tipo_existencia_compra = crear_tipo_cuenta( nombre=TIPO_CUENTA_EXISTENCIA_COMPRAS, statement='income', nombre_padre=TIPO_PADRE_EXISTENCIAS, empresa=company, existencia=True) tipo_existencia_venta = crear_tipo_cuenta( nombre=TIPO_CUENTA_EXISTENCIA_VENTAS, statement='income', nombre_padre=TIPO_PADRE_EXISTENCIAS, empresa=company, existencia=True) cuenta_existencia_perdido = crear_cuenta( CUENTA_EXISTENCIA_PERDIDO_NOMBRE, CUENTA_EXISTENCIA_PERDIDO, tipo_existencia_perdido, CUENTA_PADRE_EXISTENCIAS, company, en_balance=True ) cuenta_existencia_venta = crear_cuenta( CUENTA_EXISTENCIA_VENTAS_NOMBRE, CUENTA_EXISTENCIA_VENTAS, tipo_existencia_venta, CUENTA_PADRE_EXISTENCIAS, company, en_balance=True ) cuenta_existencia_compra = crear_cuenta( CUENTA_EXISTENCIA_COMPRAS_NOMBRE, CUENTA_EXISTENCIA_COMPRAS, tipo_existencia_compra, CUENTA_PADRE_EXISTENCIAS, company, en_balance=True ) # crear categoria contable para producto categoria_contable_producto = crear_categoria_contable_producto( CATEGORIA_CONTABLE_PRODUCTOS, cuenta_compras, chart.form.category_account_revenue, cuenta_existencia, cuenta_existencia_venta, cuenta_existencia_compra, cuenta_existencia_perdido) # crear listas precios for lista in LISTAS_PRECIOS: ListaPrecio(name=lista).save() # crear Metodos de pago Efectivo journal_cash, = Journal.find([('type', '=', 'cash')]) payment_method = PaymentMethod() payment_method.name = 'Efectivo' payment_method.journal = journal_cash payment_method.credit_account = cuenta_caja payment_method.debit_account = cuenta_caja payment_method.save() # crear Metodos de pago Factura inicial cuenta_pago_patrimonio, = Account.find( [('code', '=', CUENTA_PATRIMONIO_FACTURA_INICIAL)]) journal_cash, = Journal.find([('type', '=', 'cash')]) payment_method = PaymentMethod() payment_method.name = 'Factura Inicial' payment_method.journal = journal_cash #@todo verificar si es este diario payment_method.credit_account = cuenta_pago_patrimonio payment_method.debit_account = cuenta_pago_patrimonio payment_method.save() # configurar almacen almacen, = Almacen.find([('name', 'in', ('Warehouse', 'Almacén'))]) almacen.input_location = almacen.storage_location almacen.output_location = almacen.storage_location almacen.save() # configurar tienda mostrador = Party(name=NOMBRE_TERCERO_MOSTRADOR) mostrador.save() admin, = Usuario.find([('login', '=', 'admin')]) tienda = Tienda(name="Principal", company=company, warehouse=almacen) tienda.users.append(admin) tienda.party = mostrador tienda.self_pick_up = True tienda.save() # secuencias necesarias Sequence = Model.get('ir.sequence') secuencia_libro_ingresos, = Sequence.find([('name', '=', 'Libro Ingresos')]) secuencia_libro_bancos, = Sequence.find([('name', '=', 'Libro Bancos')]) secuencia_de_compra, = Sequence.find([('name', '=', 'Purchase')]) # crear diarios tipo registros para diarios de pagos journal_pago_efectivo = Journal( name='Efectivo PTV', code='EPTV', active=True, type='statement', sequence=secuencia_libro_bancos) journal_pago_efectivo.save() journal_pago_banco = Journal( name='Banco PTV', code='BPTV', active=True, type='statement', sequence=secuencia_libro_bancos) journal_pago_banco.save() # cuenta banco cuenta_banco, = Account.find([('code', '=', CUENTA_BANCO)]) cuenta_banco.template_override = True cuenta_banco.party_required = False cuenta_banco.save() #crear diarios de pagos StatementJournal = Model.get('account.statement.journal') diario_de_pago_efectivo = StatementJournal( name="Efectivo", journal=journal_pago_efectivo, account=cuenta_caja, validation='balance') diario_de_pago_efectivo.save() diario_de_pago_banco = StatementJournal( name="Banco", journal=journal_pago_banco, account=cuenta_banco, validation='balance') diario_de_pago_banco.save() #configurar ptv Device = Model.get('sale.device') device = Device(name='Principal') device.change_unit_price = True # error cuando agrega la tienda por primera vez try: device.shop = tienda except: pass device.shop = tienda device.journals.extend([diario_de_pago_banco, diario_de_pago_efectivo]) device.journal = diario_de_pago_efectivo device.save() #configurar ptv a usuario administrador admin.shop = tienda admin.sale_device = device #ajustar idioma español al administrador Lang = Model.get('ir.lang') es, = Lang.find([('code', '=', 'es')]) admin.language = es admin.save() # configurando destino de compras por defecto ConfPurchase = Model.get('purchase.configuration') conf_compra = ConfPurchase(1) conf_compra.purchase_sequence = secuencia_de_compra conf_compra.one_click_to_location = almacen.storage_location conf_compra.save() # configurando metodo de coste por defecto de productos ProductConf = Model.get('product.configuration') conf_producto = ProductConf(1) conf_producto.default_cost_price_method = 'average' conf_producto.save() def run(): print("#################################") print("Recuerde Iniciar la base de datos") print("createdb base_datos") print("trytond-admin -c trytond.conf --all -d base_datos -l es") print("trytond-admin -c trytond.conf -d base_datos -u country") print("python enlace_a_modules/country/scripts/import_countries.py -c trytond.conf -d base_datos") print("trytond-admin -c trytond.conf -d auto -u currency") print("python enlace_a_modules/currency/scripts/import_currencies.py -c trytond.conf -d base_datos") print("#################################") parser = ArgumentParser() parser.add_argument('-d', '--database', dest='database') parser.add_argument('-c', '--config', dest='config_file', help='the trytond config file') args = parser.parse_args() if not args.database: parser.error('Missing database') main(args.database, args.config_file) if __name__ == '__main__': run()