Skip to content

[ADD] *: practice task implementation #690

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: 18.0
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions deposite_in_rental/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
11 changes: 11 additions & 0 deletions deposite_in_rental/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "deposite_in_rental",
"depends": ["base", "account_invoice_extract", "sale_renting", "website_sale"],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"depends": ["base", "account_invoice_extract", "sale_renting", "website_sale"],
"depends": ["website_sale_renting"],

No need for base module and are we using account_invoice_extract?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually was having issue while installing rental app.Something related to this account_invoice_extract module thats why I did that however with website_sale_renting its now working fine.

"data": [
"views/res_config_setting_rental_view.xml",
"views/product_template_inherit_view.xml",
"views/website_rental_inherit.xml",
"views/sale_order_line_inherit_view.xml",
],
"license": "LGPL-3",
}
3 changes: 3 additions & 0 deletions deposite_in_rental/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import res_config_settings_inherit
from . import product_template_inherit
from . import sale_order_line_rental_inherit
8 changes: 8 additions & 0 deletions deposite_in_rental/models/product_template_inherit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from odoo import fields, models


class ProductTemplateInherit(models.Model):
_inherit = "product.template"

require_deposite = fields.Boolean(string="Requires Deposite?")
deposite_amount = fields.Monetary(string="Deposite Amount")
21 changes: 21 additions & 0 deletions deposite_in_rental/models/res_config_settings_inherit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from odoo import api, fields, models


class ResConfigSettingInherit(models.TransientModel):
_inherit = "res.config.settings"

rental_product_id = fields.Many2one(
"product.product",
string="Deposite Product",
inverse="_set_rental_product",
compute="_get_rental_product",
)

def _set_rental_product(self):
self.env["ir.config_parameter"].set_param(
"rental.deposite_product", self.rental_product_id.id or ""
)

@api.depends()
def _get_rental_product(self):
return int(self.env["ir.config_parameter"].get_param("rental.deposite_product"))
44 changes: 44 additions & 0 deletions deposite_in_rental/models/sale_order_line_rental_inherit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from odoo import api, models, fields


class SaleOrderLineRentalInherit(models.Model):
_inherit = "sale.order.line"
main_rental_id = fields.Many2one("sale.order.line", ondelete="cascade")
child_rental_id = fields.Many2one("sale.order.line", ondelete="cascade")

@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
deposit_product_id = (
self.env["ir.config_parameter"].sudo().get_param("rental.deposite_product")
)
for line in res:
if (
deposit_product_id
and line.product_template_id.require_deposite
and line.product_template_id.deposite_amount
):
child_rental_ol = self.env["sale.order.line"].create(
{
"order_id": line.order_id.id,
"product_id": (int)(deposit_product_id),
"name": f"Deposit for {line.product_id.name}",
"product_uom_qty": line.product_uom_qty,
"price_unit": line.product_template_id.deposite_amount,
"main_rental_id": line.id,
}
)
line.child_rental_id = child_rental_ol.id
return res

def write(self, vals):
for line in self:
if line.child_rental_id and "product_uom_qty" in vals:
qty = vals["product_uom_qty"]
line.child_rental_id.write(
{
"product_uom_qty": qty,
"price_unit": line.product_template_id.deposite_amount,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this in write method?

}
)
return super().write(vals)
14 changes: 14 additions & 0 deletions deposite_in_rental/views/product_template_inherit_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0"?>
<odoo>
<record id="product_template_rental_inherit" model="ir.ui.view">

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ID naming should be according to the coding guidelines! Check all files.
https://www.odoo.com/documentation/18.0/contributing/development/coding_guidelines.html#xml-ids-and-naming

<field name="name">Product.Template.Rental.Inherit</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="sale_renting.product_template_form_view_rental"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='pricing']//group[@name='extra_rental']" position="inside">
<field name="require_deposite"/>
<field name="deposite_amount" invisible="not require_deposite"/>
</xpath>
</field>
</record>
</odoo>
16 changes: 16 additions & 0 deletions deposite_in_rental/views/res_config_setting_rental_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<odoo>
<record id="rental_config_setting_inherit" model="ir.ui.view">
<field name="name">Rental config inherit</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="sale_renting.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//form//setting[@name='rental_delay_costs']//div[hasclass('content-group')]" position='inside'>
<div class="row mt2 oe-inline">
<label for="rental_product_id"/>
<field name="rental_product_id"/>
</div>
</xpath>
</field>
</record>
</odoo>
19 changes: 19 additions & 0 deletions deposite_in_rental/views/sale_order_line_inherit_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<odoo>
<record id="sale_order_inherit_view_rental" model="ir.ui.view">
<field name="name">Sale.Order.Inherit.View.Rental</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='order_line']//list//field[@name='product_template_id']" position="attributes">
<attribute name="readonly">main_rental_id</attribute>
</xpath>
<xpath expr="//field[@name='order_line']//list//field[@name='product_uom_qty']" position="attributes">
<attribute name="readonly">main_rental_id</attribute>
</xpath>
<xpath expr="//field[@name='order_line']//list//field[@name='price_unit']" position="attributes">
<attribute name="readonly">main_rental_id</attribute>
</xpath>
</field>
</record>
</odoo>
16 changes: 16 additions & 0 deletions deposite_in_rental/views/website_rental_inherit.xml

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any changes from this file.. cart_lines will be added automatically, no need to change in that.
And there's no change in product page, check specs properly.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<odoo>
<template id="website_product_rental" inherit_id="website_sale.product">
<xpath expr="//div[@id='product_detail_main']//div[@id='o_wsale_cta_wrapper']" position="after">
<div class="my-2" t-if='product.deposite_amount'>
<h4>Deposite Amount: $<t t-esc='product.deposite_amount'/>
</h4>
</div>
</xpath>
</template>
<template id="website_sale_stock_cart_lines" inherit_id="website_sale.cart_lines" name="Shopping Cart Lines">
<xpath expr="//div[@name='website_sale_cart_line_quantity']" position="attributes">
<attribute name="t-att-class">'d-none' if line.main_rental_id else ''+('css_quantity input-group mb-2')</attribute>
</xpath>
</template>
</odoo>
1 change: 1 addition & 0 deletions discount_update/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
6 changes: 6 additions & 0 deletions discount_update/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "Update Discount OL",
"depends": ["base", "sale", "sale_management"],
"data": [],
"license": "LGPL-3",
}
2 changes: 2 additions & 0 deletions discount_update/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import sale_order_inherit
from . import sale_order_line_inherit
65 changes: 65 additions & 0 deletions discount_update/models/sale_order_inherit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from collections import defaultdict
from odoo import _, models


class SaleOrderInherit(models.Model):
_inherit = "sale.order"

def recalculate_discount(self):
for order in self:
discount_ol = order.order_line.filtered(
lambda ol: ol.is_global_discount_line
)
if not discount_ol:
return

discount_per = discount_ol[0].discount_percentage
discount_product = discount_ol[0].product_id
discount_ol.unlink()
total_price_per_tax_groups = defaultdict(float)

for line in order.order_line:
if not line.product_uom_qty or not line.price_unit:
continue

total_price_per_tax_groups[line.tax_id] += (
line.price_unit * line.product_uom_qty
)

if not total_price_per_tax_groups:
return

elif len(total_price_per_tax_groups) == 1:
taxes = next(iter(total_price_per_tax_groups.keys()))
subtotal = total_price_per_tax_groups[taxes]
self.env["sale.order.line"].create(
{
"order_id": order.id,
"product_id": discount_product.id,
"name": _("Discount: %(percent)s%%", percent=discount_per),
"product_uom_qty": 1,
"tax_id": [(6, 0, taxes.ids)],
"price_unit": -subtotal * discount_per / 100,
}
)

else:
vals_list = [
(
{
"order_id": order.id,
"product_id": discount_product.id,
"name": _(
"Discount: %(percent)s%%"
"- On products with the following taxes %(taxes)s",
percent=discount_per,
taxes=", ".join(taxes.mapped("name")),
),
"product_uom_qty": 1,
"tax_id": [(6, 0, taxes.ids)],
"price_unit": -subtotal * discount_per / 100,
}
)
for taxes, subtotal in total_price_per_tax_groups.items()
]
self.env["sale.order.line"].create(vals_list)
44 changes: 44 additions & 0 deletions discount_update/models/sale_order_line_inherit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import re
from odoo import api, fields, models


class SaleOrderLineInherit(models.Model):
_inherit = "sale.order.line"

is_global_discount_line = fields.Boolean(default=False)
discount_percentage = fields.Float()

@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
for line in res:
if "%" in line.name:
match = re.search(r"(\d+(?:\.\d+)?)%", line.name)
if match:
value = float(match.group(1))
line.discount_percentage = value
line.is_global_discount_line = True
else:
line.order_id.recalculate_discount()
return res

def write(self, vals):
if self.env.context.get("skip_recalculate_discount"):
return super().write(vals)

res = super().write(vals)

for line in self:
line.order_id.with_context(
skip_recalculate_discount=True
).recalculate_discount()
return res

def unlink(self):
orders = self.filtered(lambda ol: not ol.is_global_discount_line).mapped(
"order_id"
)
res = super().unlink()
for order in orders:
order.recalculate_discount()
return res
1 change: 1 addition & 0 deletions inventory_task/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
7 changes: 7 additions & 0 deletions inventory_task/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "Inventory Task",
"description": "Inventory UI customization module",
"depends": ["base", "product", "stock"],
"data": ["views/product_template_views.xml"],
"license": "LGPL-3",
}
1 change: 1 addition & 0 deletions inventory_task/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import product_template
68 changes: 68 additions & 0 deletions inventory_task/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from odoo import api, fields, models


class ProductTemplate(models.Model):
_inherit = "product.template"

qty_input = fields.Float(
"Quantity on Hand", compute="_compute_qty_input", inverse="_inverse_qty_input"
)

is_multi_location = fields.Boolean(
compute="_compute_is_multi_location", store=False
)

@api.depends("company_id")
def _compute_is_multi_location(self):
for product in self:
product.is_multi_location = self.env.user.has_group(
"stock.group_stock_multi_locations"
)

@api.depends("qty_available")
def _compute_qty_input(self):
for record in self:
record.qty_input = record.qty_available

def _inverse_qty_input(self):
return

@api.onchange("qty_input")
def _onchange_new_qty(self):
for product in self:
if product.qty_input >= 0:
if not product.product_variant_id:
continue
stock_quant = self.env["stock.quant"].search(
[
("product_id", "=", product.product_variant_id.id),
],
limit=1,
)

if stock_quant:
stock_quant.sudo().write({"quantity": product.qty_input})
else:
warehouse = self.env["stock.warehouse"].search(
[("company_id", "=", self.env.company.id)], limit=1
)
self.env["stock.quant"].with_context(inventory_mode=True).create(
{
"product_id": product.product_variant_id.id,
"location_id": warehouse.lot_stock_id.id,
"quantity": product.qty_input,
}
)

def action_product_replenish(self):
return {
"name": "Low on stock? Let's replenish.",
"type": "ir.actions.act_window",
"res_model": "product.replenish",
"view_mode": "form",
"view_id": self.env.ref("stock.view_product_replenish").id,
"target": "new",
"context": {
"default_product_tmpl_id": self.id,
},
}
Loading