Skip to content
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
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,10 @@ dmypy.json

# Pyre type checker
.pyre/

node_modules
.eslintignore
.eslintrc.json
jsconfig.json
package-lock.json
package.json
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
17 changes: 17 additions & 0 deletions modular_types/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
'name': 'Modular Types',
'version': '1.0',
'category': 'Manufacturing',
'author': 'haman',
'depends': ['product', 'mrp', 'sale_management'],
'license': 'LGPL-3',
'data': [
'security/ir.model.access.csv',
'views/product_views.xml',
'views/mrp_bom_views.xml',
'views/sale_order_views.xml',
'views/mrp_modular_views.xml',
'wizard/modular_type_wizard_views.xml',
],
'installable': True,
}
6 changes: 6 additions & 0 deletions modular_types/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
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_line_modular_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(required=True)
13 changes: 13 additions & 0 deletions modular_types/models/mrp_bom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from odoo import api, fields, models


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_type_ids')

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


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

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


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

has_modular_type = fields.Boolean(compute='_compute_has_modular_type', store=True)
modular_value_ids = fields.One2many('sale.order.line.modular.value', 'order_line_id')

@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
)
10 changes: 10 additions & 0 deletions modular_types/models/sale_order_line_modular_value.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from odoo import fields, models


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

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


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

modular_type_id = fields.Many2one('modular.type', compute="_compute_modular_type", store=True)
sale_order_line_modular_value_id = fields.Many2one('sale.order.line.modular.value')
base_bom_qty = fields.Float()

@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

@api.model_create_multi
def create(self, vals_list):
moves = super().create(vals_list)
for move in moves:
mo = move.raw_material_production_id
so_line = mo.sale_line_id
bom = mo.bom_id
bom_line = bom.bom_line_ids.filtered(
lambda l: l.product_id == move.product_id
)[:1]
base_qty = bom_line.product_qty * mo.product_qty
move.base_bom_qty = base_qty
modular_map = {
mv.modular_type_id.id: mv.value
for mv in so_line.modular_value_ids
}
if move.modular_type_id and move.modular_type_id.id in modular_map:
move.product_uom_qty = (
base_qty * modular_map[move.modular_type_id.id]
)
return moves
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
15 changes: 15 additions & 0 deletions modular_types/views/mrp_bom_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="mrp_bom_form_view_inherit_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 Types"/>
</xpath>
</field>
</record>

</odoo>
15 changes: 15 additions & 0 deletions modular_types/views/mrp_modular_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="mrp_modular_inherit_view_form" model="ir.ui.view">
<field name="name">mrp.production.view.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>
15 changes: 15 additions & 0 deletions modular_types/views/product_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="product_template_form_view_modular_types" model="ir.ui.view">
<field name="name">product.template.form.modular.types</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">
<field name="modular_types" widget="many2many_tags"/>
</xpath>
</field>
</record>

</odoo>
27 changes: 27 additions & 0 deletions modular_types/views/sale_order_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?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_modular_button_view" model="ir.ui.view">
<field name="name">sale.order.form.modular.button</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form" />
<field name="arch" type="xml">
<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
53 changes: 53 additions & 0 deletions modular_types/wizard/modular_type_wizard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from odoo import api, exceptions, fields, models


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

product_id = fields.Many2one('product.template', readonly=True)
wizard_line_ids = fields.One2many('modular.type.wizard.line', 'wizard_id')

@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
order_line = self.env['sale.order.line'].browse(
self.env.context.get('active_order_line_id')
)
product = order_line.product_template_id
res.update({
'product_id': product.id,
'wizard_line_ids': [
(0, 0, {'modular_type_id': mt.id, 'value': 0})
for mt in product.modular_types
]
})
return res

def add_modular_value(self):
active_order_line_id = self.env.context.get('active_order_line_id')
if not self.product_id:
raise exceptions.UserError("Sales order line not found.")
for line in self.wizard_line_ids:
existing = self.env['sale.order.line.modular.value'].search([
('order_line_id', '=', active_order_line_id),
('modular_type_id', '=', line.modular_type_id.id),
], limit=1)
if existing:
existing.value = line.value
else:
self.env['sale.order.line.modular.value'].create({
'order_line_id': active_order_line_id,
'modular_type_id': line.modular_type_id.id,
'value': line.value,
})
return


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.Float()
29 changes: 29 additions & 0 deletions modular_types/wizard/modular_type_wizard_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?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>
<field name="wizard_line_ids" nolabel="1">
<list editable="bottom" create="false" delete="false">
<field name="modular_type_id"/>
<field name="value"/>
</list>
</field>
<footer>
<button string="Add" type="object" name="add_modular_value" class="btn-primary"/>
<button string="Cancel" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="modular_type_wizard_action" model="ir.actions.act_window">
<field name="name">Set Modular Type Value</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>