trytond-agronomics/contract.py

208 lines
7.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 fields, Workflow, ModelView, ModelSQL
from trytond.pyson import Eval
from decimal import Decimal
from trytond.pyson import If
from trytond.exceptions import UserError
from trytond.pool import Pool
from trytond.i18n import gettext
_STATES = {
'readonly': Eval('state') != 'draft',
}
_DEPENDS = ['state']
class AgronomicsContractProductPriceListTypePriceList(ModelSQL, ModelView):
"Agronomics Contract Product Price List Type Price List"
__name__ = 'agronomics.contract-product.price_list.type-product.price_list'
_table = 'agronomics_contract_price_list_rel'
contract = fields.Many2One('agronomics.contract', "Contract")
price_list_type = fields.Many2One(
'product.price_list.type', "Price List Type")
price_list = fields.Many2One('product.price_list', "Price List")
class AgronomicsContract(Workflow, ModelSQL, ModelView):
"Agronomics Contract"
__name__ = 'agronomics.contract'
reference = fields.Char('Reference')
state = fields.Selection([
('draft', 'Draft'),
('active', 'Active'),
('cancelled', "Cancelled"),
('done', 'Done'),
], 'State', readonly=True, required=True)
crop = fields.Many2One(
'agronomics.crop', "Crop", states=_STATES, depends=_DEPENDS,
required=True)
start_date = fields.Function(
fields.Date('Start Date'), 'on_change_with_start_date')
end_date = fields.Function(
fields.Date('End Date'), 'on_change_with_end_date')
party = fields.Many2One(
'party.party', "Party", states=_STATES, depends=_DEPENDS,
required=True)
price_list_types = fields.One2Many(
'agronomics.contract-product.price_list.type-product.price_list',
'contract', "Price List Types", states=_STATES, depends=_DEPENDS)
lines = fields.One2Many(
'agronomics.contract.line', 'contract', "Lines", states=_STATES,
depends=_DEPENDS)
weighings = fields.One2Many('agronomics.weighing', 'purchase_contract',
"Weighings", readonly=True)
@classmethod
def __setup__(cls):
super(AgronomicsContract, cls).__setup__()
cls._transitions |= set((
('draft', 'active'),
('active', 'cancelled'),
('active', 'done'),
('active', 'draft'),
('cancelled', 'draft'),
))
cls._buttons.update({
'draft': {
'invisible': ~Eval('state').in_(['cancelled', 'active']),
'icon': If(Eval('state') == 'cancelled', 'tryton-undo',
'tryton-back'),
},
'active': {
'invisible': Eval('state') != 'draft',
'icon': 'tryton-forward',
},
'cancel': {
'invisible': Eval('state') != 'active',
'icon': 'tryton-cancel',
},
'done': {
'invisible': Eval('state') != 'active',
'icon': 'tryton-ok',
},
})
@staticmethod
def default_state():
return 'draft'
def get_rec_name(self, name):
ret = self.party and self.party.rec_name or ''
if self.start_date:
ret += ' - %s' % (self.start_date)
return ret
@fields.depends('crop')
def on_change_with_start_date(self, name=None):
if self.crop:
return self.crop.start_date
return None
@fields.depends('crop')
def on_change_with_end_date(self, name=None):
if self.crop:
return self.crop.end_date
return None
@classmethod
@ModelView.button
@Workflow.transition('draft')
def draft(cls, contracts):
pass
@classmethod
@ModelView.button
@Workflow.transition('active')
def active(cls, contracts):
pool = Pool()
ContractLine = pool.get('agronomics.contract.line')
for contract in contracts:
for line in contract.lines:
active_lines = ContractLine.search([
('contract.crop', '=', contract.crop),
('parcel', '=', line.parcel),
('contract.state', '=', 'active'),
])
if active_lines:
raise UserError(gettext(
'agronomics.msg_cant_active_contract',
contract=contract.rec_name,
parcel=line.parcel.rec_name))
@classmethod
@ModelView.button
@Workflow.transition('cancelled')
def cancel(cls, contracts):
pass
@classmethod
@ModelView.button
@Workflow.transition('done')
def done(cls, contracts):
pass
class AgronomicsContractLine(ModelSQL, ModelView):
"Agronomics Contract Line"
__name__ = 'agronomics.contract.line'
contract = fields.Many2One('agronomics.contract', 'Contract',
required=True, ondelete='CASCADE')
parcel = fields.Many2One('agronomics.parcel', "Parcel",
domain=[
('producer', '=', Eval('_parent_contract.party')),
('crop', '=', Eval('_parent_contract.crop'))
])
product = fields.Function(
fields.Many2One('product.template', "Product"),
'on_change_with_product')
unit = fields.Function(fields.Many2One('product.uom', "Unit"),
'on_change_with_unit')
unit_digits = fields.Function(fields.Integer("Unit Digits"),
'on_change_with_unit_digits')
agreed_quantity = fields.Float("Agreed Quantity",
digits=(16, Eval('unit_digits', 2)), depends=['unit_digits'])
purchased_quantity = fields.Function(
fields.Float("Purchased Quantity", digits=(16, Eval('unit_digits', 2)),
depends=['unit_digits']),'on_change_with_purchased_quantity')
remaining_quantity = fields.Function(
fields.Float("Remaining Quantity", digits=(16, Eval('unit_digits', 2)),
depends=['unit_digits']), 'on_change_with_remaining_quantity')
@fields.depends('parcel')
def on_change_with_product(self, name=None):
if self.parcel:
return self.parcel.product.id
return None
@fields.depends('product', methods=['on_change_with_product'])
def on_change_with_unit(self, name=None):
if self.product:
return self.product.purchase_uom.id
return None
@fields.depends('unit')
def on_change_with_unit_digits(self, name=None):
if self.unit:
return self.unit.digits
return 2
@fields.depends('parcel')
def on_change_with_purchased_quantity(self, name=None):
if self.parcel:
if self.parcel.purchased_quantity:
return self.parcel.purchased_quantity
return Decimal(0)
@fields.depends('agreed_quantity', 'purchased_quantity')
def on_change_with_remaining_quantity(self, name=None):
if self.agreed_quantity:
if self.purchased_quantity:
return self.agreed_quantity - self.purchased_quantity
else:
return self.agreed_quantity
return None