361 lines
14 KiB
Python
361 lines
14 KiB
Python
from trytond.pool import Pool, PoolMeta
|
|
from trytond.model import (
|
|
ModelSQL, ModelView, Workflow, fields)
|
|
from trytond.modules.company import CompanyReport
|
|
from trytond.pyson import Eval, If, Bool
|
|
from trytond.modules.company.model import set_employee
|
|
from trytond.exceptions import UserError
|
|
from trytond.transaction import Transaction
|
|
from trytond.wizard import (
|
|
Button, StateAction, StateTransition, StateView, Wizard)
|
|
|
|
from trytond.modules.currency.fields import Monetary
|
|
from trytond.modules.product import price_digits
|
|
|
|
import datetime
|
|
from datetime import timedelta, date
|
|
|
|
|
|
class Cron(metaclass=PoolMeta):
|
|
__name__ = 'ir.cron'
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super().__setup__()
|
|
cls.method.selection.append(
|
|
('optical_equipment.contract|contract_expiration', 'Contract Expiration'),
|
|
)
|
|
|
|
|
|
class Contract(Workflow, ModelSQL, ModelView):
|
|
'Contracts'
|
|
__name__ = 'optical_equipment.contract'
|
|
_rec_name = 'number'
|
|
_order_name = 'number'
|
|
|
|
company = fields.Many2One(
|
|
'company.company', "Company", required=True,
|
|
states={
|
|
'readonly': (Eval('state') != 'draft') | Eval('party', True),
|
|
}, help="Make the subscription belong to the company.")
|
|
number = fields.Char(
|
|
"Number", readonly=True,
|
|
help="The main identification of the subscription.")
|
|
reference = fields.Char(
|
|
"Reference",
|
|
help="The identification of an external origin.")
|
|
description = fields.Char("Description",
|
|
states={
|
|
'readonly': Eval('state') != 'draft',
|
|
})
|
|
party = fields.Many2One(
|
|
'party.party', "Party", required=True,
|
|
states={
|
|
'readonly': (Eval('state') != 'draft') | Eval('party', True),
|
|
}, help="The party who subscribes.")
|
|
equipment = fields.Many2One('optical_equipment.equipment', "Equipment")
|
|
contact = fields.Many2One('party.contact_mechanism', "Contact", required=True)
|
|
invoice_address = fields.Many2One('party.address', 'Invoice Address',
|
|
required=True, domain=[('party', '=', Eval('party'))],
|
|
states={
|
|
'readonly': (Eval('state') != 'draft') | Eval('party', True),
|
|
})
|
|
start_date = fields.Date("Start Date", required=True,)
|
|
end_date = fields.Date("End Date",
|
|
domain=['OR',
|
|
('end_date', '>=', If(
|
|
Bool(Eval('start_date')),
|
|
Eval('start_date', datetime.date.min),
|
|
datetime.date.min)),
|
|
('end_date', '=', None),
|
|
],
|
|
states={
|
|
'readonly': Eval('state') != 'draft',
|
|
})
|
|
|
|
maintenance_services = fields.Many2Many('optical_equipment_maintenance.service-equipment.contract',
|
|
'contract', 'maintenance_services', "Prorogues",
|
|
states={'readonly': Eval('state') != 'draft'})
|
|
|
|
current_equipments = fields.Many2Many('optical_equipment.contract-optical_equipment.equipment',
|
|
'contract', 'equipment', "Current Equipments",
|
|
states={'readonly': Eval('state') != 'draft'})
|
|
history_equipments = fields.One2Many('optical_equipment.equipment', 'contract', "Equipments",
|
|
states={'readonly': Eval('state') != 'draft'})
|
|
price_contract = Monetary("Price Contract", digits=price_digits, currency='currency', required=True,
|
|
states={'readonly': Eval('state') != 'draft'})
|
|
state = fields.Selection([
|
|
('draft', "Draft"),
|
|
('running', "Running"),
|
|
('closed', "Closed"),
|
|
('cancelled', "Cancelled"),
|
|
], "State", readonly=True, required=False, sort=False,
|
|
help="The current state of the subscription.")
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super(Contract, cls).__setup__()
|
|
cls._order = [
|
|
('number', 'DESC NULLS FIRST'),
|
|
('id', 'DESC'),
|
|
]
|
|
cls._transitions = ({
|
|
('draft', 'running'),
|
|
('running', 'draft'),
|
|
('running', 'closed'),
|
|
('running', 'cancelled'),
|
|
('cancelled', 'draft')
|
|
})
|
|
cls._buttons.update({
|
|
'draft': {'invisible': Eval('state').in_(['draft', 'closed'])},
|
|
'running': {'invisible': Eval('state').in_(['cancelled', 'running'])},
|
|
'closed': {'invisible': Eval('state').in_(['draft', 'cancelled'])},
|
|
'cancelled': {'invisible': Eval('state').in_(['draft', 'cancelled'])}
|
|
})
|
|
|
|
@staticmethod
|
|
def default_company():
|
|
return Transaction().context.get('company')
|
|
|
|
@staticmethod
|
|
def default_state():
|
|
return 'draft'
|
|
|
|
@classmethod
|
|
def set_number(cls, contracts):
|
|
pool = Pool()
|
|
Config = pool.get('optical_equipment.configuration')
|
|
config = Config(4)
|
|
|
|
if config.contract_sequence is not None:
|
|
if not contracts[0].number:
|
|
try:
|
|
contracts[0].number = config.contract_sequence.get()
|
|
cls.save(contracts)
|
|
except UserError:
|
|
raise UserError(str('Validation Error'))
|
|
else:
|
|
raise UserError(gettext('optical_equipment.msg_not_sequence_equipment'))
|
|
|
|
@classmethod
|
|
def contract_expiration(cls):
|
|
pool = Pool()
|
|
Contracts = pool.get('optical_equipment.contract')
|
|
|
|
contracts_to_expire = cls.search([('state', '=', 'running'),
|
|
('end_date', '<=', date.today())])
|
|
|
|
if contracts_to_expire != []:
|
|
for contract in contracts_to_expire:
|
|
cls.closed([contract])
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('draft')
|
|
def draft(cls, contracts):
|
|
contract = contracts[0]
|
|
for equipment in contract.current_equipments:
|
|
equipment.state = "uncontrated"
|
|
equipment.contract_history += (contract.id,)
|
|
equipment.save()
|
|
contract.save()
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('closed')
|
|
def closed(cls, contracts):
|
|
contract = contracts[0]
|
|
for equipment in contract.current_equipments:
|
|
equipment.state = "uncontrated"
|
|
equipment.save()
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('running')
|
|
def running(cls, contracts):
|
|
contract = contracts[0]
|
|
for equipment in contract.current_equipments:
|
|
equipment.state = "contrated"
|
|
equipment.contract_history += (contract.id,)
|
|
equipment.save()
|
|
|
|
cls.set_number(contracts)
|
|
contract.state = 'running'
|
|
contract.save()
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('cancelled')
|
|
def cancelled(cls, contracts):
|
|
contract = contracts[0]
|
|
for equipment in contract.current_equipments:
|
|
equipment.state = "uncontrated"
|
|
equipment.save()
|
|
|
|
|
|
class ContractMaintenanceServices(ModelSQL):
|
|
'Contract - Maintenance Services'
|
|
__name__ = 'optical_equipment_maintenance.service-equipment.contract'
|
|
|
|
maintenance_services = fields.Many2One(
|
|
'optical_equipment_maintenance.service', "Maintenance Service", )
|
|
contract = fields.Many2One('optical_equipment.contract', "Contract")
|
|
|
|
|
|
class ContractEquipment(ModelSQL):
|
|
'Optical Equipment - Contract'
|
|
__name__ = 'optical_equipment.contract-optical_equipment.equipment'
|
|
|
|
equipment = fields.Many2One('optical_equipment.equipment', 'Equipment', )
|
|
contract = fields.Many2One('optical_equipment.contract', 'Contract', )
|
|
|
|
|
|
class ContractReport(CompanyReport):
|
|
__name__ = 'optical_equipment.contract'
|
|
|
|
@classmethod
|
|
def execute(cls, ids, data):
|
|
with Transaction().set_context(address_with_party=True):
|
|
return super(ContractReport, cls).execute(ids, data)
|
|
|
|
@classmethod
|
|
def get_context(cls, records, header, data):
|
|
pool = Pool()
|
|
Date = pool.get('ir.date')
|
|
context = super().get_context(records, header, data)
|
|
context['today'] = Date.today()
|
|
|
|
return context
|
|
|
|
|
|
class CreateContractInitial(ModelView, ModelSQL):
|
|
'Create Contract Inicial'
|
|
__name__ = 'optical_equipment_create.contract'
|
|
|
|
currency = fields.Many2One('currency.currency', 'Currency', required=True)
|
|
company = fields.Many2One(
|
|
'company.company', "Company", readonly=True, required=True,
|
|
states={
|
|
'readonly': (Eval('state') != 'draft') | Eval('party', True),
|
|
}, help="Make the subscription belong to the company.")
|
|
party = fields.Many2One(
|
|
'party.party', "Party", required=True,
|
|
help="The party who subscribes.")
|
|
invoice_address = fields.Many2One('party.address', 'Invoice Address',
|
|
required=True, domain=[('party', '=', Eval('party'))])
|
|
payment_term = fields.Many2One('account.invoice.payment_term',
|
|
'Payment Term')
|
|
contact = fields.Many2One(
|
|
'party.contact_mechanism', "Contact", required=True,
|
|
domain=[('party', '=', Eval('party'))],
|
|
context={
|
|
'company': Eval('company', -1),
|
|
})
|
|
start_date = fields.Date("Start Date", required=True)
|
|
end_date = fields.Date("End Date",
|
|
domain=['OR',
|
|
('end_date', '>=', If(
|
|
Bool(Eval('start_date')),
|
|
Eval('start_date', datetime.date.min),
|
|
datetime.date.min)),
|
|
('end_date', '=', None),
|
|
])
|
|
unit_price = Monetary("Unit Price", digits=price_digits, currency='currency', required=True)
|
|
|
|
@staticmethod
|
|
def default_company():
|
|
return Transaction().context.get('company')
|
|
|
|
@staticmethod
|
|
def default_currency():
|
|
Company = Pool().get('company.company')
|
|
if Transaction().context.get('company'):
|
|
company = Company(Transaction().context['company'])
|
|
return company.currency.id
|
|
|
|
@classmethod
|
|
def default_start_date(cls):
|
|
pool = Pool()
|
|
Date = pool.get('ir.date')
|
|
return Date.today()
|
|
|
|
@fields.depends('party')
|
|
def on_change_party(self):
|
|
pool = Pool()
|
|
Date = pool.get('ir.date')
|
|
if self.party:
|
|
self.invoice_address = self.party.address_get(type='invoice')
|
|
if self.party.customer_type == "ips":
|
|
self.end_date = Date.today() + timedelta(days=182)
|
|
else:
|
|
self.end_date = Date.today() + timedelta(days=365)
|
|
|
|
|
|
class CreateContract(Wizard):
|
|
__name__ = 'optical_equipment.maintenance.contract'
|
|
|
|
start = StateView('optical_equipment_create.contract',
|
|
'optical_equipment.create_contract_view_form', [
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Create', 'create_contract', 'tryton-ok', default=True),
|
|
])
|
|
create_contract = StateAction('optical_equipment.act_contract_form')
|
|
|
|
def default_start(self, fields):
|
|
if self.record:
|
|
default = {'party': self.record.propietary.id,
|
|
'invoice_address': self.record.propietary_address.id,
|
|
'unit_price': (self.record.sale_origin.amount
|
|
if self.record.sale_origin.__name__ == "sale.line"
|
|
else self.record.sale_origin.total_amount),
|
|
}
|
|
return default
|
|
|
|
@property
|
|
def _subscription_start(self):
|
|
return dict(
|
|
party=self.start.party,
|
|
contact=self.start.contact,
|
|
start_date=self.start.start_date,
|
|
end_date=self.start.end_date,
|
|
invoice_address=self.start.invoice_address,
|
|
unit_price=self.start.unit_price
|
|
)
|
|
|
|
def do_create_contract(self, action):
|
|
maintenance_service = self.records[0]
|
|
pool = Pool()
|
|
Contract = pool.get('optical_equipment.contract')
|
|
|
|
dates = self._subscription_start
|
|
|
|
prorogues = (maintenance_service,)
|
|
equipments = []
|
|
for line in maintenance_service.lines:
|
|
equipments.append(line.equipment.id)
|
|
|
|
if maintenance_service.contract_origin:
|
|
contract = maintenance_service.contract_origin
|
|
contract.history_equipments += tuple(equipments)
|
|
contract.current_equipments = equipments
|
|
contract.invoice_address = dates['invoice_address']
|
|
contract.contact = dates['contact']
|
|
contract.start_date = dates['start_date']
|
|
contract.end_date = dates['end_date']
|
|
contract.maintenance_services += prorogues
|
|
contract.state = 'draft'
|
|
contract.price_contract = dates['unit_price']
|
|
else:
|
|
contract = Contract(party=dates['party'],
|
|
invoice_address=dates['invoice_address'],
|
|
contact=dates['contact'],
|
|
start_date=dates['start_date'],
|
|
end_date=dates['end_date'],
|
|
maintenance_services=prorogues,
|
|
current_equipments=equipments,
|
|
state='draft',
|
|
price_contract=dates['unit_price']
|
|
)
|
|
|
|
contract.save()
|