493 lines
20 KiB
Python
493 lines
20 KiB
Python
from trytond.pool import Pool, PoolMeta
|
|
from trytond.model import (
|
|
ModelSQL, ModelView, Workflow, fields)
|
|
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
|
|
|
|
|
|
class Contract(ModelSQL, ModelView):
|
|
'Contracts'
|
|
__name__ = 'optical_equipment.contract'
|
|
|
|
company = fields.Many2One(
|
|
'company.company', "Company", readonly=True, required=True, select=True,
|
|
states={
|
|
'readonly': (Eval('state') != 'draft') | Eval('party', True),
|
|
},help="Make the subscription belong to the company.")
|
|
number = fields.Char(
|
|
"Number", readonly=True, select=True,
|
|
help="The main identification of the subscription.")
|
|
reference = fields.Char(
|
|
"Reference", select=True,
|
|
help="The identification of an external origin.")
|
|
description = fields.Char("Description",
|
|
states={
|
|
'readonly': Eval('state') != 'draft',
|
|
})
|
|
party = fields.Many2One(
|
|
'party.party', "Party", readonly=True, required=True,
|
|
help="The party who subscribes.")
|
|
contact = fields.Many2One(
|
|
'party.contact_mechanism', "Contact", readonly=True)
|
|
invoice_address = fields.Many2One('party.address', 'Invoice Address', readonly=True,
|
|
required=True, domain=[('party', '=', Eval('party'))])
|
|
invoice_recurrence = fields.Many2One(
|
|
'sale.subscription.recurrence.rule.set', "Invoice Recurrence", readonly=True,
|
|
required=True)
|
|
start_date = fields.Date("Start Date", readonly=True, required=False,)
|
|
end_date = fields.Date(
|
|
"End Date", readonly=True,
|
|
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',
|
|
}
|
|
)
|
|
state = fields.Selection([
|
|
('draft', "Draft"),
|
|
('quotation', "Quotation"),
|
|
('running', "Running"),
|
|
('closed', "Closed"),
|
|
('cancelled', "Cancelled"),
|
|
], "State", readonly=True, required=False, sort=False,
|
|
help="The current state of the subscription.")
|
|
contract = fields.Many2One('sale.subscription', "Contract", readonly=True)
|
|
prorogues = fields.Many2Many('sale.subscription-optical_equipment.contract',
|
|
'contract', 'subscription', 'Prorrogation')
|
|
equipments = fields.Many2Many('optical_equipment.contract-optical_equipment.equipment', 'equipment',
|
|
'contract', "Equipments", readonly=True,
|
|
domain=[['OR',
|
|
('state', '=', 'registred'),
|
|
('state', '=', 'uncontrated')]
|
|
])
|
|
|
|
@staticmethod
|
|
def default_company():
|
|
return Transaction().context.get('company')
|
|
|
|
@staticmethod
|
|
def default_state():
|
|
return 'draft'
|
|
|
|
|
|
class CreateNextProrogue(ModelView):
|
|
'Create Next Prorogue'
|
|
__name__ = 'optical_equipment_prorogue.next'
|
|
|
|
initial_contract = fields.Many2One('optical_equipment.contract', "Initial Contract")
|
|
party = fields.Many2One('party.party', "Party", required=True,
|
|
help="The party who subscribes.")
|
|
contact = fields.Many2One('party.contact_mechanism', "Contact")
|
|
invoice_address = fields.Many2One('party.address', 'Invoice Address',
|
|
required=True, domain=[('party', '=', Eval('party'))])
|
|
invoice_recurrence = fields.Many2One('sale.subscription.recurrence.rule.set', "Invoice Recurrence",
|
|
required=True)
|
|
payment_term = fields.Many2One(
|
|
'account.invoice.payment_term', "Payment Term")
|
|
start_date = fields.Date("Start Date", required=True,)
|
|
end_date = fields.Date("End Date", required=True,
|
|
domain=['OR',
|
|
('end_date', '>=', If(
|
|
Bool(Eval('start_date')),
|
|
Eval('start_date', datetime.date.min),
|
|
datetime.date.min)),
|
|
('end_date', '=', None),
|
|
])
|
|
invoice_start_date = fields.Date("Invoice Start Date", required=True,
|
|
help='Billing start date')
|
|
service = fields.Many2One('sale.subscription.service', "Service", required=True)
|
|
quantity = fields.Float("Quantity", digits='unit', required=True)
|
|
unit_price = Monetary("Unit Price", currency='currency',
|
|
digits=price_digits,required=True
|
|
)
|
|
equipments = fields.Many2Many('sale.subscription-optical_equipment.equipment', 'subscription',
|
|
'equipment', "Equipments", required=True,
|
|
domain=[['OR',
|
|
('state', '=', 'registred'),
|
|
('state', '=', 'uncontrated')]
|
|
])
|
|
@fields.depends('initial_contract', 'party', 'contact', 'invoice_address',
|
|
'invoice_recurrence', 'start_date', 'end_date',
|
|
'equipments')
|
|
def on_change_initial_contract(self):
|
|
if self.initial_contract:
|
|
contract = self.initial_contract
|
|
self.party = contract.party.id
|
|
self.contact = contract.contact.id
|
|
self.invoice_address = contract.invoice_address.id
|
|
self.invoice_recurrence = contract.invoice_recurrence.id
|
|
self.start_date = contract.end_date
|
|
self.equipments = contract.equipments
|
|
else:
|
|
self.party = None
|
|
self.contact = None
|
|
self.invoice_address = None
|
|
self.invoice_recurrence = None
|
|
self.start_date = None
|
|
self.equipments = []
|
|
|
|
class CreateProrogue(Wizard):
|
|
'Create Prorogue'
|
|
__name__ = 'optical_equipment.prorogue'
|
|
|
|
start = StateView('optical_equipment_prorogue.next',
|
|
'optical_equipment.create_prorogue_view_form',
|
|
[Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Create', 'create_prorogue', 'tryton-ok', default=True),
|
|
])
|
|
|
|
create_prorogue = StateAction('sale_subscription.act_subscription_form')
|
|
|
|
done_ = StateView('optical_equipment_prorogue.next',
|
|
'optical_equipment.create_prorogue_view_form',[
|
|
Button('Done', 'end', 'tryton-cancel'),
|
|
])
|
|
|
|
@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,
|
|
payment_term=self.start.payment_term,
|
|
invoice_address=self.start.invoice_address,
|
|
invoice_recurrence=self.start.invoice_recurrence,
|
|
invoice_start_date=self.start.invoice_start_date,
|
|
service=self.start.service,
|
|
quantity=self.start.quantity,
|
|
unit_price=self.start.unit_price,
|
|
equipments=self.start.equipments)
|
|
|
|
def do_create_prorogue(self, action):
|
|
pool = Pool()
|
|
Subscription = pool.get('sale.subscription')
|
|
SubscriptionLine = pool.get('sale.subscription.line')
|
|
|
|
a = self._subscription_start
|
|
|
|
equipments_to_subscription=self.start.equipments
|
|
subscription_lines = [SubscriptionLine(
|
|
start_date=a['start_date'],
|
|
end_date=a['end_date'],
|
|
consumption_recurrence=a['invoice_recurrence'],
|
|
service=a['service'],
|
|
unit=a['service'].product.default_uom,
|
|
quantity=a['quantity'],
|
|
unit_price=a['unit_price']
|
|
)]
|
|
|
|
subscription = Subscription(
|
|
state='draft',
|
|
type='prorrogation',
|
|
party=a['party'],
|
|
invoice_address=a['invoice_address'],
|
|
payment_term=a['payment_term'],
|
|
start_date=a['start_date'],
|
|
end_date=a['end_date'],
|
|
invoice_recurrence=a['invoice_recurrence'],
|
|
invoice_start_date=a['invoice_start_date'],
|
|
contact=a['contact'],
|
|
invoice_party=a['party'],
|
|
lines=subscription_lines,
|
|
equipments=equipments_to_subscription,
|
|
)
|
|
|
|
subscription.save()
|
|
|
|
IdInitialContract = self.start.initial_contract.id
|
|
pool = Pool()
|
|
Contract = pool.get('optical_equipment.contract')
|
|
contract = Contract.search(['id', '=', IdInitialContract])[0]
|
|
contract.start_date = a['start_date']
|
|
contract.end_date = a['end_date']
|
|
contract.invoice_address = a['invoice_address']
|
|
contract.contact = a['contact']
|
|
contract.invoice_recurrence = a['invoice_recurrence']
|
|
contract.state = subscription.state
|
|
|
|
contract.prorogues += (contract.id,)
|
|
|
|
contract.equipments = equipments_to_subscription
|
|
contract.save()
|
|
|
|
|
|
|
|
class CreateInitialContract(ModelView):
|
|
'Create Initial Contract'
|
|
__name__ = 'optical_equipment_contract.initial'
|
|
|
|
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)
|
|
start_date = fields.Date("Start Date", required=True)
|
|
end_date = fields.Date("End Date", required=True)
|
|
invoice_recurrence = fields.Many2One('sale.subscription.recurrence.rule.set',
|
|
"Invoice Recurrence",required=True)
|
|
invoice_start_date = fields.Date("Invoice Start Date", required=True,
|
|
help='Billing start date')
|
|
service = fields.Many2One('sale.subscription.service', "Service", required=True)
|
|
quantity = fields.Float("Quantity", digits='unit', required=True)
|
|
unit_price = Monetary("Unit Price", currency='currency',
|
|
digits=price_digits,required=True
|
|
)
|
|
equipments = fields.Many2Many('sale.subscription-optical_equipment.equipment', 'subscription',
|
|
'equipment', "Equipments", required=True,
|
|
domain=[['OR',
|
|
('state', '=', 'registred'),
|
|
('state', '=', 'uncontrated')]
|
|
])
|
|
|
|
@classmethod
|
|
def default_start_date(cls):
|
|
pool = Pool()
|
|
Date = pool.get('ir.date')
|
|
return Date.today()
|
|
|
|
@classmethod
|
|
@fields.depends(methods=['default_start_date'])
|
|
def default_invoice_start_date(self):
|
|
invoice_start_date = self.default_start_date()
|
|
return invoice_start_date
|
|
|
|
class CreateContract(Wizard):
|
|
'Create Contract'
|
|
__name__ = 'sale.create.contract'
|
|
|
|
start = StateView('optical_equipment_contract.initial',
|
|
'optical_equipment.create_contract_view_form',[
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Create', 'create_contract', 'tryton-ok', default=True),
|
|
])
|
|
create_contract = StateAction('sale_subscription.act_subscription_form')
|
|
|
|
done_ = StateView('optical_equipment_contract.initial',
|
|
'optical_equipment.create_contract_view_form',[
|
|
Button('Done', 'end', 'tryton-cancel'),
|
|
])
|
|
|
|
@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,
|
|
payment_term=self.start.payment_term,
|
|
invoice_address=self.start.invoice_address,
|
|
invoice_recurrence=self.start.invoice_recurrence,
|
|
invoice_start_date=self.start.invoice_start_date,
|
|
service=self.start.service,
|
|
quantity=self.start.quantity,
|
|
unit_price=self.start.unit_price,
|
|
equipments=self.start.equipments)
|
|
|
|
def _create_contract_base(self,dates, subscription):
|
|
pool = Pool()
|
|
#Subscription = pool.get('sale.subscription')
|
|
#subscription = Subscription.search(['id', '=', subscription.id])
|
|
ContractBase = pool.get('optical_equipment.contract')
|
|
|
|
a = self._subscription_start
|
|
|
|
contractBase = ContractBase(
|
|
state='draft',
|
|
party=a['party'],
|
|
invoice_address=a['invoice_address'],
|
|
start_date=a['start_date'],
|
|
end_date=a['end_date'],
|
|
invoice_recurrence=a['invoice_recurrence'],
|
|
contact=a['contact'],
|
|
contract=subscription,
|
|
equipments=a['equipments']
|
|
)
|
|
contractBase.save()
|
|
|
|
def do_create_contract(self, action):
|
|
pool = Pool()
|
|
Subscription = pool.get('sale.subscription')
|
|
SubscriptionLine = pool.get('sale.subscription.line')
|
|
|
|
a = self._subscription_start
|
|
|
|
equipments_to_subscription=self.start.equipments
|
|
subscription_lines = [SubscriptionLine(
|
|
start_date=a['start_date'],
|
|
end_date=a['end_date'],
|
|
consumption_recurrence=a['invoice_recurrence'],
|
|
service=a['service'],
|
|
unit=a['service'].product.default_uom,
|
|
quantity=a['quantity'],
|
|
unit_price=a['unit_price']
|
|
)]
|
|
|
|
subscription = Subscription(
|
|
state='draft',
|
|
type='contract',
|
|
party=a['party'],
|
|
invoice_address=a['invoice_address'],
|
|
payment_term=a['payment_term'],
|
|
start_date=a['start_date'],
|
|
end_date=a['end_date'],
|
|
invoice_recurrence=a['invoice_recurrence'],
|
|
invoice_start_date=a['invoice_start_date'],
|
|
contact=a['contact'],
|
|
invoice_party=a['party'],
|
|
lines=subscription_lines,
|
|
equipments=equipments_to_subscription,
|
|
)
|
|
antes = subscription.id
|
|
subscription.save()
|
|
despues = subscription.id
|
|
andes = str(antes) + str(despues)
|
|
#raise UserError(str(andes))
|
|
self._create_contract_base(a, subscription)
|
|
|
|
|
|
class Subscription(metaclass=PoolMeta):
|
|
__name__ = 'sale.subscription'
|
|
|
|
type = fields.Selection([
|
|
('contract', "Main"),
|
|
('prorrogation', "Extension"),
|
|
], "Type", select=True, required=True,
|
|
states={
|
|
'readonly': ((Eval('state') != 'draft')
|
|
| Eval('context', {}).get('type')
|
|
),
|
|
})
|
|
|
|
equipments = fields.Many2Many('sale.subscription-optical_equipment.equipment', 'subscription',
|
|
'equipment', "Equipments",
|
|
domain=[['OR',
|
|
('state', '=', 'registred'),
|
|
('state', '=', 'uncontrated')]
|
|
])
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('running')
|
|
@set_employee('run_by')
|
|
def run(cls, subscriptions):
|
|
pool = Pool()
|
|
Line = pool.get('sale.subscription.line')
|
|
lines = []
|
|
|
|
pool = Pool()
|
|
Equipments = pool.get('optical_equipment.equipment')
|
|
|
|
for subscription in subscriptions:
|
|
if not subscription.next_invoice_date:
|
|
subscription.next_invoice_date = (
|
|
subscription.compute_next_invoice_date())
|
|
for line in subscription.lines:
|
|
if (line.next_consumption_date is None
|
|
and not line.consumed_until):
|
|
line.next_consumption_date = (
|
|
line.compute_next_consumption_date())
|
|
lines.extend(subscription.lines)
|
|
for equipment in subscription.equipments:
|
|
equipment.state = "contrated"
|
|
equipment.save()
|
|
Line.save(lines)
|
|
cls.save(subscriptions)
|
|
|
|
class CreateSubscriptionInvoice(Wizard):
|
|
"Create Subscription Invoice"
|
|
__name__ = 'sale.subscription.create_invoice'
|
|
|
|
start = StateView(
|
|
'sale.subscription.create_invoice.start',
|
|
'sale_subscription.create_invoice_start_view_form', [
|
|
Button("Cancel", 'end', 'tryton-cancel'),
|
|
Button("Create", 'create_', 'tryton-ok', default=True),
|
|
])
|
|
|
|
create_ = StateTransition()
|
|
|
|
def generate_invoice(self, date=None):
|
|
pool = Pool()
|
|
Date = pool.get('ir.date')
|
|
Configuration = pool.get('account.configuration')
|
|
Config = Configuration(1)
|
|
Journals = pool.get('account.journal')
|
|
Invoice = pool.get('account.invoice')
|
|
InvoiceLine = pool.get('account.invoice.line')
|
|
invoice_lines = []
|
|
|
|
if date is None:
|
|
date = Date.today()
|
|
|
|
for subscription in self.records:
|
|
for line in subscription.lines:
|
|
invoice_lines.append(
|
|
InvoiceLine(
|
|
origin=line,
|
|
product=line.service,
|
|
account=line.service.product.account_revenue_used,
|
|
quantity=line.quantity,
|
|
unit=line.unit,
|
|
unit_price=line.unit_price,
|
|
)
|
|
)
|
|
|
|
invoice = Invoice(
|
|
type='out',
|
|
journal=Journals.search(['type', '=', 'revenue'])[0],
|
|
account=Config.default_account_receivable,
|
|
party=subscription.party,
|
|
invoice_date=date,
|
|
invoice_address=subscription.invoice_address,
|
|
lines=invoice_lines,
|
|
)
|
|
invoice.save()
|
|
|
|
def transition_create_(self):
|
|
pool = Pool()
|
|
Subscription = pool.get('sale.subscription')
|
|
self.generate_invoice(date=self.start.date)
|
|
|
|
return 'end'
|
|
|
|
|
|
class ContractEquipment(ModelSQL):
|
|
'Optical Equipment - Contract'
|
|
__name__ = 'optical_equipment.contract-optical_equipment.equipment'
|
|
|
|
equipment = fields.Many2One('optical_equipment.equipment', 'Equipment', select=True)
|
|
contract = fields.Many2One('optical_equipment.contract', 'Contract', select=True)
|
|
|
|
class SubscriptionEquipment(ModelSQL):
|
|
'Optical Equipment - Subscription'
|
|
__name__ = 'sale.subscription-optical_equipment.equipment'
|
|
|
|
subscription = fields.Many2One('sale.subscription', 'Subscription', select=True)
|
|
equipment = fields.Many2One('optical_equipment.equipment', 'Equipment', select=True)
|
|
|
|
class ContractSupscription(ModelSQL):
|
|
'Prorrogation to the Contract'
|
|
__name__='sale.subscription-optical_equipment.contract'
|
|
|
|
contract = fields.Many2One('optical_equipment.contract', 'Contract', select=True)
|
|
subscription = fields.Many2One('sale.subscription', 'Subscription', select=True)
|