Purchase landed costs - Alternative option

purchase_landed_cost
REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/19.0/purchase_landed_cost
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSTecnativa, Odoo Community Association (OCA), AvanzOSC, Joaquín Gutierrez
MAINTAINERS
MAINTAINERSTecnativa, Odoo Community Association (OCA), AvanzOSC, Joaquín Gutierrez
COMMITTERS
COMMITTERSWeblate, OCA-git-bot, oca-ci, Andrii9090-tecnativa
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:40:50
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase_stock
    - stock_account
    - stock
    - product
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
    - uom
    - barcodes_gs1_nomenclature
    - barcodes
    - digest
    - portal
    - http_routing
    - auth_signup
    - resource
    - account
    - onboarding
    - analytic
    - purchase
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
## This module manages your purchase expenses

The functionality of this module is to provide a way to manage your
purchase costs more easily than the official module
(*stock_landed_cost*) and allow to distribute them with a lot of
methods.

**Main features:**

- Possibility to assign landed cost afterwards in a separate screen.
- Management of expense types with preconfigured calculation methods.
- Distribution of costs based on weight, volume, product price, etc.
- Types marked as default are automatically added to each new purchase
  distribution.
- Management orders shopping expenses associated with one or more entry
  slips.

Code Analysis

Views touched (17)
XML IDNameModelTypeStatus
import_invoice_line_wizard_view import.invoice.line.wizard.form import.invoice.line.wizard form New
import_landed_cost_pickings_wizard_view import.landed.cost.pickings.wizard form New
picking_import_wizard_view picking.import.wizard.form picking.import.wizard form New
purchase_cost_distribution_form purchase.cost.distribution.form purchase.cost.distribution form New
purchase_cost_distribution_search purchase.cost.distribution.search purchase.cost.distribution search New
purchase_expense_type_tree purchase.expense.type list New
purchase_order_form purchase.order div Inherits purchase.purchase_order_form
view_move_form account.move notebook Inherits account.view_move_form
view_picking_form stock.picking div Inherits stock.view_picking_form
view_purchase_cost_distribution_calendar purchase.cost.distribution.calendar purchase.cost.distribution calendar New
view_purchase_cost_distribution_expense_invoice_form purchase.cost.distribution.expense list New
view_purchase_cost_distribution_graph purchase.cost.distribution.graph purchase.cost.distribution graph New
view_purchase_cost_distribution_line_expense_search purchase.cost.distribution.line.expense.search purchase.cost.distribution.line.expense search New
view_purchase_cost_distribution_line_expense_tree purchase.cost.distribution.line.expense list New
view_purchase_cost_distribution_line_form purchase.cost.distribution.line.form purchase.cost.distribution.line form New
view_purchase_cost_distribution_line_tree purchase.cost.distribution.line list New
view_purchase_cost_distribution_tree purchase.cost.distribution.tree purchase.cost.distribution list New
Models touched (12)

New fields (1)
  • expense_line_ids One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' inverse_name='invoice_id' string='Landed costs'
Public methods (0)

No public methods.

New fields (1)
  • expense_line_ids One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' inverse_name='invoice_line' string='Landed costs'
Public methods (0)

No public methods.

New fields (4)
  • expense_type Many2one → purchase.expense.type
    comodel_name='purchase.expense.type' required=True string='Expense type'
  • invoice Many2one → account.move
    comodel_name='account.move' domain="[('partner_id', '=', supplier), ('move_type', '=', 'in_invoice'),('state', '=', 'posted')]" required=True
  • invoice_line Many2one → account.move.line
    comodel_name='account.move.line' domain="[('move_id', '=', invoice)]" required=True string='Invoice line'
  • supplier Many2one → res.partner
    comodel_name='res.partner' required=True
Public methods (1)
  • action_import_invoice_line(self)

New fields (2)
  • picking_ids Many2many → stock.picking
    comodel_name='stock.picking' domain="[('id', 'in', possible_picking_ids)]" relation='import_landed_cost_pickings_wizard_stock_picking_rel' string='Pickings'
  • possible_picking_ids Many2many → stock.picking
    comodel_name='stock.picking' relation='import_landed_cost_pickings_possible_picking_rel' string='Possible pickings'
Public methods (2)
  • button_import(self)
  • default_get(self, fields_list)
    @api.model

New fields (3)
  • pickings Many2many → stock.picking
    column1='wizard_id' column2='picking_id' comodel_name='stock.picking' relation='distribution_import_picking_rel' required=True string='Incoming shipments'
  • prev_pickings Many2many → stock.picking
    comodel_name='stock.picking'
  • supplier Many2one → res.partner
    comodel_name='res.partner' required=True
Public methods (2)
  • action_import_picking(self)
  • default_get(self, field_list)
    @api.model
    Get pickings previously imported.

New fields (15)
  • amount_total Float
    compute='_compute_amount_total' digits='Account' string='Total'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • cost_lines One2many → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' inverse_name='distribution' string='Distribution lines'
  • currency_id Many2one → res.currency
    comodel_name='res.currency' related='company_id.currency_id' string='Currency'
  • date Date
    default=fields.Date.context_today index=True readonly=True required=True
  • expense_lines One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' default=<expr> inverse_name='distribution' string='Expenses'
  • name Char
    default='/' index=True required=True string='Distribution number'
  • note Text
    string='Documentation for this order'
  • state Selection
    default='draft' readonly=True string='Status' args: [('draft', 'Draft'), ('calculated', 'Calculated'), ('done', 'Done')]
  • total_expense Float
    compute='_compute_total_expense' digits='Account' string='Total expenses'
  • total_price_unit Float
    compute='_compute_total_price_unit' digits='Product Price' string='Total price unit'
  • total_purchase Float
    compute='_compute_total_purchase' digits='Account' string='Total purchase'
  • total_uom_qty Float
    compute='_compute_total_uom_qty' digits='Product UoS' readonly=True string='Total quantity'
  • total_volume Float
    compute='_compute_total_volume' readonly=True string='Total volume'
  • total_weight Float
    compute='_compute_total_weight' digits='Stock Weight' readonly=True string='Total gross weight'
Public methods (5)
  • action_calculate(self)
  • action_done(self)
  • action_draft(self)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (11)
  • affected_lines Many2many → purchase.cost.distribution.line
    column1='expense_id' column2='line_id' comodel_name='purchase.cost.distribution.line' domain="[('id', 'in', imported_lines)]" help='Put here specific lines that this expense is going to be distributed across. Leave it blank to use all imported lines.' relation='distribution_expense_aff_rel' string='Affected lines'
  • calculation_method Selection
    readonly=True related='type.calculation_method' string='Calculation method'
  • company_id Many2one → res.company
    comodel_name='res.company' related='distribution.company_id' store=True
  • display_name Char
    compute='_compute_display_name' store=True
  • distribution Many2one → purchase.cost.distribution
    comodel_name='purchase.cost.distribution' index=True ondelete='cascade' required=True string='Cost distribution'
  • expense_amount Float
    digits='Account' required=True string='Expense amount'
  • imported_lines Many2many → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' compute='_compute_imported_lines' string='Imported lines'
  • invoice_id Many2one → account.move
    comodel_name='account.move' string='Invoice'
  • invoice_line Many2one → account.move.line
    comodel_name='account.move.line' domain="[('move_id.move_type', '=', 'in_invoice'),('move_id.state', '=', 'posted')]" string='Supplier invoice line'
  • ref Char
    string='Reference'
  • type Many2one → purchase.expense.type
    comodel_name='purchase.expense.type' index=True ondelete='restrict' string='Expense type'
Public methods (3)
  • button_duplicate(self)
  • onchange_invoice_line(self)
    @api.onchange('invoice_line')
    set expense_amount in the currency of the distribution
  • onchange_type(self)
    @api.onchange('type')
    set expense_amount in the currency of the distribution

New fields (22)
  • company_id Many2one → res.company
    comodel_name='res.company' related='distribution.company_id' store=True
  • cost_ratio Float
    compute='_compute_cost_ratio' string='Unit cost'
  • distribution Many2one → purchase.cost.distribution
    comodel_name='purchase.cost.distribution' ondelete='cascade' required=True string='Cost distribution'
  • expense_amount Float
    compute='_compute_expense_amount' digits='Account' string='Cost amount'
  • expense_lines One2many → purchase.cost.distribution.line.expense
    comodel_name='purchase.cost.distribution.line.expense' inverse_name='distribution_line' string='Expenses distribution lines'
  • move_id Many2one → stock.move
    comodel_name='stock.move' ondelete='restrict' required=True string='Picking line'
  • name Char
    compute='_compute_name' store=True
  • partner Many2one → res.partner
    comodel_name='res.partner' readonly=True related='move_id.purchase_line_id.order_id.partner_id' string='Supplier'
  • picking_id Many2one → stock.picking
    related='move_id.picking_id' store=True string='Picking' args: 'stock.picking'
  • product_id Many2one → product.product
    comodel_name='product.product' compute='_compute_product_id' store=True string='Product'
  • product_price_unit Float
    related='move_id.price_unit' string='Unit price'
  • product_qty Float
    compute='_compute_product_qty' store=True string='Quantity'
  • product_uom Many2one → uom.uom
    comodel_name='uom.uom' related='move_id.product_uom' string='Unit of measure'
  • product_volume Float
    help='The volume in m3.' related='product_id.product_tmpl_id.volume' string='Volume'
  • product_weight Float
    help='The gross weight in Kg.' related='product_id.product_tmpl_id.weight' string='Gross weight'
  • purchase_id Many2one → purchase.order
    comodel_name='purchase.order' readonly=True related='move_id.purchase_line_id.order_id' store=True string='Purchase order'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' related='move_id.purchase_line_id' string='Purchase order line'
  • standard_price_new Float
    compute='_compute_standard_price_new' digits='Product Price' string='New cost'
  • standard_price_old Float
    compute='_compute_standard_price_old' digits='Product Price' store=True string='Previous cost'
  • total_amount Float
    compute='_compute_total_amount' digits='Account' string='Amount line'
  • total_volume Float
    compute='_compute_total_volume' help='The line volume in m3.' store=True string='Line volume'
  • total_weight Float
    compute='_compute_total_weight' digits='Stock Weight' help='The line gross weight in Kg.' store=True string='Line weight'
Public methods (1)
  • get_action_purchase_cost_distribution(self)
    @api.model

New fields (8)
  • company_id Many2one → res.company
    comodel_name='res.company' readonly=True related='distribution_line.company_id' store=True
  • cost_ratio Float
    args: 'Unit cost'
  • distribution_expense Many2one → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' ondelete='cascade' string='Distribution expense'
  • distribution_line Many2one → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' ondelete='cascade' string='Cost distribution line'
  • expense_amount Float
    digits='Account' string='Expense amount'
  • picking_date_done Datetime
    readonly=True related='picking_id.date_done' store=True
  • picking_id Many2one → stock.picking
    comodel_name='stock.picking' readonly=True related='distribution_line.picking_id' store=True
  • type Many2one → purchase.expense.type
    readonly=True related='distribution_expense.type' store=True string='Expense type' args: 'purchase.expense.type'
Public methods (0)

No public methods.

New fields (6)
  • calculation_method Selection
    default='amount' string='Calculation method' args: [('amount', 'By amount of the line'), ('price', 'By product price'), ('qty', 'By product quantity'), ('weight', 'By product weight'), ('volume', 'By product volume'), ('equal', 'Equally to all lines')]
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> string='Company'
  • default_amount Float
    help='If set, this amount is put in the expense line when you select this expense type' string='Default amount'
  • default_expense Boolean
    help='Specify if the expense will be automatically added in a purchase cost distribution.'
  • name Char
    index='trigram' required=True translate=True
  • note Text
    string='Cost documentation'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • action_open_landed_cost(self)

New fields (0)

No new fields.

Public methods (1)
  • action_open_landed_cost(self)
REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/16.0/purchase_landed_cost
VERSION
VERSION 1.0.2
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSTecnativa, Odoo Community Association (OCA), AvanzOSC, Joaquín Gutierrez
MAINTAINERS
MAINTAINERSTecnativa, Odoo Community Association (OCA), AvanzOSC, Joaquín Gutierrez
COMMITTERS
COMMITTERSPedro M. Baeza, Víctor Martínez, Weblate, OCA-git-bot, oca-ci, Carolina Fernandez
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:53:55
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase_stock
    - stock_account
    - stock
    - product
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - uom
    - barcodes_gs1_nomenclature
    - barcodes
    - digest
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - resource
    - account
    - analytic
    - purchase
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (17)
XML IDNameModelTypeStatus
import_invoice_line_wizard_view import.invoice.line.wizard.form import.invoice.line.wizard form New
import_landed_cost_pickings_wizard_view import.landed.cost.pickings.wizard form New
picking_import_wizard_view picking.import.wizard.form picking.import.wizard form New
purchase_cost_distribution_form purchase.cost.distribution.form purchase.cost.distribution form New
purchase_cost_distribution_search purchase.cost.distribution.search purchase.cost.distribution search New
purchase_expense_type_tree purchase.expense.type tree New
purchase_order_form purchase.order div Inherits purchase.purchase_order_form
view_move_form account.move notebook Inherits account.view_move_form
view_picking_form stock.picking div Inherits stock.view_picking_form
view_purchase_cost_distribution_calendar purchase.cost.distribution.calendar purchase.cost.distribution calendar New
view_purchase_cost_distribution_expense_invoice_form purchase.cost.distribution.expense tree New
view_purchase_cost_distribution_graph purchase.cost.distribution.graph purchase.cost.distribution graph New
view_purchase_cost_distribution_line_expense_search purchase.cost.distribution.line.expense search New
view_purchase_cost_distribution_line_expense_tree purchase.cost.distribution.line.expense tree New
view_purchase_cost_distribution_line_form purchase.cost.distribution.line.form purchase.cost.distribution.line form New
view_purchase_cost_distribution_line_tree purchase.cost.distribution.line tree New
view_purchase_cost_distribution_tree purchase.cost.distribution.tree purchase.cost.distribution tree New
Models touched (12)

New fields (1)
  • expense_line_ids One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' inverse_name='invoice_id' string='Landed costs'
Public methods (0)

No public methods.

New fields (1)
  • expense_line_ids One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' inverse_name='invoice_line' string='Landed costs'
Public methods (0)

No public methods.

New fields (4)
  • expense_type Many2one → purchase.expense.type
    comodel_name='purchase.expense.type' required=True string='Expense type'
  • invoice Many2one → account.move
    comodel_name='account.move' domain="[('partner_id', '=', supplier), ('move_type', '=', 'in_invoice'),('state', '=', 'posted')]" required=True
  • invoice_line Many2one → account.move.line
    comodel_name='account.move.line' domain="[('move_id', '=', invoice)]" required=True string='Invoice line'
  • supplier Many2one → res.partner
    comodel_name='res.partner' required=True
Public methods (1)
  • action_import_invoice_line(self)

New fields (2)
  • picking_ids Many2many → stock.picking
    comodel_name='stock.picking' domain="[('id', 'in', possible_picking_ids)]" relation='import_landed_cost_pickings_wizard_stock_picking_rel' string='Pickings'
  • possible_picking_ids Many2many → stock.picking
    comodel_name='stock.picking' relation='import_landed_cost_pickings_possible_picking_rel' string='Possible pickings'
Public methods (2)
  • button_import(self)
  • default_get(self, fields_list)
    @api.model

New fields (3)
  • pickings Many2many → stock.picking
    column1='wizard_id' column2='picking_id' comodel_name='stock.picking' relation='distribution_import_picking_rel' required=True string='Incoming shipments'
  • prev_pickings Many2many → stock.picking
    comodel_name='stock.picking'
  • supplier Many2one → res.partner
    comodel_name='res.partner' required=True
Public methods (2)
  • action_import_picking(self)
  • default_get(self, field_list)
    @api.model
    Get pickings previously imported.

New fields (15)
  • amount_total Float
    compute=_compute_amount_total digits='Account' string='Total'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • cost_lines One2many → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' inverse_name='distribution' string='Distribution lines'
  • currency_id Many2one → res.currency
    comodel_name='res.currency' related='company_id.currency_id' string='Currency'
  • date Date
    default=fields.Date.context_today index=True readonly=True required=True states={'draft': [('readonly', False)]}
  • expense_lines One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' default=_expense_lines_default inverse_name='distribution' string='Expenses'
  • name Char
    default='/' index=True required=True string='Distribution number'
  • note Text
    string='Documentation for this order'
  • state Selection
    default='draft' readonly=True string='Status' args: [('draft', 'Draft'), ('calculated', 'Calculated'), ('done', 'Done')]
  • total_expense Float
    compute=_compute_total_expense digits='Account' string='Total expenses'
  • total_price_unit Float
    compute=_compute_total_price_unit digits='Product Price' string='Total price unit'
  • total_purchase Float
    compute=_compute_total_purchase digits='Account' string='Total purchase'
  • total_uom_qty Float
    compute=_compute_total_uom_qty digits='Product UoS' readonly=True string='Total quantity'
  • total_volume Float
    compute=_compute_total_volume readonly=True string='Total volume'
  • total_weight Float
    compute=_compute_total_weight digits='Stock Weight' readonly=True string='Total gross weight'
Public methods (6)
  • action_calculate(self)
  • action_done(self)
  • action_draft(self)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
  • write(self, vals)

New fields (11)
  • affected_lines Many2many → purchase.cost.distribution.line
    column1='expense_id' column2='line_id' comodel_name='purchase.cost.distribution.line' domain="[('id', 'in', imported_lines)]" help='Put here specific lines that this expense is going to be distributed across. Leave it blank to use all imported lines.' relation='distribution_expense_aff_rel' string='Affected lines'
  • calculation_method Selection
    readonly=True related='type.calculation_method' string='Calculation method'
  • company_id Many2one → res.company
    comodel_name='res.company' related='distribution.company_id' store=True
  • display_name Char
    compute='_compute_display_name' store=True
  • distribution Many2one → purchase.cost.distribution
    comodel_name='purchase.cost.distribution' index=True ondelete='cascade' required=True string='Cost distribution'
  • expense_amount Float
    digits='Account' required=True string='Expense amount'
  • imported_lines Many2many → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' compute='_compute_imported_lines' string='Imported lines'
  • invoice_id Many2one → account.move
    comodel_name='account.move' string='Invoice'
  • invoice_line Many2one → account.move.line
    comodel_name='account.move.line' domain="[('move_id.move_type', '=', 'in_invoice'),('move_id.state', '=', 'posted')]" string='Supplier invoice line'
  • ref Char
    string='Reference'
  • type Many2one → purchase.expense.type
    comodel_name='purchase.expense.type' index=True ondelete='restrict' string='Expense type'
Public methods (3)
  • button_duplicate(self)
  • onchange_invoice_line(self)
    @api.onchange('invoice_line')
    set expense_amount in the currency of the distribution
  • onchange_type(self)
    @api.onchange('type')
    set expense_amount in the currency of the distribution

New fields (22)
  • company_id Many2one → res.company
    comodel_name='res.company' related='distribution.company_id' store=True
  • cost_ratio Float
    compute='_compute_cost_ratio' string='Unit cost'
  • distribution Many2one → purchase.cost.distribution
    comodel_name='purchase.cost.distribution' ondelete='cascade' required=True string='Cost distribution'
  • expense_amount Float
    compute='_compute_expense_amount' digits='Account' string='Cost amount'
  • expense_lines One2many → purchase.cost.distribution.line.expense
    comodel_name='purchase.cost.distribution.line.expense' inverse_name='distribution_line' string='Expenses distribution lines'
  • move_id Many2one → stock.move
    comodel_name='stock.move' ondelete='restrict' required=True string='Picking line'
  • name Char
    compute='_compute_name' store=True
  • partner Many2one → res.partner
    comodel_name='res.partner' readonly=True related='move_id.purchase_line_id.order_id.partner_id' string='Supplier'
  • picking_id Many2one → stock.picking
    related='move_id.picking_id' store=True string='Picking' args: 'stock.picking'
  • product_id Many2one → product.product
    comodel_name='product.product' compute='_compute_product_id' store=True string='Product'
  • product_price_unit Float
    related='move_id.price_unit' string='Unit price'
  • product_qty Float
    compute='_compute_product_qty' store=True string='Quantity'
  • product_uom Many2one → uom.uom
    comodel_name='uom.uom' related='move_id.product_uom' string='Unit of measure'
  • product_volume Float
    help='The volume in m3.' related='product_id.product_tmpl_id.volume' string='Volume'
  • product_weight Float
    help='The gross weight in Kg.' related='product_id.product_tmpl_id.weight' string='Gross weight'
  • purchase_id Many2one → purchase.order
    comodel_name='purchase.order' readonly=True related='move_id.purchase_line_id.order_id' store=True string='Purchase order'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' related='move_id.purchase_line_id' string='Purchase order line'
  • standard_price_new Float
    compute='_compute_standard_price_new' digits='Product Price' string='New cost'
  • standard_price_old Float
    compute='_compute_standard_price_old' digits='Product Price' store=True string='Previous cost'
  • total_amount Float
    compute=_compute_total_amount digits='Account' string='Amount line'
  • total_volume Float
    compute=_compute_total_volume help='The line volume in m3.' store=True string='Line volume'
  • total_weight Float
    compute=_compute_total_weight digits='Stock Weight' help='The line gross weight in Kg.' store=True string='Line weight'
Public methods (1)
  • get_action_purchase_cost_distribution(self)
    @api.model

New fields (8)
  • company_id Many2one → res.company
    comodel_name='res.company' readonly=True related='distribution_line.company_id' store=True
  • cost_ratio Float
    args: 'Unit cost'
  • distribution_expense Many2one → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' ondelete='cascade' string='Distribution expense'
  • distribution_line Many2one → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' ondelete='cascade' string='Cost distribution line'
  • expense_amount Float
    digits='Account' string='Expense amount'
  • picking_date_done Datetime
    readonly=True related='picking_id.date_done' store=True
  • picking_id Many2one → stock.picking
    comodel_name='stock.picking' readonly=True related='distribution_line.picking_id' store=True
  • type Many2one → purchase.expense.type
    readonly=True related='distribution_expense.type' store=True string='Expense type' args: 'purchase.expense.type'
Public methods (0)

No public methods.

New fields (6)
  • calculation_method Selection
    default='amount' string='Calculation method' args: [('amount', 'By amount of the line'), ('price', 'By product price'), ('qty', 'By product quantity'), ('weight', 'By product weight'), ('volume', 'By product volume'), ('equal', 'Equally to all lines')]
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> string='Company'
  • default_amount Float
    help='If set, this amount is put in the expense line when you select this expense type' string='Default amount'
  • default_expense Boolean
    help='Specify if the expense will be automatically added in a purchase cost distribution.'
  • name Char
    index=True required=True translate=True
  • note Text
    string='Cost documentation'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • action_open_landed_cost(self)

New fields (0)

No new fields.

Public methods (1)
  • action_open_landed_cost(self)
REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/13.0/purchase_landed_cost
VERSION
VERSION 1.2.1
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSTecnativa, Odoo Community Association (OCA), AvanzOSC, Joaquín Gutierrez
MAINTAINERS
MAINTAINERSTecnativa, Odoo Community Association (OCA), AvanzOSC, Joaquín Gutierrez
COMMITTERS
COMMITTERSPedro M. Baeza, Víctor Martínez, Ernesto Tejeda, oca-travis, Weblate, OCA-git-bot, Carolina Fernandez
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:34:18
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase_stock
    - stock_account
    - stock
    - product
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - uom
    - barcodes
    - account
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - purchase
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (17)
XML IDNameModelTypeStatus
import_invoice_line_wizard_view import.invoice.line.wizard.form import.invoice.line.wizard form New
import_landed_cost_pickings_wizard_view import.landed.cost.pickings.wizard p New
picking_import_wizard_view picking.import.wizard.form picking.import.wizard form New
purchase_cost_distribution_form purchase.cost.distribution.form purchase.cost.distribution form New
purchase_cost_distribution_search purchase.cost.distribution.search purchase.cost.distribution search New
purchase_expense_type_tree purchase.expense.type tree New
purchase_order_form purchase.order div Inherits purchase.purchase_order_form
view_move_form account.move notebook Inherits account.view_move_form
view_picking_form stock.picking div Inherits stock.view_picking_form
view_purchase_cost_distribution_calendar purchase.cost.distribution.calendar purchase.cost.distribution calendar New
view_purchase_cost_distribution_expense_invoice_form purchase.cost.distribution.expense tree New
view_purchase_cost_distribution_graph purchase.cost.distribution.graph purchase.cost.distribution graph New
view_purchase_cost_distribution_line_expense_search purchase.cost.distribution.line.expense search New
view_purchase_cost_distribution_line_expense_tree purchase.cost.distribution.line.expense tree New
view_purchase_cost_distribution_line_form purchase.cost.distribution.line.form purchase.cost.distribution.line form New
view_purchase_cost_distribution_line_tree purchase.cost.distribution.line tree New
view_purchase_cost_distribution_tree purchase.cost.distribution.tree purchase.cost.distribution tree New
Models touched (12)

New fields (1)
  • expense_line_ids One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' inverse_name='invoice_id' string='Landed costs'
Public methods (0)

No public methods.

New fields (1)
  • expense_line_ids One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' inverse_name='invoice_line' string='Landed costs'
Public methods (0)

No public methods.

New fields (4)
  • expense_type Many2one → purchase.expense.type
    comodel_name='purchase.expense.type' required=True string='Expense type'
  • invoice Many2one → account.move
    comodel_name='account.move' domain="[('partner_id', '=', supplier), ('type', '=', 'in_invoice'),('state', '=', 'posted')]" required=True string='Invoice'
  • invoice_line Many2one → account.move.line
    comodel_name='account.move.line' domain="[('move_id', '=', invoice)]" required=True string='Invoice line'
  • supplier Many2one → res.partner
    comodel_name='res.partner' required=True string='Supplier'
Public methods (1)
  • action_import_invoice_line(self)

New fields (2)
  • picking_ids Many2many → stock.picking
    comodel_name='stock.picking' domain="[('id', 'in', possible_picking_ids)]" relation='import_landed_cost_pickings_wizard_stock_picking_rel' string='Pickings'
  • possible_picking_ids Many2many → stock.picking
    comodel_name='stock.picking' relation='import_landed_cost_pickings_possible_picking_rel' string='Possible pickings'
Public methods (2)
  • button_import(self)
  • default_get(self, fields_list)
    @api.model

New fields (3)
  • pickings Many2many → stock.picking
    column1='wizard_id' column2='picking_id' comodel_name='stock.picking' relation='distribution_import_picking_rel' required=True string='Incoming shipments'
  • prev_pickings Many2many → stock.picking
    comodel_name='stock.picking'
  • supplier Many2one → res.partner
    comodel_name='res.partner' required=True string='Supplier'
Public methods (2)
  • action_import_picking(self)
  • default_get(self, field_list)
    @api.model
    Get pickings previously imported.

New fields (15)
  • amount_total Float
    compute=_compute_amount_total digits='Account' string='Total'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • cost_lines One2many → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' inverse_name='distribution' string='Distribution lines'
  • currency_id Many2one → res.currency
    comodel_name='res.currency' related='company_id.currency_id' string='Currency'
  • date Date
    default=fields.Date.context_today index=True readonly=True required=True states={'draft': [('readonly', False)]} string='Date'
  • expense_lines One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' default=_expense_lines_default inverse_name='distribution' string='Expenses'
  • name Char
    default='/' index=True required=True string='Distribution number'
  • note Text
    string='Documentation for this order'
  • state Selection
    default='draft' readonly=True string='Status' args: [('draft', 'Draft'), ('calculated', 'Calculated'), ('done', 'Done')]
  • total_expense Float
    compute=_compute_total_expense digits='Account' string='Total expenses'
  • total_price_unit Float
    compute=_compute_total_price_unit digits='Product Price' string='Total price unit'
  • total_purchase Float
    compute=_compute_total_purchase digits='Account' string='Total purchase'
  • total_uom_qty Float
    compute=_compute_total_uom_qty digits='Product UoS' readonly=True string='Total quantity'
  • total_volume Float
    compute=_compute_total_volume readonly=True string='Total volume'
  • total_weight Float
    compute=_compute_total_weight digits='Stock Weight' readonly=True string='Total gross weight'
Public methods (6)
  • action_calculate(self)
  • action_done(self)
  • action_draft(self)
  • create(self, vals)
    @api.model
  • unlink(self)
  • write(self, vals)

New fields (11)
  • affected_lines Many2many → purchase.cost.distribution.line
    column1='expense_id' column2='line_id' comodel_name='purchase.cost.distribution.line' domain="[('id', 'in', imported_lines)]" help='Put here specific lines that this expense is going to be distributed across. Leave it blank to use all imported lines.' relation='distribution_expense_aff_rel' string='Affected lines'
  • calculation_method Selection
    readonly=True related='type.calculation_method' string='Calculation method'
  • company_id Many2one → res.company
    comodel_name='res.company' related='distribution.company_id' store=True
  • display_name Char
    compute='_compute_display_name' store=True
  • distribution Many2one → purchase.cost.distribution
    comodel_name='purchase.cost.distribution' index=True ondelete='cascade' required=True string='Cost distribution'
  • expense_amount Float
    digits='Account' required=True string='Expense amount'
  • imported_lines Many2many → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' compute='_compute_imported_lines' string='Imported lines'
  • invoice_id Many2one → account.move
    comodel_name='account.move' string='Invoice'
  • invoice_line Many2one → account.move.line
    comodel_name='account.move.line' domain="[('move_id.type', '=', 'in_invoice'),('move_id.state', '=', 'posted')]" string='Supplier invoice line'
  • ref Char
    string='Reference'
  • type Many2one → purchase.expense.type
    comodel_name='purchase.expense.type' index=True ondelete='restrict' string='Expense type'
Public methods (3)
  • button_duplicate(self)
  • onchange_invoice_line(self)
    @api.onchange('invoice_line')
    set expense_amount in the currency of the distribution
  • onchange_type(self)
    @api.onchange('type')
    set expense_amount in the currency of the distribution

New fields (22)
  • company_id Many2one → res.company
    comodel_name='res.company' related='distribution.company_id' store=True
  • cost_ratio Float
    compute='_compute_cost_ratio' string='Unit cost'
  • distribution Many2one → purchase.cost.distribution
    comodel_name='purchase.cost.distribution' ondelete='cascade' required=True string='Cost distribution'
  • expense_amount Float
    compute='_compute_expense_amount' digits='Account' string='Cost amount'
  • expense_lines One2many → purchase.cost.distribution.line.expense
    comodel_name='purchase.cost.distribution.line.expense' inverse_name='distribution_line' string='Expenses distribution lines'
  • move_id Many2one → stock.move
    comodel_name='stock.move' ondelete='restrict' required=True string='Picking line'
  • name Char
    compute='_compute_name' store=True string='Name'
  • partner Many2one → res.partner
    comodel_name='res.partner' readonly=True related='move_id.purchase_line_id.order_id.partner_id' string='Supplier'
  • picking_id Many2one → stock.picking
    related='move_id.picking_id' store=True string='Picking' args: 'stock.picking'
  • product_id Many2one → product.product
    comodel_name='product.product' compute='_compute_product_id' store=True string='Product'
  • product_price_unit Float
    related='move_id.price_unit' string='Unit price'
  • product_qty Float
    compute='_compute_product_qty' store=True string='Quantity'
  • product_uom Many2one → uom.uom
    comodel_name='uom.uom' related='move_id.product_uom' string='Unit of measure'
  • product_volume Float
    help='The volume in m3.' related='product_id.product_tmpl_id.volume' string='Volume'
  • product_weight Float
    help='The gross weight in Kg.' related='product_id.product_tmpl_id.weight' string='Gross weight'
  • purchase_id Many2one → purchase.order
    comodel_name='purchase.order' readonly=True related='move_id.purchase_line_id.order_id' store=True string='Purchase order'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' related='move_id.purchase_line_id' string='Purchase order line'
  • standard_price_new Float
    compute='_compute_standard_price_new' digits='Product Price' string='New cost'
  • standard_price_old Float
    compute='_compute_standard_price_old' digits='Product Price' store=True string='Previous cost'
  • total_amount Float
    compute=_compute_total_amount digits='Account' string='Amount line'
  • total_volume Float
    compute=_compute_total_volume help='The line volume in m3.' store=True string='Line volume'
  • total_weight Float
    compute=_compute_total_weight digits='Stock Weight' help='The line gross weight in Kg.' store=True string='Line weight'
Public methods (1)
  • get_action_purchase_cost_distribution(self)
    @api.model

New fields (8)
  • company_id Many2one → res.company
    comodel_name='res.company' readonly=True related='distribution_line.company_id' store=True
  • cost_ratio Float
    args: 'Unit cost'
  • distribution_expense Many2one → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' ondelete='cascade' string='Distribution expense'
  • distribution_line Many2one → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' ondelete='cascade' string='Cost distribution line'
  • expense_amount Float
    digits='Account' string='Expense amount'
  • picking_date_done Datetime
    readonly=True related='picking_id.date_done' store=True
  • picking_id Many2one → stock.picking
    comodel_name='stock.picking' readonly=True related='distribution_line.picking_id' store=True
  • type Many2one → purchase.expense.type
    readonly=True related='distribution_expense.type' store=True string='Expense type' args: 'purchase.expense.type'
Public methods (0)

No public methods.

New fields (6)
  • calculation_method Selection
    default='amount' string='Calculation method' args: [('amount', 'By amount of the line'), ('price', 'By product price'), ('qty', 'By product quantity'), ('weight', 'By product weight'), ('volume', 'By product volume'), ('equal', 'Equally to all lines')]
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> string='Company'
  • default_amount Float
    help='If set, this amount is put in the expense line when you select this expense type' string='Default amount'
  • default_expense Boolean
    help='Specify if the expense will be automatically added in a purchase cost distribution.' string='Default Expense'
  • name Char
    index=True required=True string='Name' translate=True
  • note Text
    string='Cost documentation'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • action_open_landed_cost(self)

New fields (0)

No new fields.

Public methods (1)
  • action_open_landed_cost(self)
REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/12.0/purchase_landed_cost
VERSION
VERSION 1.1.1
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSTecnativa, Odoo Community Association (OCA), AvanzOSC, Joaquín Gutierrez
MAINTAINERS
MAINTAINERSTecnativa, Odoo Community Association (OCA), AvanzOSC, Joaquín Gutierrez
COMMITTERS
COMMITTERSGitHub, mreficent, OCA Transbot, oca-travis, Weblate, OCA-git-bot, clementmbr
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:29:23
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - purchase_stock
    - stock_account
    - stock
    - product
    - base
    - decimal_precision
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - uom
    - barcodes
    - account
    - analytic
    - portal
    - http_routing
    - digest
    - purchase
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (17)
XML IDNameModelTypeStatus
import_invoice_line_wizard_view import.invoice.line.wizard.form import.invoice.line.wizard form New
import_landed_cost_pickings_wizard_view import.landed.cost.pickings.wizard p New
invoice_supplier_form account.invoice notebook Inherits account.invoice_supplier_form
picking_import_wizard_view picking.import.wizard.form picking.import.wizard form New
purchase_cost_distribution_form purchase.cost.distribution.form purchase.cost.distribution form New
purchase_cost_distribution_search purchase.cost.distribution.search purchase.cost.distribution search New
purchase_expense_type_tree purchase.expense.type tree New
purchase_order_form purchase.order div Inherits purchase.purchase_order_form
view_picking_form stock.picking div Inherits stock.view_picking_form
view_purchase_cost_distribution_calendar purchase.cost.distribution.calendar purchase.cost.distribution calendar New
view_purchase_cost_distribution_expense_invoice_form purchase.cost.distribution.expense tree New
view_purchase_cost_distribution_graph purchase.cost.distribution.graph purchase.cost.distribution graph New
view_purchase_cost_distribution_line_expense_search purchase.cost.distribution.line.expense search New
view_purchase_cost_distribution_line_expense_tree purchase.cost.distribution.line.expense tree New
view_purchase_cost_distribution_line_form purchase.cost.distribution.line.form purchase.cost.distribution.line form New
view_purchase_cost_distribution_line_tree purchase.cost.distribution.line tree New
view_purchase_cost_distribution_tree purchase.cost.distribution.tree purchase.cost.distribution tree New
Models touched (12)

New fields (1)
  • expense_line_ids One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' inverse_name='invoice_id' string='Landed costs'
Public methods (0)

No public methods.

New fields (1)
  • expense_line_ids One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' inverse_name='invoice_line' string='Landed costs'
Public methods (0)

No public methods.

New fields (4)
  • expense_type Many2one → purchase.expense.type
    comodel_name='purchase.expense.type' required=True string='Expense type'
  • invoice Many2one → account.invoice
    comodel_name='account.invoice' domain="[('partner_id', '=', supplier), ('type', '=', 'in_invoice'),('state', 'in', ['open', 'paid'])]" required=True string='Invoice'
  • invoice_line Many2one → account.invoice.line
    comodel_name='account.invoice.line' domain="[('invoice_id', '=', invoice)]" required=True string='Invoice line'
  • supplier Many2one → res.partner
    comodel_name='res.partner' domain="[('supplier', '=', True)]" required=True string='Supplier'
Public methods (1)
  • action_import_invoice_line(self)
    @api.multi

New fields (2)
  • picking_ids Many2many → stock.picking
    comodel_name='stock.picking' domain="[('id', 'in', possible_picking_ids)]" string='Pickings'
  • possible_picking_ids Many2many → stock.picking
    comodel_name='stock.picking' string='Possible pickings'
Public methods (2)
  • button_import(self)
    @api.multi
  • default_get(self, fields_list)
    @api.model

New fields (3)
  • pickings Many2many → stock.picking
    column1='wizard_id' column2='picking_id' comodel_name='stock.picking' relation='distribution_import_picking_rel' required=True string='Incoming shipments'
  • prev_pickings Many2many → stock.picking
    comodel_name='stock.picking'
  • supplier Many2one → res.partner
    comodel_name='res.partner' domain="[('supplier', '=', True)]" required=True string='Supplier'
Public methods (2)
  • action_import_picking(self)
    @api.multi
  • default_get(self, field_list)
    @api.model
    Get pickings previously imported.

New fields (16)
  • amount_total Float
    compute=_compute_amount_total digits=dp.get_precision('Account') string='Total'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • cost_lines One2many → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' inverse_name='distribution' ondelete='cascade' string='Distribution lines'
  • cost_update_type Selection
    default='direct' required=True string='Cost Update Type' args: [('direct', 'Direct Update')]
  • currency_id Many2one → res.currency
    comodel_name='res.currency' related='company_id.currency_id' string='Currency'
  • date Date
    default=fields.Date.context_today index=True readonly=True required=True states={'draft': [('readonly', False)]} string='Date'
  • expense_lines One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' default=_expense_lines_default inverse_name='distribution' ondelete='cascade' string='Expenses'
  • name Char
    default='/' index=True required=True string='Distribution number'
  • note Text
    string='Documentation for this order'
  • state Selection
    default='draft' readonly=True string='Status' args: [('draft', 'Draft'), ('calculated', 'Calculated'), ('done', 'Done'), ('error', 'Error'), ('cancel', 'Cancel')]
  • total_expense Float
    compute=_compute_total_expense digits=dp.get_precision('Account') string='Total expenses'
  • total_price_unit Float
    compute=_compute_total_price_unit digits=dp.get_precision('Product Price') string='Total price unit'
  • total_purchase Float
    compute=_compute_total_purchase digits=dp.get_precision('Account') string='Total purchase'
  • total_uom_qty Float
    compute=_compute_total_uom_qty digits=dp.get_precision('Product UoS') readonly=True string='Total quantity'
  • total_volume Float
    compute=_compute_total_volume readonly=True string='Total volume'
  • total_weight Float
    compute=_compute_total_weight digits=dp.get_precision('Stock Weight') readonly=True string='Total gross weight'
Public methods (7)
  • action_calculate(self)
    @api.multi
  • action_cancel(self)
    @api.multi
    Perform all moves that touch the same product in batch.
  • action_done(self)
    @api.multi
    Perform all moves that touch the same product in batch.
  • action_draft(self)
    @api.multi
  • create(self, vals)
    @api.model
  • unlink(self)
    @api.multi
  • write(self, vals)
    @api.multi

New fields (11)
  • affected_lines Many2many → purchase.cost.distribution.line
    column1='expense_id' column2='line_id' comodel_name='purchase.cost.distribution.line' domain="[('id', 'in', imported_lines)]" help='Put here specific lines that this expense is going to be distributed across. Leave it blank to use all imported lines.' relation='distribution_expense_aff_rel' string='Affected lines'
  • calculation_method Selection
    readonly=True related='type.calculation_method' string='Calculation method'
  • company_id Many2one → res.company
    comodel_name='res.company' related='distribution.company_id' store=True
  • display_name Char
    compute='_compute_display_name' store=True
  • distribution Many2one → purchase.cost.distribution
    comodel_name='purchase.cost.distribution' index=True ondelete='cascade' required=True string='Cost distribution'
  • expense_amount Float
    digits=dp.get_precision('Account') required=True string='Expense amount'
  • imported_lines Many2many → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' compute='_compute_imported_lines' string='Imported lines'
  • invoice_id Many2one → account.invoice
    comodel_name='account.invoice' string='Invoice'
  • invoice_line Many2one → account.invoice.line
    comodel_name='account.invoice.line' domain="[('invoice_id.type', '=', 'in_invoice'),('invoice_id.state', 'in', ('open', 'paid'))]" string='Supplier invoice line'
  • ref Char
    string='Reference'
  • type Many2one → purchase.expense.type
    comodel_name='purchase.expense.type' index=True ondelete='restrict' string='Expense type'
Public methods (3)
  • button_duplicate(self)
    @api.multi
  • onchange_invoice_line(self)
    @api.onchange('invoice_line')
    set expense_amount in the currency of the distribution
  • onchange_type(self)
    @api.onchange('type')
    set expense_amount in the currency of the distribution

New fields (22)
  • company_id Many2one → res.company
    comodel_name='res.company' related='distribution.company_id' store=True
  • cost_ratio Float
    compute='_compute_cost_ratio' string='Unit cost'
  • distribution Many2one → purchase.cost.distribution
    comodel_name='purchase.cost.distribution' ondelete='cascade' required=True string='Cost distribution'
  • expense_amount Float
    compute='_compute_expense_amount' digits=dp.get_precision('Account') string='Cost amount'
  • expense_lines One2many → purchase.cost.distribution.line.expense
    comodel_name='purchase.cost.distribution.line.expense' inverse_name='distribution_line' string='Expenses distribution lines'
  • move_id Many2one → stock.move
    comodel_name='stock.move' ondelete='restrict' required=True string='Picking line'
  • name Char
    compute='_compute_name' store=True string='Name'
  • partner Many2one → res.partner
    comodel_name='res.partner' readonly=True related='move_id.purchase_line_id.order_id.partner_id' string='Supplier'
  • picking_id Many2one → stock.picking
    related='move_id.picking_id' store=True string='Picking' args: 'stock.picking'
  • product_id Many2one → product.product
    comodel_name='product.product' compute='_compute_product_id' store=True string='Product'
  • product_price_unit Float
    related='move_id.price_unit' string='Unit price'
  • product_qty Float
    compute='_compute_product_qty' store=True string='Quantity'
  • product_uom Many2one → uom.uom
    comodel_name='uom.uom' related='move_id.product_uom' string='Unit of measure'
  • product_volume Float
    help='The volume in m3.' related='product_id.product_tmpl_id.volume' string='Volume'
  • product_weight Float
    help='The gross weight in Kg.' related='product_id.product_tmpl_id.weight' string='Gross weight'
  • purchase_id Many2one → purchase.order
    comodel_name='purchase.order' readonly=True related='move_id.purchase_line_id.order_id' store=True string='Purchase order'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' related='move_id.purchase_line_id' string='Purchase order line'
  • standard_price_new Float
    compute='_compute_standard_price_new' digits=dp.get_precision('Product Price') string='New cost'
  • standard_price_old Float
    compute='_compute_standard_price_old' digits=dp.get_precision('Product Price') store=True string='Previous cost'
  • total_amount Float
    compute=_compute_total_amount digits=dp.get_precision('Account') string='Amount line'
  • total_volume Float
    compute=_compute_total_volume help='The line volume in m3.' store=True string='Line volume'
  • total_weight Float
    compute=_compute_total_weight digits=dp.get_precision('Stock Weight') help='The line gross weight in Kg.' store=True string='Line weight'
Public methods (1)
  • get_action_purchase_cost_distribution(self)
    @api.model

New fields (8)
  • company_id Many2one → res.company
    comodel_name='res.company' readonly=True related='distribution_line.company_id' store=True
  • cost_ratio Float
    args: 'Unit cost'
  • distribution_expense Many2one → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' ondelete='cascade' string='Distribution expense'
  • distribution_line Many2one → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' ondelete='cascade' string='Cost distribution line'
  • expense_amount Float
    digits=dp.get_precision('Account') string='Expense amount'
  • picking_date_done Datetime
    readonly=True related='picking_id.date_done' store=True
  • picking_id Many2one → stock.picking
    comodel_name='stock.picking' readonly=True related='distribution_line.picking_id' store=True
  • type Many2one → purchase.expense.type
    readonly=True related='distribution_expense.type' store=True string='Expense type' args: 'purchase.expense.type'
Public methods (0)

No public methods.

New fields (6)
  • calculation_method Selection
    default='amount' string='Calculation method' args: [('amount', 'By amount of the line'), ('price', 'By product price'), ('qty', 'By product quantity'), ('weight', 'By product weight'), ('volume', 'By product volume'), ('equal', 'Equally to all lines')]
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> string='Company'
  • default_amount Float
    help='If set, this amount is put in the expense line when you select this expense type' string='Default amount'
  • default_expense Boolean
    help='Specify if the expense will be automatically added in a purchase cost distribution.' string='Default Expense'
  • name Char
    index=True required=True string='Name' translate=True
  • note Text
    string='Cost documentation'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • action_open_landed_cost(self)
    @api.multi

New fields (0)

No new fields.

Public methods (1)
  • action_open_landed_cost(self)
    @api.multi
REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/11.0/purchase_landed_cost
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSTecnativa, Odoo Community Association (OCA), AvanzOSC, Joaquín Gutierrez
MAINTAINERS
MAINTAINERSTecnativa, Odoo Community Association (OCA), AvanzOSC, Joaquín Gutierrez
COMMITTERS
COMMITTERSPedro M. Baeza, GitHub, OCA Transbot, oca-travis, Weblate, OCA-git-bot
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:24:01
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - stock_account
    - stock
    - product
    - base
    - decimal_precision
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - barcodes
    - web_planner
    - account
    - analytic
    - portal
    - http_routing
    - purchase
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (17)
XML IDNameModelTypeStatus
import_invoice_line_wizard_view import.invoice.line.wizard.form import.invoice.line.wizard form New
import_landed_cost_pickings_wizard_view import.landed.cost.pickings.wizard p New
invoice_supplier_form account.invoice notebook Inherits account.invoice_supplier_form
picking_import_wizard_view picking.import.wizard.form picking.import.wizard form New
purchase_cost_distribution_form purchase.cost.distribution.form purchase.cost.distribution form New
purchase_cost_distribution_search purchase.cost.distribution.search purchase.cost.distribution search New
purchase_expense_type_tree purchase.expense.type tree New
purchase_order_form purchase.order div Inherits purchase.purchase_order_form
view_picking_form stock.picking div Inherits stock.view_picking_form
view_purchase_cost_distribution_calendar purchase.cost.distribution.calendar purchase.cost.distribution calendar New
view_purchase_cost_distribution_expense_invoice_form purchase.cost.distribution.expense tree New
view_purchase_cost_distribution_graph purchase.cost.distribution.graph purchase.cost.distribution graph New
view_purchase_cost_distribution_line_expense_search purchase.cost.distribution.line.expense search New
view_purchase_cost_distribution_line_expense_tree purchase.cost.distribution.line.expense tree New
view_purchase_cost_distribution_line_form purchase.cost.distribution.line.form purchase.cost.distribution.line form New
view_purchase_cost_distribution_line_tree purchase.cost.distribution.line tree New
view_purchase_cost_distribution_tree purchase.cost.distribution.tree purchase.cost.distribution tree New
Models touched (12)

New fields (1)
  • expense_line_ids One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' inverse_name='invoice_id' string='Landed costs'
Public methods (0)

No public methods.

New fields (1)
  • expense_line_ids One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' inverse_name='invoice_line' string='Landed costs'
Public methods (0)

No public methods.

New fields (4)
  • expense_type Many2one → purchase.expense.type
    comodel_name='purchase.expense.type' required=True string='Expense type'
  • invoice Many2one → account.invoice
    comodel_name='account.invoice' domain="[('partner_id', '=', supplier), ('type', '=', 'in_invoice'),('state', 'in', ['open', 'paid'])]" required=True string='Invoice'
  • invoice_line Many2one → account.invoice.line
    comodel_name='account.invoice.line' domain="[('invoice_id', '=', invoice)]" required=True string='Invoice line'
  • supplier Many2one → res.partner
    comodel_name='res.partner' domain="[('supplier', '=', True)]" required=True string='Supplier'
Public methods (1)
  • action_import_invoice_line(self)
    @api.multi

New fields (2)
  • picking_ids Many2many → stock.picking
    comodel_name='stock.picking' domain="[('id', 'in', possible_picking_ids)]" string='Pickings'
  • possible_picking_ids Many2many → stock.picking
    comodel_name='stock.picking' string='Possible pickings'
Public methods (2)
  • button_import(self)
    @api.multi
  • default_get(self, fields_list)
    @api.model

New fields (3)
  • pickings Many2many → stock.picking
    column1='wizard_id' column2='picking_id' comodel_name='stock.picking' relation='distribution_import_picking_rel' required=True string='Incoming shipments'
  • prev_pickings Many2many → stock.picking
    comodel_name='stock.picking'
  • supplier Many2one → res.partner
    comodel_name='res.partner' domain="[('supplier', '=', True)]" required=True string='Supplier'
Public methods (2)
  • action_import_picking(self)
    @api.multi
  • default_get(self, field_list)
    @api.model
    Get pickings previously imported.

New fields (16)
  • amount_total Float
    compute=_compute_amount_total digits=dp.get_precision('Account') string='Total'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • cost_lines One2many → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' inverse_name='distribution' ondelete='cascade' string='Distribution lines'
  • cost_update_type Selection
    default='direct' required=True string='Cost Update Type' args: [('direct', 'Direct Update')]
  • currency_id Many2one → res.currency
    comodel_name='res.currency' related='company_id.currency_id' string='Currency'
  • date Date
    default=fields.Date.context_today index=True readonly=True required=True states={'draft': [('readonly', False)]} string='Date'
  • expense_lines One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' default=_expense_lines_default inverse_name='distribution' ondelete='cascade' string='Expenses'
  • name Char
    default='/' index=True required=True string='Distribution number'
  • note Text
    string='Documentation for this order'
  • state Selection
    default='draft' readonly=True string='Status' args: [('draft', 'Draft'), ('calculated', 'Calculated'), ('done', 'Done'), ('error', 'Error'), ('cancel', 'Cancel')]
  • total_expense Float
    compute=_compute_total_expense digits=dp.get_precision('Account') string='Total expenses'
  • total_price_unit Float
    compute=_compute_total_price_unit digits=dp.get_precision('Product Price') string='Total price unit'
  • total_purchase Float
    compute=_compute_total_purchase digits=dp.get_precision('Account') string='Total purchase'
  • total_uom_qty Float
    compute=_compute_total_uom_qty digits=dp.get_precision('Product UoS') readonly=True string='Total quantity'
  • total_volume Float
    compute=_compute_total_volume readonly=True string='Total volume'
  • total_weight Float
    compute=_compute_total_weight digits=dp.get_precision('Stock Weight') readonly=True string='Total gross weight'
Public methods (7)
  • action_calculate(self)
    @api.multi
  • action_cancel(self)
    @api.multi
    Perform all moves that touch the same product in batch.
  • action_done(self)
    @api.multi
    Perform all moves that touch the same product in batch.
  • action_draft(self)
    @api.multi
  • create(self, vals)
    @api.model
  • unlink(self)
    @api.multi
  • write(self, vals)
    @api.multi

New fields (11)
  • affected_lines Many2many → purchase.cost.distribution.line
    column1='expense_id' column2='line_id' comodel_name='purchase.cost.distribution.line' domain="[('id', 'in', imported_lines)]" help='Put here specific lines that this expense is going to be distributed across. Leave it blank to use all imported lines.' relation='distribution_expense_aff_rel' string='Affected lines'
  • calculation_method Selection
    readonly=True related='type.calculation_method' string='Calculation method'
  • company_id Many2one → res.company
    comodel_name='res.company' related='distribution.company_id' store=True
  • display_name Char
    compute='_compute_display_name' store=True
  • distribution Many2one → purchase.cost.distribution
    comodel_name='purchase.cost.distribution' index=True ondelete='cascade' required=True string='Cost distribution'
  • expense_amount Float
    digits=dp.get_precision('Account') required=True string='Expense amount'
  • imported_lines Many2many → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' compute='_get_imported_lines' string='Imported lines'
  • invoice_id Many2one → account.invoice
    comodel_name='account.invoice' string='Invoice'
  • invoice_line Many2one → account.invoice.line
    comodel_name='account.invoice.line' domain="[('invoice_id.type', '=', 'in_invoice'),('invoice_id.state', 'in', ('open', 'paid'))]" string='Supplier invoice line'
  • ref Char
    string='Reference'
  • type Many2one → purchase.expense.type
    comodel_name='purchase.expense.type' index=True ondelete='restrict' string='Expense type'
Public methods (3)
  • button_duplicate(self)
    @api.multi
  • onchange_invoice_line(self)
    @api.onchange('invoice_line')
  • onchange_type(self)
    @api.onchange('type')

New fields (22)
  • company_id Many2one → res.company
    comodel_name='res.company' related='distribution.company_id' store=True
  • cost_ratio Float
    compute='_compute_cost_ratio' string='Unit cost'
  • distribution Many2one → purchase.cost.distribution
    comodel_name='purchase.cost.distribution' ondelete='cascade' required=True string='Cost distribution'
  • expense_amount Float
    compute='_compute_expense_amount' digits=dp.get_precision('Account') string='Cost amount'
  • expense_lines One2many → purchase.cost.distribution.line.expense
    comodel_name='purchase.cost.distribution.line.expense' inverse_name='distribution_line' string='Expenses distribution lines'
  • move_id Many2one → stock.move
    comodel_name='stock.move' ondelete='restrict' required=True string='Picking line'
  • name Char
    compute='_compute_name' store=True string='Name'
  • partner Many2one → res.partner
    comodel_name='res.partner' readonly=True related='move_id.purchase_line_id.order_id.partner_id' string='Supplier'
  • picking_id Many2one → stock.picking
    related='move_id.picking_id' store=True string='Picking' args: 'stock.picking'
  • product_id Many2one → product.product
    comodel_name='product.product' compute='_compute_product_id' store=True string='Product'
  • product_price_unit Float
    related='move_id.price_unit' string='Unit price'
  • product_qty Float
    compute='_get_product_qty' store=True string='Quantity'
  • product_uom Many2one → product.uom
    comodel_name='product.uom' related='move_id.product_uom' string='Unit of measure'
  • product_volume Float
    help='The volume in m3.' related='product_id.product_tmpl_id.volume' string='Volume'
  • product_weight Float
    help='The gross weight in Kg.' related='product_id.product_tmpl_id.weight' string='Gross weight'
  • purchase_id Many2one → purchase.order
    comodel_name='purchase.order' readonly=True related='move_id.purchase_line_id.order_id' store=True string='Purchase order'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' related='move_id.purchase_line_id' string='Purchase order line'
  • standard_price_new Float
    compute='_compute_standard_price_new' digits=dp.get_precision('Product Price') string='New cost'
  • standard_price_old Float
    compute='_compute_standard_price_old' digits=dp.get_precision('Product Price') store=True string='Previous cost'
  • total_amount Float
    compute=_compute_total_amount digits=dp.get_precision('Account') string='Amount line'
  • total_volume Float
    compute=_compute_total_volume help='The line volume in m3.' store=True string='Line volume'
  • total_weight Float
    compute=_compute_total_weight digits=dp.get_precision('Stock Weight') help='The line gross weight in Kg.' store=True string='Line weight'
Public methods (0)

No public methods.

New fields (8)
  • company_id Many2one → res.company
    comodel_name='res.company' readonly=True related='distribution_line.company_id' store=True
  • cost_ratio Float
    args: 'Unit cost'
  • distribution_expense Many2one → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' ondelete='cascade' string='Distribution expense'
  • distribution_line Many2one → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' ondelete='cascade' string='Cost distribution line'
  • expense_amount Float
    digits=dp.get_precision('Account') string='Expense amount'
  • picking_date_done Datetime
    readonly=True related='picking_id.date_done' store=True
  • picking_id Many2one → stock.picking
    comodel_name='stock.picking' readonly=True related='distribution_line.picking_id' store=True
  • type Many2one → purchase.expense.type
    readonly=True related='distribution_expense.type' store=True string='Expense type' args: 'purchase.expense.type'
Public methods (0)

No public methods.

New fields (6)
  • calculation_method Selection
    default='amount' string='Calculation method' args: [('amount', 'By amount of the line'), ('price', 'By product price'), ('qty', 'By product quantity'), ('weight', 'By product weight'), ('volume', 'By product volume'), ('equal', 'Equally to all lines')]
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> string='Company'
  • default_amount Float
    help='If set, this amount is put in the expense line when you select this expense type' string='Default amount'
  • default_expense Boolean
    help='Specify if the expense will be automatically added in a purchase cost distribution.' string='Default Expense'
  • name Char
    index=True required=True string='Name' translate=True
  • note Text
    string='Cost documentation'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • action_open_landed_cost(self)
    @api.multi

New fields (0)

No new fields.

Public methods (1)
  • action_open_landed_cost(self)
    @api.multi
REPOSITORY
REPOSITORYOCA/purchase-workflow
GIT
GIThttps://github.com/OCA/purchase-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/purchase-workflow/tree/10.0/purchase_landed_cost
VERSION
VERSION 2.0.0
CATEGORY
CATEGORYPurchase Management
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSTecnativa, Odoo Community Association (OCA), AvanzOSC, OdooMRP team, Joaquín Gutierrez
MAINTAINERS
MAINTAINERSTecnativa, Odoo Community Association (OCA), AvanzOSC, OdooMRP team, Joaquín Gutierrez
COMMITTERS
COMMITTERSPedro M. Baeza, OCA Transbot, oca-travis, Weblate
WEBSITE
WEBSITEhttps://github.com/OCA/purchase-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:20:01
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - stock
    - product
    - base
    - decimal_precision
    - mail
    - base_setup
    - web_kanban
    - web
    - bus
    - web_tour
    - report
    - procurement
    - barcodes
    - web_planner
    - purchase
    - stock_account
    - account
    - analytic
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (17)
XML IDNameModelTypeStatus
import_invoice_line_wizard_view import.invoice.line.wizard.form import.invoice.line.wizard form New
import_landed_cost_pickings_wizard_view import.landed.cost.pickings.wizard p New
invoice_supplier_form account.invoice notebook Inherits account.invoice_supplier_form
picking_import_wizard_view picking.import.wizard.form picking.import.wizard form New
purchase_cost_distribution_form purchase.cost.distribution.form purchase.cost.distribution form New
purchase_cost_distribution_search purchase.cost.distribution.search purchase.cost.distribution search New
purchase_expense_type_tree purchase.expense.type tree New
purchase_order_form purchase.order div Inherits purchase.purchase_order_form
view_picking_form stock.picking div Inherits stock.view_picking_form
view_purchase_cost_distribution_calendar purchase.cost.distribution.calendar purchase.cost.distribution calendar New
view_purchase_cost_distribution_expense_invoice_form purchase.cost.distribution.expense tree New
view_purchase_cost_distribution_graph purchase.cost.distribution.graph purchase.cost.distribution graph New
view_purchase_cost_distribution_line_expense_search purchase.cost.distribution.line.expense search New
view_purchase_cost_distribution_line_expense_tree purchase.cost.distribution.line.expense tree New
view_purchase_cost_distribution_line_form purchase.cost.distribution.line.form purchase.cost.distribution.line form New
view_purchase_cost_distribution_line_tree purchase.cost.distribution.line tree New
view_purchase_cost_distribution_tree purchase.cost.distribution.tree purchase.cost.distribution tree New
Models touched (12)

New fields (1)
  • expense_line_ids One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' inverse_name='invoice_id' string='Landed costs'
Public methods (0)

No public methods.

New fields (1)
  • expense_line_ids One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' inverse_name='invoice_line' string='Landed costs'
Public methods (0)

No public methods.

New fields (4)
  • expense_type Many2one → purchase.expense.type
    comodel_name='purchase.expense.type' required=True string='Expense type'
  • invoice Many2one → account.invoice
    comodel_name='account.invoice' domain="[('partner_id', '=', supplier), ('type', '=', 'in_invoice'),('state', 'in', ['open', 'paid'])]" required=True string='Invoice'
  • invoice_line Many2one → account.invoice.line
    comodel_name='account.invoice.line' domain="[('invoice_id', '=', invoice)]" required=True string='Invoice line'
  • supplier Many2one → res.partner
    comodel_name='res.partner' domain="[('supplier', '=', True)]" required=True string='Supplier'
Public methods (1)
  • action_import_invoice_line(self)
    @api.multi

New fields (2)
  • picking_ids Many2many → stock.picking
    comodel_name='stock.picking' domain="[('id', 'in', possible_picking_ids[0][2])]" string='Pickings'
  • possible_picking_ids Many2many → stock.picking
    comodel_name='stock.picking' string='Possible pickings'
Public methods (2)
  • button_import(self)
    @api.multi
  • default_get(self, fields_list)
    @api.model

New fields (3)
  • pickings Many2many → stock.picking
    column1='wizard_id' column2='picking_id' comodel_name='stock.picking' relation='distribution_import_picking_rel' required=True string='Incoming shipments'
  • prev_pickings Many2many → stock.picking
    comodel_name='stock.picking'
  • supplier Many2one → res.partner
    comodel_name='res.partner' domain="[('supplier', '=', True)]" required=True string='Supplier'
Public methods (2)
  • action_import_picking(self)
    @api.multi
  • default_get(self, field_list)
    @api.model
    Get pickings previously imported.

New fields (16)
  • amount_total Float
    compute=_compute_amount_total digits=dp.get_precision('Account') string='Total'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> required=True string='Company'
  • cost_lines One2many → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' inverse_name='distribution' ondelete='cascade' string='Distribution lines'
  • cost_update_type Selection
    default='direct' required=True string='Cost Update Type' args: [('direct', 'Direct Update')]
  • currency_id Many2one → res.currency
    comodel_name='res.currency' related='company_id.currency_id' string='Currency'
  • date Date
    default=fields.Date.context_today index=True readonly=True required=True states={'draft': [('readonly', False)]} string='Date'
  • expense_lines One2many → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' default=_expense_lines_default inverse_name='distribution' ondelete='cascade' string='Expenses'
  • name Char
    default='/' index=True required=True string='Distribution number'
  • note Text
    string='Documentation for this order'
  • state Selection
    default='draft' readonly=True string='Status' args: [('draft', 'Draft'), ('calculated', 'Calculated'), ('done', 'Done'), ('error', 'Error'), ('cancel', 'Cancel')]
  • total_expense Float
    compute=_compute_total_expense digits=dp.get_precision('Account') string='Total expenses'
  • total_price_unit Float
    compute=_compute_total_price_unit digits=dp.get_precision('Product Price') string='Total price unit'
  • total_purchase Float
    compute=_compute_total_purchase digits=dp.get_precision('Account') string='Total purchase'
  • total_uom_qty Float
    compute=_compute_total_uom_qty digits=dp.get_precision('Product UoS') readonly=True string='Total quantity'
  • total_volume Float
    compute=_compute_total_volume readonly=True string='Total volume'
  • total_weight Float
    compute=_compute_total_weight digits=dp.get_precision('Stock Weight') readonly=True string='Total gross weight'
Public methods (7)
  • action_calculate(self)
    @api.multi
  • action_cancel(self)
    @api.multi
    Perform all moves that touch the same product in batch.
  • action_done(self)
    @api.multi
    Perform all moves that touch the same product in batch.
  • action_draft(self)
    @api.multi
  • create(self, vals)
    @api.model
  • unlink(self)
    @api.multi
  • write(self, vals)
    @api.multi

New fields (11)
  • affected_lines Many2many → purchase.cost.distribution.line
    column1='expense_id' column2='line_id' comodel_name='purchase.cost.distribution.line' domain="[('id', 'in', imported_lines[0][2])]" help='Put here specific lines that this expense is going to be distributed across. Leave it blank to use all imported lines.' relation='distribution_expense_aff_rel' string='Affected lines'
  • calculation_method Selection
    readonly=True related='type.calculation_method' string='Calculation method'
  • company_id Many2one → res.company
    comodel_name='res.company' related='distribution.company_id' store=True
  • display_name Char
    compute='_compute_display_name' store=True
  • distribution Many2one → purchase.cost.distribution
    comodel_name='purchase.cost.distribution' index=True ondelete='cascade' required=True string='Cost distribution'
  • expense_amount Float
    digits=dp.get_precision('Account') required=True string='Expense amount'
  • imported_lines Many2many → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' compute='_get_imported_lines' string='Imported lines'
  • invoice_id Many2one → account.invoice
    comodel_name='account.invoice' string='Invoice'
  • invoice_line Many2one → account.invoice.line
    comodel_name='account.invoice.line' domain="[('invoice_id.type', '=', 'in_invoice'),('invoice_id.state', 'in', ('open', 'paid'))]" string='Supplier invoice line'
  • ref Char
    string='Reference'
  • type Many2one → purchase.expense.type
    comodel_name='purchase.expense.type' index=True ondelete='restrict' string='Expense type'
Public methods (3)
  • button_duplicate(self)
    @api.multi
  • onchange_invoice_line(self)
    @api.onchange('invoice_line')
  • onchange_type(self)
    @api.onchange('type')

New fields (22)
  • company_id Many2one → res.company
    comodel_name='res.company' related='distribution.company_id' store=True
  • cost_ratio Float
    compute='_compute_cost_ratio' string='Unit cost'
  • distribution Many2one → purchase.cost.distribution
    comodel_name='purchase.cost.distribution' ondelete='cascade' required=True string='Cost distribution'
  • expense_amount Float
    compute='_compute_expense_amount' digits=dp.get_precision('Account') string='Cost amount'
  • expense_lines One2many → purchase.cost.distribution.line.expense
    comodel_name='purchase.cost.distribution.line.expense' inverse_name='distribution_line' string='Expenses distribution lines'
  • move_id Many2one → stock.move
    comodel_name='stock.move' ondelete='restrict' required=True string='Picking line'
  • name Char
    compute='_compute_name' store=True string='Name'
  • partner Many2one → res.partner
    comodel_name='res.partner' readonly=True related='move_id.purchase_line_id.order_id.partner_id' string='Supplier'
  • picking_id Many2one → stock.picking
    related='move_id.picking_id' store=True string='Picking' args: 'stock.picking'
  • product_id Many2one → product.product
    comodel_name='product.product' compute='_compute_product_id' store=True string='Product'
  • product_price_unit Float
    related='move_id.price_unit' string='Unit price'
  • product_qty Float
    compute='_get_product_qty' store=True string='Quantity'
  • product_uom Many2one → product.uom
    comodel_name='product.uom' related='move_id.product_uom' string='Unit of measure'
  • product_volume Float
    help='The volume in m3.' related='product_id.product_tmpl_id.volume' string='Volume'
  • product_weight Float
    help='The gross weight in Kg.' related='product_id.product_tmpl_id.weight' string='Gross weight'
  • purchase_id Many2one → purchase.order
    comodel_name='purchase.order' readonly=True related='move_id.purchase_line_id.order_id' store=True string='Purchase order'
  • purchase_line_id Many2one → purchase.order.line
    comodel_name='purchase.order.line' related='move_id.purchase_line_id' string='Purchase order line'
  • standard_price_new Float
    compute='_compute_standard_price_new' digits=dp.get_precision('Product Price') string='New cost'
  • standard_price_old Float
    compute='_compute_standard_price_old' digits=dp.get_precision('Product Price') store=True string='Previous cost'
  • total_amount Float
    compute=_compute_total_amount digits=dp.get_precision('Account') string='Amount line'
  • total_volume Float
    compute=_compute_total_volume help='The line volume in m3.' store=True string='Line volume'
  • total_weight Float
    compute=_compute_total_weight digits=dp.get_precision('Stock Weight') help='The line gross weight in Kg.' store=True string='Line weight'
Public methods (0)

No public methods.

New fields (8)
  • company_id Many2one → res.company
    comodel_name='res.company' readonly=True related='distribution_line.company_id' store=True
  • cost_ratio Float
    args: 'Unit cost'
  • distribution_expense Many2one → purchase.cost.distribution.expense
    comodel_name='purchase.cost.distribution.expense' ondelete='cascade' string='Distribution expense'
  • distribution_line Many2one → purchase.cost.distribution.line
    comodel_name='purchase.cost.distribution.line' ondelete='cascade' string='Cost distribution line'
  • expense_amount Float
    digits=dp.get_precision('Account') string='Expense amount'
  • picking_date_done Datetime
    readonly=True related='picking_id.date_done' store=True
  • picking_id Many2one → stock.picking
    comodel_name='stock.picking' readonly=True related='distribution_line.picking_id' store=True
  • type Many2one → purchase.expense.type
    readonly=True related='distribution_expense.type' store=True string='Expense type' args: 'purchase.expense.type'
Public methods (0)

No public methods.

New fields (6)
  • calculation_method Selection
    default='amount' string='Calculation method' args: [('amount', 'By amount of the line'), ('price', 'By product price'), ('qty', 'By product quantity'), ('weight', 'By product weight'), ('volume', 'By product volume'), ('equal', 'Equally to all lines')]
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> string='Company'
  • default_amount Float
    help='If set, this amount is put in the expense line when you select this expense type' string='Default amount'
  • default_expense Boolean
    help='Specify if the expense will be automatically added in a purchase cost distribution.' string='Default Expense'
  • name Char
    index=True required=True string='Name' translate=True
  • note Text
    string='Cost documentation'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • action_open_landed_cost(self)
    @api.multi

New fields (0)

No new fields.

Public methods (1)
  • action_open_landed_cost(self)
    @api.multi