1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/sale_renting/report/rental_schedule.py
2024-12-10 09:04:09 +07:00

213 lines
8.6 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, tools
from odoo.addons.sale.models.sale_order import SALE_ORDER_STATE
from odoo.addons.sale_renting.models.sale_order import RENTAL_STATUS
class RentalSchedule(models.Model):
_name = "sale.rental.schedule"
_description = "Rental Schedule"
_auto = False
_order = 'order_date desc'
_rec_name = 'card_name'
@api.model
def _read_group_report_line_status(self, report_line_status, domain, order):
return [key for key, val in self._fields['report_line_status'].selection]
@api.model
def _read_group_product_ids(self, products, domain, order):
if self._context.get('restrict_renting_products'):
return products
all_rental_products = products.search([('rent_ok', '=', True)], order=order)
if len(all_rental_products) > 80:
return products
return all_rental_products
@api.model
def get_gantt_data(self, domain, groupby, read_specification, limit=None, offset=0):
if (
limit
and not offset
and len(groupby) == 1
and not self.env.context.get('restrict_renting_products')
and limit >= self.env['product.product'].search_count(
[('rent_ok', '=', True)],
limit=limit + 1,
)
):
# If there are less rental products in the database than the given limit, drop the limit
# so that the read_group is lazy and the `group_expand` is called
limit = None
return super().get_gantt_data(domain, groupby, read_specification, limit=limit, offset=offset)
name = fields.Char('Order Reference', readonly=True)
product_name = fields.Char('Product Reference', readonly=True)
description = fields.Char('Description', readonly=True)
order_date = fields.Datetime('Order Date', readonly=True)
pickup_date = fields.Datetime('Pickup Date', readonly=True)
return_date = fields.Datetime('Return Date', readonly=True)
product_id = fields.Many2one('product.product', 'Product', readonly=True, group_expand="_read_group_product_ids")
product_uom = fields.Many2one('uom.uom', 'Unit of Measure', readonly=True)
product_uom_qty = fields.Float('Qty Ordered', readonly=True)
qty_delivered = fields.Float('Qty Picked-Up', readonly=True)
qty_returned = fields.Float('Qty Returned', readonly=True)
partner_id = fields.Many2one('res.partner', 'Customer', readonly=True)
card_name = fields.Char(string="Customer Name", readonly=True)
company_id = fields.Many2one('res.company', 'Company', readonly=True)
user_id = fields.Many2one('res.users', 'Salesperson', readonly=True)
product_tmpl_id = fields.Many2one('product.template', 'Product Template', readonly=True)
categ_id = fields.Many2one('product.category', 'Product Category', readonly=True)
analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account', readonly=True)
team_id = fields.Many2one('crm.team', 'Sales Team', readonly=True)
country_id = fields.Many2one('res.country', 'Customer Country', readonly=True)
commercial_partner_id = fields.Many2one('res.partner', 'Customer Entity', readonly=True)
rental_status = fields.Selection(selection=RENTAL_STATUS, string="Rental Status", readonly=True)
state = fields.Selection(selection=SALE_ORDER_STATE, string="Status", readonly=True)
order_id = fields.Many2one('sale.order', 'Order #', readonly=True)
order_line_id = fields.Many2one('sale.order.line', 'Order line #', readonly=True)
report_line_status = fields.Selection([
('reserved', 'Reserved'),
('pickedup', 'Pickedup'),
('returned', 'Returned'),
], string="Rental Status (advanced)", readonly=True, group_expand="_read_group_report_line_status")
color = fields.Integer(readonly=True)
late = fields.Boolean("Is Late", readonly=True)
def _with(self):
return """ """
def _id(self):
return """sol.id as id"""
def _get_product_name(self):
return """t.name as product_name"""
def _quantity(self):
return """
sum(sol.product_uom_qty / u.factor * u2.factor) as product_uom_qty,
sum(sol.qty_delivered / u.factor * u2.factor) as qty_delivered,
sum(sol.qty_returned / u.factor * u2.factor) as qty_returned
"""
def _late(self):
return """
CASE WHEN sol.state != 'sale' THEN FALSE
WHEN s.rental_start_date < NOW() AT TIME ZONE 'UTC' AND sol.qty_delivered < sol.product_uom_qty THEN TRUE
WHEN s.rental_return_date < NOW() AT TIME ZONE 'UTC' AND sol.qty_returned < sol.qty_delivered THEN TRUE
ELSE FALSE
END as late
"""
def _report_line_status(self):
return """
CASE WHEN sol.qty_returned = sol.qty_delivered
AND sol.qty_delivered = sol.product_uom_qty THEN 'returned'
WHEN sol.qty_delivered = sol.product_uom_qty THEN 'pickedup'
ELSE 'reserved'
END as report_line_status
"""
def _color(self):
"""2 = orange (pickedup), 4 = blue(reserved), 6 = red(late return), 7 = green(returned)"""
return """
CASE WHEN s.rental_start_date < NOW() AT TIME ZONE 'UTC' AND sol.qty_delivered < sol.product_uom_qty THEN 4
WHEN s.rental_return_date < NOW() AT TIME ZONE 'UTC' AND sol.qty_returned < sol.qty_delivered THEN 6
WHEN sol.qty_returned = sol.qty_delivered AND sol.qty_delivered = sol.product_uom_qty THEN 7
WHEN sol.qty_delivered = sol.product_uom_qty THEN 2
ELSE 4
END as color
"""
def _select(self):
return """%s,
%s,
sol.product_id as product_id,
t.uom_id as product_uom,
sol.name as description,
s.name as name,
%s,
s.date_order as order_date,
s.rental_start_date as pickup_date,
s.rental_return_date as return_date,
s.state as state,
s.rental_status as rental_status,
s.partner_id as partner_id,
s.user_id as user_id,
s.company_id as company_id,
extract(epoch from avg(date_trunc('day',s.rental_return_date)-date_trunc('day',s.rental_start_date)))/(24*60*60)::decimal(16,2) as delay,
t.categ_id as categ_id,
s.pricelist_id as pricelist_id,
s.analytic_account_id as analytic_account_id,
s.team_id as team_id,
p.product_tmpl_id,
partner.country_id as country_id,
partner.commercial_partner_id as commercial_partner_id,
CONCAT(partner.name, ', ', s.name) as card_name,
s.id as order_id,
sol.id as order_line_id,
%s,
%s,
%s
""" % (self._id(), self._get_product_name(), self._quantity(), self._report_line_status(), self._late(), self._color())
def _from(self):
return """
sale_order_line sol
join sale_order s on (sol.order_id=s.id)
join res_partner partner on s.partner_id = partner.id
left join product_product p on (sol.product_id=p.id)
left join product_template t on (p.product_tmpl_id=t.id)
left join uom_uom u on (u.id=sol.product_uom)
left join uom_uom u2 on (u2.id=t.uom_id)
"""
def _groupby(self):
return """
sol.product_id,
sol.order_id,
t.uom_id,
t.categ_id,
t.name,
s.name,
s.date_order,
s.rental_start_date,
s.rental_return_date,
s.partner_id,
s.user_id,
s.rental_status,
s.company_id,
s.pricelist_id,
s.analytic_account_id,
s.team_id,
p.product_tmpl_id,
partner.country_id,
partner.commercial_partner_id,
partner.name,
s.id,
sol.id
"""
def _query(self):
return """
%s (SELECT %s
FROM %s
WHERE sol.product_id IS NOT NULL
AND sol.is_rental
GROUP BY %s)
""" % (
self._with(),
self._select(),
self._from(),
self._groupby()
)
def init(self):
# self._table = sale_rental_report
tools.drop_view_if_exists(self.env.cr, self._table)
self.env.cr.execute("""CREATE or REPLACE VIEW %s as (%s)""" % (self._table, self._query()))