trytondo-optical_equipment/sale.py

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()