oc-trytond-configuracion_in.../configurar_tryton.md

1190 lines
43 KiB
Markdown

# 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)
<a id="org3225ee4"></a>
# 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.
<a id="org7f56056"></a>
## Contexto
<a id="orgaad26ae"></a>
### 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)
<a id="orgff293ae"></a>
### 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'
}
<a id="org1e89720"></a>
### 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
<a id="orgfa74ab7"></a>
## 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
<a id="orge7c1f97"></a>
## 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()
<a id="org14b13c7"></a>
## 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()
<a id="org60739d5"></a>
## 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()