Compare commits

..

1 Commits

Author SHA1 Message Date
clementmbr
80a8f674a7 purchase_usability: remove unnecessary field delivery_partner_id 2021-06-23 10:48:21 +02:00
167 changed files with 478 additions and 3545 deletions

View File

@@ -52,7 +52,6 @@ This modules adds the following functions:
* don't attach PDF upon invoice report generation on supplier invoices/refunds
* Add filter on debit and credit amount for Move Lines
* Add supplier invoice number in invoice tree view
* Add date in outstanding payment widget on invoice form view (requires `odoo PR 84180 <https://github.com/odoo/odoo/pull/84180>`_)
Together with this module, I recommend the use of the following modules:

View File

@@ -19,9 +19,6 @@
'data': [
'views/account_account_type.xml',
'views/account_account.xml',
'views/account_group.xml',
'views/account_analytic_account.xml',
'views/account_analytic_group.xml',
'views/account_bank_statement.xml',
'views/account_invoice_report.xml',
'views/account_journal.xml',
@@ -31,14 +28,10 @@
'views/product.xml',
'views/res_config_settings.xml',
'views/res_partner.xml',
'views/res_company.xml',
'views/account_report.xml',
'wizard/account_invoice_mark_sent_view.xml',
'wizard/account_group_generate_view.xml',
'wizard/account_payment_register_views.xml',
'security/ir.model.access.csv',
'report/invoice_report.xml',
],
'qweb': ['static/src/xml/account_payment.xml'],
'installable': True,
}

View File

@@ -6,6 +6,4 @@ from . import account_journal
from . import account_move
from . import account_partial_reconcile
from . import res_partner
from . import res_company
from . import product
from . import account_invoice_report

View File

@@ -27,7 +27,9 @@ class AccountBankStatement(models.Model):
def _check_balance_end_real_same_as_computed(self):
for stmt in self:
if not stmt.hide_bank_statement_balance:
if stmt.hide_bank_statement_balance:
continue
else:
super(AccountBankStatement, stmt)._check_balance_end_real_same_as_computed()
return True
@@ -78,8 +80,7 @@ class AccountBankStatementLine(models.Model):
def show_account_move(self):
self.ensure_one()
action = self.env["ir.actions.actions"]._for_xml_id(
'account.action_move_line_form')
action = self.env.ref('account.action_move_line_form').read()[0]
# Note: this action is on account.move, not account.move.line !
action.update({
'views': False,

View File

@@ -14,13 +14,3 @@ class AccountIncoterms(models.Model):
for rec in self:
res.append((rec.id, '[%s] %s' % (rec.code, rec.name)))
return res
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
if args is None:
args = []
if name and operator == 'ilike':
recs = self.search([('code', '=ilike', name + '%')] + args, limit=limit)
if recs:
return recs.name_get()
return super().name_search(name=name, args=args, operator=operator, limit=limit)

View File

@@ -1,17 +0,0 @@
# Copyright 2022 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class AccountInvoiceReport(models.Model):
_inherit = 'account.invoice.report'
industry_id = fields.Many2one('res.partner.industry', string='Partner Industry', readonly=True)
@api.model
def _select(self):
res = super()._select()
res += ", COALESCE(partner.industry_id, commercial_partner.industry_id) AS industry_id"
return res

View File

@@ -16,13 +16,6 @@ class AccountJournal(models.Model):
"you don't want to enter the start/end balance manually: it "
"will prevent the display of wrong information in the accounting "
"dashboard and on bank statements.")
# Used to set default user_type_id on account fields
account_type_current_liabilities_id = fields.Many2one(
'account.account.type',
default=lambda self: self.env.ref('account.data_account_type_current_liabilities').id)
account_type_current_assets_id = fields.Many2one(
'account.account.type',
default=lambda self: self.env.ref('account.data_account_type_current_assets').id)
@api.depends(
'name', 'currency_id', 'company_id', 'company_id.currency_id', 'code')

View File

@@ -2,17 +2,17 @@
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models, _
from odoo import api, fields, models
from odoo.tools import float_is_zero
from odoo.tools.misc import format_date
from odoo.osv import expression
from datetime import timedelta
from odoo.exceptions import UserError
class AccountMove(models.Model):
_inherit = 'account.move'
default_move_line_name = fields.Char(
string='Default Label', states={'posted': [('readonly', True)]})
# By default, we can still modify "ref" when account move is posted
# which seems a bit lazy for me...
ref = fields.Char(states={'posted': [('readonly', True)]})
@@ -123,11 +123,7 @@ class AccountMove(models.Model):
has_sections = False
subtotal = 0.0
sign = self.move_type == 'out_refund' and -1 or 1
# Warning: the order of invoice line is forced in the view
# <tree editable="bottom" default_order="sequence, date desc, move_name desc, id"
# it's not the same as the _order in the class AccountMoveLine
lines = self.env['account.move.line'].search([('exclude_from_invoice_tab', '=', False), ('move_id', '=', self.id)], order="sequence, date desc, move_name desc, id")
for line in lines:
for line in self.invoice_line_ids:
if line.display_type == 'line_section':
# insert line
if has_sections:
@@ -154,13 +150,13 @@ class AccountMove(models.Model):
""" French law requires to set sale order dates into invoice
returned string: "sale1 (date1), sale2 (date2) ..."
"""
for move in self:
sales = move.invoice_line_ids.mapped(
for inv in self:
sales = inv.invoice_line_ids.mapped(
'sale_line_ids').mapped('order_id')
dates = ["%s (%s)" % (
x.name, format_date(move.env, x.date_order))
x.name, format_date(inv.env, self.date_order))
for x in sales]
move.sale_dates = ", ".join(dates)
inv.sale_dates = ", ".join(dates)
# allow to manually create moves not only in general journals,
# but also in cash journal and check journals (= bank journals not linked to a bank account)
@@ -180,47 +176,6 @@ class AccountMove(models.Model):
])
move.suitable_journal_ids = self.env['account.journal'].search(domain)
def button_draft(self):
super().button_draft()
# Delete attached pdf invoice
try:
report_invoice = self.env['ir.actions.report']._get_report_from_name('account.report_invoice')
except IndexError:
report_invoice = False
if report_invoice and report_invoice.attachment:
for move in self.filtered(lambda x: x.move_type in ('out_invoice', 'out_refund')):
# The pb is that the filename is dynamic and related to move.state
# in v12, the feature was native and they used that kind of code:
# with invoice.env.do_in_draft():
# invoice.number, invoice.state = invoice.move_name, 'open'
# attachment = self.env.ref('account.account_invoices').retrieve_attachment(invoice)
# But do_in_draft() doesn't exists in v14
# If you know how we could do that, please update the code below
attachment = self.env['ir.attachment'].search([
('name', '=', self._get_invoice_attachment_name()),
('res_id', '=', move.id),
('res_model', '=', self._name),
('type', '=', 'binary'),
], limit=1)
if attachment:
attachment.unlink()
def _get_invoice_attachment_name(self):
self.ensure_one()
return '%s.pdf' % (self.name and self.name.replace('/', '_') or 'INV')
def _get_accounting_date(self, invoice_date, has_tax):
# On vendor bills/refunds, we want date = invoice_date unless
# we have a company tax_lock_date and the invoice has taxes
# and invoice_date <= tax_lock_date
date = super()._get_accounting_date(invoice_date, has_tax)
if self.is_purchase_document(include_receipts=True):
tax_lock_date = self.company_id.tax_lock_date
if invoice_date and tax_lock_date and has_tax and invoice_date <= tax_lock_date:
invoice_date = tax_lock_date + timedelta(days=1)
date = invoice_date
return date
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
@@ -245,8 +200,7 @@ class AccountMoveLine(models.Model):
def show_account_move_form(self):
self.ensure_one()
action = self.env["ir.actions.actions"]._for_xml_id(
'account.action_move_line_form')
action = self.env.ref('account.action_move_line_form').read()[0]
action.update({
'res_id': self.move_id.id,
'view_id': False,
@@ -266,25 +220,3 @@ class AccountMoveLine(models.Model):
rec_str = ', '.join([
'a%d' % pr.id for pr in line.matched_debit_ids + line.matched_credit_ids])
line.reconcile_string = rec_str
def _get_computed_name(self):
# This is useful when you want to have the product code in a dedicated
# column in your customer invoice report
# The same ir.config_parameter is used in sale_usability,
# purchase_usability and account_usability
no_product_code_param = self.env['ir.config_parameter'].sudo().get_param(
'usability.line_name_no_product_code')
if no_product_code_param and no_product_code_param == 'True':
self = self.with_context(display_default_code=False)
return super()._get_computed_name()
def reconcile(self):
"""Explicit error message if unposted lines"""
unposted_ids = self.filtered(lambda l: l.move_id.state != "posted")
if unposted_ids:
m = _("Please post the following entries before reconciliation :")
sep = "\n - "
unpost = sep.join([am.display_name for am in unposted_ids.move_id])
raise UserError(m + sep + unpost)
return super().reconcile()

View File

@@ -1,21 +0,0 @@
# Copyright 2021 Akretion France (https://akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ResCompany(models.Model):
_inherit = 'res.company'
# There is a native field invoice_terms which is displayed on res.config.settings
# when the ir.config_parameter account.use_invoice_terms is True
# But there are several problems with this native field:
# - it is copied on the 'narration' field of account.move => we don't want that
# - the text block is very small on the form view of res.config.settings
# So I decided to have our own field "fixed_invoice_terms"
# The native field can still be used when you need to customise some
# terms and conditions on each invoice (not very common, but...)
# To underline this different with the native field, I prefix it with 'static_'
static_invoice_terms = fields.Text(
translate=True, string="Legal Terms on Invoice")

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2022 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<templates id="template" xml:space="preserve">
<!-- Requires https://github.com/odoo/odoo/pull/84180 -->
<t t-extend="ShowPaymentInfo" >
<t t-jquery="td:first" t-operation="after">
<td style="max-width: 25em;" id="outstanding-date">
<div class="oe_form_field" style="margin-right: 5px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;"><t t-esc="line.date"></t></div>
</td>
</t>
</t>
</templates>

View File

@@ -31,9 +31,6 @@
<field name="name" position="after">
<field name="code" filter_domain="[('code', '=like', str(self)+'%')]" string="Code"/>
</field>
<filter name="accounttype" position="after">
<filter name="group_groupby" string="Group" context="{'group_by': 'group_id'}"/>
</filter>
</field>
</record>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015-2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_account_analytic_account_list" model="ir.ui.view">
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_list"/>
<field name="arch" type="xml">
<field name="code" position="after">
<field name="group_id" optional="show"/>
</field>
</field>
</record>
<record id="view_account_analytic_account_search" model="ir.ui.view">
<field name="model">account.analytic.account</field>
<field name="inherit_id" ref="analytic.view_account_analytic_account_search"/>
<field name="arch" type="xml">
<filter name="associatedpartner" position="before">
<filter name="group_groupby" string="Group" context="{'group_by': 'group_id'}"/>
</filter>
</field>
</record>
</odoo>

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="account_analytic_group_tree_view" model="ir.ui.view">
<field name="model">account.analytic.group</field>
<field name="inherit_id" ref="analytic.account_analytic_group_tree_view"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="parent_id" optional="show"/>
</field>
</field>
</record>
</odoo>

View File

@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_account_group_form" model="ir.ui.view">
<field name="model">account.group</field>
<field name="inherit_id" ref="account.view_account_group_form"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="parent_id"/>
</field>
</field>
</record>
<record id="view_account_group_tree" model="ir.ui.view">
<field name="model">account.group</field>
<field name="inherit_id" ref="account.view_account_group_tree"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="parent_id" optional="show"/>
</field>
</field>
</record>
</odoo>

View File

@@ -14,38 +14,26 @@
<field name="arch" type="xml">
<tree string="Invoices Analysis">
<field name="move_id"/>
<field name="journal_id" optional="hide"/>
<field name="company_id" optional="hide" groups="base.group_multi_company"/>
<field name="invoice_date"/>
<field name="invoice_date_due"/>
<field name="move_type"/>
<field name="commercial_partner_id"/>
<field name="partner_id" optional="hide"/>
<field name="country_id" optional="hide"/>
<field name="industry_id" optional="hide"/>
<field name="invoice_user_id"/>
<field name="fiscal_position_id" optional="hide"/>
<field name="product_id"/>
<field name="product_categ_id" optional="hide"/>
<field name="account_id" optional="hide"/>
<field name="analytic_account_id" optional="hide" groups="analytic.group_analytic_accounting"/>
<field name="quantity" sum="1"/>
<field name="product_uom_id" groups="uom.group_uom"/>
<field name="price_subtotal" sum="1"/>
<field name="state"/>
<field name="payment_state" optional="hide"/>
</tree>
</field>
</record>
<record id="account.action_account_invoice_report_all_supp" model="ir.actions.act_window">
<field name="context">{'search_default_current': 1, 'search_default_supplier': 1, 'group_by': ['invoice_date']}</field> <!-- Remove group_by_no_leaf, which breaks tree view -->
<field name="view_mode">pivot,graph</field>
</record>
<record id="account.action_account_invoice_report_all" model="ir.actions.act_window">
<field name="context">{'search_default_current': 1, 'search_default_customer': 1, 'group_by': ['invoice_date']}</field> <!-- Remove group_by_no_leaf, which breaks tree view -->
<field name="view_mode">pivot,graph</field>
</record>
<record id="view_account_invoice_report_pivot" model="ir.ui.view">

View File

@@ -14,17 +14,6 @@
<field name="arch" type="xml">
<field name="bank_statements_source" position="after">
<field name="hide_bank_statement_balance" groups="account.group_account_readonly"/>
<field name="account_type_current_liabilities_id" invisible="1"/>
<field name="account_type_current_assets_id" invisible="1"/>
</field>
<field name="suspense_account_id" position="attributes">
<attribute name="context">{'default_user_type_id': account_type_current_liabilities_id, 'default_reconcile': True}</attribute>
</field>
<field name="payment_debit_account_id" position="attributes">
<attribute name="context">{'default_user_type_id': account_type_current_assets_id, 'default_reconcile': True}</attribute>
</field>
<field name="payment_credit_account_id" position="attributes">
<attribute name="context">{'default_user_type_id': account_type_current_assets_id, 'default_reconcile': True}</attribute>
</field>
</field>
</record>

View File

@@ -18,20 +18,8 @@
<field name="invoice_incoterm_id" position="attributes">
<attribute name="widget">selection</attribute>
</field>
<button name="action_register_payment" position="attributes">
<attribute name="class">btn-default</attribute>
</button>
<button name="action_register_payment" position="before">
<button name="%(account.account_invoices)d" type="action" string="Print" attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
</button>
<button name="preview_invoice" position="attributes">
<attribute name="attrs">{'invisible': 1}</attribute>
</button>
<!-- move sent field and make it visible -->
<field name="is_move_sent" position="replace"/>
<field name="invoice_origin" position="attributes">
<attribute name="invisible">0</attribute>
</field>
<field name="invoice_origin" position="after">
<field name="is_move_sent" attrs="{'invisible': [('move_type', 'not in', ('out_invoice', 'out_refund'))]}"/>
</field>
@@ -88,11 +76,10 @@
<field name="debit" filter_domain="['|', ('debit', '=', self), ('credit', '=', self)]" string="Debit or Credit"/>
</field>
<filter name="unreconciled" position="before">
<filter name="reconciled" string="Fully Reconciled" domain="[('reconciled', '=', True)]"/>
<filter name="reconciled" string="Fully Reconciled" domain="[('full_reconcile_id', '!=', False)]"/>
</filter>
<filter name="unreconciled" position="attributes">
<attribute name="string">Unreconciled or Partially Reconciled</attribute>
<attribute name="domain">[('reconciled', '=', False), ('balance', '!=', 0), ('account_id.reconcile', '=', True)]</attribute>
</filter>
<!--
<field name="name" position="attributes">

View File

@@ -27,7 +27,7 @@ Here, we set all those fields on account.group_account_invoice
</field>
<field name="list_price" position="replace">
<div name="list_price">
<field name="list_price" widget='monetary' options="{'currency_field': 'currency_id', 'field_digits': True}" class="oe_inline"/>
<field name="list_price" widget='monetary' options="{'currency_field': 'currency_id'}" class="oe_inline"/>
<label for="sale_price_type" string=" "/>
<field name="sale_price_type"/>
</div>

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 Akretion (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_company_form" model="ir.ui.view">
<field name="name">account_usability.res.company.form</field>
<field name="model">res.company</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name="arch" type="xml">
<notebook position="inside">
<page string="Legal Terms" name="legal_terms">
<group string="Invoice Legal Terms" name="static_invoice_terms">
<field name="static_invoice_terms" nolabel="1"/>
</group>
</page>
</notebook>
</field>
</record>
</odoo>

View File

@@ -16,9 +16,6 @@
<field name="property_account_position_id" position="attributes">
<attribute name="widget">selection</attribute>
</field>
<xpath expr="//field[@name='bank_ids']/tree/field[@name='acc_number']" position="after">
<field name="acc_type"/>
</xpath>
</field>
</record>

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<!-- When you change the date, it resets the amount via the onchange
So, in the view, the date should be BEFORE the amount -->
<record id="view_account_payment_register_form" model="ir.ui.view">
<field name="model">account.payment.register</field>
<field name="inherit_id" ref="account.view_account_payment_register_form"/>
<field name="arch" type="xml">
<label for="amount" position="before">
<field name="payment_date" position="move"/>
</label>
</field>
</record>
</odoo>

View File

@@ -1 +0,0 @@
from . import models

View File

@@ -1,62 +0,0 @@
# Copyright 2020-2021 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Base Dynamic List',
'version': '14.0.1.0.0',
'category': 'Tools',
'license': 'AGPL-3',
'summary': 'Dynamic lists',
'description': """
Base Dynamic List
=================
Very often during an Odoo implementation, we need to add selection fields on a native objet, and we don't want to have a hard-coded selection list (fields.Selection), but a selection list that can be changed by users (Many2one field). For that, the developper needs to add a new object (with just a 'name' and 'sequence' field) with a form/tree view. The goal of this module is to speed-up this process by defining a dynamic list object that already has all the required views.
This module provides several ready-to-go objects:
* simple list : fields *name*, *sequence* and *active*
* translatable list : fields *name* with translate=True, *sequence* and *active*
* code list : fields *code* (unique), *name*, *sequence* and *active*
* translatable code list : fields *code* (unique), *name* with translate=True, *sequence* and *active*
These objects are readable by the employee group. The system group has full rights on it.
To use it, you need to do 2 or 3 things :
1) Add an entry in the domain field and the object you selected:
domain = fields.Selection(selection_add=[('risk.type', "Risk Type")], ondelete={"risk.type": "cascade"})
2) Add the many2one field on your object:
risk_type_id = fields.Many2one(
'dynamic.list', string="Risk Type",
ondelete='restrict', domain=[('domain', '=', 'risk.type')])
3) Optionally, you can add a dedicated action and a menu entry (otherwize, you can use the generic menu entry under *Settings > Technical > Dynamic Lists*:
<record id="dynamic_list_risk_type_action" model="ir.actions.act_window">
<field name="name">Risk Type</field>
<field name="res_model">dynamic.list</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('domain', '=', 'risk.type')]</field>
<field name="context">{'default_domain': 'risk.type'}</field>
</record>
<menuitem id="dynamic_list_risk_type_menu" action="dynamic_list_risk_type_action"
parent="parent_menu_xmlid"/>
Limitation: when you want to have different access rights on these lists depending on the source object, you should prefer to use dedicated objects.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['base'],
'data': [
'security/ir.model.access.csv',
'views/dynamic_list.xml',
],
'installable': True,
}

View File

@@ -1 +0,0 @@
from . import dynamic_list

View File

@@ -1,115 +0,0 @@
# Copyright 2020-2021 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class DynamicList(models.Model):
_name = 'dynamic.list'
_description = 'Dynamic List (non translatable)'
_order = 'sequence, id'
name = fields.Char(required=True)
sequence = fields.Integer(default=10)
active = fields.Boolean(default=True)
domain = fields.Selection([], string='Domain', required=True, index=True)
_sql_constraint = [(
'domain_name_uniq',
'unique(domain, name)',
'This entry already exists!'
)]
class DynamicListTranslate(models.Model):
_name = 'dynamic.list.translate'
_description = 'Translatable Dynamic List'
_order = 'sequence, id'
name = fields.Char(translate=True, required=True)
sequence = fields.Integer(default=10)
active = fields.Boolean(default=True)
domain = fields.Selection([], string='Domain', required=True, index=True)
_sql_constraint = [(
'domain_name_uniq',
'unique(domain, name)',
'This entry already exists!'
)]
class DynamicListCode(models.Model):
_name = 'dynamic.list.code'
_description = 'Dynamic list with code'
_order = 'sequence, id'
code = fields.Char(required=True)
name = fields.Char(translate=True, required=True)
sequence = fields.Integer(default=10)
active = fields.Boolean(default=True)
domain = fields.Selection([], string='Domain', required=True, index=True)
_sql_constraint = [(
'domain_code_uniq',
'unique(domain, code)',
'This code already exists!'
)]
@api.depends('code', 'name')
def name_get(self):
res = []
for rec in self:
res.append((rec.id, '[%s] %s' % (rec.code, rec.name)))
return res
@api.model
def name_search(
self, name='', args=None, operator='ilike', limit=80):
if args is None:
args = []
if name and operator == 'ilike':
recs = self.search(
[('code', '=', name)] + args, limit=limit)
if recs:
return recs.name_get()
return super().name_search(
name=name, args=args, operator=operator, limit=limit)
class DynamicListCodeTranslate(models.Model):
_name = 'dynamic.list.code.translate'
_description = 'Translatable dynamic list with code'
_order = 'sequence, id'
code = fields.Char(required=True)
name = fields.Char(translate=True, required=True)
sequence = fields.Integer(default=10)
active = fields.Boolean(default=True)
domain = fields.Selection([], string='Domain', required=True, index=True)
_sql_constraint = [(
'domain_code_uniq',
'unique(domain, code)',
'This code already exists!'
)]
@api.depends('code', 'name')
def name_get(self):
res = []
for rec in self:
res.append((rec.id, '[%s] %s' % (rec.code, rec.name)))
return res
@api.model
def name_search(
self, name='', args=None, operator='ilike', limit=80):
if args is None:
args = []
if name and operator == 'ilike':
recs = self.search(
[('code', '=', name)] + args, limit=limit)
if recs:
return recs.name_get()
return super().name_search(
name=name, args=args, operator=operator, limit=limit)

View File

@@ -1,9 +0,0 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_dynamic_list_read,Read access on dynamic.list to employees,model_dynamic_list,base.group_user,1,0,0,0
access_dynamic_list_full,Full access to dynamic.list to System group,model_dynamic_list,base.group_system,1,1,1,1
access_dynamic_list_translate_read,Read access on dynamic.list.translate to employees,model_dynamic_list_translate,base.group_user,1,0,0,0
access_dynamic_list_translate_full,Full access to dynamic.list.translate to System group,model_dynamic_list_translate,base.group_system,1,1,1,1
access_dynamic_list_code_read,Read access on dynamic.list.code to employees,model_dynamic_list_code,base.group_user,1,0,0,0
access_dynamic_list_code_full,Full access to dynamic.list.code to System group,model_dynamic_list_code,base.group_system,1,1,1,1
access_dynamic_list_code_translate_read,Read access on dynamic.list.code.translate to employees,model_dynamic_list_code_translate,base.group_user,1,0,0,0
access_dynamic_list_code_translate_full,Full access to dynamic.list.code.translate to System group,model_dynamic_list_code_translate,base.group_system,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_dynamic_list_read Read access on dynamic.list to employees model_dynamic_list base.group_user 1 0 0 0
3 access_dynamic_list_full Full access to dynamic.list to System group model_dynamic_list base.group_system 1 1 1 1
4 access_dynamic_list_translate_read Read access on dynamic.list.translate to employees model_dynamic_list_translate base.group_user 1 0 0 0
5 access_dynamic_list_translate_full Full access to dynamic.list.translate to System group model_dynamic_list_translate base.group_system 1 1 1 1
6 access_dynamic_list_code_read Read access on dynamic.list.code to employees model_dynamic_list_code base.group_user 1 0 0 0
7 access_dynamic_list_code_full Full access to dynamic.list.code to System group model_dynamic_list_code base.group_system 1 1 1 1
8 access_dynamic_list_code_translate_read Read access on dynamic.list.code.translate to employees model_dynamic_list_code_translate base.group_user 1 0 0 0
9 access_dynamic_list_code_translate_full Full access to dynamic.list.code.translate to System group model_dynamic_list_code_translate base.group_system 1 1 1 1

View File

@@ -1,220 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020-2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<menuitem id="dynamic_list_root_menu" name="Dynamic Lists" parent="base.menu_custom" sequence="100"/>
<record id="dynamic_list_form" model="ir.ui.view">
<field name="model">dynamic.list</field>
<field name="arch" type="xml">
<form>
<sheet>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<group name="main">
<field name="name"/>
<field name="domain" invisible="not context.get('dynamic_list_main_view')"/>
<field name="active" invisible="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="dynamic_list_tree" model="ir.ui.view">
<field name="model">dynamic.list</field>
<field name="arch" type="xml">
<tree>
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="domain" invisible="not context.get('dynamic_list_main_view')"/>
</tree>
</field>
</record>
<record id="dynamic_list_search" model="ir.ui.view">
<field name="model">dynamic.list</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<group string="Group By" name="groupby">
<filter name="domain_groupby" string="Domain" context="{'group_by': 'domain'}"/>
</group>
</search>
</field>
</record>
<record id="dynamic_list_action" model="ir.actions.act_window">
<field name="name">Simple List</field>
<field name="res_model">dynamic.list</field>
<field name="view_mode">tree,form</field>
<field name="context">{'dynamic_list_main_view': True, 'search_default_domain_groupby': True}</field>
</record>
<menuitem id="dynamic_list_menu" action="dynamic_list_action" parent="dynamic_list_root_menu" sequence="10"/>
<record id="dynamic_list_translate_form" model="ir.ui.view">
<field name="model">dynamic.list.translate</field>
<field name="arch" type="xml">
<form>
<sheet>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<group name="main">
<field name="name"/>
<field name="domain" invisible="not context.get('dynamic_list_translate_main_view')"/>
<field name="active" invisible="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="dynamic_list_translate_tree" model="ir.ui.view">
<field name="model">dynamic.list.translate</field>
<field name="arch" type="xml">
<tree>
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="domain" invisible="not context.get('dynamic_list_translate_main_view')"/>
</tree>
</field>
</record>
<record id="dynamic_list_translate_search" model="ir.ui.view">
<field name="model">dynamic.list.translate</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<group string="Group By" name="groupby">
<filter name="domain_groupby" string="Domain" context="{'group_by': 'domain'}"/>
</group>
</search>
</field>
</record>
<record id="dynamic_list_translate_action" model="ir.actions.act_window">
<field name="name">Translatable Simple List</field>
<field name="res_model">dynamic.list.translate</field>
<field name="view_mode">tree,form</field>
<field name="context">{'dynamic_list_translate_main_view': True, 'search_default_domain_groupby': True}</field>
</record>
<menuitem id="dynamic_list_translate_menu" action="dynamic_list_translate_action" parent="dynamic_list_root_menu" sequence="20"/>
<record id="dynamic_list_code_form" model="ir.ui.view">
<field name="model">dynamic.list.code</field>
<field name="arch" type="xml">
<form>
<sheet>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<group name="main">
<field name="code"/>
<field name="name"/>
<field name="domain" invisible="not context.get('dynamic_list_code_main_view')"/>
<field name="active" invisible="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="dynamic_list_code_tree" model="ir.ui.view">
<field name="model">dynamic.list.code</field>
<field name="arch" type="xml">
<tree>
<field name="sequence" widget="handle"/>
<field name="code"/>
<field name="name"/>
<field name="domain" invisible="not context.get('dynamic_list_code_main_view')"/>
</tree>
</field>
</record>
<record id="dynamic_list_code_search" model="ir.ui.view">
<field name="model">dynamic.list.code</field>
<field name="arch" type="xml">
<search>
<field name="name" string="Name or Code" filter_domain="['|', ('name', 'ilike', self), ('code', 'ilike', self)]"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<field name="code"/>
<group string="Group By" name="groupby">
<filter name="domain_groupby" string="Domain" context="{'group_by': 'domain'}"/>
</group>
</search>
</field>
</record>
<record id="dynamic_list_code_action" model="ir.actions.act_window">
<field name="name">Code List</field>
<field name="res_model">dynamic.list.code</field>
<field name="view_mode">tree,form</field>
<field name="context">{'dynamic_list_code_main_view': True, 'search_default_domain_groupby': True}</field>
</record>
<menuitem id="dynamic_list_code_menu" action="dynamic_list_code_action" parent="dynamic_list_root_menu" sequence="30"/>
<record id="dynamic_list_code_translate_form" model="ir.ui.view">
<field name="model">dynamic.list.code.translate</field>
<field name="arch" type="xml">
<form>
<sheet>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<group name="main">
<field name="code"/>
<field name="name"/>
<field name="domain" invisible="not context.get('dynamic_list_code_translate_main_view')"/>
<field name="active" invisible="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="dynamic_list_code_translate_tree" model="ir.ui.view">
<field name="model">dynamic.list.code.translate</field>
<field name="arch" type="xml">
<tree>
<field name="sequence" widget="handle"/>
<field name="code"/>
<field name="name"/>
<field name="domain" invisible="not context.get('dynamic_list_code_translate_main_view')"/>
</tree>
</field>
</record>
<record id="dynamic_list_code_translate_search" model="ir.ui.view">
<field name="model">dynamic.list.code.translate</field>
<field name="arch" type="xml">
<search>
<field name="name" string="Name or Code" filter_domain="['|', ('name', 'ilike', self), ('code', 'ilike', self)]"/>
<field name="code"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<group string="Group By" name="groupby">
<filter name="domain_groupby" string="Domain" context="{'group_by': 'domain'}"/>
</group>
</search>
</field>
</record>
<record id="dynamic_list_code_translate_action" model="ir.actions.act_window">
<field name="name">Translatable Code List</field>
<field name="res_model">dynamic.list.code.translate</field>
<field name="view_mode">tree,form</field>
<field name="context">{'dynamic_list_code_translate_main_view': True, 'search_default_domain_groupby': True}</field>
</record>
<menuitem id="dynamic_list_code_translate_menu" action="dynamic_list_code_translate_action" parent="dynamic_list_root_menu" sequence="40"/>
</odoo>

View File

@@ -1 +0,0 @@
from . import models

View File

@@ -1,21 +0,0 @@
# Copyright 2017-2022 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Mail Sender Bcc',
'version': '14.0.1.0.0',
'category': 'Mail',
'license': 'AGPL-3',
'summary': "Always send a copy of the mail to the sender",
'description': """
Mail Sender Bcc
===============
With this module, when Odoo sends an outgoing email, it adds the sender as Bcc (blind copy) of the email.
""",
'author': 'Akretion',
'website': 'https://github.com/akretion/odoo-usability',
'depends': ['base'],
'installable': True,
}

View File

@@ -1 +0,0 @@
from . import ir_mail_server

View File

@@ -1,27 +0,0 @@
# Copyright 2017-2022 Akretion France
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models
class IrMailServer(models.Model):
_inherit = 'ir.mail_server'
def build_email(
self, email_from, email_to, subject, body, email_cc=None,
email_bcc=None, reply_to=False, attachments=None,
message_id=None, references=None, object_id=False,
subtype='plain', headers=None,
body_alternative=None, subtype_alternative='plain'):
if email_from:
if email_bcc is None:
email_bcc = [email_from]
elif isinstance(email_bcc, list) and email_from not in email_bcc:
email_bcc.append(email_from)
return super().build_email(
email_from, email_to, subject, body, email_cc=email_cc,
email_bcc=email_bcc, reply_to=reply_to, attachments=attachments,
message_id=message_id, references=references, object_id=object_id,
subtype=subtype, headers=headers,
body_alternative=body_alternative, subtype_alternative=subtype_alternative)

View File

@@ -1,14 +1,14 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * base_partner_one2many_phone
# * base_partner_one2many_phone
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-10-29 21:12+0000\n"
"PO-Revision-Date: 2021-10-29 21:12+0000\n"
"Last-Translator: \n"
"POT-Creation-Date: 2020-01-27 18:03+0000\n"
"PO-Revision-Date: 2020-01-27 18:03+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -16,120 +16,92 @@ msgstr ""
"Plural-Forms: \n"
#. module: base_partner_one2many_phone
#: model:ir.model,name:base_partner_one2many_phone.model_res_partner
msgid "Contact"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__create_uid
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_create_uid
msgid "Created by"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__create_date
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_create_date
msgid "Created on"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner__display_name
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__display_name
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_display_name
msgid "Display Name"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__email
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_email
msgid "E-Mail"
msgstr ""
#. module: base_partner_one2many_phone
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
#: code:addons/base_partner_one2many_phone/partner_phone.py:61
#, python-format
msgid ""
"E-mail field must be empty when type is Primary/Secondary Phone, "
"Primary/Secondary Mobile or Primary/Secondary Fax."
msgid "E-mail field must be empty when type is Primary/Secondary Phone, Primary/Secondary Mobile or Primary/Secondary Fax."
msgstr ""
#. module: base_partner_one2many_phone
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
#: code:addons/base_partner_one2many_phone/partner_phone.py:51
#, python-format
msgid ""
"E-mail field must have a value when type is Primary E-mail or Secondary "
"E-mail."
msgid "E-mail field must have a value when type is Primary E-mail or Secondary E-mail."
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner__email
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_users__email
msgid "Email"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner__id
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__id
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_id
msgid "ID"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner____last_update
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone____last_update
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone___last_update
msgid "Last Modified on"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__write_uid
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_write_uid
msgid "Last Updated by"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__write_date
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_write_date
msgid "Last Updated on"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner__mobile
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_users__mobile
msgid "Mobile"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model,name:base_partner_one2many_phone.model_res_partner_phone
msgid "Multiple emails and phones for partners"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__note
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_note
msgid "Note"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner__phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_users__phone
#: model:ir.model,name:base_partner_one2many_phone.model_res_partner
msgid "Partner"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_phone
msgid "Phone"
msgstr ""
#. module: base_partner_one2many_phone
#: model_terms:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_form
msgid "Phone and E-mail"
msgstr ""
#. module: base_partner_one2many_phone
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
#: code:addons/base_partner_one2many_phone/partner_phone.py:54
#, python-format
msgid ""
"Phone field must be empty when type is Primary E-mail or Secondary E-mail."
msgid "Phone field must be empty when type is Primary E-mail or Secondary E-mail."
msgstr ""
#. module: base_partner_one2many_phone
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
#: code:addons/base_partner_one2many_phone/partner_phone.py:58
#, python-format
msgid ""
"Phone field must have a value when type is Primary/Secondary Phone, "
"Primary/Secondary Mobile or Primary/Secondary Fax."
msgid "Phone field must have a value when type is Primary/Secondary Phone, Primary/Secondary Mobile or Primary/Secondary Fax."
msgstr ""
#. module: base_partner_one2many_phone
#: model_terms:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_tree
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_ids
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_users_phone_ids
msgid "Phones"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_tree
msgid "Phones and E-mail"
msgstr ""
@@ -140,63 +112,63 @@ msgid "Phones/E-mails"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner__phone_ids
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_users__phone_ids
msgid "Phones/Emails"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__1_email_primary
#: selection:res.partner.phone,type:0
msgid "Primary E-mail"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__7_fax_primary
#: selection:res.partner.phone,type:0
msgid "Primary Fax"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__5_mobile_primary
#: selection:res.partner.phone,type:0
msgid "Primary Mobile"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__3_phone_primary
#: selection:res.partner.phone,type:0
msgid "Primary Phone"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__partner_id
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_partner_id
msgid "Related Partner"
msgstr ""
#. module: base_partner_one2many_phone
#: model_terms:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_search
#: model:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_search
msgid "Search Phones/E-mail"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__2_email_secondary
#: selection:res.partner.phone,type:0
msgid "Secondary E-mail"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__8_fax_secondary
#: selection:res.partner.phone,type:0
msgid "Secondary Fax"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__6_mobile_secondary
#: selection:res.partner.phone,type:0
msgid "Secondary Mobile"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__4_phone_secondary
#: selection:res.partner.phone,type:0
msgid "Secondary Phone"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__type
#: model_terms:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_search
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_type
#: model:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_search
msgid "Type"
msgstr ""
#. module: base_partner_one2many_phone
#: model:ir.model,name:base_partner_one2many_phone.model_res_partner_phone
msgid "res.partner.phone"
msgstr ""

View File

@@ -1,14 +1,14 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * base_partner_one2many_phone
# * base_partner_one2many_phone
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-10-29 21:12+0000\n"
"PO-Revision-Date: 2021-10-29 21:12+0000\n"
"Last-Translator: \n"
"POT-Creation-Date: 2020-01-27 17:56+0000\n"
"PO-Revision-Date: 2020-01-27 17:56+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -16,187 +16,159 @@ msgstr ""
"Plural-Forms: \n"
#. module: base_partner_one2many_phone
#: model:ir.model,name:base_partner_one2many_phone.model_res_partner
msgid "Contact"
msgstr "Contact"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__create_uid
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_create_uid
msgid "Created by"
msgstr "Créé par"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__create_date
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_create_date
msgid "Created on"
msgstr "Créé le"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner__display_name
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__display_name
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_display_name
msgid "Display Name"
msgstr "Nom affiché"
msgstr "Nom à afficher"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__email
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_email
msgid "E-Mail"
msgstr "E-Mail"
msgstr "Courriel"
#. module: base_partner_one2many_phone
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
#: code:addons/base_partner_one2many_phone/partner_phone.py:61
#, python-format
msgid ""
"E-mail field must be empty when type is Primary/Secondary Phone, "
"Primary/Secondary Mobile or Primary/Secondary Fax."
msgstr "Le champ E-mail doit être vide quand le type est Tél. principal/secondaire, Portable principal/secondaire ou Fax principal/secondaire."
msgid "E-mail field must be empty when type is Primary/Secondary Phone, Primary/Secondary Mobile or Primary/Secondary Fax."
msgstr "Le champ courriel doit être vide quand le type est tél. primaire/secondaire, portable primaire/secondaire ou fax primaire/secondaire."
#. module: base_partner_one2many_phone
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
#: code:addons/base_partner_one2many_phone/partner_phone.py:51
#, python-format
msgid ""
"E-mail field must have a value when type is Primary E-mail or Secondary "
"E-mail."
msgstr "Le champ E-mail doit avoir une valeur quand le type est E-mail principal ou secondaire."
msgid "E-mail field must have a value when type is Primary E-mail or Secondary E-mail."
msgstr "Le champ courriel doit être renseigné quand le type est courriel primaire ou courriel secondaire."
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner__email
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_users__email
msgid "Email"
msgstr "E-mail"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner__id
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__id
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_id
msgid "ID"
msgstr ""
msgstr "ID"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner____last_update
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone____last_update
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone___last_update
msgid "Last Modified on"
msgstr "Dernière modification le"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__write_uid
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_write_uid
msgid "Last Updated by"
msgstr "Dernière modification par"
msgstr "Dernière mise à jour par"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__write_date
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_write_date
msgid "Last Updated on"
msgstr "Dernière modification le"
msgstr "Dernière mise à jour le"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner__mobile
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_users__mobile
msgid "Mobile"
msgstr "Portable"
#. module: base_partner_one2many_phone
#: model:ir.model,name:base_partner_one2many_phone.model_res_partner_phone
msgid "Multiple emails and phones for partners"
msgstr "Multiples e-mails et téléphones pour les partenaires"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__note
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_note
msgid "Note"
msgstr "Note"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner__phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_users__phone
#: model:ir.model,name:base_partner_one2many_phone.model_res_partner
msgid "Partner"
msgstr "Partenaire"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_phone
msgid "Phone"
msgstr "Tél."
msgstr "Téléphone"
#. module: base_partner_one2many_phone
#: model_terms:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_form
msgid "Phone and E-mail"
msgstr "Tél. et E-mail"
#. module: base_partner_one2many_phone
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
#: code:addons/base_partner_one2many_phone/partner_phone.py:54
#, python-format
msgid ""
"Phone field must be empty when type is Primary E-mail or Secondary E-mail."
msgstr "Le champ Tél. doit être vide quand le type est E-mail principal ou E-mail secondaire."
msgid "Phone field must be empty when type is Primary E-mail or Secondary E-mail."
msgstr "Le champ téléphone doit être vide quand le type est courriel primaire ou courriel secondaire."
#. module: base_partner_one2many_phone
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
#: code:addons/base_partner_one2many_phone/partner_phone.py:58
#, python-format
msgid ""
"Phone field must have a value when type is Primary/Secondary Phone, "
"Primary/Secondary Mobile or Primary/Secondary Fax."
msgstr "Le champ Tél. doit avoir une valeur quand le type est Tél. principal/secondaire, Portable principal/secondaire ou Fax principal/secondaire."
msgid "Phone field must have a value when type is Primary/Secondary Phone, Primary/Secondary Mobile or Primary/Secondary Fax."
msgstr "Le champ téléphone doit être renseigné quand le type est tél. primaire/secondaire, portable primaire/secondaire ou fax primaire/secondaire.."
#. module: base_partner_one2many_phone
#: model_terms:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_tree
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_ids
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_users_phone_ids
msgid "Phones"
msgstr "Téléphones"
#. module: base_partner_one2many_phone
#: model:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_tree
msgid "Phones and E-mail"
msgstr "Téls et E-mail"
msgstr "Téls et courriels"
#. module: base_partner_one2many_phone
#: model:ir.actions.act_window,name:base_partner_one2many_phone.res_partner_phone_action
#: model:ir.ui.menu,name:base_partner_one2many_phone.res_partner_phone_menu
msgid "Phones/E-mails"
msgstr "Téls/E-mails"
msgstr "Téls/Courriels"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner__phone_ids
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_users__phone_ids
msgid "Phones/Emails"
msgstr "Téls/E-mails"
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__1_email_primary
#: selection:res.partner.phone,type:0
msgid "Primary E-mail"
msgstr "E-mail principal"
msgstr "Courriel principal"
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__7_fax_primary
#: selection:res.partner.phone,type:0
msgid "Primary Fax"
msgstr "Fax principal"
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__5_mobile_primary
#: selection:res.partner.phone,type:0
msgid "Primary Mobile"
msgstr "Portable principal"
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__3_phone_primary
#: selection:res.partner.phone,type:0
msgid "Primary Phone"
msgstr "Tél. principal"
msgstr "Tél principal"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__partner_id
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_partner_id
msgid "Related Partner"
msgstr "Partenaire associé"
#. module: base_partner_one2many_phone
#: model_terms:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_search
#: model:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_search
msgid "Search Phones/E-mail"
msgstr ""
msgstr "Search Phones/E-mail"
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__2_email_secondary
#: selection:res.partner.phone,type:0
msgid "Secondary E-mail"
msgstr "E-mail secondaire"
msgstr "Courriel secondaire"
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__8_fax_secondary
#: selection:res.partner.phone,type:0
msgid "Secondary Fax"
msgstr "Fax secondaire"
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__6_mobile_secondary
#: selection:res.partner.phone,type:0
msgid "Secondary Mobile"
msgstr "Portable secondaire"
#. module: base_partner_one2many_phone
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__4_phone_secondary
#: selection:res.partner.phone,type:0
msgid "Secondary Phone"
msgstr "Tél. secondaire"
#. module: base_partner_one2many_phone
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone__type
#: model_terms:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_search
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_type
#: model:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_search
msgid "Type"
msgstr "Type"
#. module: base_partner_one2many_phone
#: model:ir.model,name:base_partner_one2many_phone.model_res_partner_phone
msgid "res.partner.phone"
msgstr "res.partner.phone"

View File

@@ -46,7 +46,7 @@ class ResPartnerPhone(models.Model):
@api.onchange('phone', 'partner_id')
def _onchange_phone_validation(self):
if self.phone:
self.phone = self.phone_format(self.phone, country=self.partner_id.country_id)
self.phone = self.phone_format(self.phone)
@api.constrains('type', 'phone', 'email')
def _check_partner_phone(self):

View File

@@ -14,7 +14,7 @@
<field name="name">res.partner.phone.tree</field>
<field name="model">res.partner.phone</field>
<field name="arch" type="xml">
<tree editable="bottom">
<tree string="Phones and E-mail" editable="bottom">
<field name="partner_id" invisible="not context.get('partner_phone_main_view')"/>
<field name="type"/>
<field name="phone" widget="phone" options="{'enable_sms': false}" attrs="{'required': [('type', 'not in', ('1_email_primary', '2_email_secondary'))], 'readonly': [('type', 'in', ('1_email_primary', '2_email_secondary'))]}"/>
@@ -28,7 +28,7 @@
<field name="name">res.partner.phone.form</field>
<field name="model">res.partner.phone</field>
<field name="arch" type="xml">
<form>
<form string="Phone and E-mail">
<group name="main">
<field name="partner_id" invisible="not context.get('partner_phone_main_view')"/>
<field name="type"/>
@@ -44,7 +44,7 @@
<field name="name">res.partner.phone.search</field>
<field name="model">res.partner.phone</field>
<field name="arch" type="xml">
<search>
<search string="Search Phones/E-mail">
<field name="phone" />
<field name="email" />
<group name="groupby">

View File

@@ -1 +1 @@
from . import models
from . import partner

View File

@@ -1,10 +1,10 @@
# Copyright 2017-2021 Akretion (http://www.akretion.com)
# Copyright 2017-2019 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Base Partner Reference',
'version': '14.0.1.0.0',
'version': '12.0.1.0.0',
'category': 'Partner',
'license': 'AGPL-3',
'summary': "Improve usage of partner's Internal Reference",
@@ -21,6 +21,6 @@ Base Partner Reference
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['base'],
'data': ['views/res_partner.xml'],
'installable': True,
'data': ['partner_view.xml'],
'installable': False,
}

View File

@@ -1 +0,0 @@
from . import res_partner

View File

@@ -1,4 +1,4 @@
# Copyright 2017-2021 Akretion
# Copyright 2017-2019 Akretion
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@@ -18,9 +18,9 @@ class ResPartner(models.Model):
)]
# add 'ref' in depends
@api.depends('ref', 'invalidate_display_name')
@api.depends('is_company', 'name', 'parent_id.name', 'type', 'company_name', 'ref', 'invalidate_display_name')
def _compute_display_name(self):
super()._compute_display_name()
super(ResPartner, self)._compute_display_name()
def _get_name(self):
partner = self
@@ -28,17 +28,16 @@ class ResPartner(models.Model):
# START modif of native method
if partner.ref:
name = "[%s] %s" % (partner.ref, name)
name = u"[%s] %s" % (partner.ref, name)
# END modif of native method
if partner.company_name or partner.parent_id:
if not name and partner.type in ['invoice', 'delivery', 'other']:
name = dict(self.fields_get(
['type'])['type']['selection'])[partner.type]
name = dict(self.fields_get(['type'])['type']['selection'])[partner.type]
if not partner.is_company:
# START modif of native name_get() method
company_name = partner.commercial_company_name or partner.parent_id.name
if partner.parent_id.ref:
company_name = "[%s] %s" % (partner.parent_id.ref, company_name)
company_name = u"[%s] %s" % (partner.parent_id.ref, company_name)
name = "%s, %s" % (company_name, name)
# END modif of native name_get() method
if self._context.get('show_address_only'):
@@ -48,8 +47,7 @@ class ResPartner(models.Model):
name = name.replace('\n\n', '\n')
name = name.replace('\n\n', '\n')
if self._context.get('address_inline'):
splitted_names = name.split("\n")
name = ", ".join([n for n in splitted_names if n.strip()])
name = name.replace('\n', ', ')
if self._context.get('show_email') and partner.email:
name = "%s <%s>" % (name, partner.email)
if self._context.get('html_format'):
@@ -57,14 +55,3 @@ class ResPartner(models.Model):
if self._context.get('show_vat') and partner.vat:
name = "%s %s" % (name, partner.vat)
return name
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
if args is None:
args = []
if name and operator == 'ilike':
recs = self.search([('ref', '=', name)] + args, limit=limit)
if recs:
rec_childs = self.search([('id', 'child_of', recs.ids)])
return rec_childs.name_get()
return super().name_search(name=name, args=args, operator=operator, limit=limit)

View File

@@ -11,34 +11,29 @@
<field name="name">Move ref in partner form to make it more visible</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="priority">1000</field> <!-- inherit after l10n_fr -->
<field name="arch" type="xml">
<field name="type" position="after">
<field name="ref"/>
</field>
<xpath expr="//page[@name='sales_purchases']//field[@name='ref']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//page[@name='sales_purchases']//field[@name='ref']" position="replace"/>
</field>
</record>
<!-- show name and ref in separate columns -->
<!-- ref is added in tree view by base_usability with optional="hide"
<record id="view_partner_tree" model="ir.ui.view">
<field name="name">Add ref in partner tree view</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_tree"/>
<field name="arch" type="xml">
<!-- show name and ref in separate columns -->
<field name="display_name" position="after">
<field name="name"/>
<field name="ref" optional="hide"/>
<field name="ref"/>
</field>
<field name="display_name" position="attributes">
<attribute name="invisible">1</attribute>
</field>
</field>
</record>
-->
<record id="res_partner_kanban_view" model="ir.ui.view">
<field name="name">Add ref in partner kanban view</field>

View File

@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-07-01 10:02+0000\n"
"PO-Revision-Date: 2021-07-01 10:02+0000\n"
"POT-Creation-Date: 2021-02-17 16:55+0000\n"
"PO-Revision-Date: 2021-02-17 16:55+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"

View File

@@ -6,9 +6,9 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-07-01 10:02+0000\n"
"PO-Revision-Date: 2021-07-01 12:15+0200\n"
"Last-Translator: Alexis de Lattre <alexis@via.ecp.fr>\n"
"POT-Creation-Date: 2021-02-17 16:55+0000\n"
"PO-Revision-Date: 2021-02-17 16:55+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -33,15 +33,16 @@ msgstr "Sociétés"
#. module: base_usability
#: model:ir.model,name:base_usability.model_res_partner
msgid "Contact"
msgstr "Contact"
msgstr ""
#. module: base_usability
#: model_terms:ir.ui.view,arch_db:base_usability.res_country_search
msgid "Currency"
msgstr "Devise"
msgstr "Monnaie"
#. module: base_usability
#: code:addons/base_usability/models/res_partner.py:0
#: code:addons/base_usability/models/res_partner.py:0
#, python-format
msgid "Customer Number:"
msgstr "N° client :"
@@ -67,7 +68,7 @@ msgstr "E-mail :"
#. module: base_usability
#: model_terms:ir.ui.view,arch_db:base_usability.res_country_search
msgid "Group By"
msgstr "Grouper par"
msgstr ""
#. module: base_usability
#: model:ir.model.fields,field_description:base_usability.field_ir_mail_server__id
@@ -78,12 +79,12 @@ msgstr "Grouper par"
#: model:ir.model.fields,field_description:base_usability.field_res_partner_category__id
#: model:ir.model.fields,field_description:base_usability.field_res_users__id
msgid "ID"
msgstr "ID"
msgstr ""
#. module: base_usability
#: model_terms:ir.ui.view,arch_db:base_usability.view_module_filter
msgid "Installable"
msgstr "Installable"
msgstr ""
#. module: base_usability
#: model:ir.model.fields,field_description:base_usability.field_ir_mail_server____last_update
@@ -99,7 +100,7 @@ msgstr "Dernière modification le"
#. module: base_usability
#: model:ir.model,name:base_usability.model_ir_mail_server
msgid "Mail Server"
msgstr "Serveur mail"
msgstr "Serveur d'email"
#. module: base_usability
#: code:addons/base_usability/models/res_partner.py:0
@@ -131,7 +132,7 @@ msgstr "Nom avec titre"
#. module: base_usability
#: model:res.groups,name:base_usability.group_nobody
msgid "Nobody (used to hide native menus)"
msgstr "Personne (utilisé pour cacher des entrées de menu natifs)"
msgstr ""
#. module: base_usability
#: model:ir.model,name:base_usability.model_res_partner_category
@@ -151,6 +152,7 @@ msgstr ""
#. module: base_usability
#: code:addons/base_usability/models/res_partner.py:0
#: code:addons/base_usability/models/res_partner.py:0
#, python-format
msgid "Supplier Number:"
msgstr "N° fournisseur :"

View File

@@ -4,5 +4,4 @@ from . import res_partner_bank
from . import res_partner_category
from . import res_company
from . import ir_mail_server
from . import ir_actions_report
from . import ir_model

View File

@@ -1,15 +0,0 @@
# Copyright 2021 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class IrActionsReport(models.Model):
_inherit = "ir.actions.report"
# since v13, print_report_name is a translatable field
# It means that you can't set the value via an inherit of
# ir.actions.report as XML
# I think it was easier when this field was not translatable
print_report_name = fields.Char(translate=False)

View File

@@ -8,9 +8,25 @@ from odoo import models, fields, api, _
class ResPartner(models.Model):
_inherit = 'res.partner'
# tracking=True is handled in the 'mail' module, and base_usability
# doesn't depend on 'mail', so adding tracking on res.partner fields
# has been moved to mail_usability
# track_visibility is handled in the 'mail' module, and base_usability
# doesn't depend on 'mail', but that doesn't hurt, it will just be
# ignored if mail is not installed
# TODO move to mail module
# name = fields.Char(tracking=True)
# parent_id = fields.Many2one(tracking=True)
# ref = fields.Char(tracking=True)
# lang = fields.Selection(tracking=True)
# user_id = fields.Many2one(tracking=True)
# vat = fields.Char(tracking=True)
# street = fields.Char(tracking=True)
# street2 = fields.Char(tracking=True)
# zip = fields.Char(tracking=True)
# city = fields.Char(tracking=True)
# state_id = fields.Many2one(tracking=True)
# country_id = fields.Many2one(tracking=True)
# is_company = fields.Boolean(tracking=True)
# active = fields.Boolean(tracking=True)
# company_id = fields.Many2one(tracking=True)
ref = fields.Char(copy=False)
# For reports
name_title = fields.Char(

View File

@@ -25,7 +25,7 @@
<field name="name">base_usability.res.country.search</field>
<field name="model">res.country</field>
<field name="arch" type="xml">
<search>
<search string="Search Countries">
<field name="name" filter_domain="['|', ('name', 'ilike', self), ('code', '=', self)]" string="Name or Code"/>
<field name="code"/>
<field name="currency_id"/>

View File

@@ -39,9 +39,6 @@
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_tree"/>
<field name="arch" type="xml">
<field name="display_name" position="after">
<field name="ref" optional="hide"/>
</field>
<field name="phone" position="after">
<field name="mobile" optional="show" widget="phone" class="o_force_ltr"/>
</field>

View File

@@ -1 +0,0 @@
from . import models

View File

@@ -1,25 +0,0 @@
# Copyright 2016-2021 Akretion (http://www.akretion.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# @author Alexis de Lattre <alexis.delattre@akretion.com>
{
'name': 'CRM Usability',
'version': '14.0.1.0.0',
'category': 'Customer Relationship Management',
'license': 'AGPL-3',
'summary': 'CRM usability enhancements',
'description': """
CRM Usability
=============
This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['crm'],
'data': [
'views/crm_lead.xml',
],
'installable': True,
}

View File

@@ -1 +0,0 @@
from . import crm_lead

View File

@@ -1,13 +0,0 @@
# Copyright 2017-2021 Akretion (http://www.akretion.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# @author Alexis de Lattre <alexis.delattre@akretion.com>
from odoo import fields, models
class CrmLead(models.Model):
_inherit = 'crm.lead'
probability = fields.Float(tracking=100)
date_deadline = fields.Date(tracking=110)
name = fields.Char(tracking=1)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017-2021 Akretion (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<!-- SEARCH OPPOR -->
<record id="view_crm_case_opportunities_filter" model="ir.ui.view">
<field name="name">usability.crm.lead.opportunity.search</field>
<field name="model">crm.lead</field>
<field name="inherit_id" ref="crm.view_crm_case_opportunities_filter"/>
<field name="arch" type="xml">
<filter name="saleschannel" position="after">
<filter name="partner_groupby" string="Customer" context="{'group_by': 'partner_id'}"/>
</filter>
</field>
</record>
</odoo>

View File

@@ -1 +1 @@
from . import models
from . import stock

View File

@@ -1,10 +1,10 @@
# Copyright 2018-2021 Akretion (http://www.akretion.com)
# Copyright 2018-2019 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Delivery Usability',
'version': '14.0.1.0.0',
'version': '12.0.1.0.0',
'category': 'Stock',
'license': 'AGPL-3',
'summary': 'Several usability enhancements in Delivery',
@@ -14,6 +14,7 @@ Delivery Usability
The usability enhancements include:
* allow modification of carrier and it's tracking ref. on a done picking
* display field 'invoice_shipping_on_delivery' on sale.order form view
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
@@ -21,7 +22,8 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
'website': 'http://www.akretion.com',
'depends': ['delivery'],
'data': [
'views/stock_picking.xml',
'sale_view.xml',
'stock_view.xml',
],
'installable': True,
'installable': False,
}

View File

@@ -1 +0,0 @@
from . import stock_picking

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018-2019 Akretion
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_order_form_with_carrier" model="ir.ui.view">
<field name="name">delivery_usability.sale.order.form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="delivery.view_order_form_with_carrier"/>
<field name="arch" type="xml">
<group name="sale_pay" position="inside">
<field name="invoice_shipping_on_delivery"/>
</group>
</field>
</record>
</odoo>

View File

@@ -1,4 +1,4 @@
# Copyright 2018-2021 Akretion (http://www.akretion.com)
# Copyright 2018-2019 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@@ -8,5 +8,5 @@ from odoo import fields, models
class StockPicking(models.Model):
_inherit = 'stock.picking'
carrier_id = fields.Many2one(tracking=True)
carrier_tracking_ref = fields.Char(tracking=True)
carrier_id = fields.Many2one(track_visibility='onchange')
carrier_tracking_ref = fields.Char(track_visibility='onchange')

View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018-2021 Akretion France
@author: Alexis de Lattre <alexis.delattre@akretion.com>
Copyright 2018 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->

View File

@@ -1,9 +1,9 @@
# Copyright 2014-2021 Akretion France (http://www.akretion.com)
# Copyright 2014-2019 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
{
'name': 'Eradicate Quick Create',
'version': '14.0.1.0.0',
'version': '12.0.2.0.0',
'category': 'Tools',
'license': 'AGPL-3',
'summary': 'Disable quick create on all objects',
@@ -13,7 +13,7 @@ Eradicate Quick Create
Disable quick create on all objects of Odoo.
This module uses the module *web_m2x_options* from the OCA *web* project (in v10 and lower, it was using the module *base_optional_quick_create* from the OCA project *server-ux*).
This new version of the module uses the module *web_m2x_options* from the OCA *web* project instead of the module *base_optional_quick_create* from the OCA project *server-ux*.
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
""",
@@ -21,5 +21,5 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
'website': 'http://www.akretion.com',
'depends': ['web_m2x_options'],
'post_init_hook': 'web_m2x_options_create',
'installable': True,
'installable': False,
}

View File

@@ -1,4 +1,4 @@
# Copyright 2019-2021 Akretion France
# Copyright 2019 Akretion France
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@@ -11,7 +11,7 @@ def web_m2x_options_create(cr, registry):
config_parameter = env['ir.config_parameter'].search(
[('key', '=', 'web_m2x_options.create')])
if config_parameter and config_parameter.value != 'False':
config_parameter.write({'value': 'False'})
config_parameter.value = 'False'
else:
env['ir.config_parameter'].create({
'key': 'web_m2x_options.create',

View File

@@ -1 +0,0 @@
from . import models

View File

@@ -1,20 +0,0 @@
# Copyright 2021 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'HR Contract Usability',
'version': '14.0.1.0.0',
'category': 'Human Resources/Contracts',
'license': 'AGPL-3',
'summary': 'Usability improvements on HR Contract module',
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': [
'hr_contract',
],
'data': [
'views/hr_payroll_structure_type.xml',
],
'installable': True,
}

View File

@@ -1 +0,0 @@
from . import hr_payroll_structure_type

View File

@@ -1,10 +0,0 @@
# Copyright 2021 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class HrPayrollStructureType(models.Model):
_inherit = 'hr.payroll.structure.type'
active = fields.Boolean(default=True)

View File

@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="hr_payroll_structure_type_form" model="ir.ui.view">
<field name="model">hr.payroll.structure.type</field>
<field name="arch" type="xml">
<form>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<group name="main">
<field name="name"/>
<field name="default_resource_calendar_id"/>
<field name="active" invisible="1"/>
<field name="country_id"/>
</group>
</form>
</field>
</record>
<record id="hr_payroll_structure_type_tree" model="ir.ui.view">
<field name="model">hr.payroll.structure.type</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="default_resource_calendar_id" optional="show"/>
<field name="country_id"/>
</tree>
</field>
</record>
<record id="hr_payroll_structure_type_search" model="ir.ui.view">
<field name="model">hr.payroll.structure.type</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<separator/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<group name="groupby">
<filter name="country_groupby" string="Country" context="{'group_by': 'country_id'}"/>
</group>
</search>
</field>
</record>
<record id="hr_payroll_structure_type_action" model="ir.actions.act_window">
<field name="name">Salary Structure Types</field>
<field name="res_model">hr.payroll.structure.type</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem
id="hr_payroll_structure_type_menu"
action="hr_payroll_structure_type_action"
parent="hr_contract.menu_human_resources_configuration_contract"
sequence="10"/>
</odoo>

View File

@@ -1,27 +0,0 @@
# Copyright 2019-2021 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Link Tracker Usability',
'version': '14.0.1.0.0',
'category': 'Marketing',
'license': 'AGPL-3',
'summary': 'Improve usability for link tracker',
'description': """
Link Tracker Usability
======================
Several small usability improvements.
This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['link_tracker'],
'data': [
'views/link_tracker_click.xml',
],
'installable': True,
}

View File

@@ -1,45 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019-2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="link_tracker_click_view_tree" model="ir.ui.view">
<field name="name">usability.link.tracker.click.tree</field>
<field name="model">link.tracker.click</field>
<field name="inherit_id" ref="link_tracker.link_tracker_click_view_tree"/>
<field name="arch" type="xml">
<field name="country_id" position="after">
<field name="create_date" string="Click Date"/>
</field>
</field>
</record>
<record id="link_tracker_click_view_form" model="ir.ui.view">
<field name="name">usability.link.tracker.click.form</field>
<field name="model">link.tracker.click</field>
<field name="inherit_id" ref="link_tracker.link_tracker_click_view_form"/>
<field name="arch" type="xml">
<field name="country_id" position="after">
<field name="create_date" string="Click Date"/>
</field>
</field>
</record>
<record id="link_tracker_click_view_search" model="ir.ui.view">
<field name="name">usability.link.tracker.click.search</field>
<field name="model">link.tracker.click</field>
<field name="inherit_id" ref="link_tracker.link_tracker_click_view_search"/>
<field name="arch" type="xml">
<filter name="groupby_link_id" position="before">
<filter name="create_date_groupby" string="Click Date" context="{'group_by': 'create_date'}"/>
</filter>
</field>
</record>
</odoo>

View File

@@ -1 +0,0 @@
from . import models

View File

@@ -1,32 +0,0 @@
# Copyright 2016-2021 Akretion France (http://www.akretion.com)
# @author Benoît Guillot <benoit.guillot@akretion.com>
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Mail Usability',
'version': '14.0.1.0.0',
'category': 'Productivity/Discuss',
'license': 'AGPL-3',
'summary': 'Usability improvements on mails',
'description': """
Mail Usability
==============
Small usability improvements on mails:
* remove link in mail footer (TODO mig v14)
* remove 'sent by' in notification footer (TODO mig v14)
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['mail'],
'data': [
#'views/mail_view.xml',
#'data/mail_data.xml',
#'wizard/email_template_preview_view.xml',
#'wizard/mail_compose_message_view.xml',
],
'installable': True,
}

View File

@@ -1,2 +0,0 @@
from . import res_partner
from . import mail_template

View File

@@ -1,11 +0,0 @@
# Copyright 2018-2021 Akretion France (http://www.akretion.com).
# @author Sébastien BEAU <sebastien.beau@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class MailTemplate(models.Model):
_inherit = 'mail.template'
auto_delete = fields.Boolean(default=False)

View File

@@ -1,26 +0,0 @@
# Copyright 2015-2021 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields
class ResPartner(models.Model):
_inherit = 'res.partner'
# tracking=True is handled in the 'mail' module, so it's better
# to have this in mail_usability than in base_usability
name = fields.Char(tracking=True)
parent_id = fields.Many2one(tracking=True)
ref = fields.Char(tracking=True)
lang = fields.Selection(tracking=True)
vat = fields.Char(tracking=True)
street = fields.Char(tracking=True)
street2 = fields.Char(tracking=True)
zip = fields.Char(tracking=True)
city = fields.Char(tracking=True)
state_id = fields.Many2one(tracking=True)
country_id = fields.Many2one(tracking=True)
is_company = fields.Boolean(tracking=True)
active = fields.Boolean(tracking=True)
company_id = fields.Many2one(tracking=True)

View File

@@ -1 +0,0 @@
from . import models

View File

@@ -1,29 +0,0 @@
# Copyright 2019-2021 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Mass Mailing Campaigns Usability',
'version': '14.0.1.0.0',
'category': 'Marketing',
'license': 'AGPL-3',
'summary': 'Improve usability of mass mailing campaigns',
'description': """
Mass Mailing Campaigns Usability
================================
Several small usability improvements on the module mass_mailing:
* show fields on link.tracker.click that are not displayed by default
This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['mass_mailing', 'link_tracker_usability'],
'data': [
# 'views/link_tracker.xml',
],
'installable': False,
}

View File

@@ -1,48 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019 Akretion (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_link_tracker_click_tree" model="ir.ui.view">
<field name="name">mm.usability.link.tracker.click.tree</field>
<field name="model">link.tracker.click</field>
<field name="inherit_id" ref="link_tracker.view_link_tracker_click_tree"/>
<field name="arch" type="xml">
<field name="country_id" position="after">
<field name="mass_mailing_id"/>
<field name="mail_stat_recipient"/>
</field>
</field>
</record>
<record id="view_link_tracker_click_form" model="ir.ui.view">
<field name="name">mm.usability.link.tracker.click.form</field>
<field name="model">link.tracker.click</field>
<field name="inherit_id" ref="link_tracker.view_link_tracker_click_form"/>
<field name="arch" type="xml">
<field name="country_id" position="after">
<field name="mass_mailing_id"/>
<field name="mass_mailing_campaign_id"/>
<field name="mail_stat_id"/>
<field name="mail_stat_recipient"/>
</field>
</field>
</record>
<record id="link_tracker_click_search" model="ir.ui.view">
<field name="name">mm.usability.link.tracker.click.search</field>
<field name="model">link.tracker.click</field>
<field name="inherit_id" ref="link_tracker_usability.link_tracker_click_search"/>
<field name="arch" type="xml">
<field name="link_id" position="after">
<field name="mail_stat_recipient"/>
</field>
</field>
</record>
</odoo>

View File

@@ -12,20 +12,16 @@ class ProductTemplate(models.Model):
only one BoM form or a list of BoMs."""
self.ensure_one()
if self.bom_count == 1:
action_xml_id = "mrp.mrp_bom_form_action"
action = self.env["ir.actions.actions"]._for_xml_id(action_xml_id)
action = self.env.ref("mrp.mrp_bom_form_action").read()[0]
bom = self.env["mrp.bom"].search([("product_tmpl_id", "=", self.id)])
action.update(
{
"context": {"default_product_tmpl_id": self.id},
"views": False,
"view_mode": "form,tree",
"res_id": bom.id,
}
)
action.update({
"context": {"default_product_tmpl_id": self.id},
"views": False,
"view_mode": "form,tree",
"res_id": bom.id,
})
else:
action_xml_id = "mrp.template_open_bom"
action = self.env["ir.actions.actions"]._for_xml_id(action_xml_id)
action = self.env.ref("mrp.template_open_bom").read()[0]
return action
@@ -36,11 +32,9 @@ class ProductProduct(models.Model):
action = super().action_view_bom()
bom_target_ids = self.env["mrp.bom"].search(action["domain"])
if len(bom_target_ids) == 1:
action.update(
{
"views": False,
"view_mode": "form,tree",
"res_id": bom_target_ids[0].id,
}
)
action.update({
"views": False,
"view_mode": "form,tree",
"res_id": bom_target_ids[0].id,
})
return action

View File

@@ -0,0 +1,28 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'POS No Product Template Menu',
'version': '12.0.1.0.0',
'category': 'Point of sale',
'license': 'AGPL-3',
'summary': "Replace product.template menu entries by product.product menu",
'description': """
POS No Product Template
=======================
This module replaces the menu entry for product.template by menu entries
for product.product in the *Point Of Sale > Product* menu.
This module also switches to the tree view by default
for Product menu entries, instead of the kanban view.
This module has been written by David Béal
from Akretion <david.beal@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['point_of_sale', 'sale_purchase_no_product_template_menu'],
'auto_install': True,
'data': ['pos_view.xml'],
'installable': False,
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="product_product_action_pos" model="ir.actions.act_window">
<field name="name">Products</field>
<field name="res_model">product.product</field>
<field name="view_mode">kanban,tree,form</field>
<field name="context">{'default_available_in_pos': True, 'search_default_filter_to_availabe_pos': 1}</field>
</record>
<record id="point_of_sale.menu_pos_products" model="ir.ui.menu">
<field name="action" ref="product_product_action_pos"/>
</record>
</odoo>

View File

@@ -28,9 +28,7 @@ Akretion:
"depends": ["point_of_sale"],
"data": [
"report/pos.xml",
"views/report_pos_order.xml",
"views/pos_category.xml",
"views/pos_session.xml",
"views/product.xml",
],
"installable": True,

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_pos_session_form" model="ir.ui.view">
<field name="model">pos.session</field>
<field name="inherit_id" ref="point_of_sale.view_pos_session_form"/>
<field name="arch" type="xml">
<button name="show_journal_items" position="after">
<button name="%(point_of_sale.action_report_pos_order_all)d" type="action" class="oe_stat_button" icon="fa-table" string="Stats" context="{'search_default_session_id': active_id}"/>
</button>
</field>
</record>
<record id="view_pos_session_tree" model="ir.ui.view">
<field name="model">pos.session</field>
<field name="inherit_id" ref="point_of_sale.view_pos_session_tree"/>
<field name="arch" type="xml">
<field name="state" position="attributes">
<attribute name="decoration-success">state == 'opened'</attribute>
</field>
</field>
</record>
</odoo>

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_report_pos_order_search" model="ir.ui.view">
<field name="model">report.pos.order</field>
<field name="inherit_id" ref="point_of_sale.view_report_pos_order_search"/>
<field name="arch" type="xml">
<field name="product_categ_id" position="after">
<field name="session_id"/>
</field>
</field>
</record>
<record id="point_of_sale.action_report_pos_order_all" model="ir.actions.act_window">
<field name="view_mode">pivot,graph</field> <!-- invert native order -->
</record>
</odoo>

View File

@@ -32,7 +32,6 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
'views/product_pricelist_item.xml',
'views/product_template_view.xml',
'views/product_product.xml',
'views/product_category_view.xml',
],
'installable': True,
}

View File

@@ -2,4 +2,3 @@ from . import product_product
from . import product_template
from . import product_supplierinfo
from . import product_pricelist
from . import product_category

View File

@@ -1,13 +0,0 @@
# Copyright 2022 Akretion (https://www.akretion.com).
# @author Sébastien BEAU <sebastien.beau@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ProductCategory(models.Model):
_inherit = ['product.category', "mail.thread", "mail.activity.mixin"]
_name = 'product.category'
name = fields.Char(tracking=10)
parent_id = fields.Many2one(tracking=20)

View File

@@ -1,21 +1,21 @@
# Copyright 2015-2021 Akretion (http://www.akretion.com)
# Copyright 2015-2020 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Raphaël Valyi <rvalyi@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models, fields
from odoo import models, fields
class ProductProduct(models.Model):
_inherit = 'product.product'
default_code = fields.Char(copy=False, tracking=10)
barcode = fields.Char(tracking=20)
weight = fields.Float(tracking=30)
active = fields.Boolean(tracking=40)
barcode_code128 = fields.Char(
compute='_compute_barcode_code128',
help="Barcode in Code128-B with start char, checksum and stop char")
default_code = fields.Char(copy=False)
# track_visibility='onchange',
# barcode = fields.Char(track_visibility='onchange',
# weight = fields.Float(track_visibility='onchange')
# active = fields.Boolean(track_visibility='onchange')
_sql_constraints = [(
# Maybe it could be better to have a constrain per company
@@ -26,32 +26,3 @@ class ProductProduct(models.Model):
'default_code_uniq',
'unique(default_code)',
'This internal reference already exists!')]
@api.model
def _compute_code128_checksum(self, code):
# This is NOT a full implementation of code128 checksum
csum = 104 # Start B
i = 0
for char in code:
i += 1
char_val = ord(char) - 32
csum += char_val * i
remainder = csum % 103
checksum = chr(remainder + 32)
return checksum
@api.depends('barcode')
def _compute_barcode_code128(self):
# We use Code128-B. Useful info on code128:
# https://boowiki.info/art/codes-a-barres/code-128.html
# Use code128.ttf and copy it in /usr/local/share/fonts/
startb = chr(209)
stop = chr(211)
for product in self:
code128 = False
barcode = product.barcode
if barcode and all([32 <= ord(x) <= 127 for x in barcode]):
checksum = self._compute_code128_checksum(barcode)
if checksum:
code128 = startb + barcode + checksum + stop
product.barcode_code128 = code128

View File

@@ -1,4 +1,4 @@
# Copyright 2015-2021 Akretion (http://www.akretion.com)
# Copyright 2015-2020 Akretion (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Raphaël Valyi <rvalyi@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@@ -21,12 +21,9 @@ class ProductTemplate(models.Model):
# are only shown in the form view of product.template, not in the form
# view of product.product
name = fields.Char(tracking=10)
barcode = fields.Char(tracking=20)
default_code = fields.Char(tracking=30)
categ_id = fields.Many2one(tracking=40)
type = fields.Selection(tracking=50)
list_price = fields.Float(tracking=60)
weight = fields.Float(tracking=70)
sale_ok = fields.Boolean(tracking=80)
purchase_ok = fields.Boolean(tracking=90)
active = fields.Boolean(tracking=100)
categ_id = fields.Many2one(tracking=20)
type = fields.Selection(tracking=30)
list_price = fields.Float(tracking=40)
sale_ok = fields.Boolean(tracking=50)
purchase_ok = fields.Boolean(tracking=60)
active = fields.Boolean(tracking=70)

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="product_category_form_view" model="ir.ui.view">
<field name="model">product.category</field>
<field name="inherit_id" ref="product.product_category_form_view" />
<field name="arch" type="xml">
<sheet position="after">
<div class="oe_chatter">
<field name="message_follower_ids"/>
<field name="activity_ids"/>
<field name="message_ids"/>
</div>
</sheet>
</field>
</record>
</odoo>

View File

@@ -12,7 +12,7 @@
<field name="inherit_id" ref="product.product_supplierinfo_search_view"/>
<field name="arch" type="xml">
<field name="product_tmpl_id" position="after">
<field name="product_name" filter_domain="['|', ('product_code', 'ilike', self), ('product_name', 'ilike', self)]" />
<field name="product_code"/>
</field>
</field>
</record>

View File

@@ -10,17 +10,3 @@ class PurchaseOrder(models.Model):
picking_type_id = fields.Many2one(tracking=True)
incoterm_id = fields.Many2one(tracking=True)
# inherit compute method of the field delivery_partner_id
# defined in purchase_usability
@api.depends('dest_address_id', 'picking_type_id')
def _compute_delivery_partner_id(self):
for o in self:
delivery_partner_id = False
if o.dest_address_id:
delivery_partner_id = o.dest_address_id
elif (
o.picking_type_id.warehouse_id and
o.picking_type_id.warehouse_id.partner_id):
delivery_partner_id = o.picking_type_id.warehouse_id.partner_id
o.delivery_partner_id = delivery_partner_id

View File

@@ -1,185 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * purchase_usability
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-30 13:35+0000\n"
"PO-Revision-Date: 2021-11-30 13:35+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: purchase_usability
#: model_terms:ir.ui.view,arch_db:purchase_usability.purchase_order_line_search
msgid "Analytic Account"
msgstr ""
#. module: purchase_usability
#: model_terms:ir.ui.view,arch_db:purchase_usability.purchase_order_form
msgid "Are you sure you want to cancel this purchase order?"
msgstr "Êtes-vous sûr de vouloir annuler cette commande?"
#. module: purchase_usability
#: model_terms:ir.ui.view,arch_db:purchase_usability.view_purchase_order_filter
msgid "Billing Status"
msgstr ""
#. module: purchase_usability
#: model:ir.model,name:purchase_usability.model_res_partner
msgid "Contact"
msgstr ""
#. module: purchase_usability
#: model:ir.model.fields,field_description:purchase_usability.field_product_product__purchase_method
#: model:ir.model.fields,field_description:purchase_usability.field_product_template__purchase_method
msgid "Control Policy"
msgstr "Politique de contrôle"
#. module: purchase_usability
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order__currency_id
msgid "Currency"
msgstr "Devise"
#. module: purchase_usability
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order__delivery_partner_id
msgid "Delivery Partner"
msgstr ""
#. module: purchase_usability
#: model:ir.model.fields,field_description:purchase_usability.field_product_template__display_name
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order__display_name
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order_line__display_name
#: model:ir.model.fields,field_description:purchase_usability.field_res_partner__display_name
msgid "Display Name"
msgstr "Nom"
#. module: purchase_usability
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order__dest_address_id
msgid "Drop Ship Address"
msgstr "Adresse de livraison directe"
#. module: purchase_usability
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order__fiscal_position_id
msgid "Fiscal Position"
msgstr "Position fiscale"
#. module: purchase_usability
#: model:ir.model.fields,field_description:purchase_usability.field_product_template__id
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order__id
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order_line__id
#: model:ir.model.fields,field_description:purchase_usability.field_res_partner__id
msgid "ID"
msgstr ""
#. module: purchase_usability
#: model:ir.model.fields,help:purchase_usability.field_purchase_order_line__product_barcode
msgid "International Article Number used for product identification."
msgstr ""
#. module: purchase_usability
#: model:ir.model.fields,field_description:purchase_usability.field_product_template____last_update
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order____last_update
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order_line____last_update
#: model:ir.model.fields,field_description:purchase_usability.field_res_partner____last_update
msgid "Last Modified on"
msgstr "Dernière modification le"
#. module: purchase_usability
#: model:ir.model.fields,help:purchase_usability.field_product_product__purchase_method
#: model:ir.model.fields,help:purchase_usability.field_product_template__purchase_method
msgid ""
"On ordered quantities: Control bills based on ordered quantities.\n"
"On received quantities: Control bills based on received quantities."
msgstr ""
"Sur base des quantités commandées: factures de controle basées sur les quantités commandées. \n"
"Sur base des quantités reçues: factures de controle basées sur les quantités reçues."
#. module: purchase_usability
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order__payment_term_id
msgid "Payment Terms"
msgstr "Conditions de paiement"
#. module: purchase_usability
#: model_terms:ir.ui.view,arch_db:purchase_usability.purchase_order_form
msgid "Print"
msgstr "Imprimer"
#. module: purchase_usability
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order_line__product_barcode
msgid "Product Barcode"
msgstr ""
#. module: purchase_usability
#: model:ir.model,name:purchase_usability.model_product_template
msgid "Product Template"
msgstr "Modèle de produit"
#. module: purchase_usability
#: model:ir.model,name:purchase_usability.model_purchase_order
#: model:ir.model.fields,field_description:purchase_usability.field_res_partner__purchase_warn
#: model:ir.model.fields,field_description:purchase_usability.field_res_users__purchase_warn
msgid "Purchase Order"
msgstr "Commande fournisseur"
#. module: purchase_usability
#: model:ir.model,name:purchase_usability.model_purchase_order_line
msgid "Purchase Order Line"
msgstr "Ligne de commande d'achat"
#. module: purchase_usability
#: model:ir.model.fields,field_description:purchase_usability.field_product_product__purchase_line_warn
#: model:ir.model.fields,field_description:purchase_usability.field_product_template__purchase_line_warn
msgid "Purchase Order Line Warning"
msgstr "Avertissement Ligne de Commande "
#. module: purchase_usability
#: model:ir.model.fields,help:purchase_usability.field_purchase_order__dest_address_id
msgid ""
"Put an address if you want to deliver directly from the vendor to the "
"customer. Otherwise, keep empty to deliver to your own company."
msgstr ""
"Ajoutez une adresse si vous voulez livrer directement du fournisseur au "
"client. Sinon, laissez vide pour vous faire livrer à votre société."
#. module: purchase_usability
#: model:ir.model.fields,help:purchase_usability.field_purchase_order__partner_ref
msgid ""
"Reference of the sales order or bid sent by the vendor. It's used to do the "
"matching when you receive the products as this reference is usually written "
"on the delivery order sent by your vendor."
msgstr ""
"Référence de la commande client ou offre envoyée par le fournisseur. Utilisé"
" principalement pour faire la correspondance lors de la réception des "
"articles, puisque cette référence est généralement écrite sur le bon de "
"livraison envoyé par votre fournisseur."
#. module: purchase_usability
#: model_terms:ir.ui.view,arch_db:purchase_usability.view_purchase_order_filter
msgid "Reference, Origin or Vendor Reference"
msgstr ""
#. module: purchase_usability
#: model:ir.model.fields,help:purchase_usability.field_product_product__purchase_line_warn
#: model:ir.model.fields,help:purchase_usability.field_product_template__purchase_line_warn
#: model:ir.model.fields,help:purchase_usability.field_res_partner__purchase_warn
#: model:ir.model.fields,help:purchase_usability.field_res_users__purchase_warn
msgid ""
"Selecting the \"Warning\" option will notify user with the message, "
"Selecting \"Blocking Message\" will throw an exception with the message and "
"block the flow. The Message has to be written in the next field."
msgstr ""
"Sélectionner l'option 'Avertissement' notifiera l'utilisateur avec le "
"Message. Sélectionner 'Message Bloquant' lancera une exception avec le "
"message et bloquera le flux. Le Message doit être encodé dans le champ "
"suivant."
#. module: purchase_usability
#: model:ir.model.fields,field_description:purchase_usability.field_purchase_order__partner_ref
msgid "Vendor Reference"
msgstr "Référence fournisseur"

View File

@@ -14,15 +14,11 @@ class PurchaseOrder(models.Model):
payment_term_id = fields.Many2one(tracking=True)
fiscal_position_id = fields.Many2one(tracking=True)
partner_ref = fields.Char(tracking=True)
# the field 'delivery_partner_id' is used in report
# the compute method of that field is inherited in purchase_stock_usability
delivery_partner_id = fields.Many2one(
'res.partner', compute='_compute_delivery_partner_id')
@api.depends('dest_address_id')
def _compute_delivery_partner_id(self):
for order in self:
order.delivery_partner_id = order.dest_address_id
def print_order(self):
report = self.env.ref('purchase.action_report_purchase_order')
action = report.report_action(self)
return action
# Re-write native name_get() to use amount_untaxed instead of amount_total
@api.depends('name', 'partner_ref')
@@ -73,28 +69,3 @@ class PurchaseOrderLine(models.Model):
# for optional display in tree view
product_barcode = fields.Char(related='product_id.barcode', string="Product Barcode")
product_supplier_code = fields.Char(
compute='_compute_product_supplier_code', string='Vendor Product Code')
def _compute_product_supplier_code(self):
for line in self:
code = False
if not line.display_type and line.product_id and line.order_id:
partner_id = line.order_id.partner_id.commercial_partner_id.id
if partner_id:
for supplier_info in line.product_id.seller_ids:
if supplier_info.name.id == partner_id:
code = supplier_info.product_code
break
line.product_supplier_code = code
def _get_product_purchase_description(self, product_lang):
# This is useful when you want to have the product code in a dedicated
# column in your purchase order report
# The same ir.config_parameter is used in sale_usability,
# purchase_usability and account_usability
no_product_code_param = self.env['ir.config_parameter'].sudo().get_param(
'usability.line_name_no_product_code')
if no_product_code_param and no_product_code_param == 'True':
product_lang = product_lang.with_context(display_default_code=False)
return super()._get_product_purchase_description(product_lang)

View File

@@ -14,7 +14,7 @@
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<button name="action_rfq_send" states="purchase" position="after">
<button name="%(purchase.action_report_purchase_order)d" states="purchase,done" string="Print" type="action"/>
<button name="print_order" states="purchase" string="Print Order" type="object"/>
</button>
<field name="fiscal_position_id" position="attributes">
<attribute name="widget">selection</attribute>
@@ -35,7 +35,6 @@
<attribute name="groups">analytic.group_analytic_tags</attribute>
</xpath>
<xpath expr="//field[@name='order_line']/tree//field[@name='product_id']" position="after">
<field name="product_supplier_code" optional="hide"/>
<field name="product_barcode" optional="hide"/>
</xpath>
</field>

View File

@@ -1,2 +0,0 @@
from . import models
from . import wizard

View File

@@ -1,38 +0,0 @@
# Copyright 2017-2021 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Sale Confirm Wizard',
'version': '14.0.1.0.0',
'category': 'Sales',
'license': 'AGPL-3',
'summary': 'Open a wizard when you confirm a sale order to update important info',
'description': """
Sale Confirm Wizard
===================
When you confirm a quotation, Odoo will open a small wizard where you will be able to check and update important information:
* customer PO number,
* delivery address,
* invoicing address,
* payment terms.
It will also display the sale warning if the customer's company has one. And it is a blocker warning, the user won't be able to confirm the quotation.
This module has been developped because the experience has shown, when a sales assistant confirms a quotation in Odoo, it overlooks the important information written in the customer PO that may be different from the information of the quotation in Odoo, which causes many errors in delivery and invoicing.
This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['sale'],
'data': [
'wizard/sale_confirm_view.xml',
'views/sale_order.xml',
'security/ir.model.access.csv',
],
'installable': True,
}

View File

@@ -1 +0,0 @@
from . import sale_order

View File

@@ -1,17 +0,0 @@
# Copyright 2020-2021 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models
class SaleOrder(models.Model):
_inherit = 'sale.order'
def sale_confirm_wizard_button(self):
"""This method is designed to be inherited.
For example, inherit it if you don't want to start the wizard in
some scenarios"""
action = self.sudo().env.ref(
'sale_confirm_wizard.sale_confirm_action').read()[0]
return action

View File

@@ -1,2 +0,0 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sale_confirm_wizard,Full access on sale.confirm wizard,model_sale_confirm,sales_team.group_sale_salesman,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sale_confirm_wizard Full access on sale.confirm wizard model_sale_confirm sales_team.group_sale_salesman 1 1 1 1

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017-2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_order_form" model="ir.ui.view">
<field name="name">sale.confirm.wizard.sale_order_form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<button id="action_confirm" position="attributes">
<attribute name="name">sale_confirm_wizard_button</attribute>
</button>
<button name="action_confirm" attrs="{'invisible': [('state', 'not in', ['draft'])]}" position="attributes">
<attribute name="name">sale_confirm_wizard_button</attribute>
</button>
</field>
</record>
</odoo>

Some files were not shown because too many files have changed in this diff Show More