feat: introduce landed cost tags and integrate them with purchase order and line models and views.

This commit is contained in:
admin.suherdy 2025-12-06 19:19:11 +07:00
parent d672bc70f7
commit 8be264bb60
19 changed files with 265 additions and 265 deletions

View File

@ -1,24 +1,24 @@
{ {
'name': 'Purchase RFQ Comparison', 'name': 'Purchase RFQ Comparison',
'version': '18.0.1.0.0', 'version': '18.0.1.0.0',
'category': 'Purchase', 'category': 'Purchase',
'summary': 'Add comparison page in RFQ forms with additional fields', 'summary': 'Add comparison page in RFQ forms with additional fields',
'description': ''' 'description': '''
This module extends the Purchase RFQ functionality by adding: This module extends the Purchase RFQ functionality by adding:
- New "To Compare" page in RFQ forms - New "To Compare" page in RFQ forms
- Additional fields: Notes, Garansi (warranty), Landed Cost options - Additional fields: Notes, Garansi (warranty), Landed Cost options
- Landed Cost tags with predefined options - Landed Cost tags with predefined options
- Enhanced Compare Alternative RFQ view with new fields and Payment Terms - Enhanced Compare Alternative RFQ view with new fields and Payment Terms
''', ''',
'author': 'Suherdy Yacob', 'author': 'Suherdy Yacob',
'depends': ['purchase', 'purchase_requisition'], 'depends': ['purchase', 'purchase_requisition'],
'data': [ 'data': [
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'data/landed_cost_tags_data.xml', 'data/landed_cost_tags_data.xml',
'views/purchase_order_views.xml', 'views/purchase_order_views.xml',
'views/purchase_order_alternative_views.xml', 'views/purchase_order_alternative_views.xml',
], ],
'installable': True, 'installable': True,
'application': False, 'application': False,
'license': 'LGPL-3', 'license': 'LGPL-3',
} }

Binary file not shown.

Binary file not shown.

View File

@ -1,37 +1,37 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<data noupdate="1"> <data noupdate="1">
<!-- Landed Cost Tags --> <!-- Landed Cost Tags -->
<record id="landed_cost_tag_ongkir" model="purchase.landed.cost.tag"> <record id="landed_cost_tag_ongkir" model="purchase.landed.cost.tag">
<field name="name">Biaya Ongkir</field> <field name="name">Biaya Ongkir</field>
<field name="code">ONGKIR</field> <field name="code">ONGKIR</field>
<field name="color">1</field> <field name="color">1</field>
</record> </record>
<record id="landed_cost_tag_pasang" model="purchase.landed.cost.tag"> <record id="landed_cost_tag_pasang" model="purchase.landed.cost.tag">
<field name="name">Biaya Pasang</field> <field name="name">Biaya Pasang</field>
<field name="code">PASANG</field> <field name="code">PASANG</field>
<field name="color">2</field> <field name="color">2</field>
</record> </record>
<record id="landed_cost_tag_bongkar" model="purchase.landed.cost.tag"> <record id="landed_cost_tag_bongkar" model="purchase.landed.cost.tag">
<field name="name">Biaya Bongkar</field> <field name="name">Biaya Bongkar</field>
<field name="code">BONGKAR</field> <field name="code">BONGKAR</field>
<field name="color">3</field> <field name="color">3</field>
</record> </record>
<record id="landed_cost_tag_muat" model="purchase.landed.cost.tag"> <record id="landed_cost_tag_muat" model="purchase.landed.cost.tag">
<field name="name">Biaya Muat</field> <field name="name">Biaya Muat</field>
<field name="code">MUAT</field> <field name="code">MUAT</field>
<field name="color">4</field> <field name="color">4</field>
</record> </record>
<record id="landed_cost_tag_dokumen" model="purchase.landed.cost.tag"> <record id="landed_cost_tag_dokumen" model="purchase.landed.cost.tag">
<field name="name">Biaya Dokumen</field> <field name="name">Biaya Dokumen</field>
<field name="code">DOKUMEN</field> <field name="code">DOKUMEN</field>
<field name="color">5</field> <field name="color">5</field>
</record> </record>
</data> </data>
</odoo> </odoo>

View File

@ -1,3 +1,3 @@
from . import purchase_order from . import purchase_order
from . import purchase_order_line from . import purchase_order_line
from . import landed_cost_tag from . import landed_cost_tag

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,12 +1,12 @@
from odoo import models, fields from odoo import models, fields
class LandedCostTag(models.Model): class LandedCostTag(models.Model):
_name = 'purchase.landed.cost.tag' _name = 'purchase.landed.cost.tag'
_description = 'Landed Cost Tag' _description = 'Landed Cost Tag'
_rec_name = 'name' _rec_name = 'name'
name = fields.Char(string='Name', required=True) name = fields.Char(string='Name', required=True)
code = fields.Char(string='Code', required=True) code = fields.Char(string='Code', required=True)
color = fields.Integer(string='Color') color = fields.Integer(string='Color')
active = fields.Boolean(string='Active', default=True) active = fields.Boolean(string='Active', default=True)

View File

@ -1,21 +1,21 @@
from odoo import models, fields, api from odoo import models, fields, api
class PurchaseOrder(models.Model): class PurchaseOrder(models.Model):
_inherit = 'purchase.order' _inherit = 'purchase.order'
# Fields for "To Compare" page # Fields for "To Compare" page
comparison_notes = fields.Text(string='Notes') comparison_notes = fields.Text(string='Notes')
garansi = fields.Boolean(string='Garansi') garansi = fields.Boolean(string='Garansi')
landed_cost = fields.Boolean(string='Landed Cost') landed_cost = fields.Boolean(string='Landed Cost')
landed_cost_tag_ids = fields.Many2many( landed_cost_tag_ids = fields.Many2many(
'purchase.landed.cost.tag', 'purchase.landed.cost.tag',
string='Landed Cost Tags', string='Landed Cost Tags',
help='Select applicable landed cost types' help='Select applicable landed cost types'
) )
@api.onchange('landed_cost') @api.onchange('landed_cost')
def _onchange_landed_cost(self): def _onchange_landed_cost(self):
"""Clear landed cost tags when landed cost is disabled""" """Clear landed cost tags when landed cost is disabled"""
if not self.landed_cost: if not self.landed_cost:
self.landed_cost_tag_ids = [(5, 0, 0)] # Remove all tags self.landed_cost_tag_ids = [(5, 0, 0)] # Remove all tags

View File

@ -1,56 +1,56 @@
from odoo import models, fields, api from odoo import models, fields, api
class PurchaseOrderLine(models.Model): class PurchaseOrderLine(models.Model):
_inherit = 'purchase.order.line' _inherit = 'purchase.order.line'
# Computed fields for comparison data from purchase.order # Computed fields for comparison data from purchase.order
order_payment_term_id = fields.Many2one( order_payment_term_id = fields.Many2one(
'account.payment.term', 'account.payment.term',
string='Payment Terms', string='Payment Terms',
compute='_compute_order_comparison_fields', compute='_compute_order_comparison_fields',
help='Payment terms from the purchase order' help='Payment terms from the purchase order'
) )
order_comparison_notes = fields.Text( order_comparison_notes = fields.Text(
string='Notes', string='Notes',
compute='_compute_order_comparison_fields', compute='_compute_order_comparison_fields',
help='Comparison notes from the purchase order' help='Comparison notes from the purchase order'
) )
order_garansi = fields.Boolean( order_garansi = fields.Boolean(
string='Garansi', string='Garansi',
compute='_compute_order_comparison_fields', compute='_compute_order_comparison_fields',
help='Warranty information from the purchase order' help='Warranty information from the purchase order'
) )
order_landed_cost = fields.Boolean( order_landed_cost = fields.Boolean(
string='Landed Cost', string='Landed Cost',
compute='_compute_order_comparison_fields', compute='_compute_order_comparison_fields',
help='Landed cost flag from the purchase order' help='Landed cost flag from the purchase order'
) )
order_landed_cost_tag_ids = fields.Many2many( order_landed_cost_tag_ids = fields.Many2many(
'purchase.landed.cost.tag', 'purchase.landed.cost.tag',
string='LC Tags', string='LC Tags',
compute='_compute_order_comparison_fields', compute='_compute_order_comparison_fields',
help='Landed cost tags from the purchase order' help='Landed cost tags from the purchase order'
) )
@api.depends('order_id', 'order_id.payment_term_id', 'order_id.comparison_notes', @api.depends('order_id', 'order_id.payment_term_id', 'order_id.comparison_notes',
'order_id.garansi', 'order_id.landed_cost', 'order_id.landed_cost_tag_ids') 'order_id.garansi', 'order_id.landed_cost', 'order_id.landed_cost_tag_ids')
def _compute_order_comparison_fields(self): def _compute_order_comparison_fields(self):
"""Compute comparison fields from the related purchase order""" """Compute comparison fields from the related purchase order"""
for line in self: for line in self:
if line.order_id: if line.order_id:
line.order_payment_term_id = line.order_id.payment_term_id line.order_payment_term_id = line.order_id.payment_term_id
line.order_comparison_notes = line.order_id.comparison_notes line.order_comparison_notes = line.order_id.comparison_notes
line.order_garansi = line.order_id.garansi line.order_garansi = line.order_id.garansi
line.order_landed_cost = line.order_id.landed_cost line.order_landed_cost = line.order_id.landed_cost
line.order_landed_cost_tag_ids = line.order_id.landed_cost_tag_ids line.order_landed_cost_tag_ids = line.order_id.landed_cost_tag_ids
else: else:
line.order_payment_term_id = False line.order_payment_term_id = False
line.order_comparison_notes = False line.order_comparison_notes = False
line.order_garansi = False line.order_garansi = False
line.order_landed_cost = False line.order_landed_cost = False
line.order_landed_cost_tag_ids = False line.order_landed_cost_tag_ids = False

View File

@ -1,3 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_purchase_landed_cost_tag_user,purchase.landed.cost.tag.user,model_purchase_landed_cost_tag,purchase.group_purchase_user,1,1,1,0 access_purchase_landed_cost_tag_user,purchase.landed.cost.tag.user,model_purchase_landed_cost_tag,purchase.group_purchase_user,1,1,1,0
access_purchase_landed_cost_tag_manager,purchase.landed.cost.tag.manager,model_purchase_landed_cost_tag,purchase.group_purchase_manager,1,1,1,1 access_purchase_landed_cost_tag_manager,purchase.landed.cost.tag.manager,model_purchase_landed_cost_tag,purchase.group_purchase_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_purchase_landed_cost_tag_user purchase.landed.cost.tag.user model_purchase_landed_cost_tag purchase.group_purchase_user 1 1 1 0
3 access_purchase_landed_cost_tag_manager purchase.landed.cost.tag.manager model_purchase_landed_cost_tag purchase.group_purchase_manager 1 1 1 1

View File

@ -1,35 +1,35 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Extend Alternative Purchase Orders list to show comparison fields --> <!-- Extend Alternative Purchase Orders list to show comparison fields -->
<record id="purchase_order_alternative_list_inherit_comparison" model="ir.ui.view"> <record id="purchase_order_alternative_list_inherit_comparison" model="ir.ui.view">
<field name="name">purchase.order.alternative.list.inherit.comparison</field> <field name="name">purchase.order.alternative.list.inherit.comparison</field>
<field name="model">purchase.order</field> <field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase_requisition.purchase_order_form_inherit"/> <field name="inherit_id" ref="purchase_requisition.purchase_order_form_inherit"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='alternative_po_ids']//field[@name='amount_total']" position="after"> <xpath expr="//field[@name='alternative_po_ids']//field[@name='amount_total']" position="after">
<field name="payment_term_id" string="Payment Terms" optional="show"/> <field name="payment_term_id" string="Payment Terms" optional="show"/>
<field name="comparison_notes" string="Notes" optional="show"/> <field name="comparison_notes" string="Notes" optional="show"/>
<field name="garansi" string="Garansi" optional="show"/> <field name="garansi" string="Garansi" optional="show"/>
<field name="landed_cost" string="Landed Cost" optional="show"/> <field name="landed_cost" string="Landed Cost" optional="show"/>
<field name="landed_cost_tag_ids" widget="many2many_tags" string="LC Tags" optional="show"/> <field name="landed_cost_tag_ids" widget="many2many_tags" string="LC Tags" optional="show"/>
</xpath> </xpath>
</field> </field>
</record> </record>
<!-- Extend Purchase Order Line Compare tree to show comparison fields for detailed comparison --> <!-- Extend Purchase Order Line Compare tree to show comparison fields for detailed comparison -->
<record id="purchase_order_line_compare_tree_inherit_comparison" model="ir.ui.view"> <record id="purchase_order_line_compare_tree_inherit_comparison" model="ir.ui.view">
<field name="name">purchase.order.line.compare.list.inherit.comparison</field> <field name="name">purchase.order.line.compare.list.inherit.comparison</field>
<field name="model">purchase.order.line</field> <field name="model">purchase.order.line</field>
<field name="inherit_id" ref="purchase_requisition.purchase_order_line_compare_tree"/> <field name="inherit_id" ref="purchase_requisition.purchase_order_line_compare_tree"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='partner_id']" position="after"> <xpath expr="//field[@name='partner_id']" position="after">
<field name="order_payment_term_id" string="Payment Terms" optional="show"/> <field name="order_payment_term_id" string="Payment Terms" optional="show"/>
<field name="order_comparison_notes" string="Notes" optional="show"/> <field name="order_comparison_notes" string="Notes" optional="show"/>
<field name="order_garansi" string="Garansi" optional="show"/> <field name="order_garansi" string="Garansi" optional="show"/>
<field name="order_landed_cost" string="Landed Cost" optional="show"/> <field name="order_landed_cost" string="Landed Cost" optional="show"/>
<field name="order_landed_cost_tag_ids" widget="many2many_tags" string="LC Tags" optional="show"/> <field name="order_landed_cost_tag_ids" widget="many2many_tags" string="LC Tags" optional="show"/>
</xpath> </xpath>
</field> </field>
</record> </record>
</odoo> </odoo>

View File

@ -1,83 +1,83 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<!-- Extend Purchase Order form to add "To Compare" page --> <!-- Extend Purchase Order form to add "To Compare" page -->
<record id="view_purchase_order_form_inherit_comparison" model="ir.ui.view"> <record id="view_purchase_order_form_inherit_comparison" model="ir.ui.view">
<field name="name">purchase.order.form.inherit.comparison</field> <field name="name">purchase.order.form.inherit.comparison</field>
<field name="model">purchase.order</field> <field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/> <field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//notebook" position="inside"> <xpath expr="//notebook" position="inside">
<page string="To Compare" name="to_compare"> <page string="To Compare" name="to_compare">
<group> <group>
<group name="comparison_info"> <group name="comparison_info">
<field name="comparison_notes" string="Notes"/> <field name="comparison_notes" string="Notes"/>
<field name="garansi" string="Garansi"/> <field name="garansi" string="Garansi"/>
<field name="landed_cost" string="Landed Cost"/> <field name="landed_cost" string="Landed Cost"/>
<field name="landed_cost_tag_ids" <field name="landed_cost_tag_ids"
string="Landed Cost Tags" string="Landed Cost Tags"
widget="many2many_tags" widget="many2many_tags"
options="{'color_field': 'color'}" options="{'color_field': 'color'}"
invisible="not landed_cost"/> invisible="not landed_cost"/>
</group> </group>
</group> </group>
</page> </page>
</xpath> </xpath>
</field> </field>
</record> </record>
<!-- List view for Landed Cost Tags --> <!-- List view for Landed Cost Tags -->
<record id="view_landed_cost_tag_list" model="ir.ui.view"> <record id="view_landed_cost_tag_list" model="ir.ui.view">
<field name="name">purchase.landed.cost.tag.list</field> <field name="name">purchase.landed.cost.tag.list</field>
<field name="model">purchase.landed.cost.tag</field> <field name="model">purchase.landed.cost.tag</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<list string="Landed Cost Tags"> <list string="Landed Cost Tags">
<field name="name"/> <field name="name"/>
<field name="code"/> <field name="code"/>
<field name="active"/> <field name="active"/>
</list> </list>
</field> </field>
</record> </record>
<!-- Form view for Landed Cost Tags --> <!-- Form view for Landed Cost Tags -->
<record id="view_landed_cost_tag_form" model="ir.ui.view"> <record id="view_landed_cost_tag_form" model="ir.ui.view">
<field name="name">purchase.landed.cost.tag.form</field> <field name="name">purchase.landed.cost.tag.form</field>
<field name="model">purchase.landed.cost.tag</field> <field name="model">purchase.landed.cost.tag</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Landed Cost Tag"> <form string="Landed Cost Tag">
<sheet> <sheet>
<group> <group>
<field name="name"/> <field name="name"/>
<field name="code"/> <field name="code"/>
<field name="color" widget="color"/> <field name="color" widget="color"/>
<field name="active"/> <field name="active"/>
</group> </group>
</sheet> </sheet>
</form> </form>
</field> </field>
</record> </record>
<!-- Action for Landed Cost Tags --> <!-- Action for Landed Cost Tags -->
<record id="action_landed_cost_tag" model="ir.actions.act_window"> <record id="action_landed_cost_tag" model="ir.actions.act_window">
<field name="name">Landed Cost Tags</field> <field name="name">Landed Cost Tags</field>
<field name="res_model">purchase.landed.cost.tag</field> <field name="res_model">purchase.landed.cost.tag</field>
<field name="view_mode">list,form</field> <field name="view_mode">list,form</field>
<field name="help" type="html"> <field name="help" type="html">
<p class="o_view_nocontent_smiling_face"> <p class="o_view_nocontent_smiling_face">
Create your first landed cost tag! Create your first landed cost tag!
</p> </p>
<p> <p>
Landed cost tags help categorize different types of additional costs Landed cost tags help categorize different types of additional costs
like shipping, installation, loading, unloading, or documentation fees. like shipping, installation, loading, unloading, or documentation fees.
</p> </p>
</field> </field>
</record> </record>
<!-- Menu item for Landed Cost Tags --> <!-- Menu item for Landed Cost Tags -->
<menuitem <menuitem
id="menu_landed_cost_tag" id="menu_landed_cost_tag"
name="Landed Cost Tags" name="Landed Cost Tags"
action="action_landed_cost_tag" action="action_landed_cost_tag"
parent="purchase.menu_purchase_config" parent="purchase.menu_purchase_config"
sequence="5"/> sequence="5"/>
</odoo> </odoo>