2017-10-08 02:23:22 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# This file is part of lims_account_invoice module for Tryton.
|
|
|
|
# The COPYRIGHT file at the top level of this repository contains
|
|
|
|
# the full copyright notices and license terms.
|
|
|
|
from decimal import Decimal
|
|
|
|
|
|
|
|
from trytond.model import fields
|
|
|
|
from trytond.pool import Pool, PoolMeta
|
|
|
|
from trytond.transaction import Transaction
|
2019-07-23 23:27:33 +02:00
|
|
|
from trytond.exceptions import UserError
|
|
|
|
from trytond.i18n import gettext
|
2017-10-08 02:23:22 +02:00
|
|
|
|
|
|
|
|
2019-03-04 15:41:58 +01:00
|
|
|
class FractionType(metaclass=PoolMeta):
|
2017-10-08 02:23:22 +02:00
|
|
|
__name__ = 'lims.fraction.type'
|
|
|
|
|
|
|
|
invoiceable = fields.Boolean('Invoiceable')
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def default_invoiceable():
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
2019-03-04 15:41:58 +01:00
|
|
|
class Entry(metaclass=PoolMeta):
|
2017-10-08 02:23:22 +02:00
|
|
|
__name__ = 'lims.entry'
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def on_hold(cls, entries):
|
2020-08-06 19:52:36 +02:00
|
|
|
super().on_hold(entries)
|
2017-10-08 02:23:22 +02:00
|
|
|
cls.create_invoice_lines(entries)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def create_invoice_lines(cls, entries):
|
2018-05-10 04:48:19 +02:00
|
|
|
Service = Pool().get('lims.service')
|
2017-10-08 02:23:22 +02:00
|
|
|
|
|
|
|
with Transaction().set_context(_check_access=False):
|
2018-05-10 04:48:19 +02:00
|
|
|
services = Service.search([
|
2017-10-08 02:23:22 +02:00
|
|
|
('entry', 'in', [e.id for e in entries]),
|
2020-12-16 15:13:05 +01:00
|
|
|
('annulled', '=', False),
|
2017-10-08 02:23:22 +02:00
|
|
|
])
|
|
|
|
for service in services:
|
|
|
|
service.create_invoice_line('out')
|
|
|
|
|
|
|
|
|
2019-03-04 15:41:58 +01:00
|
|
|
class Fraction(metaclass=PoolMeta):
|
2017-10-08 02:23:22 +02:00
|
|
|
__name__ = 'lims.fraction'
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def confirm(cls, fractions):
|
|
|
|
fractions_to_invoice = [f for f in fractions if
|
|
|
|
f.sample.entry.state != 'pending']
|
2020-08-06 19:52:36 +02:00
|
|
|
super().confirm(fractions)
|
2017-10-08 02:23:22 +02:00
|
|
|
if fractions_to_invoice:
|
|
|
|
cls.create_invoice_lines(fractions_to_invoice)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def create_invoice_lines(cls, fractions):
|
2018-05-10 04:48:19 +02:00
|
|
|
Service = Pool().get('lims.service')
|
2017-10-08 02:23:22 +02:00
|
|
|
|
|
|
|
with Transaction().set_context(_check_access=False):
|
2018-05-10 04:48:19 +02:00
|
|
|
services = Service.search([
|
2017-10-08 02:23:22 +02:00
|
|
|
('fraction', 'in', [f.id for f in fractions]),
|
2020-12-16 15:13:05 +01:00
|
|
|
('annulled', '=', False),
|
2017-10-08 02:23:22 +02:00
|
|
|
])
|
|
|
|
for service in services:
|
|
|
|
service.create_invoice_line('out')
|
|
|
|
|
|
|
|
|
2019-03-04 15:41:58 +01:00
|
|
|
class Service(metaclass=PoolMeta):
|
2017-10-08 02:23:22 +02:00
|
|
|
__name__ = 'lims.service'
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def create(cls, vlist):
|
2020-08-06 19:52:36 +02:00
|
|
|
services = super().create(vlist)
|
2017-10-08 02:23:22 +02:00
|
|
|
services_to_invoice = [s for s in services if
|
|
|
|
s.entry.state == 'pending']
|
|
|
|
for service in services_to_invoice:
|
|
|
|
service.create_invoice_line('out')
|
|
|
|
return services
|
|
|
|
|
|
|
|
def create_invoice_line(self, invoice_type):
|
|
|
|
InvoiceLine = Pool().get('account.invoice.line')
|
|
|
|
|
|
|
|
if (not self.fraction.type.invoiceable or
|
|
|
|
self.fraction.cie_fraction_type):
|
|
|
|
return
|
|
|
|
invoice_line = self.get_invoice_line(invoice_type)
|
|
|
|
if not invoice_line:
|
|
|
|
return
|
|
|
|
with Transaction().set_context(_check_access=False):
|
|
|
|
InvoiceLine.create([invoice_line])
|
|
|
|
|
|
|
|
def get_invoice_line(self, invoice_type):
|
|
|
|
Company = Pool().get('company.company')
|
|
|
|
|
|
|
|
company = Transaction().context.get('company')
|
|
|
|
currency = Company(company).currency.id
|
|
|
|
product = self.analysis.product if self.analysis else None
|
|
|
|
if not product:
|
|
|
|
return
|
|
|
|
account_revenue = product.account_revenue_used
|
|
|
|
if not account_revenue:
|
2019-07-23 23:27:33 +02:00
|
|
|
raise UserError(
|
|
|
|
gettext('lims_account_invoice.msg_missing_account_revenue',
|
|
|
|
product=self.analysis.product.rec_name,
|
|
|
|
service=self.rec_name))
|
2017-10-08 02:23:22 +02:00
|
|
|
|
|
|
|
party = self.entry.invoice_party
|
|
|
|
taxes = []
|
|
|
|
pattern = {}
|
|
|
|
for tax in product.customer_taxes_used:
|
|
|
|
if 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.customer_tax_rule:
|
|
|
|
tax_ids = party.customer_tax_rule.apply(None, pattern)
|
|
|
|
if tax_ids:
|
|
|
|
taxes.extend(tax_ids)
|
|
|
|
taxes_to_add = None
|
|
|
|
if taxes:
|
|
|
|
taxes_to_add = [('add', taxes)]
|
|
|
|
|
|
|
|
return {
|
|
|
|
'company': company,
|
|
|
|
'currency': currency,
|
|
|
|
'invoice_type': invoice_type,
|
|
|
|
'party': party,
|
|
|
|
'description': self.number + ' - ' + self.analysis.rec_name,
|
|
|
|
'origin': str(self),
|
|
|
|
'quantity': 1,
|
|
|
|
'unit': product.default_uom,
|
|
|
|
'product': product,
|
|
|
|
'unit_price': Decimal('1.00'),
|
|
|
|
'taxes': taxes_to_add,
|
|
|
|
'account': account_revenue,
|
|
|
|
}
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def delete(cls, services):
|
|
|
|
cls.delete_invoice_lines(services)
|
2020-08-06 19:52:36 +02:00
|
|
|
super().delete(services)
|
2017-10-08 02:23:22 +02:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def delete_invoice_lines(cls, services):
|
|
|
|
InvoiceLine = Pool().get('account.invoice.line')
|
|
|
|
|
|
|
|
lines_to_delete = []
|
|
|
|
for service in services:
|
|
|
|
lines = InvoiceLine.search([
|
|
|
|
('origin', '=', str(service)),
|
|
|
|
])
|
|
|
|
lines_to_delete.extend(lines)
|
|
|
|
if lines_to_delete:
|
|
|
|
for line in lines_to_delete:
|
|
|
|
if line.invoice:
|
2019-07-23 23:27:33 +02:00
|
|
|
raise UserError(gettext(
|
|
|
|
'lims_account_invoice.msg_delete_service_invoice'))
|
2017-10-08 02:23:22 +02:00
|
|
|
with Transaction().set_context(_check_access=False,
|
|
|
|
delete_service=True):
|
|
|
|
InvoiceLine.delete(lines_to_delete)
|
2018-05-10 04:48:19 +02:00
|
|
|
|
|
|
|
|
2019-03-04 15:41:58 +01:00
|
|
|
class ManageServices(metaclass=PoolMeta):
|
2018-05-10 04:48:19 +02:00
|
|
|
__name__ = 'lims.manage_services'
|
|
|
|
|
|
|
|
def create_service(self, service, fraction):
|
2020-08-06 19:52:36 +02:00
|
|
|
new_service = super().create_service(service, fraction)
|
2018-05-10 04:48:19 +02:00
|
|
|
new_service.create_invoice_line('out')
|
|
|
|
return new_service
|