156 lines
5.4 KiB
Python
156 lines
5.4 KiB
Python
# The COPYRIGHT file at the top level of this repository contains the full
|
|
# copyright notices and license terms.
|
|
from decimal import Decimal
|
|
from trytond.pool import PoolMeta, Pool
|
|
from trytond.model import fields
|
|
from trytond.pyson import Eval, Not, Bool, Or
|
|
from trytond.transaction import Transaction
|
|
from trytond.exceptions import UserError
|
|
from trytond.i18n import gettext
|
|
from sql.operators import Concat
|
|
from functools import partial
|
|
from itertools import groupby
|
|
|
|
|
|
class SaleCost(metaclass=PoolMeta):
|
|
__name__ = 'sale.cost'
|
|
|
|
purchase = fields.Function(
|
|
fields.Many2One('purchase.purchase', 'Purchase', readonly=True,
|
|
states={
|
|
'invisible': Eval('apply_method', '') != 'purchase'
|
|
}, depends=['apply_method']), 'get_purchase')
|
|
purchase_lines = fields.One2Many('purchase.line', 'origin',
|
|
'Purchase lines',
|
|
states={
|
|
'invisible': Eval('apply_method', '') != 'purchase'
|
|
}, depends=['apply_method'])
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super().__setup__()
|
|
invisible_condition = cls._buttons['apply']['invisible']
|
|
cls._buttons['apply']['invisible'] = Or(
|
|
invisible_condition,
|
|
Bool(Eval('purchase')))
|
|
cls._buttons['apply']['depends'].append('purchase')
|
|
invisible_condition = cls._buttons['unapply']['invisible']
|
|
cls._buttons['unapply']['invisible'] = Or(
|
|
invisible_condition,
|
|
Not(Bool(Eval('purchase'))))
|
|
cls._buttons['unapply']['depends'].append('purchase')
|
|
cls.apply_method.selection.append(('purchase', 'Purchase'))
|
|
cls.invoice_party.states['invisible'] &= (
|
|
Eval('apply_method') != 'purchase')
|
|
|
|
@classmethod
|
|
def __register__(cls, module_name):
|
|
table = cls.__table_handler__(module_name)
|
|
Purchase_lines = Pool().get('purchase.line')
|
|
cursor = Transaction().connection.cursor()
|
|
sql_table = cls.__table__()
|
|
purchase_line = Purchase_lines.__table__()
|
|
|
|
purchase_exists = table.column_exist('purchase')
|
|
|
|
super(SaleCost, cls).__register__(module_name)
|
|
|
|
if purchase_exists:
|
|
cursor.execute(*purchase_line.join(sql_table,
|
|
condition=purchase_line.purchase == sql_table.purchase
|
|
).select(
|
|
purchase_line.id,
|
|
sql_table.id,
|
|
where=(purchase_line.type == 'line'))
|
|
)
|
|
|
|
for pline_id, cost_id in cursor.fetchall():
|
|
cursor.execute(*purchase_line.update(
|
|
columns=[purchase_line.origin],
|
|
values=[Concat(cls.__name__ + ',', cost_id)],
|
|
where=purchase_line.id == pline_id
|
|
))
|
|
|
|
table.drop_column('purchase')
|
|
|
|
def get_purchase(self, name=None):
|
|
if self.purchase_lines:
|
|
return self.purchase_lines[0].purchase.id
|
|
|
|
@classmethod
|
|
def _apply_method(cls, apply_method, costs):
|
|
Purchase = Pool().get('purchase.purchase')
|
|
|
|
if apply_method != 'purchase':
|
|
return super()._apply_method(apply_method, costs)
|
|
|
|
cost_keyfunc = partial(cls._get_purchase_keygroup)
|
|
sorted_cost_lines = sorted(costs, key=cost_keyfunc)
|
|
purchases = []
|
|
for key, grouped_lines in groupby(sorted_cost_lines, key=cost_keyfunc):
|
|
purchase = Purchase(**dict(key))
|
|
purchase.on_change_party()
|
|
lines = []
|
|
|
|
group_lines = list(grouped_lines)
|
|
for cost in group_lines:
|
|
lines.append(cost._get_purchase_line(purchase))
|
|
purchase.lines = lines
|
|
purchases.append(purchase)
|
|
Purchase.save(purchases)
|
|
Purchase.quote(purchases)
|
|
|
|
return []
|
|
|
|
def _get_purchase_line(self, purchase):
|
|
pool = Pool()
|
|
PurchaseLine = pool.get('purchase.line')
|
|
|
|
line = PurchaseLine()
|
|
line.purchase = purchase
|
|
line.type = 'line'
|
|
line.product = self.type_.product
|
|
line.on_change_product()
|
|
line.quantity = self.quantity
|
|
line.on_change_quantity()
|
|
digits = PurchaseLine.unit_price.digits[1]
|
|
line.unit_price = (self.amount / Decimal(str(self.quantity))
|
|
).quantize(Decimal(10) ** -Decimal(digits))
|
|
line.amount = line.on_change_with_amount()
|
|
line.origin = self
|
|
return line
|
|
|
|
@classmethod
|
|
def _get_purchase_keygroup(cls, cost):
|
|
if not cost.invoice_party:
|
|
raise UserError(gettext('document_cost_apply_invoice.'
|
|
'msg_document_cost_apply_invoice_invoice_no_party',
|
|
type_=cost.type_.rec_name,
|
|
cost=cost.document.rec_name))
|
|
return [
|
|
('company', cost.document.company),
|
|
('party', cost.invoice_party),
|
|
('purchase_date', cost.sale.sale_date)]
|
|
|
|
@classmethod
|
|
def _unapply_method(cls, apply_method, costs):
|
|
pool = Pool()
|
|
Purchase = pool.get('purchase.purchase')
|
|
|
|
if apply_method != 'purchase':
|
|
super(SaleCost, cls)._unapply_method(apply_method, costs)
|
|
|
|
purchases = Purchase.search([
|
|
('id', 'in', [c.purchase.id for c in costs if c.purchase])])
|
|
if purchases:
|
|
Purchase.delete(purchases)
|
|
|
|
|
|
class CostType(metaclass=PoolMeta):
|
|
__name__ = 'sale.cost.type'
|
|
|
|
@classmethod
|
|
def __setup__(cls):
|
|
super(CostType, cls).__setup__()
|
|
cls.apply_method.selection.append(('purchase', 'Purchase'))
|