[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:
Maximilien (malb)
2023-07-12 21:45:44 +02:00
parent bc63d134eb
commit 9ddc128d7b
15 changed files with 83 additions and 62 deletions
+9
View File
@@ -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"
+8 -3
View File
@@ -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>
+7 -1
View File
@@ -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>
+5 -1
View File
@@ -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>
+9
View File
@@ -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 &amp; 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>
+2 -2
View File
@@ -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>