trytondo-sale_order/sale_order.py

210 lines
6.5 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.model import ModelView, ModelSQL, fields, Workflow
from trytond.pool import Pool
from trytond.transaction import Transaction
from trytond.modules.currency.fields import Monetary
from trytond.modules.product import price_digits
from trytond.pyson import Eval, Bool
from decimal import Decimal
from datetime import date
class SaleOrder (Workflow, ModelView, ModelSQL):
"Sale Order"
__name__ = 'sale.order'
_states = {
'readonly': Eval('state').in_(['confirmed', 'done'])
}
company = fields.Many2One(
'company.company', "Company", states={
'readonly': True,
'required': True
})
currency = fields.Many2One(
'currency.currency', 'Currency', states={
'readonly': True,
'required': True
})
number = fields.Char(
"Number", readonly=True)
party = fields.Many2One(
'party.party', "Party", required=True, states=_states)
order_address = fields.Many2One(
'party.address', 'Address', required=True, states=_states)
pickup_location = fields.Selection([
("on_site", "On Site"),
("at_home", "At Home")], 'Pickup Location', states=_states)
order_mobile = fields.Char('Mobile', states=_states)
date = fields.Date("Date", required=True, states=_states)
lines = fields.One2Many(
'order.line', 'order', 'Lines', states=_states)
total_order = fields.Function(
Monetary("Total", currency='currency', digits='currency'),
'on_change_with_total_order')
state = fields.Selection([
('draft', 'Draft'),
('confirmed', 'Confirmed'),
('done', "Done")
], "State", readonly=True)
@classmethod
def __setup__(cls):
super(SaleOrder, cls).__setup__()
cls._buttons.update({
'confirm': {
'readonly': Eval('state').in_(['confirmed']),
'invisible': Eval('state').in_(['confirmed']) | ~Bool(
Eval('lines', [0]))
}
})
cls._transitions |= set((
('draft', 'confirmed'),
))
@classmethod
def set_code(cls, orders):
for order in orders:
order.number = cls.get_number()[0].get()
order.save()
@classmethod
def get_number(cls):
pool = Pool()
Sequence = pool.get('ir.sequence')
order_sequence = Sequence.search([(
'sequence_type.name', '=', "Order")])
return order_sequence
@staticmethod
def default_company():
return Transaction().context.get('company')
@classmethod
def default_currency(cls, **pattern):
pool = Pool()
Company = pool.get('company.company')
company = pattern.get('company')
if not company:
company = cls.default_company()
if company:
return Company(company).currency.id
@staticmethod
def default_date():
return date.today()
@staticmethod
def default_state():
return 'draft'
@fields.depends('party')
def on_change_party(self):
if self.party:
self.order_address =\
self.party.addresses[0].id if self.party.addresses else None
@fields.depends('lines')
def on_change_with_total_order(self, name=None):
total = Decimal('0.0')
if self.lines:
for line in self.lines:
if line.total_amount:
total += Decimal(line.total_amount)
return total
@fields.depends('party')
def on_change_with_order_mobile(self, name=None):
if self.party:
pool = Pool()
ContactMechanism = pool.get('party.contact_mechanism')
mechanisms = ContactMechanism.search([
('party', '=', self.party.id),
('type', '=', 'mobile')
])
if mechanisms:
return mechanisms[0].value
return
@classmethod
@ModelView.button
@Workflow.transition('confirmed')
def confirm(cls, orders):
for order in orders:
if order.number:
continue
else:
cls.set_code([order])
class OrderLine(ModelView, ModelSQL):
"Order Line"
__name__ = 'order.line'
_states = {
'readonly': Eval('_parent_order.state').in_(['confirmed'])
}
order = fields.Many2One(
'sale.order', "Order")
company = fields.Many2One(
'company.company', "Company", states={
'readonly': True,
'required': True
})
currency = fields.Many2One(
'currency.currency', 'Currency', states={
'readonly': True,
'required': True
})
product = fields.Many2One(
'product.product', 'Product', required=True, states=_states)
unit = fields.Many2One(
'product.uom', 'Unit', required=True, states=_states
)
product_uom_category = fields.Function(
fields.Many2One('product.uom.category', 'Product UOM Category'),
'on_change_with_product_uom_category')
quantity = fields.Float(
"Quantity", digits=('unit'), required=True, states=_states)
unitprice = Monetary(
"Unit Price",
digits=price_digits,
currency='currency', required=True, states=_states)
total_amount = fields.Function(
Monetary("Total Amount", currency='currency', digits='currency'),
'on_change_with_total_amount')
@staticmethod
def default_company():
return Transaction().context.get('company')
@classmethod
def default_currency(cls, **pattern):
pool = Pool()
Company = pool.get('company.company')
company = pattern.get('company')
if not company:
company = cls.default_company()
if company:
return Company(company).currency.id
@fields.depends('product')
def on_change_product(self):
if self.product:
self.unit = self.product.default_uom.id
@fields.depends('product')
def on_change_with_product_uom_category(self, name=None):
if self.product:
return self.product.default_uom.category.id
return None
@fields.depends('quantity', 'unitprice')
def on_change_with_total_amount(self, name=None):
if self.unitprice and self.quantity:
total_amount = self.unitprice * Decimal(self.quantity)
return total_amount