# 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 datetime import date from trytond.model import fields, ModelSQL, ModelView from trytond.pool import PoolMeta, Pool from trytond.i18n import gettext from trytond.pyson import Eval from trytond.exceptions import UserError from .schedule import PAYMENT_METHOD class ContractProductLine(metaclass=PoolMeta): __name__ = 'sale.contract.product_line' shift_payment_method = fields.Selection(PAYMENT_METHOD, 'Shift Payment Method', states={'invisible': ~Eval('require_plan', False)}) location = fields.Many2One('surveillance.location', 'Location', states={'invisible': ~Eval('require_plan', False)}) require_plan = fields.Boolean('Require Plan', help='Check this option if product require surveillance plan') positions_plan = fields.One2Many('sale.contract.product.position', 'product_line', 'Products Plan', states={'invisible': ~Eval('require_plan', False)}, context={ 'location': Eval('location', -1) }) class SaleContract(metaclass=PoolMeta): __name__ = 'sale.contract' @classmethod def _get_origin(cls): return super(SaleContract, cls)._get_origin() + ['crm.opportunity'] @classmethod def confirm(cls, contracts): super(SaleContract, cls).confirm(contracts) for contract in contracts: contract.create_plan() def create_plan(self): pool = Pool() Plan = pool.get('surveillance.plan') plans = Plan.search([ ('customer', '=', self.party.id), ]) if not plans: plan, = Plan.create([{ 'customer': self.party.id, 'company': self.company.id, 'state': 'draft', }]) else: plan = plans[0] to_add = [] for li in self.product_lines: if not li.require_plan: continue if not li.location: raise UserError(gettext('surveillance.msg_missing_location')) to_add.append({ 'location': li.location.id, 'contract': li.contract.id, 'hired_service': li.id, 'start_date': li.start_date, 'end_date': li.end_date, 'shift_payment_method': li.shift_payment_method, 'state': 'preoperative', 'comment': li.description, }) if to_add: Plan.write([plan], { 'lines': [('create', to_add)] }) class SaleOpportunity(metaclass=PoolMeta): __name__ = "crm.opportunity" contracts = fields.One2Many('sale.contract', 'origin', 'Contract') @classmethod def convert(cls, opportunities): # Contract = Pool().get('sale.contract') contracts = [o.create_contract() for o in opportunities if not o.contracts] def create_contract(self): ''' Create a sale contract for the opportunity and return the contract ''' contract = self.get_contract_opportunity() contract_lines = [] for line in self.lines: contract_lines.append(self.get_contract_line(line)) contract.product_lines = contract_lines contract.save() return contract def get_contract_opportunity(self): ''' Return contract for an opportunity ''' SaleContract = Pool().get('sale.contract') contract = { 'description': self.description, 'party': self.party, 'payment_term': self.payment_term, 'company': self.company, 'currency': self.company.currency, 'comment': self.comment, 'contract_date': date.today(), 'start_date': date.today(), 'invoice_method': 'standard', 'origin': str(self), } contract, = SaleContract.create([contract]) return contract def get_contract_line(self, line): value = { 'product': line.product.id, 'unit_price': line.unit_price or 0, 'description': line.product.rec_name, 'type': 'line', # 'quantity': line.quantity, } return value class ContractProductPosition(ModelSQL, ModelView): "Contract Product Position" __name__ = "sale.contract.product.position" product_line = fields.Many2One('sale.contract.product_line', 'Product Line', required=True, ondelete='CASCADE') position = fields.Many2One('surveillance.location.position', 'Position', domain=[ ('location', '=', Eval('_parent_product_line', {}).get('location')) ], required=True)