mirror of
https://github.com/NaN-tic/trytond-product_oneclick.git
synced 2023-12-14 06:42:53 +01:00
193 lines
6.5 KiB
Python
193 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, {}
|