Skip to content

[ADD] modular_types: implement modular type-based qty adjustments in … #708

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 1 commit into
base: 18.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions modular_types/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import wizard
19 changes: 19 additions & 0 deletions modular_types/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
'name': 'modular Types',
'version': '1.0',
'summary': 'Add modular types to products and set price of MO lines according to modular types',
'author': 'chirag Gami(chga)',
'category': 'Manufacture',
'depends': ['base', 'sale_management', 'mrp'],
'license': 'LGPL-3',
'data': [
'security/ir.model.access.csv',
'views/product_views.xml',
'views/mrp_bom_views.xml',
'views/sale_order_views.xml',
'wizard/modular_type_wizard_views.xml',
'views/mrp_production_views.xml',
],
'installable': True,
'application': True,
}
7 changes: 7 additions & 0 deletions modular_types/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from . import product_template
from . import modular_type
from . import mrp_bom
from . import stock_move
from . import sale_order_line
from . import sale_order
from . import sale_order_line_modular_type_value
8 changes: 8 additions & 0 deletions modular_types/models/modular_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from odoo import fields, models


class ModularType(models.Model):
_name = 'modular.type'
_description = "Modular Type "

name = fields.Char(string="name")
18 changes: 18 additions & 0 deletions modular_types/models/mrp_bom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from odoo import fields, models, api


class MrpBomLine(models.Model):
_inherit = 'mrp.bom.line'

modular_type_id = fields.Many2one('modular.type', domain="[('id', 'in', available_modular_type_ids)]")

available_modular_type_ids = fields.Many2many(
'modular.type',
compute='_compute_available_modular_types',
string="Available Modular Types",
)

@api.depends('product_id')
def _compute_available_modular_types(self):
for line in self:
line.available_modular_type_ids = line.parent_product_tmpl_id.modular_types if line.product_id else False
8 changes: 8 additions & 0 deletions modular_types/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from odoo import fields, models


class ProductTemplate(models.Model):
''' Add field modular_types m2m for store Modular Types of products '''
_inherit = 'product.template'

modular_types = fields.Many2many('modular.type')
26 changes: 26 additions & 0 deletions modular_types/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from odoo import models


class SaleOrder(models.Model):
_inherit = 'sale.order'

def action_confirm(self):
res = super().action_confirm()
for order in self:
for production in order.mrp_production_ids:
# Find matching order line
matching_order_lines = order.order_line.filtered(lambda line:
line.product_id == production.product_id and
line.product_uom_qty == production.product_qty
)
if not matching_order_lines:
continue
for matching_line in matching_order_lines:
for component in production.move_raw_ids.filtered(lambda comp: comp.modular_type_id):
# Look up modular value for that line and modular type
modular_value = self.env['sale.order.line.modular.value'].search([
('order_line_id', '=', matching_line.id),
('modular_type_id', '=', component.modular_type_id.id)
], limit=1)
component.product_uom_qty *= modular_value.value if modular_value else 0.0
return res
17 changes: 17 additions & 0 deletions modular_types/models/sale_order_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from odoo import models, fields, api


class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'

has_modular_type = fields.Boolean(
string="Has Modular Type",
compute="_compute_has_modular_type",
store=True
)
modular_value_ids = fields.One2many('sale.order.line.modular.value', 'order_line_id', string="Modular Values")

@api.depends('product_template_id', 'product_template_id.modular_types')
def _compute_has_modular_type(self):
for line in self:
line.has_modular_type = bool(line.product_template_id.modular_types)
9 changes: 9 additions & 0 deletions modular_types/models/sale_order_line_modular_type_value.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from odoo import models, fields


class SaleOrderLineModularValue(models.Model):
_name = 'sale.order.line.modular.value'

order_line_id = fields.Many2one('sale.order.line', ondelete='cascade')
modular_type_id = fields.Many2one('modular.type', required=True)
value = fields.Float()
12 changes: 12 additions & 0 deletions modular_types/models/stock_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from odoo import fields, models, api


class StockMove(models.Model):
_inherit = 'stock.move'

modular_type_id = fields.Many2one('modular.type', compute="_compute_modular_type")

@api.depends('production_id.bom_id.bom_line_ids')
def _compute_modular_type(self):
for move in self:
move.modular_type_id = move.raw_material_production_id.bom_id.bom_line_ids.filtered(lambda line: line.product_id == move.product_id).modular_type_id
5 changes: 5 additions & 0 deletions modular_types/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
modular_types.access_modular_type,access_modular_type,modular_types.model_modular_type,base.group_user,1,1,1,1
access_modular_type_wizard,modular.type.wizard,model_modular_type_wizard,base.group_user,1,1,1,1
access_modular_type_wizard_line,modular.type.wizard.line,model_modular_type_wizard_line,base.group_user,1,1,1,1
access_sale_order_line_modular_value,sale.order.line.modular.value,model_sale_order_line_modular_value,base.group_user,1,1,1,1
13 changes: 13 additions & 0 deletions modular_types/views/mrp_bom_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="mrp_bom_form_view_modular_type" model="ir.ui.view">
<field name="name">mrp.bom.form.modular.type</field>
<field name="model">mrp.bom</field>
<field name="inherit_id" ref="mrp.mrp_bom_form_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='bom_line_ids']//list//field[@name='product_qty']" position="before">
<field name="modular_type_id" string="Modular Type"/>
</xpath>
</field>
</record>
</odoo>
13 changes: 13 additions & 0 deletions modular_types/views/mrp_production_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="mrp_production_form_view_inherit" model="ir.ui.view">
<field name="name">pmrp.production.form.inherit</field>
<field name="model">mrp.production</field>
<field name="inherit_id" ref="mrp.mrp_production_form_view"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='components']//list//field[@name='product_id']" position='after'>
<field name='modular_type_id' />
</xpath>
</field>
</record>
</odoo>
14 changes: 14 additions & 0 deletions modular_types/views/product_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="product_template_only_form_view_inherit" model="ir.ui.view">
<field name="name">product.template.product.only.form.inherit</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='group_general']" position='inside'>
<label for="modular_types"/>
<field name='modular_types' nolabel='1' widget="many2many_tags" />
</xpath>
</field>
</record>
</odoo>
26 changes: 26 additions & 0 deletions modular_types/views/sale_order_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="modular_type_wizard_action" model="ir.actions.act_window">
<field name="name">Modular Type Value</field>
<field name="res_model">modular.type.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>

<record id="sale_order_inherit_view" model="ir.ui.view">
<field name="name">sale.order.inherit.view</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<!-- add button next to product name coloumn -->
<xpath expr="//list/field[@name='product_template_id']" position="after">
<button name="%(modular_type_wizard_action)d"
type="action"
icon="fa-flask"
context="{'active_order_line_id': id}"
invisible="not has_modular_type"
/>
</xpath>
</field>
</record>
</odoo>
1 change: 1 addition & 0 deletions modular_types/wizard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import modular_type_wizard
68 changes: 68 additions & 0 deletions modular_types/wizard/modular_type_wizard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from odoo import api, fields, models
from odoo.exceptions import UserError


class ModularTypeWizard(models.TransientModel):
_name = "modular.type.wizard"
_description = "Modular Type Wizard"

product_id = fields.Many2one('product.template', string='product Id')
wizard_lines = fields.One2many('modular.type.wizard.line', 'wizard_id')

@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
product_template = self.env['sale.order.line'].browse(self.env.context.get('active_id')).product_template_id

if product_template:
modular_types = product_template.modular_types
modular_types_data = [
(
0, 0, {
'modular_type_id': type.id,
'value': 0,
},
)
for type in modular_types
]
else:
raise UserError("Product Template Id not found.....!!!")
res.update({
'product_id': product_template.id,
'wizard_lines': modular_types_data,
})

return res

def action_add(self):
active_order_line_id = self.env.context.get('active_order_line_id')
for record in self:
if not record.product_id:
raise UserError("Product Template Id not found.....!!!")
for wizard_line in record.wizard_lines:
if not wizard_line.modular_type_id:
raise UserError("Please select a Modular Type for all lines before submitting.")
existing = self.env['sale.order.line.modular.value'].search([
('order_line_id', '=', active_order_line_id),
('modular_type_id', '=', wizard_line.modular_type_id.id)
], limit=1)

if existing:
existing.value = wizard_line.value
else:
self.env['sale.order.line.modular.value'].create({
'order_line_id': active_order_line_id,
'modular_type_id': wizard_line.modular_type_id.id,
'value': wizard_line.value,
})
return


# contain remaining line's indivudual data
class ModularTypeWizardLine(models.TransientModel):
_name = "modular.type.wizard.line"
_description = "Modular Type Wizard Line"

wizard_id = fields.Many2one('modular.type.wizard')
modular_type_id = fields.Many2one('modular.type')
value = fields.Integer(string='Value')
32 changes: 32 additions & 0 deletions modular_types/wizard/modular_type_wizard_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="modular_type_wizard_form" model="ir.ui.view">
<field name="name">modular.type.wizard.form</field>
<field name="model">modular.type.wizard</field>
<field name="arch" type="xml">
<form string="Modular Type">
<sheet>
<group>
<field name="wizard_lines" nolabel="1">
<list editable="bottom" create="false" delete="false">
<field name="modular_type_id" force_save="1" readonly="1"/>
<field name="value"/>
</list>
</field>
</group>
<footer>
<button string="Add" type="object" name="action_add" class="btn-primary"/>
<button string="Cancel" special="cancel" class="btn-secondary"/>
</footer>
</sheet>
</form>
</field>
</record>
<record id="modular_type_wizard_action" model="ir.actions.act_window">
<field name="name">modular type</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">modular.type.wizard</field>
<field name="view_mode">form</field>
<field name="view_id" ref="modular_type_wizard_form"/>
</record>
</odoo>