255 lines
9.4 KiB
Python
255 lines
9.4 KiB
Python
from trytond.pool import Pool, PoolMeta
|
|
from trytond.model import ModelView, ModelSQL, fields
|
|
from trytond.modules.currency.fields import Monetary
|
|
from trytond.pyson import Eval, Bool, If
|
|
from decimal import Decimal
|
|
from trytond.modules.product import price_digits
|
|
from trytond.transaction import Transaction
|
|
from trytond.model import Workflow
|
|
from trytond.modules.company.model import (
|
|
employee_field, set_employee, reset_employee)
|
|
|
|
from trytond.exceptions import UserError
|
|
|
|
from trytond.wizard import (
|
|
Button, StateAction, StateTransition, StateView, Wizard)
|
|
|
|
class Sale(metaclass=PoolMeta):
|
|
'Sale'
|
|
__name__ = 'sale.sale'
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
@Workflow.transition('confirmed')
|
|
@set_employee('confirmed_by')
|
|
def confirm(cls, sales):
|
|
pool = Pool()
|
|
Configuration = pool.get('sale.configuration')
|
|
cls.set_sale_date(sales)
|
|
cls.store_cache(sales)
|
|
config = Configuration(1)
|
|
|
|
pool = Pool()
|
|
Equipments = pool.get('optical_equipment.equipment')
|
|
|
|
for sale in sales:
|
|
for line in sale.lines:
|
|
if line.equipment:
|
|
equipment=line.equipment
|
|
equipment.propietary=sale.party.id
|
|
equipment.propietary_address=sale.shipment_address.id
|
|
equipment.state="uncontrated"
|
|
equipment.save()
|
|
|
|
with Transaction().set_context(
|
|
queue_name='sale',
|
|
queue_scheduled_at=config.sale_process_after):
|
|
cls.__queue__.process(sales)
|
|
|
|
|
|
class SaleLine(metaclass=PoolMeta):
|
|
'SaleLine'
|
|
__name__ = 'sale.line'
|
|
|
|
product_equipment = fields.Boolean("Product Equipment")
|
|
equipment = fields.Many2One('optical_equipment.equipment', "Equipment",
|
|
domain=[('state', '=', 'registred')],
|
|
states={'invisible': If(~Eval('product_equipment'), True)},)
|
|
address_equipment = fields.Many2One('party.address', "Direccion")
|
|
unit_digits = fields.Function(fields.Integer('Unit Digits'),
|
|
'on_change_with_unit_digits')
|
|
|
|
def on_change_with_unit_digits(self, name=None):
|
|
if self.unit:
|
|
return self.unit.digits
|
|
return 2
|
|
|
|
@fields.depends('equipment', 'sale', '_parent_sale.shipment_address', methods=['on_change_product'])
|
|
def on_change_equipment(self):
|
|
if self.equipment:
|
|
self.product = self.equipment.product.id
|
|
self.address_equipment = self.sale.shipment_address.id
|
|
self.on_change_product()
|
|
else:
|
|
self.address_equipment = None
|
|
self.product = None
|
|
self.unit= None
|
|
self.quantity = None
|
|
self.unit_price = None
|
|
self.amount = None
|
|
self.on_change_product()
|
|
|
|
@fields.depends('product_equipment', methods=['on_change_equipment'])
|
|
def on_change_product_equipment(self):
|
|
if self.product_equipment == False:
|
|
self.equipment = None
|
|
self.on_change_equipment()
|
|
|
|
|
|
|
|
@fields.depends('product', 'unit', 'quantity', 'sale',
|
|
'_parent_sale.party',methods=['_get_tax_rule_pattern',
|
|
'_get_context_sale_price','on_change_with_amount'])
|
|
def on_change_product(self):
|
|
Product = Pool().get('product.product')
|
|
if not self.product:
|
|
self.product_equipment = False
|
|
self.unit = None
|
|
return
|
|
|
|
party = None
|
|
|
|
if self.sale and self.sale.party:
|
|
self.product_equipment = False
|
|
party = self.sale.party
|
|
|
|
# Set taxes before unit_price to have taxes in context of sale price
|
|
taxes = []
|
|
pattern = self._get_tax_rule_pattern()
|
|
for tax in self.product.customer_taxes_used:
|
|
if party and party.customer_tax_rule:
|
|
tax_ids = party.customer_tax_rule.apply(tax, pattern)
|
|
if tax_ids:
|
|
taxes.extend(tax_ids)
|
|
continue
|
|
taxes.append(tax.id)
|
|
|
|
if party and party.customer_tax_rule:
|
|
tax_ids = party.customer_tax_rule.apply(None, pattern)
|
|
if tax_ids:
|
|
taxes.extend(tax_ids)
|
|
self.taxes = taxes
|
|
|
|
category = self.product.sale_uom.category
|
|
if not self.unit or self.unit.category != category:
|
|
self.unit = self.product.sale_uom
|
|
self.unit_digits = self.product.sale_uom.digits
|
|
|
|
with Transaction().set_context(self._get_context_sale_price()):
|
|
self.unit_price = Product.get_sale_price([self.product],
|
|
self.quantity or 0)[self.product.id]
|
|
|
|
if self.unit_price:
|
|
self.unit_price = self.unit_price.quantize(
|
|
Decimal(1) / 10 ** self.__class__.unit_price.digits[1])
|
|
|
|
self.type = 'line'
|
|
self.amount = self.on_change_with_amount()
|
|
self.product_equipment = True
|
|
|
|
@classmethod
|
|
@ModelView.button
|
|
def process(cls, sales):
|
|
states = {'confirmed', 'processing', 'done'}
|
|
sales = [s for s in sales if s.state in states]
|
|
cls.lock(sales)
|
|
cls._process_invoice(sales)
|
|
cls._process_shipment(sales)
|
|
cls._process_invoice_shipment_states(sales)
|
|
cls._process_state(sales)
|
|
|
|
@classmethod
|
|
def view_attributes(cls):
|
|
return super(SaleLine, cls).view_attributes() + [
|
|
('//page[@id="equipment"]', 'states', {
|
|
'invisible': ~Eval('product_equipment', True),
|
|
})]
|
|
|
|
|
|
class CreateSubscriptionStart(ModelView):
|
|
'Create Subscription Start'
|
|
__name__ = 'sale.create.subscription.start'
|
|
|
|
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",
|
|
help='Billing start date')
|
|
service = fields.Many2One('sale.subscription.service', "Service")
|
|
quantity = fields.Float("Quantity", digits='unit')
|
|
unit_price = Monetary("Unit Price", currency='currency',
|
|
digits=price_digits,
|
|
)
|
|
|
|
@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 CreateSubscription(Wizard):
|
|
'Create Subscription'
|
|
__name__ = 'sale.create.subscription'
|
|
|
|
start = StateView('sale.create.subscription.start',
|
|
'optical_equipment.create_subscription_view_form',[
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Create', 'create_subscription', 'tryton-ok', default=True),
|
|
])
|
|
create_subscription = StateAction('sale_subscription.act_subscription_form')
|
|
|
|
done_ = StateView('sale.create.subscription.start',
|
|
'optical_equipment.create_subscription_view_form',[
|
|
Button('Done', 'end', 'tryton-cancel'),
|
|
])
|
|
@property
|
|
def _subscription_start(self):
|
|
return dict(start_date=self.start.start_date,
|
|
end_date=self.start.end_date,
|
|
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)
|
|
|
|
def _equipments_to_subscription(self):
|
|
sale = self.records[0]
|
|
equipments_to_subscription = []
|
|
for line in sale.lines:
|
|
if line.product_equipment:
|
|
equipments_to_subscription.append(line.equipment)
|
|
|
|
return equipments_to_subscription
|
|
|
|
def do_create_subscription(self, action):
|
|
pool = Pool()
|
|
Subscription = pool.get('sale.subscription')
|
|
SubscriptionLine = pool.get('sale.subscription.line')
|
|
|
|
sale = self.records[0]
|
|
a = self._subscription_start
|
|
|
|
equipments_to_subscription=self._equipments_to_subscription()
|
|
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(
|
|
start_date=a['start_date'],
|
|
end_date=a['end_date'],
|
|
invoice_recurrence=a['invoice_recurrence'],
|
|
invoice_start_date=a['invoice_start_date'],
|
|
party=sale.party.id,
|
|
contact=sale.contact.id if sale.contact else None,
|
|
invoice_party=sale.invoice_party.id if sale.invoice_party else None,
|
|
invoice_address=sale.invoice_address.id,
|
|
payment_term=sale.payment_term.id if sale.payment_term else None,
|
|
lines=subscription_lines,
|
|
equipments=equipments_to_subscription,
|
|
)
|
|
subscription.save()
|