trytond-product_oneclick/product_oneclick.py

194 lines
6.5 KiB
Python

# This file is part of product_oneclick module for Tryton.
# The COPYRIGHT file at the top level of this repository contains
# the full copyright notices and license terms.
from trytond.model import ModelView, fields
from trytond.pool import Pool
from trytond.pyson import Eval, Not, Bool, PYSONEncoder
from trytond.wizard import Wizard, StateView, StateAction, StateTransition, \
Button
from trytond.config import config as config_
from trytond.i18n import gettext
from trytond.exceptions import UserError
__all__ = ['ProductOneClickView', 'ProductOneClick']
DIGITS = config_.getint('product', 'price_decimal', default=4)
class ProductOneClickView(ModelView):
'Product OneClick View'
__name__ = 'product.oneclick.view'
name = fields.Char('Name', size=None, required=True)
code = fields.Char('Code', size=None, select=True, required=True)
description = fields.Text('Description')
type = fields.Selection([
('goods', 'Goods'),
('assets', 'Assets'),
('service', 'Service')
], 'Type', required=True)
category = fields.Many2One('product.category', 'Category', required=True)
list_price = fields.Numeric('List Price', digits=(16, DIGITS),
states={
'required': Eval('salable', False),
})
cost_price = fields.Numeric('Cost Price', digits=(16, DIGITS),
states={
'required': Eval('purchasable', False),
})
cost_price_method = fields.Selection([
("fixed", "Fixed"),
("average", "Average")
], 'Cost Method', required=True)
default_uom = fields.Many2One('product.uom', 'Default UOM', required=True)
default_uom_category = fields.Function(
fields.Many2One('product.uom.category', 'Default UOM Category'),
'on_change_with_default_uom_category')
salable = fields.Boolean('Salable')
sale_uom = fields.Many2One('product.uom', 'Sale UOM',
states={
'invisible': ~Eval('salable', False),
'required': Eval('salable', False),
},
domain=[
('category', '=', Eval('default_uom_category')),
],
depends=['salable', 'default_uom_category'])
purchasable = fields.Boolean('Purchasable')
purchase_uom = fields.Many2One('product.uom', 'Purchase UOM',
states={
'invisible': ~Eval('purchasable'),
'required': Eval('purchasable', False),
},
domain=[('category', '=', Eval('default_uom_category'))],
depends=['purchasable', 'default_uom_category'])
@staticmethod
def default_type():
return 'goods'
@staticmethod
def default_salable():
return 1
@staticmethod
def default_purchasable():
return 1
@staticmethod
def default_cost_price_method():
return 'fixed'
@fields.depends('default_uom', 'sale_uom', 'salable',
'purchase_uom', 'purchasable')
def on_change_default_uom(self):
Template = Pool().get('product.template')
template = Template()
template.default_uom = self.default_uom
template.salable = self.salable
template.sale_uom = self.sale_uom
template.purchasable = self.purchasable
template.purchase_uom = self.purchase_uom
template.on_change_default_uom()
self.sale_uom = template.sale_uom
self.purchase_uom = template.purchase_uom
@fields.depends('default_uom')
def on_change_with_default_uom_category(self):
if self.default_uom:
return self.default_uom.category.id
@classmethod
def view_attributes(cls):
return super(ProductOneClickView, cls).view_attributes() + [
('//page[@id="sale"]', 'states', {
'invisible': Not(Bool(Eval('salable'))),
}),
('//page[@id="purchase"]', 'states', {
'invisible': Not(Bool(Eval('purchasable'))),
})]
class ProductOneClick(Wizard):
'Product OneClick'
__name__ = 'product.oneclick'
start_state = 'view'
view = StateView('product.oneclick.view',
'product_oneclick.product_oneclick_view', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Create', 'create_', 'tryton-ok', default=True),
])
create_ = StateTransition()
open_ = StateAction('product.act_product_form')
@classmethod
def get_template_values(self, vals):
values = {
'name': vals.name,
'type': vals.type,
'category': vals.category or None,
'list_price': vals.list_price or 0,
'cost_price': vals.cost_price or 0,
'cost_price_method': vals.cost_price_method,
'default_uom': vals.default_uom,
'account_category': True,
}
if vals.salable:
values.update({
'salable': vals.salable,
'sale_uom': vals.sale_uom,
})
if vals.purchasable:
values.update({
'purchasable': vals.purchasable,
'purchase_uom': vals.purchase_uom,
})
return values
@classmethod
def get_product_values(self, vals):
values = {
'code': vals.code,
'description': vals.description,
}
return values
def transition_create_(self, values=False):
'''Create a product'''
pool = Pool()
Template = pool.get('product.template')
Product = pool.get('product.product')
name = self.view.name
code = self.view.code
product = None
if name and not code:
product, = (Template.search([('name', '=', name)], limit=1)
or [None])
else:
product, = Product.search([('code', '=', code)], limit=1) or [None]
if product:
raise UserError(gettext('product_exist',
name=product.rec_name,
code=product.code,
))
vals = self.view
tpl_values = self.get_template_values(vals)
prod_values = self.get_product_values(vals)
# create template
self.template = Template.create([tpl_values])[0]
# create product
prod_values['template'] = self.template
self.product = Product.create([prod_values])[0]
return 'open_'
def do_open_(self, action):
action['pyson_domain'] = PYSONEncoder().encode([
('id', '=', self.product.id),
])
return action, {}