[IMP] sale, purchase, account: incoterm location
Before this PR, the incoterm location was not present in the account module. This pr does multiple things: - Add the Incoterm Location field in Accounting on Customer Invoices and Vendor Bills. The field already exists on Sale Orders and Purchase Orders. When you create an Invoice from a Sales Order, or a Vendor Bill from a PO, copy the value of the field on the invoices. - Update the PDF to display the field value if present, and remove the useless duplication - Remove incoterm setting on sale - Remove useless xpath since now it is displayed directly on invoice when incoterm field is fill. Task-id: 3273460 Part-of: odoo/odoo#118954
This commit is contained in:
@@ -538,6 +538,12 @@ class AccountMove(models.Model):
|
||||
help='International Commercial Terms are a series of predefined commercial '
|
||||
'terms used in international transactions.',
|
||||
)
|
||||
incoterm_location = fields.Char(
|
||||
string='Incoterm Location',
|
||||
compute='_compute_incoterm_location',
|
||||
readonly=False,
|
||||
store=True,
|
||||
)
|
||||
invoice_cash_rounding_id = fields.Many2one(
|
||||
comodel_name='account.cash.rounding',
|
||||
string='Cash Rounding Method',
|
||||
@@ -1545,6 +1551,9 @@ class AccountMove(models.Model):
|
||||
for move in self:
|
||||
move[attachment_field] = move_vals.get(move._origin.id, False)
|
||||
|
||||
def _compute_incoterm_location(self):
|
||||
pass
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# INVERSE METHODS
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@@ -1215,6 +1215,7 @@
|
||||
attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund'))]}">
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="invoice_incoterm_id"/>
|
||||
<field name="incoterm_location"/>
|
||||
<field name="fiscal_position_id"/>
|
||||
<field name="invoice_cash_rounding_id" groups="account.group_cash_rounding"/>
|
||||
<field name="invoice_source_email"
|
||||
|
||||
@@ -90,6 +90,14 @@
|
||||
<strong>Reference:</strong>
|
||||
<p class="m-0" t-field="o.ref"/>
|
||||
</div>
|
||||
<div t-attf-class="#{'col-auto col-3 mw-100' if report_type != 'html' else 'col'} mb-2" t-if="o.invoice_incoterm_id" name="incoterm_id">
|
||||
<strong>Incoterm:</strong>
|
||||
<p t-if="o.incoterm_location">
|
||||
<span t-field="o.invoice_incoterm_id.code"/> <br/>
|
||||
<span t-field="o.incoterm_location"/>
|
||||
</p>
|
||||
<p t-else="" t-field="o.invoice_incoterm_id.code" class="m-0"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<t t-set="display_discount" t-value="any(l.discount for l in o.invoice_line_ids)"/>
|
||||
@@ -272,9 +280,6 @@
|
||||
<div class="text-muted mb-3" t-attf-style="#{'text-align:justify;text-justify:inter-word;' if o.company_id.terms_type != 'html' else ''}" t-if="not is_html_empty(o.narration)" name="comment">
|
||||
<span t-field="o.narration"/>
|
||||
</div>
|
||||
<p t-if="o.invoice_incoterm_id" name="incoterm">
|
||||
<strong>Incoterm: </strong><t t-out="o.invoice_incoterm_id.code"/> - <t t-out="o.invoice_incoterm_id.name"/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -222,7 +222,13 @@
|
||||
<!-- We do not have remitos implement yet. print here the remito number when we have it -->
|
||||
|
||||
<t t-if="o.invoice_incoterm_id">
|
||||
<br/><strong>Incoterm:</strong><span t-field="o.invoice_incoterm_id.name"/>
|
||||
<br/>
|
||||
<strong>Incoterm:</strong>
|
||||
<p t-if="o.incoterm_location">
|
||||
<span t-field="o.invoice_incoterm_id.code"/> <br/>
|
||||
<span t-field="o.incoterm_location"/>
|
||||
</p>
|
||||
<p t-else="" t-field="o.invoice_incoterm_id.name" class="m-0"/>
|
||||
</t>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -111,7 +111,11 @@
|
||||
<t t-if="o.invoice_incoterm_id">
|
||||
<br/>
|
||||
<strong>Incoterm:</strong>
|
||||
<span t-field="o.invoice_incoterm_id.name"/>
|
||||
<span t-if="o.incoterm_location">
|
||||
<span t-field="o.invoice_incoterm_id.code"/> -
|
||||
<span t-field="o.incoterm_location"/>
|
||||
</span>
|
||||
<span t-else="" t-field="o.invoice_incoterm_id.name" class="m-0"/>
|
||||
</t>
|
||||
|
||||
<t t-if="o.partner_shipping_id and o.partner_id not in o.partner_shipping_id" >
|
||||
|
||||
@@ -535,27 +535,21 @@
|
||||
</p>
|
||||
<p t-if="o.invoice_incoterm_id" name="incoterm">
|
||||
<div class="row">
|
||||
<div class="col-6 text-start">
|
||||
<strong>Incoterm:
|
||||
</strong>
|
||||
<span
|
||||
t-out="o.invoice_incoterm_id.code"/>
|
||||
-
|
||||
<span
|
||||
t-out="o.invoice_incoterm_id.name"/>
|
||||
<div class="col-2 offset-6">
|
||||
<strong>Incoterm:</strong>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<strong>شرط تجاري:
|
||||
</strong>
|
||||
<span
|
||||
t-out="o_sec.invoice_incoterm_id.code"/>
|
||||
<div class="col-2 text-nowrap">
|
||||
<span t-out="o.invoice_incoterm_id.code"/>
|
||||
-
|
||||
<span
|
||||
t-out="o_sec.invoice_incoterm_id.name"/>
|
||||
<span t-out="o.invoice_incoterm_id.name"/>
|
||||
-
|
||||
<span t-if="o.incoterm_location" t-out="o.incoterm_location"/>
|
||||
</div>
|
||||
<div class="col-2 text-end">
|
||||
<strong>:شرط تجاري</strong>
|
||||
</div>
|
||||
</div>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
from odoo import fields, models, api
|
||||
from odoo.tools import float_compare, float_is_zero
|
||||
from odoo.tools.misc import groupby
|
||||
|
||||
@@ -193,3 +193,13 @@ class AccountMove(models.Model):
|
||||
for invoice in self.filtered(lambda x: x.move_type == 'in_refund'):
|
||||
rslt += invoice.mapped('invoice_line_ids.purchase_line_id.move_ids').filtered(lambda x: x.state == 'done' and x.location_dest_id.usage == 'supplier')
|
||||
return rslt
|
||||
|
||||
@api.depends('purchase_id')
|
||||
def _compute_incoterm_location(self):
|
||||
super()._compute_incoterm_location()
|
||||
for move in self:
|
||||
purchase_locations = move.line_ids.purchase_line_id.order_id.mapped('incoterm_location')
|
||||
incoterm_res = next((incoterm for incoterm in purchase_locations if incoterm), False)
|
||||
# if multiple purchase order we take an incoterm that is not false
|
||||
if incoterm_res:
|
||||
move.incoterm_location = incoterm_res
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
<xpath expr="//div[@t-elif='o.date_order']" position="after">
|
||||
<div t-if="o.incoterm_id" class="col-3 bm-2">
|
||||
<strong>Incoterm:</strong>
|
||||
<p t-if="o.incoterm_location" t-out="'%s %s' % (o.incoterm_id.code, o.incoterm_location)" class="m-0"/>
|
||||
<p t-if="o.incoterm_location">
|
||||
<span t-field="o.incoterm_id.code"/> <br/>
|
||||
<span t-field="o.incoterm_location"/>
|
||||
</p>
|
||||
<p t-else="" t-field="o.incoterm_id.code" class="m-0"/>
|
||||
</div>
|
||||
</xpath>
|
||||
@@ -38,7 +41,10 @@
|
||||
<div id="informations" class="row mt16 mb16">
|
||||
<div t-if="o.incoterm_id" class="col-3 bm-2">
|
||||
<strong>Incoterm:</strong>
|
||||
<p t-if="o.incoterm_location" t-out="'%s %s' % (o.incoterm_id.code, o.incoterm_location)" class="m-0"/>
|
||||
<p t-if="o.incoterm_location">
|
||||
<span t-field="o.invoice_incoterm_id.code"/> <br/>
|
||||
<span t-field="o.incoterm_location"/>
|
||||
</p>
|
||||
<p t-else="" t-field="o.incoterm_id.code" class="m-0"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -118,6 +118,15 @@ class AccountMove(models.Model):
|
||||
if effective_date_res:
|
||||
move.delivery_date = effective_date_res
|
||||
|
||||
@api.depends('line_ids.sale_line_ids.order_id')
|
||||
def _compute_incoterm_location(self):
|
||||
super()._compute_incoterm_location()
|
||||
for move in self:
|
||||
sale_locations = move.line_ids.sale_line_ids.order_id.mapped('incoterm_location')
|
||||
incoterm_res = next((incoterm for incoterm in sale_locations if incoterm), False)
|
||||
# if multiple purchase order we take an incoterm that is not false
|
||||
if incoterm_res:
|
||||
move.incoterm_location = incoterm_res
|
||||
|
||||
class AccountMoveLine(models.Model):
|
||||
_inherit = "account.move.line"
|
||||
|
||||
@@ -8,7 +8,6 @@ class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
security_lead = fields.Float(related='company_id.security_lead', string="Security Lead Time", readonly=False)
|
||||
group_display_incoterm = fields.Boolean("Incoterms", implied_group='sale_stock.group_display_incoterm')
|
||||
use_security_lead = fields.Boolean(
|
||||
string="Security Lead Time for Sales",
|
||||
config_parameter='sale_stock.use_security_lead',
|
||||
|
||||
@@ -2,20 +2,14 @@
|
||||
<odoo>
|
||||
<template id="report_saleorder_document_inherit_sale_stock" inherit_id="sale.report_saleorder_document">
|
||||
<xpath expr="//div[@name='expiration_date']" position="after">
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="doc.incoterm" groups="sale_stock.group_display_incoterm">
|
||||
<div class="col-auto col-3 mw-100 mb-2" t-if="doc.incoterm">
|
||||
<strong>Incoterm:</strong>
|
||||
<p t-if="doc.incoterm_location" t-out="'%s %s' % (doc.incoterm.code, doc.incoterm_location)" class="m-0"/>
|
||||
<p t-if="doc.incoterm_location">
|
||||
<span t-field="doc.incoterm.code"/> <br/>
|
||||
<span t-field="doc.incoterm_location"/>
|
||||
</p>
|
||||
<p t-else="" t-field="doc.incoterm.code" class="m-0"/>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="report_invoice_document_inherit_sale_stock" inherit_id="account.report_invoice_document">
|
||||
<xpath expr="//div[@name='reference']" position="after">
|
||||
<div class="col-auto mw-100 mb-2" t-if="o.invoice_incoterm_id" groups="sale_stock.group_display_incoterm" name="invoice_incoterm_id">
|
||||
<strong>Incoterm:</strong>
|
||||
<p class="m-0" t-field="o.invoice_incoterm_id.code"/>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="group_display_incoterm" model="res.groups">
|
||||
<field name="name">Display incoterms on Sales Order and related invoices</field>
|
||||
<field name="category_id" ref="base.module_category_hidden"/>
|
||||
</record>
|
||||
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- Stock Portal Access Rules -->
|
||||
|
||||
@@ -1,24 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="res_config_settings_view_form_sale" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.sale.stock.sale</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="sale.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//setting[@id='ups']" position="after">
|
||||
<setting id="display_incoterms_setting" help="Display incoterms on orders & invoices">
|
||||
<field name="group_display_incoterm"/>
|
||||
<div class="content-group" attrs="{'invisible': [('group_display_incoterm','=',False)]}">
|
||||
<div class="mt8">
|
||||
<button name="%(account.action_incoterms_tree)d" icon="oi-arrow-right" type="action" string="Incoterms" class="btn-link"/>
|
||||
</div>
|
||||
</div>
|
||||
</setting>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_config_settings_view_form_stock" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.sale.stock.stock</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
<xpath expr="//label[@for='commitment_date']" position="before">
|
||||
<field name="warehouse_id" invisible="1"/> <!-- needed for js logic -->
|
||||
<field name="warehouse_id" options="{'no_create': True}" groups="stock.group_stock_multi_warehouses" force_save="1"/>
|
||||
<field name="incoterm" options="{'no_open': True, 'no_create': True}" groups="sale_stock.group_display_incoterm"/>
|
||||
<field name="incoterm_location" groups="sale_stock.group_display_incoterm"/>
|
||||
<field name="incoterm" options="{'no_open': True, 'no_create': True}"/>
|
||||
<field name="incoterm_location"/>
|
||||
<field name="picking_policy" required="True"/>
|
||||
</xpath>
|
||||
<xpath expr="//span[@name='expected_date_span']" position="attributes">
|
||||
|
||||
@@ -7,7 +7,14 @@
|
||||
<xpath expr="//div[@id='so_date']" position="after">
|
||||
<div t-if="sale_order.incoterm" class="row">
|
||||
<div class="mb-3 col-6 ms-auto">
|
||||
<strong>Incoterm: </strong> <span t-field="sale_order.incoterm"/>
|
||||
<div class="col-auto mw-100 mb-2" t-if="sale_order.incoterm" name="invoice_incoterm_id">
|
||||
<strong>Incoterm:</strong>
|
||||
<p t-if="sale_order.incoterm_location">
|
||||
<span t-field="sale_order.incoterm.code"/> <br/>
|
||||
<span t-field="sale_order.incoterm_location"/>
|
||||
</p>
|
||||
<p t-else="" t-field="sale_order.incoterm.code" class="m-0"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
|
||||
Reference in New Issue
Block a user