185 lines
6.9 KiB
Python
185 lines
6.9 KiB
Python
# This file is part of 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.pool import PoolMeta, Pool
|
|
from trytond.report import Report
|
|
from trytond.model import fields, ModelView
|
|
from datetime import date
|
|
from trytond.transaction import Transaction
|
|
from trytond.wizard import (
|
|
Wizard, StateView, StateReport, Button
|
|
)
|
|
|
|
|
|
class PriceListLine(metaclass=PoolMeta):
|
|
__name__ = 'product.price_list.line'
|
|
price_computed = fields.Function(fields.Numeric('Price Computed',
|
|
digits=(16, 2), depends=['formula']), 'get_price_computed')
|
|
price_w_tax_computed = fields.Function(fields.Numeric('Price W Tax Computed',
|
|
digits=(16, 2), depends=['formula']), 'get_price_w_tax_computed')
|
|
profit = fields.Function(fields.Float('Profit',
|
|
digits=(16, 2)), 'get_profit')
|
|
|
|
def get_profit(self, name=None):
|
|
if self.product:
|
|
if self.product.cost_price and self.price_computed and self.product.cost_price != 0:
|
|
# res = float((self.list_price / self.cost_price) - 1) * 100 Oscar
|
|
res = float(1-(self.product.cost_price/self.price_computed)) * 100 # villa
|
|
return round(res, 2)
|
|
else:
|
|
return 0
|
|
|
|
@classmethod
|
|
def search_rec_name(cls, name, clause):
|
|
if clause[1].startswith('!') or clause[1].startswith('not '):
|
|
bool_op = 'AND'
|
|
else:
|
|
bool_op = 'OR'
|
|
return [
|
|
bool_op,
|
|
('product',) + tuple(clause[1:]),
|
|
]
|
|
|
|
def get_price_computed(self, name):
|
|
value = 0
|
|
if self.product:
|
|
context = self.price_list.get_context_formula(
|
|
None, self.product, self.product.list_price, 0, None)
|
|
value = self.get_unit_price(**context)
|
|
return value
|
|
|
|
def get_price_w_tax_computed(self, name=None):
|
|
if self.product:
|
|
res = self.price_computed
|
|
taxes = self.product.template.account_category.customer_taxes_used
|
|
for tax in taxes:
|
|
if tax.type == 'fixed':
|
|
res += tax.amount
|
|
elif tax.rate > 0:
|
|
res += self.price_computed * tax.rate
|
|
return Decimal(str(round(res + (self.product.extra_tax or 0))))
|
|
else:
|
|
return 0
|
|
|
|
|
|
# class ProductPriceList(Report):
|
|
# __name__ = 'product.price_list.report'
|
|
# data=None
|
|
|
|
# @classmethod
|
|
# def get_context(cls, records, header, data):
|
|
# report_context = super().get_context(records, header, data)
|
|
# report_context['records'] = records
|
|
# report_context['sysdate'] = date.today()
|
|
# return report_context
|
|
|
|
|
|
class PriceListBySupplierStart(ModelView):
|
|
'Price List By Supplier Start'
|
|
__name__ = 'sale_shop.price_list_by_supplier.start'
|
|
company = fields.Many2One('company.company', 'Company', required=True)
|
|
price_list = fields.Many2One('product.price_list', 'Price List')
|
|
suppliers = fields.Many2Many('party.party', None, None, 'Supplier')
|
|
|
|
@staticmethod
|
|
def default_company():
|
|
return Transaction().context.get('company')
|
|
|
|
|
|
class PriceListBySupplier(Wizard):
|
|
'Price List By Supplier'
|
|
__name__ = 'sale_shop.price_list_by_supplier'
|
|
start = StateView(
|
|
'sale_shop.price_list_by_supplier.start',
|
|
'sale_shop.print_price_list_start_view_form', [
|
|
Button('Cancel', 'end', 'tryton-cancel'),
|
|
Button('Print', 'print_', 'tryton-print', default=True),
|
|
])
|
|
print_ = StateReport('sale_shop.price_list_by_supplier_report')
|
|
|
|
def do_print_(self, action):
|
|
supplier_ids = None
|
|
if self.start.suppliers:
|
|
supplier_ids = [s.id for s in self.start.suppliers]
|
|
data = {
|
|
'company': self.start.company.id,
|
|
'suppliers': supplier_ids,
|
|
}
|
|
if self.start.price_list:
|
|
data['price_list'] = self.start.price_list.id
|
|
return action, data
|
|
|
|
def transition_print_(self):
|
|
return 'end'
|
|
|
|
|
|
class PriceListBySupplierReport(Report):
|
|
'Sale By Supplier Report'
|
|
__name__ = 'sale_shop.price_list_by_supplier_report'
|
|
|
|
@classmethod
|
|
def get_context(cls, records, header, data):
|
|
report_context = super().get_context(records, header, data)
|
|
pool = Pool()
|
|
Company = pool.get('company.company')
|
|
ProductSupplier = pool.get('purchase.product_supplier')
|
|
PriceListLine = pool.get('product.price_list.line')
|
|
company = Company(data['company'])
|
|
dom_supplier = [
|
|
('template.active', '=', True),
|
|
]
|
|
if data['suppliers']:
|
|
dom_supplier.append(
|
|
('party.id', 'in', data['suppliers']),
|
|
)
|
|
products_suppliers = ProductSupplier.search(dom_supplier,
|
|
order=[('party.name', 'ASC'), ('template.name', 'ASC')])
|
|
suppliers_dict = {}
|
|
for ps in products_suppliers:
|
|
# products_ids = [p.id for p in ps.product.products if p.active]
|
|
lines=[]
|
|
for p in ps.template.products:
|
|
dom_price_list = [('product.id', '=', p.id)]
|
|
if data.get('price_list'):
|
|
dom_price_list.append(
|
|
('price_list', '=', data.get('price_list'))
|
|
)
|
|
price_list_lines = PriceListLine.search(dom_price_list)
|
|
price_w_extratax = Decimal(str(round(
|
|
p.template.sale_price_w_tax + (p.extra_tax or 0))))
|
|
if price_list_lines:
|
|
for pl in price_list_lines:
|
|
lines.append({
|
|
'code': p.code,
|
|
'name': p.name,
|
|
'price_w_tax': price_w_extratax,
|
|
'profit': p.profit,
|
|
'price_w_tax_computed': pl.price_w_tax_computed,
|
|
'profit_computed': pl.profit,
|
|
'quantity': pl.quantity
|
|
})
|
|
else:
|
|
lines.append({
|
|
'code': p.code,
|
|
'name': p.name,
|
|
'price_w_tax': price_w_extratax,
|
|
'profit': p.profit,
|
|
'price_w_tax_computed': 0,
|
|
'profit_computed': 0,
|
|
'quantity': None
|
|
})
|
|
|
|
try:
|
|
suppliers_dict[ps.party.id]['products'].extend(lines)
|
|
except:
|
|
suppliers_dict[ps.party.id] = {
|
|
'party': ps.party,
|
|
'products': lines
|
|
}
|
|
|
|
report_context['records'] = suppliers_dict.values()
|
|
report_context['today'] = date.today()
|
|
report_context['company'] = company.party.name
|
|
report_context['nit'] = company.party.id_number
|
|
return report_context
|