trytond-sale_line_quick_act.../sale.py

243 lines
8.1 KiB
Python

# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from trytond.model import ModelView, fields, Model
from trytond.pool import PoolMeta, Pool
from trytond.pyson import Eval
from trytond.transaction import Transaction
from trytond.wizard import Wizard, StateTransition, StateView, Button
from trytond.exceptions import UserError
from trytond.i18n import gettext
class SaleLine(metaclass=PoolMeta):
__name__ = 'sale.line'
@classmethod
def __setup__(cls):
super().__setup__()
cls._buttons.update({
'quick_copy': {
'invisible': Eval('sale_state', 'draft') != 'draft',
'readonly': Eval('sale_state', 'draft') != 'draft',
'depends': ['sale_state']
},
'split_wizard': {
'invisible': Eval('sale_state', 'draft') != 'draft',
'readonly': Eval('sale_state', 'draft') != 'draft',
'depends': ['sale_state']
},
'move_wizard': {
'invisible': Eval('sale_state', 'draft') != 'draft',
'readonly': Eval('sale_state', 'draft') != 'draft',
'depends': ['sale_state']
}
})
@classmethod
@ModelView.button_action(
'sale_line_quick_actions.wizard_quick_actions_copy')
def quick_copy(cls, records):
pass
@classmethod
@ModelView.button_action(
'sale_line_quick_actions.wizard_quick_actions_split')
def split_wizard(cls, records):
pass
def split(self, quantity, unit, count, **kwargs):
pool = Pool()
Uom = pool.get('product.uom')
lines = [self]
remainders = {k: getattr(self, k) for k in kwargs.keys()}
remainders['quantity'] = Uom.compute_qty(
self.unit, self.quantity, unit)
if remainders['quantity'] <= quantity:
return lines
quantities = {k: v[0] for k, v in kwargs.items()}
quantities['quantity'] = quantity
quantities['unit'] = unit.id
self.write([self], quantities)
def update_remainders():
for key, value in remainders.items():
if key == 'quantity':
key_unit = unit
else:
key_unit = kwargs[key][1]
remainders[key] -= quantities[key]
if isinstance(key_unit, int):
remainders[key] = round(remainders[key], key_unit)
elif isinstance(key_unit, Model):
remainders[key] = key_unit.round(remainders[key])
update_remainders()
if count:
count -= 1
while (remainders['quantity'] > quantities['quantity']
and (count or count is None)):
with Transaction().set_context(_stock_move_split=True):
lines.extend(self.copy([self], quantities))
update_remainders()
if count:
count -= 1
assert remainders['quantity'] >= 0
if remainders['quantity']:
remainders['unit'] = unit.id
with Transaction().set_context(_stock_move_split=True):
lines.extend(self.copy([self], remainders))
return lines
@classmethod
@ModelView.button_action(
'sale_line_quick_actions.wizard_quick_actions_move')
def move_wizard(cls, records):
pass
class SaleLineQuickActionSplit(ModelView):
'''Sale line quick action split'''
__name__ = 'sale.line.quick_action.split'
count = fields.Integer('Counts', help='The limit number of lines.')
quantity = fields.Float('Quantity', required=True,
digits=(16, Eval('unit_digits', 2)),
depends=['unit_digits'])
unit = fields.Many2One('product.uom', 'Unit', required=True,
domain=[
('category', '=', Eval('uom_category'))],
depends=['uom_category'])
unit_digits = fields.Integer('Unit Digits', readonly=True)
uom_category = fields.Many2One('product.uom.category', 'Uom Category',
readonly=True)
@fields.depends('unit')
def on_change_with_unit_digits(self):
if self.unit:
return self.unit.digits
return 2
class SaleLineQuickActionMove(ModelView):
'''Sale line quick action move'''
__name__ = 'sale.line.quick_action.move'
sale = fields.Many2One('sale.sale', 'Sale', required=True,
domain=[('state', '=', 'draft')])
class SaleLineQuickActionDuplicate(ModelView):
'''Sale line quick action duplicate'''
__name__ = 'sale.line.quick_action.duplicate'
copies = fields.Integer('Copies', required=True)
sale = fields.Many2One('sale.sale', 'Sale', required=True,
domain=[('state', '=', 'draft')])
class SaleLineQuickAction(Wizard):
'''Sale line quick action'''
__name__ = 'sale.line.quick_action'
start = StateTransition()
duplicate = StateView('sale.line.quick_action.duplicate',
'sale_line_quick_actions.line_duplicate_view_form', [
Button('Cancel', 'end'),
Button('OK', 'do_duplicate', default=True)])
do_duplicate = StateTransition()
split = StateView('sale.line.quick_action.split',
'sale_line_quick_actions.line_split_view_form', [
Button('Cancel', 'end'),
Button('OK', 'do_split', default=True)]
)
do_split = StateTransition()
move = StateView('sale.line.quick_action.move',
'sale_line_quick_actions.line_move_view_form', [
Button('Cancel', 'end'),
Button('OK', 'do_move', default=True)]
)
do_move = StateTransition()
def transition_start(self):
pool = Pool()
SaleLine = pool.get('sale.line')
records = SaleLine.browse(Transaction().context['active_ids'])
if any(r.sale_state != 'draft' for r in records):
raise UserError(gettext(
'sale_line_quick_actions.msg_wrong_state'))
action_id = Transaction().context['action_id']
return self._get_action_state()[action_id]
def _get_action_state(self):
Modeldata = Pool().get('ir.model.data')
return {
Modeldata.get_id(
'sale_line_quick_actions',
'wizard_quick_actions_copy'): 'duplicate',
Modeldata.get_id(
'sale_line_quick_actions',
'wizard_quick_actions_split'): 'split',
Modeldata.get_id(
'sale_line_quick_actions',
'wizard_quick_actions_move'): 'move'
}
def transition_do_duplicate(self):
self._create_lines(self.duplicate.sale,
copies=self.duplicate.copies)
return 'end'
def default_split(self, fields):
pool = Pool()
SaleLine = pool.get('sale.line')
sale_line = SaleLine(Transaction().context['active_id'])
return {
'count': 1,
'quantity': sale_line.quantity,
'unit': sale_line.unit.id,
'unit_digits': sale_line.unit_digits,
'uom_category': sale_line.unit.category.id,
}
def transition_do_split(self):
pool = Pool()
SaleLine = pool.get('sale.line')
sale_line = SaleLine(Transaction().context['active_id'])
sale_line.split(self.split.quantity,
self.split.unit, self.split.count, **self._get_split_values())
return 'end'
def _get_split_values(self):
return {}
def transition_do_move(self, copies=1, delete_lines=True):
self._create_lines(self.move.sale, move=True)
return 'end'
def _create_lines(self, sale, copies=1, move=False):
pool = Pool()
SaleLine = pool.get('sale.line')
sale_lines = SaleLine.browse(Transaction().context['active_ids'])
SaleLine.copy(sale_lines * copies, default={
'sale': sale.id
})
if move:
SaleLine.delete(sale_lines)
def default_duplicate(self, fields):
pool = Pool()
SaleLine = pool.get('sale.line')
sale_line = SaleLine(Transaction().context['active_id'])
return {
'copies': 1,
'sale': sale_line.sale.id
}