Compare commits
74 Commits
14.0-impro
...
14.0_purch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cdcf4eb406 | ||
|
|
a22f79ef44 | ||
|
|
99dd4de4f7 | ||
|
|
f3d6b67043 | ||
|
|
1963af114b | ||
|
|
1da4c40927 | ||
|
|
edc9db5839 | ||
|
|
882d068f1a | ||
|
|
878db1d0a1 | ||
|
|
600acd2f26 | ||
|
|
059c3b4a09 | ||
|
|
895e1d9dd0 | ||
|
|
0b3ffc804f | ||
|
|
c0a03dbb0e | ||
|
|
6e5f263283 | ||
|
|
d4ebbb28d9 | ||
|
|
7dd204e57e | ||
|
|
e1a84973da | ||
|
|
13e68ac0f5 | ||
|
|
3b17c2e5fb | ||
|
|
0be112dc84 | ||
|
|
2854d4fdda | ||
|
|
6c51a92acc | ||
|
|
f3910ab528 | ||
|
|
05374c4b4a | ||
|
|
279dc7c6c0 | ||
|
|
f6ddbb48ac | ||
|
|
d3bddf5fda | ||
|
|
6f3a468a7c | ||
|
|
0bfa960153 | ||
|
|
a520ccff51 | ||
|
|
fa7611eb08 | ||
|
|
b2eda2a23b | ||
|
|
74ff1b5cb5 | ||
|
|
a7b4ed65eb | ||
|
|
7dfb32c2d6 | ||
|
|
d081bb0fd2 | ||
|
|
f3fdbec140 | ||
|
|
ac54c5cc75 | ||
|
|
78c11411c3 | ||
|
|
28ce11b216 | ||
|
|
00e034dacf | ||
|
|
8510b9518a | ||
|
|
15ef5df155 | ||
|
|
45500f5bd8 | ||
|
|
a28a853f45 | ||
|
|
82b9a1e502 | ||
|
|
b05abba064 | ||
|
|
75e3463a76 | ||
|
|
3066c0545d | ||
|
|
62a84469c8 | ||
|
|
00339e44b6 | ||
|
|
d1ae620079 | ||
|
|
3db9f0f096 | ||
|
|
732ee2c55b | ||
|
|
e08d658b25 | ||
|
|
2a7ec92a37 | ||
|
|
dc30ce4e69 | ||
|
|
32d45d228b | ||
|
|
939de0c9bd | ||
|
|
48a19b8f97 | ||
|
|
8a2e662d43 | ||
|
|
de2e5f2121 | ||
|
|
42e014bcb1 | ||
|
|
e70e3b23cf | ||
|
|
50b4944c8b | ||
|
|
96bfda6e1b | ||
|
|
cfb58ed80f | ||
|
|
91e9c1fe33 | ||
|
|
dff4e47cf5 | ||
|
|
452cc399c5 | ||
|
|
f4c22501a7 | ||
|
|
9e8874eb4b | ||
|
|
fc6c0384ed |
@@ -31,6 +31,7 @@
|
||||
'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',
|
||||
],
|
||||
'installable': True,
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
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
|
||||
|
||||
|
||||
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)]})
|
||||
@@ -49,11 +48,11 @@ class AccountMove(models.Model):
|
||||
def _compute_has_attachment(self):
|
||||
iao = self.env['ir.attachment']
|
||||
for move in self:
|
||||
if iao.search([
|
||||
if iao.search_count([
|
||||
('res_model', '=', 'account.move'),
|
||||
('res_id', '=', move.id),
|
||||
('type', '=', 'binary'),
|
||||
('company_id', '=', move.company_id.id)], limit=1):
|
||||
('company_id', '=', move.company_id.id)]):
|
||||
move.has_attachment = True
|
||||
else:
|
||||
move.has_attachment = False
|
||||
@@ -122,7 +121,11 @@ class AccountMove(models.Model):
|
||||
has_sections = False
|
||||
subtotal = 0.0
|
||||
sign = self.move_type == 'out_refund' and -1 or 1
|
||||
for line in self.invoice_line_ids:
|
||||
# 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:
|
||||
if line.display_type == 'line_section':
|
||||
# insert line
|
||||
if has_sections:
|
||||
@@ -157,6 +160,53 @@ class AccountMove(models.Model):
|
||||
for x in sales]
|
||||
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)
|
||||
@api.depends('company_id', 'invoice_filter_type_domain')
|
||||
def _compute_suitable_journal_ids(self):
|
||||
for move in self:
|
||||
if move.invoice_filter_type_domain:
|
||||
super(AccountMove, move)._compute_suitable_journal_ids()
|
||||
else:
|
||||
company_id = move.company_id.id or self.env.company.id
|
||||
domain = expression.AND([
|
||||
[('company_id', '=', company_id)],
|
||||
expression.OR([
|
||||
[('type', 'in', ('general', 'cash'))],
|
||||
[('type', '=', 'bank'), ('bank_account_id', '=', False)]
|
||||
])
|
||||
])
|
||||
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')
|
||||
|
||||
|
||||
class AccountMoveLine(models.Model):
|
||||
_inherit = 'account.move.line'
|
||||
@@ -176,6 +226,8 @@ class AccountMoveLine(models.Model):
|
||||
matched_credit_ids = fields.One2many(string='Partial Reconcile Credit')
|
||||
reconcile_string = fields.Char(
|
||||
compute='_compute_reconcile_string', string='Reconcile', store=True)
|
||||
# for optional display in tree view
|
||||
product_barcode = fields.Char(related='product_id.barcode', string="Product Barcode")
|
||||
|
||||
def show_account_move_form(self):
|
||||
self.ensure_one()
|
||||
|
||||
@@ -18,8 +18,20 @@
|
||||
<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>
|
||||
@@ -30,6 +42,9 @@
|
||||
<field name="matching_number" optional="hide"/>
|
||||
<field name="reconcile_string" optional="show"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='product_id']" position="after">
|
||||
<field name="product_barcode" optional="hide"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -58,6 +73,36 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_account_move_line_filter" model="ir.ui.view">
|
||||
<field name="name">account_usability.account_move_line_search</field>
|
||||
<field name="model">account.move.line</field>
|
||||
<field name="inherit_id" ref="account.view_account_move_line_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<filter name="unposted" position="before">
|
||||
<filter name="current_year" string="Current Year" domain="[('date', '>=', (context_today().strftime('%Y-01-01'))), ('date', '<=', (context_today().strftime('%Y-12-31')))]"/>
|
||||
<filter name="previous_year" string="Previous Year" domain="[('date', '>=', (context_today() + relativedelta(day=1, month=1, years=-1)).strftime('%Y-%m-%d')), ('date', '<=', (context_today() + relativedelta(day=31, month=12, years=-1)).strftime('%Y-%m-%d'))]"/>
|
||||
<separator/>
|
||||
</filter>
|
||||
<field name="partner_id" position="after">
|
||||
<field name="reconcile_string" />
|
||||
<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="[('full_reconcile_id', '!=', False)]"/>
|
||||
</filter>
|
||||
<filter name="unreconciled" position="attributes">
|
||||
<attribute name="string">Unreconciled or Partially Reconciled</attribute>
|
||||
</filter>
|
||||
<!--
|
||||
<field name="name" position="attributes">
|
||||
<attribute name="string">Name or Reference</attribute>
|
||||
</field> -->
|
||||
<field name="partner_id" position="attributes">
|
||||
<attribute name="domain">['|', ('parent_id', '=', False), ('is_company', '=', True)]</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="account.action_move_journal_line" model="ir.actions.act_window">
|
||||
<field name="context">{'default_move_type': 'entry', 'view_no_maturity': True}</field>
|
||||
<!-- Remove 'search_default_misc_filter': 1 -->
|
||||
|
||||
@@ -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'}" class="oe_inline"/>
|
||||
<field name="list_price" widget='monetary' options="{'currency_field': 'currency_id', 'field_digits': True}" class="oe_inline"/>
|
||||
<label for="sale_price_type" string=" "/>
|
||||
<field name="sale_price_type"/>
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
<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>
|
||||
|
||||
|
||||
23
account_usability/wizard/account_payment_register_views.xml
Normal file
23
account_usability/wizard/account_payment_register_views.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?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>
|
||||
1
base_dynamic_list/__init__.py
Normal file
1
base_dynamic_list/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import models
|
||||
62
base_dynamic_list/__manifest__.py
Normal file
62
base_dynamic_list/__manifest__.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# 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,
|
||||
}
|
||||
1
base_dynamic_list/models/__init__.py
Normal file
1
base_dynamic_list/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import dynamic_list
|
||||
115
base_dynamic_list/models/dynamic_list.py
Normal file
115
base_dynamic_list/models/dynamic_list.py
Normal file
@@ -0,0 +1,115 @@
|
||||
# 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)
|
||||
9
base_dynamic_list/security/ir.model.access.csv
Normal file
9
base_dynamic_list/security/ir.model.access.csv
Normal file
@@ -0,0 +1,9 @@
|
||||
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
|
||||
|
220
base_dynamic_list/views/dynamic_list.xml
Normal file
220
base_dynamic_list/views/dynamic_list.xml
Normal file
@@ -0,0 +1,220 @@
|
||||
<?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>
|
||||
@@ -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 10.0\n"
|
||||
"Project-Id-Version: Odoo Server 14.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-01-27 18:03+0000\n"
|
||||
"PO-Revision-Date: 2020-01-27 18:03+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"POT-Creation-Date: 2021-10-29 21:12+0000\n"
|
||||
"PO-Revision-Date: 2021-10-29 21:12+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -16,92 +16,120 @@ msgstr ""
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_create_uid
|
||||
#: 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
|
||||
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_phone_display_name
|
||||
#: 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
|
||||
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:61
|
||||
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
|
||||
#, 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:51
|
||||
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
|
||||
#, 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_phone_id
|
||||
#: 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
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: 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____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_phone_note
|
||||
#: 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
|
||||
msgid "Note"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_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
|
||||
#: 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
|
||||
msgid "Phone"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: code:addons/base_partner_one2many_phone/partner_phone.py:54
|
||||
#: 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
|
||||
#, 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:58
|
||||
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
|
||||
#, 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: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
|
||||
#: model_terms:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_tree
|
||||
msgid "Phones and E-mail"
|
||||
msgstr ""
|
||||
|
||||
@@ -112,63 +140,63 @@ msgid "Phones/E-mails"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: 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
|
||||
msgid "Primary E-mail"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__7_fax_primary
|
||||
msgid "Primary Fax"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__5_mobile_primary
|
||||
msgid "Primary Mobile"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__3_phone_primary
|
||||
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:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_search
|
||||
#: model_terms:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_search
|
||||
msgid "Search Phones/E-mail"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__2_email_secondary
|
||||
msgid "Secondary E-mail"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__8_fax_secondary
|
||||
msgid "Secondary Fax"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__6_mobile_secondary
|
||||
msgid "Secondary Mobile"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__4_phone_secondary
|
||||
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: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_terms: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 ""
|
||||
|
||||
|
||||
@@ -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 10.0\n"
|
||||
"Project-Id-Version: Odoo Server 14.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-01-27 17:56+0000\n"
|
||||
"PO-Revision-Date: 2020-01-27 17:56+0000\n"
|
||||
"Last-Translator: <>\n"
|
||||
"POT-Creation-Date: 2021-10-29 21:12+0000\n"
|
||||
"PO-Revision-Date: 2021-10-29 21:12+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -16,159 +16,187 @@ msgstr ""
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: model:ir.model.fields,field_description:base_partner_one2many_phone.field_res_partner_phone_create_uid
|
||||
#: 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
|
||||
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_phone_display_name
|
||||
#: 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
|
||||
msgid "Display Name"
|
||||
msgstr "Nom à afficher"
|
||||
msgstr "Nom affiché"
|
||||
|
||||
#. 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 "Courriel"
|
||||
msgstr "E-Mail"
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: code:addons/base_partner_one2many_phone/partner_phone.py:61
|
||||
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
|
||||
#, 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 courriel doit être vide quand le type est tél. primaire/secondaire, portable primaire/secondaire ou fax primaire/secondaire."
|
||||
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."
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: code:addons/base_partner_one2many_phone/partner_phone.py:51
|
||||
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
|
||||
#, python-format
|
||||
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."
|
||||
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."
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: 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__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
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: 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____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 mise à jour par"
|
||||
msgstr "Dernière modification 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 mise à jour le"
|
||||
msgstr "Dernière modification le"
|
||||
|
||||
#. 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__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
|
||||
msgid "Note"
|
||||
msgstr "Note"
|
||||
|
||||
#. module: base_partner_one2many_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
|
||||
#: 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
|
||||
msgid "Phone"
|
||||
msgstr "Téléphone"
|
||||
msgstr "Tél."
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: code:addons/base_partner_one2many_phone/partner_phone.py:54
|
||||
#: 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
|
||||
#, python-format
|
||||
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."
|
||||
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."
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: code:addons/base_partner_one2many_phone/partner_phone.py:58
|
||||
#: code:addons/base_partner_one2many_phone/partner_phone.py:0
|
||||
#, 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éphone doit être renseigné quand le type est tél. primaire/secondaire, portable primaire/secondaire ou fax primaire/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. doit avoir une valeur quand le type est Tél. principal/secondaire, Portable principal/secondaire ou Fax principal/secondaire."
|
||||
|
||||
#. 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"
|
||||
msgstr "Téléphones"
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: model:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_tree
|
||||
#: model_terms:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_tree
|
||||
msgid "Phones and E-mail"
|
||||
msgstr "Téls et courriels"
|
||||
msgstr "Téls et E-mail"
|
||||
|
||||
#. 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/Courriels"
|
||||
msgstr "Téls/E-mails"
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: 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
|
||||
msgid "Primary E-mail"
|
||||
msgstr "Courriel principal"
|
||||
msgstr "E-mail principal"
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__7_fax_primary
|
||||
msgid "Primary Fax"
|
||||
msgstr "Fax principal"
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__5_mobile_primary
|
||||
msgid "Primary Mobile"
|
||||
msgstr "Portable principal"
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__3_phone_primary
|
||||
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:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_search
|
||||
#: model_terms:ir.ui.view,arch_db:base_partner_one2many_phone.res_partner_phone_search
|
||||
msgid "Search Phones/E-mail"
|
||||
msgstr "Search Phones/E-mail"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__2_email_secondary
|
||||
msgid "Secondary E-mail"
|
||||
msgstr "Courriel secondaire"
|
||||
msgstr "E-mail secondaire"
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__8_fax_secondary
|
||||
msgid "Secondary Fax"
|
||||
msgstr "Fax secondaire"
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__6_mobile_secondary
|
||||
msgid "Secondary Mobile"
|
||||
msgstr "Portable secondaire"
|
||||
|
||||
#. module: base_partner_one2many_phone
|
||||
#: selection:res.partner.phone,type:0
|
||||
#: model:ir.model.fields.selection,name:base_partner_one2many_phone.selection__res_partner_phone__type__4_phone_secondary
|
||||
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: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_terms: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"
|
||||
|
||||
|
||||
@@ -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)
|
||||
self.phone = self.phone_format(self.phone, country=self.partner_id.country_id)
|
||||
|
||||
@api.constrains('type', 'phone', 'email')
|
||||
def _check_partner_phone(self):
|
||||
|
||||
@@ -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 string="Phones and E-mail" editable="bottom">
|
||||
<tree 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 string="Phone and E-mail">
|
||||
<form>
|
||||
<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 string="Search Phones/E-mail">
|
||||
<search>
|
||||
<field name="phone" />
|
||||
<field name="email" />
|
||||
<group name="groupby">
|
||||
|
||||
@@ -1 +1 @@
|
||||
from . import partner
|
||||
from . import models
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Copyright 2017-2019 Akretion (http://www.akretion.com)
|
||||
# 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).
|
||||
|
||||
{
|
||||
'name': 'Base Partner Reference',
|
||||
'version': '12.0.1.0.0',
|
||||
'version': '14.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': ['partner_view.xml'],
|
||||
'installable': False,
|
||||
'data': ['views/res_partner.xml'],
|
||||
'installable': True,
|
||||
}
|
||||
|
||||
1
base_partner_ref/models/__init__.py
Normal file
1
base_partner_ref/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import res_partner
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2017-2019 Akretion
|
||||
# Copyright 2017-2021 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('is_company', 'name', 'parent_id.name', 'type', 'company_name', 'ref', 'invalidate_display_name')
|
||||
@api.depends('ref', 'invalidate_display_name')
|
||||
def _compute_display_name(self):
|
||||
super(ResPartner, self)._compute_display_name()
|
||||
super()._compute_display_name()
|
||||
|
||||
def _get_name(self):
|
||||
partner = self
|
||||
@@ -28,16 +28,17 @@ class ResPartner(models.Model):
|
||||
|
||||
# START modif of native method
|
||||
if partner.ref:
|
||||
name = u"[%s] %s" % (partner.ref, name)
|
||||
name = "[%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 = u"[%s] %s" % (partner.parent_id.ref, company_name)
|
||||
company_name = "[%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'):
|
||||
@@ -47,7 +48,8 @@ class ResPartner(models.Model):
|
||||
name = name.replace('\n\n', '\n')
|
||||
name = name.replace('\n\n', '\n')
|
||||
if self._context.get('address_inline'):
|
||||
name = name.replace('\n', ', ')
|
||||
splitted_names = name.split("\n")
|
||||
name = ", ".join([n for n in splitted_names if n.strip()])
|
||||
if self._context.get('show_email') and partner.email:
|
||||
name = "%s <%s>" % (name, partner.email)
|
||||
if self._context.get('html_format'):
|
||||
@@ -55,3 +57,14 @@ 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)
|
||||
@@ -11,29 +11,34 @@
|
||||
<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="replace"/>
|
||||
<xpath expr="//page[@name='sales_purchases']//field[@name='ref']" position="attributes">
|
||||
<attribute name="invisible">1</attribute>
|
||||
</xpath>
|
||||
</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"/>
|
||||
<field name="ref" optional="hide"/>
|
||||
</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>
|
||||
@@ -6,8 +6,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 14.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-02-17 16:55+0000\n"
|
||||
"PO-Revision-Date: 2021-02-17 16:55+0000\n"
|
||||
"POT-Creation-Date: 2021-07-01 10:02+0000\n"
|
||||
"PO-Revision-Date: 2021-07-01 10:02+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -6,9 +6,9 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 14.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-02-17 16:55+0000\n"
|
||||
"PO-Revision-Date: 2021-02-17 16:55+0000\n"
|
||||
"Last-Translator: \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"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -33,16 +33,15 @@ msgstr "Sociétés"
|
||||
#. module: base_usability
|
||||
#: model:ir.model,name:base_usability.model_res_partner
|
||||
msgid "Contact"
|
||||
msgstr ""
|
||||
msgstr "Contact"
|
||||
|
||||
#. module: base_usability
|
||||
#: model_terms:ir.ui.view,arch_db:base_usability.res_country_search
|
||||
msgid "Currency"
|
||||
msgstr "Monnaie"
|
||||
msgstr "Devise"
|
||||
|
||||
#. 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 :"
|
||||
@@ -68,7 +67,7 @@ msgstr "E-mail :"
|
||||
#. module: base_usability
|
||||
#: model_terms:ir.ui.view,arch_db:base_usability.res_country_search
|
||||
msgid "Group By"
|
||||
msgstr ""
|
||||
msgstr "Grouper par"
|
||||
|
||||
#. module: base_usability
|
||||
#: model:ir.model.fields,field_description:base_usability.field_ir_mail_server__id
|
||||
@@ -79,12 +78,12 @@ msgstr ""
|
||||
#: 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 ""
|
||||
msgstr "ID"
|
||||
|
||||
#. module: base_usability
|
||||
#: model_terms:ir.ui.view,arch_db:base_usability.view_module_filter
|
||||
msgid "Installable"
|
||||
msgstr ""
|
||||
msgstr "Installable"
|
||||
|
||||
#. module: base_usability
|
||||
#: model:ir.model.fields,field_description:base_usability.field_ir_mail_server____last_update
|
||||
@@ -100,7 +99,7 @@ msgstr "Dernière modification le"
|
||||
#. module: base_usability
|
||||
#: model:ir.model,name:base_usability.model_ir_mail_server
|
||||
msgid "Mail Server"
|
||||
msgstr "Serveur d'email"
|
||||
msgstr "Serveur mail"
|
||||
|
||||
#. module: base_usability
|
||||
#: code:addons/base_usability/models/res_partner.py:0
|
||||
@@ -132,7 +131,7 @@ msgstr "Nom avec titre"
|
||||
#. module: base_usability
|
||||
#: model:res.groups,name:base_usability.group_nobody
|
||||
msgid "Nobody (used to hide native menus)"
|
||||
msgstr ""
|
||||
msgstr "Personne (utilisé pour cacher des entrées de menu natifs)"
|
||||
|
||||
#. module: base_usability
|
||||
#: model:ir.model,name:base_usability.model_res_partner_category
|
||||
@@ -152,7 +151,6 @@ 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 :"
|
||||
|
||||
@@ -4,4 +4,5 @@ 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
|
||||
|
||||
15
base_usability/models/ir_actions_report.py
Normal file
15
base_usability/models/ir_actions_report.py
Normal file
@@ -0,0 +1,15 @@
|
||||
# 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)
|
||||
@@ -8,25 +8,9 @@ from odoo import models, fields, api, _
|
||||
class ResPartner(models.Model):
|
||||
_inherit = 'res.partner'
|
||||
|
||||
# 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)
|
||||
# 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
|
||||
ref = fields.Char(copy=False)
|
||||
# For reports
|
||||
name_title = fields.Char(
|
||||
|
||||
@@ -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 string="Search Countries">
|
||||
<search>
|
||||
<field name="name" filter_domain="['|', ('name', 'ilike', self), ('code', '=', self)]" string="Name or Code"/>
|
||||
<field name="code"/>
|
||||
<field name="currency_id"/>
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
<xpath expr="//field[@name='child_ids']/form//field[@name='title']" position="attributes">
|
||||
<attribute name="attrs"></attribute>
|
||||
</xpath>
|
||||
<!-- Show double VAT partner even when not in editable mode -->
|
||||
<div attrs="{'invisible': [('same_vat_partner_id', '=', False)]}" position="attributes">
|
||||
<attribute name="class">alert alert-warning</attribute>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -35,6 +39,9 @@
|
||||
<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>
|
||||
|
||||
1
crm_usability/__init__.py
Normal file
1
crm_usability/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import models
|
||||
25
crm_usability/__manifest__.py
Normal file
25
crm_usability/__manifest__.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# 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,
|
||||
}
|
||||
1
crm_usability/models/__init__.py
Normal file
1
crm_usability/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import crm_lead
|
||||
13
crm_usability/models/crm_lead.py
Normal file
13
crm_usability/models/crm_lead.py
Normal file
@@ -0,0 +1,13 @@
|
||||
# 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)
|
||||
BIN
crm_usability/static/description/icon.png
Normal file
BIN
crm_usability/static/description/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.5 KiB |
22
crm_usability/views/crm_lead.xml
Normal file
22
crm_usability/views/crm_lead.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?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>
|
||||
@@ -1 +1 @@
|
||||
from . import stock
|
||||
from . import models
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Copyright 2018-2019 Akretion (http://www.akretion.com)
|
||||
# Copyright 2018-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': 'Delivery Usability',
|
||||
'version': '12.0.1.0.0',
|
||||
'version': '14.0.1.0.0',
|
||||
'category': 'Stock',
|
||||
'license': 'AGPL-3',
|
||||
'summary': 'Several usability enhancements in Delivery',
|
||||
@@ -14,7 +14,6 @@ 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>.
|
||||
""",
|
||||
@@ -22,8 +21,7 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
|
||||
'website': 'http://www.akretion.com',
|
||||
'depends': ['delivery'],
|
||||
'data': [
|
||||
'sale_view.xml',
|
||||
'stock_view.xml',
|
||||
'views/stock_picking.xml',
|
||||
],
|
||||
'installable': False,
|
||||
'installable': True,
|
||||
}
|
||||
|
||||
1
delivery_usability/models/__init__.py
Normal file
1
delivery_usability/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import stock_picking
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2018-2019 Akretion (http://www.akretion.com)
|
||||
# Copyright 2018-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).
|
||||
|
||||
@@ -8,5 +8,5 @@ from odoo import fields, models
|
||||
class StockPicking(models.Model):
|
||||
_inherit = 'stock.picking'
|
||||
|
||||
carrier_id = fields.Many2one(track_visibility='onchange')
|
||||
carrier_tracking_ref = fields.Char(track_visibility='onchange')
|
||||
carrier_id = fields.Many2one(tracking=True)
|
||||
carrier_tracking_ref = fields.Char(tracking=True)
|
||||
@@ -1,23 +0,0 @@
|
||||
<?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>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2018 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||
Copyright 2018-2021 Akretion France
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Copyright 2014-2019 Akretion France (http://www.akretion.com)
|
||||
# Copyright 2014-2021 Akretion France (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
|
||||
{
|
||||
'name': 'Eradicate Quick Create',
|
||||
'version': '12.0.2.0.0',
|
||||
'version': '14.0.1.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 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 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 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': False,
|
||||
'installable': True,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019 Akretion France
|
||||
# Copyright 2019-2021 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.value = 'False'
|
||||
config_parameter.write({'value': 'False'})
|
||||
else:
|
||||
env['ir.config_parameter'].create({
|
||||
'key': 'web_m2x_options.create',
|
||||
|
||||
1
hr_contract_usability/__init__.py
Normal file
1
hr_contract_usability/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import models
|
||||
20
hr_contract_usability/__manifest__.py
Normal file
20
hr_contract_usability/__manifest__.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# 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,
|
||||
}
|
||||
1
hr_contract_usability/models/__init__.py
Normal file
1
hr_contract_usability/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import hr_payroll_structure_type
|
||||
10
hr_contract_usability/models/hr_payroll_structure_type.py
Normal file
10
hr_contract_usability/models/hr_payroll_structure_type.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# 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)
|
||||
63
hr_contract_usability/views/hr_payroll_structure_type.xml
Normal file
63
hr_contract_usability/views/hr_payroll_structure_type.xml
Normal file
@@ -0,0 +1,63 @@
|
||||
<?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>
|
||||
27
link_tracker_usability/__manifest__.py
Normal file
27
link_tracker_usability/__manifest__.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# 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,
|
||||
}
|
||||
45
link_tracker_usability/views/link_tracker_click.xml
Normal file
45
link_tracker_usability/views/link_tracker_click.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?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>
|
||||
1
mail_usability/__init__.py
Normal file
1
mail_usability/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import models
|
||||
32
mail_usability/__manifest__.py
Normal file
32
mail_usability/__manifest__.py
Normal file
@@ -0,0 +1,32 @@
|
||||
# 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,
|
||||
}
|
||||
2
mail_usability/models/__init__.py
Normal file
2
mail_usability/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from . import res_partner
|
||||
from . import mail_template
|
||||
11
mail_usability/models/mail_template.py
Normal file
11
mail_usability/models/mail_template.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# 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)
|
||||
26
mail_usability/models/res_partner.py
Normal file
26
mail_usability/models/res_partner.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# 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)
|
||||
1
mass_mailing_usability/__init__.py
Normal file
1
mass_mailing_usability/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import models
|
||||
29
mass_mailing_usability/__manifest__.py
Normal file
29
mass_mailing_usability/__manifest__.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# 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,
|
||||
}
|
||||
48
mass_mailing_usability/views/link_tracker.xml
Normal file
48
mass_mailing_usability/views/link_tracker.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?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>
|
||||
@@ -12,16 +12,20 @@ class ProductTemplate(models.Model):
|
||||
only one BoM form or a list of BoMs."""
|
||||
self.ensure_one()
|
||||
if self.bom_count == 1:
|
||||
action = self.env.ref("mrp.mrp_bom_form_action").read()[0]
|
||||
action_xml_id = "mrp.mrp_bom_form_action"
|
||||
action = self.env["ir.actions.actions"]._for_xml_id(action_xml_id)
|
||||
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 = self.env.ref("mrp.template_open_bom").read()[0]
|
||||
action_xml_id = "mrp.template_open_bom"
|
||||
action = self.env["ir.actions.actions"]._for_xml_id(action_xml_id)
|
||||
return action
|
||||
|
||||
|
||||
@@ -32,9 +36,11 @@ 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
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# 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,
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<?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>
|
||||
@@ -28,7 +28,9 @@ 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,
|
||||
|
||||
31
pos_usability/views/pos_session.xml
Normal file
31
pos_usability/views/pos_session.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?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>
|
||||
26
pos_usability/views/report_pos_order.xml
Normal file
26
pos_usability/views/report_pos_order.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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>
|
||||
@@ -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_code"/>
|
||||
<field name="product_name" filter_domain="['|', ('product_code', 'ilike', self), ('product_name', 'ilike', self)]" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
185
purchase_usability/i18n/fr.po
Normal file
185
purchase_usability/i18n/fr.po
Normal file
@@ -0,0 +1,185 @@
|
||||
# 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"
|
||||
@@ -24,11 +24,6 @@ class PurchaseOrder(models.Model):
|
||||
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')
|
||||
def name_get(self):
|
||||
@@ -71,3 +66,10 @@ class PurchaseOrder(models.Model):
|
||||
# {'subtotal': 8932.23},
|
||||
# ]
|
||||
return res
|
||||
|
||||
|
||||
class PurchaseOrderLine(models.Model):
|
||||
_inherit = 'purchase.order.line'
|
||||
|
||||
# for optional display in tree view
|
||||
product_barcode = fields.Char(related='product_id.barcode', string="Product Barcode")
|
||||
|
||||
@@ -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="print_order" states="purchase" string="Print Order" type="object"/>
|
||||
<button name="%(purchase.action_report_purchase_order)d" states="purchase,done" string="Print" type="action"/>
|
||||
</button>
|
||||
<field name="fiscal_position_id" position="attributes">
|
||||
<attribute name="widget">selection</attribute>
|
||||
@@ -34,6 +34,9 @@
|
||||
<xpath expr="//field[@name='order_line']/form//field[@name='analytic_tag_ids']" position="attributes">
|
||||
<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_barcode" optional="hide"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
2
sale_confirm_wizard/__init__.py
Normal file
2
sale_confirm_wizard/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from . import models
|
||||
from . import wizard
|
||||
38
sale_confirm_wizard/__manifest__.py
Normal file
38
sale_confirm_wizard/__manifest__.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# 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,
|
||||
}
|
||||
1
sale_confirm_wizard/models/__init__.py
Normal file
1
sale_confirm_wizard/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import sale_order
|
||||
17
sale_confirm_wizard/models/sale_order.py
Normal file
17
sale_confirm_wizard/models/sale_order.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# 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
|
||||
2
sale_confirm_wizard/security/ir.model.access.csv
Normal file
2
sale_confirm_wizard/security/ir.model.access.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
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
|
||||
|
24
sale_confirm_wizard/views/sale_order.xml
Normal file
24
sale_confirm_wizard/views/sale_order.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?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>
|
||||
1
sale_confirm_wizard/wizard/__init__.py
Normal file
1
sale_confirm_wizard/wizard/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import sale_confirm
|
||||
78
sale_confirm_wizard/wizard/sale_confirm.py
Normal file
78
sale_confirm_wizard/wizard/sale_confirm.py
Normal file
@@ -0,0 +1,78 @@
|
||||
# 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).
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.addons.base.models.res_partner import WARNING_MESSAGE
|
||||
|
||||
|
||||
class SaleConfirm(models.TransientModel):
|
||||
_name = 'sale.confirm'
|
||||
_description = 'Wizard to confirm a sale order'
|
||||
|
||||
sale_id = fields.Many2one(
|
||||
'sale.order', string='Sale Order', readonly=True)
|
||||
client_order_ref = fields.Char(string='Customer PO Number')
|
||||
payment_term_id = fields.Many2one(
|
||||
'account.payment.term', string='Payment Terms')
|
||||
partner_invoice_id = fields.Many2one(
|
||||
'res.partner', 'Invoice Address', required=True)
|
||||
show_partner_invoice_id = fields.Many2one(
|
||||
related='partner_invoice_id',
|
||||
string='Detailed Invoice Address')
|
||||
partner_shipping_id = fields.Many2one(
|
||||
'res.partner', 'Delivery Address', required=True)
|
||||
show_partner_shipping_id = fields.Many2one(
|
||||
related='partner_shipping_id',
|
||||
string='Detailed Delivery Address')
|
||||
sale_warn = fields.Selection(
|
||||
WARNING_MESSAGE, 'Sale Warning Type', readonly=True)
|
||||
sale_warn_msg = fields.Text(string='Sale Warning Message', readonly=True)
|
||||
|
||||
@api.model
|
||||
def _prepare_default_get(self, order):
|
||||
partner = order.partner_id.commercial_partner_id
|
||||
default = {
|
||||
'sale_id': order.id,
|
||||
'client_order_ref': order.client_order_ref,
|
||||
'payment_term_id': order.payment_term_id.id or False,
|
||||
'partner_invoice_id': order.partner_invoice_id.id,
|
||||
'partner_shipping_id': order.partner_shipping_id.id,
|
||||
'sale_warn_msg': partner.sale_warn_msg,
|
||||
'sale_warn': partner.sale_warn,
|
||||
}
|
||||
return default
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
res = super().default_get(fields)
|
||||
assert self._context.get('active_model') == 'sale.order',\
|
||||
'active_model should be sale.order'
|
||||
order = self.env['sale.order'].browse(self._context.get('active_id'))
|
||||
default = self._prepare_default_get(order)
|
||||
res.update(default)
|
||||
return res
|
||||
|
||||
def _prepare_update_so(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'client_order_ref': self.client_order_ref,
|
||||
'payment_term_id': self.payment_term_id.id or False,
|
||||
'partner_invoice_id': self.partner_invoice_id.id,
|
||||
'partner_shipping_id': self.partner_shipping_id.id,
|
||||
}
|
||||
|
||||
def confirm(self):
|
||||
self.ensure_one()
|
||||
partner = self.sale_id.partner_id.commercial_partner_id
|
||||
if partner.sale_warn == 'block':
|
||||
raise UserError(_(
|
||||
"You cannot confirm this quotation because "
|
||||
"customer '%s' has a blocker sale warning:\n\n%s")
|
||||
% (partner.display_name, partner.sale_warn_msg))
|
||||
vals = self._prepare_update_so()
|
||||
self.sale_id.write(vals)
|
||||
# confirm sale order
|
||||
self.sale_id.action_confirm()
|
||||
return True
|
||||
54
sale_confirm_wizard/wizard/sale_confirm_view.xml
Normal file
54
sale_confirm_wizard/wizard/sale_confirm_view.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<?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="sale_confirm_form" model="ir.ui.view">
|
||||
<field name="name">sale.confirm.form</field>
|
||||
<field name="model">sale.confirm</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Confirm Order">
|
||||
<div><p>At this stage, you have received the Purchase Order from the customer and you are about to convert the related quotation to an order.</p></div>
|
||||
<group name="warn" groups="sale.group_warning_sale" attrs="{'invisible': ['|', ('sale_warn', '=', False), ('sale_warn', '=', 'no-message')]}" string="Warning" col="4">
|
||||
<field name="sale_warn" nolabel="1"/>
|
||||
<field name="sale_warn_msg" nolabel="1" colspan="3"/>
|
||||
</group>
|
||||
<group name="main" attrs="{'invisible': [('sale_warn', '=', 'block')]}">
|
||||
<field name="sale_id" invisible="1"/>
|
||||
<field name="client_order_ref"/>
|
||||
<field name="partner_invoice_id" context="{'default_type': 'invoice'}"
|
||||
groups="sale.group_delivery_invoice_address"/>
|
||||
<!-- partner_invoice_id can't show the full address because
|
||||
we are in edit mode -->
|
||||
<field name="show_partner_invoice_id" options="{'always_reload': True}"
|
||||
context="{'show_address': 1}"
|
||||
groups="sale.group_delivery_invoice_address"/>
|
||||
<field name="partner_shipping_id"
|
||||
context="{'default_type': 'delivery'}"
|
||||
groups="sale.group_delivery_invoice_address"/>
|
||||
<field name="show_partner_shipping_id" options="{'always_reload': True}"
|
||||
context="{'show_address': 1}"
|
||||
groups="sale.group_delivery_invoice_address"/>
|
||||
<field name="payment_term_id"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button type="object" name="confirm"
|
||||
string="Confirm Sale" class="btn-primary" attrs="{'invisible': [('sale_warn', '=', 'block')]}"/>
|
||||
<button special="cancel" string="Annuler" class="btn-default"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sale_confirm_action" model="ir.actions.act_window">
|
||||
<field name="name">Confirm Order</field>
|
||||
<field name="res_model">sale.confirm</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -1,3 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import models
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Copyright 2019 Akretion France (http://www.akretion.com/)
|
||||
# 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': 'Sale Order Route',
|
||||
'version': '12.0.1.0.0',
|
||||
'version': '14.0.1.0.0',
|
||||
'category': 'Sales',
|
||||
'license': 'AGPL-3',
|
||||
'summary': 'Set route on sale order',
|
||||
@@ -18,5 +18,5 @@ This module has been written by Alexis de Lattre from Akretion
|
||||
'website': 'http://www.akretion.com',
|
||||
'depends': ['sale_stock'],
|
||||
'data': ['views/sale_order.xml'],
|
||||
'installable': False,
|
||||
'installable': True,
|
||||
}
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import sale_order
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019 Akretion France (http://www.akretion.com/)
|
||||
# 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).
|
||||
|
||||
@@ -10,17 +10,17 @@ class SaleOrder(models.Model):
|
||||
|
||||
route_id = fields.Many2one(
|
||||
'stock.location.route', string='Route',
|
||||
ondelete='restrict', readonly=True, track_visibility='onchange',
|
||||
ondelete='restrict', readonly=True, tracking=True,
|
||||
states={'draft': [('readonly', False)], 'sent': [('readonly', False)]},
|
||||
domain=[('sale_selectable', '=', True)])
|
||||
check_company=True,
|
||||
domain="['|', ('company_id', '=', company_id), ('company_id', '=', False), ('sale_selectable', '=', True)]")
|
||||
|
||||
def _action_confirm(self):
|
||||
# Caution: take into account the scenario where
|
||||
# route_id has a value, then SO is cancelled+back to draft,
|
||||
# then route_id = False and SO is confirmed again
|
||||
# Takes into account the scenario where route_id has a value, then SO is
|
||||
# cancelled+back to draft, then route_id = False and SO is confirmed again
|
||||
for order in self:
|
||||
vals = {'route_id': order.route_id.id or False}
|
||||
order.order_line.filtered(
|
||||
lambda l:
|
||||
l.product_id.type in ('product', 'consu')).write(vals)
|
||||
super(SaleOrder, self)._action_confirm()
|
||||
l.product_id and l.product_id.type in ('product', 'consu')).write(vals)
|
||||
return super()._action_confirm()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2019 Akretion France (http://www.akretion.com/)
|
||||
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).
|
||||
-->
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
# Copyright 2015-2019 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 Purchase No Product Template Menu',
|
||||
'version': '12.0.1.0.0',
|
||||
'category': 'Sale and Purchase',
|
||||
'license': 'AGPL-3',
|
||||
'summary': "Replace product.template menu entries by product.product menu entries",
|
||||
'description': """
|
||||
Sale Purchase No Product Template
|
||||
=================================
|
||||
|
||||
This module replaces the menu entries for product.template by menu entries for product.product in the *Sales* and *Purchases* menu entries. With this module, the only menu entry for product.template is in the menu *Sales > Configuration > Product Categories and Attributes*.
|
||||
|
||||
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 Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
|
||||
""",
|
||||
'author': 'Akretion',
|
||||
'website': 'http://www.akretion.com',
|
||||
'depends': [
|
||||
'purchase',
|
||||
'sale',
|
||||
],
|
||||
'data': ['view.xml'],
|
||||
'installable': False,
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * sale_purchase_no_product_template_menu
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 8.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-30 15:27+0000\n"
|
||||
"PO-Revision-Date: 2016-05-30 15:27+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: sale_purchase_no_product_template_menu
|
||||
#: model:ir.ui.menu,name:sale_purchase_no_product_template_menu.sale_config_product_template_menu
|
||||
msgid "Product Templates"
|
||||
msgstr "Modèles d'article"
|
||||
|
||||
#. module: sale_purchase_no_product_template_menu
|
||||
#: model:ir.actions.act_window,name:sale_purchase_no_product_template_menu.product_product_action_puchased
|
||||
#: model:ir.actions.act_window,name:sale_purchase_no_product_template_menu.product_product_action_sell
|
||||
msgid "Products"
|
||||
msgstr "Articles"
|
||||
|
||||
#. module: sale_purchase_no_product_template_menu
|
||||
#: view:product.product:sale_purchase_no_product_template_menu.product_normal_form_view
|
||||
msgid "{'invisible': 1, 'required': 0}"
|
||||
msgstr "{'invisible': 1, 'required': 0}"
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * sale_purchase_no_product_template_menu
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 8.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2016-05-30 15:27+0000\n"
|
||||
"PO-Revision-Date: 2016-05-30 15:27+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: sale_purchase_no_product_template_menu
|
||||
#: model:ir.ui.menu,name:sale_purchase_no_product_template_menu.sale_config_product_template_menu
|
||||
msgid "Product Templates"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_purchase_no_product_template_menu
|
||||
#: model:ir.actions.act_window,name:sale_purchase_no_product_template_menu.product_product_action_puchased
|
||||
#: model:ir.actions.act_window,name:sale_purchase_no_product_template_menu.product_product_action_sell
|
||||
msgid "Products"
|
||||
msgstr ""
|
||||
|
||||
#. module: sale_purchase_no_product_template_menu
|
||||
#: view:product.product:sale_purchase_no_product_template_menu.product_normal_form_view
|
||||
msgid "{'invisible': 1, 'required': 0}"
|
||||
msgstr ""
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2015-2019 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>
|
||||
|
||||
<!-- PURCHASE -->
|
||||
<record id="product_product_action_purchased" model="ir.actions.act_window">
|
||||
<field name="name">Products</field>
|
||||
<field name="res_model">product.product</field>
|
||||
<field name="view_mode">tree,form,kanban</field>
|
||||
<field name="context">{'search_default_filter_to_purchase': 1}</field>
|
||||
<field name="search_view_id" eval="False"/> <!-- Force empty -->
|
||||
<field name="view_id" eval="False"/> <!-- Force empty -->
|
||||
</record>
|
||||
|
||||
<record id="purchase.menu_procurement_partner_contact_form" model="ir.ui.menu">
|
||||
<field name="action" ref="product_product_action_purchased"/>
|
||||
</record>
|
||||
|
||||
<!-- SALE -->
|
||||
<!-- I'd prefer to inherit product.product_normal_action_sell and
|
||||
change the "name" field, but it doesn't work with translation,
|
||||
so I redefine a new menu entry -->
|
||||
<record id="product_product_action_sell" model="ir.actions.act_window">
|
||||
<field name="name">Products</field>
|
||||
<field name="res_model">product.product</field>
|
||||
<field name="view_mode">tree,form,kanban</field>
|
||||
<field name="context">{'search_default_filter_to_sell': 1}</field>
|
||||
<field name="search_view_id" eval="False"/>
|
||||
<field name="view_id" ref="product.product_product_tree_view"/>
|
||||
<field name="search_view_id" ref="product.product_search_form_view"/>
|
||||
</record>
|
||||
|
||||
<!-- To keep good translations, we re-use the product.template menu
|
||||
entry and link it to product product -->
|
||||
<record id="sale.menu_product_template_action" model="ir.ui.menu">
|
||||
<!-- related action is "product.product_template_action" -->
|
||||
<field name="action" ref="product_product_action_sell"/>
|
||||
</record>
|
||||
|
||||
<record id="product.product_template_action" model="ir.actions.act_window">
|
||||
<field name="name">Product Templates</field> <!-- native value is "Products" -->
|
||||
<field name="view_mode">tree,form,kanban</field>
|
||||
<field name="view_id" eval="False"/>
|
||||
<field name="context">{}</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- Create a product template menu entry in configuration -->
|
||||
<menuitem id="sale_config_product_template_menu" action="product.product_template_action"
|
||||
parent="sale.prod_config_main"/>
|
||||
|
||||
|
||||
<record id="product.product_normal_action_sell" model="ir.actions.act_window">
|
||||
<field name="view_mode">tree,form,kanban</field>
|
||||
</record>
|
||||
|
||||
|
||||
</odoo>
|
||||
@@ -21,6 +21,9 @@ class SaleOrder(models.Model):
|
||||
fiscal_position_id = fields.Many2one(tracking=True)
|
||||
# for reports
|
||||
has_discount = fields.Boolean(compute='_compute_has_discount')
|
||||
has_attachment = fields.Boolean(
|
||||
compute='_compute_has_attachment',
|
||||
search='_search_has_attachment')
|
||||
|
||||
@api.depends('order_line.discount')
|
||||
def _compute_has_discount(self):
|
||||
@@ -34,6 +37,30 @@ class SaleOrder(models.Model):
|
||||
break
|
||||
order.has_discount = has_discount
|
||||
|
||||
def _compute_has_attachment(self):
|
||||
iao = self.env['ir.attachment']
|
||||
for order in self:
|
||||
if iao.search_count([
|
||||
('res_model', '=', 'sale.order'),
|
||||
('res_id', '=', order.id),
|
||||
('type', '=', 'binary'),
|
||||
('company_id', '=', order.company_id.id)]):
|
||||
order.has_attachment = True
|
||||
else:
|
||||
order.has_attachment = False
|
||||
|
||||
def _search_has_attachment(self, operator, value):
|
||||
att_order_ids = {}
|
||||
if operator == '=':
|
||||
search_res = self.env['ir.attachment'].search_read([
|
||||
('res_model', '=', 'sale.order'),
|
||||
('type', '=', 'binary'),
|
||||
('res_id', '!=', False)], ['res_id'])
|
||||
for att in search_res:
|
||||
att_order_ids[att['res_id']] = True
|
||||
res = [('id', value and 'in' or 'not in', list(att_order_ids))]
|
||||
return res
|
||||
|
||||
# for report
|
||||
def py3o_lines_layout(self):
|
||||
self.ensure_one()
|
||||
@@ -66,6 +93,10 @@ class SaleOrder(models.Model):
|
||||
class SaleOrderLine(models.Model):
|
||||
_inherit = 'sale.order.line'
|
||||
|
||||
# for optional display in tree view
|
||||
product_barcode = fields.Char(
|
||||
related='product_id.barcode', string="Product Barcode")
|
||||
|
||||
@api.onchange('product_uom', 'product_uom_qty')
|
||||
def product_uom_change(self):
|
||||
# When the user has manually set a custom price
|
||||
|
||||
@@ -7,24 +7,24 @@
|
||||
|
||||
<odoo>
|
||||
|
||||
<!--
|
||||
<record id="account_invoice_form" model="ir.ui.view">
|
||||
<field name="name">sale_usability.customer.invoice.form</field>
|
||||
<field name="model">account.invoice</field>
|
||||
<field name="inherit_id" ref="sale.account_invoice_form"/>
|
||||
<field name="model">account.move</field>
|
||||
<field name="inherit_id" ref="sale.account_invoice_form" />
|
||||
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_manager'))]" />
|
||||
<field name="arch" type="xml">
|
||||
<div name="button_box" position="inside">
|
||||
<button name="show_sale_orders"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-pencil-square-o"
|
||||
attrs="{'invisible': [('sale_count', '=', 0)]}">
|
||||
<field name="sale_count" widget="statinfo" string="Sale Orders"/>
|
||||
<button
|
||||
name="show_sale_orders"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-pencil-square-o"
|
||||
attrs="{'invisible': [('sale_count', '=', 0)]}">
|
||||
<field name="sale_count" widget="statinfo" string="Sale Orders" />
|
||||
</button>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
-->
|
||||
|
||||
<record id="view_move_form" model="ir.ui.view">
|
||||
<field name="name">sale_usability.account.move.form</field>
|
||||
|
||||
@@ -26,6 +26,12 @@
|
||||
<field name="date_order" position="after">
|
||||
<field name="client_order_ref"/>
|
||||
</field>
|
||||
<button name="action_quotation_send" states="sent,sale" position="after">
|
||||
<button name="%(sale.action_report_saleorder)d" type="action" string="Print" states="draft,sent,sale,done"/>
|
||||
</button>
|
||||
<xpath expr="//field[@name='order_line']/tree/field[@name='product_template_id']" position="after">
|
||||
<field name="product_barcode" optional="hide"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -62,6 +68,10 @@
|
||||
<filter name="order_month" position="after">
|
||||
<filter string="State" name="state_groupby" context="{'group_by': 'state'}"/>
|
||||
</filter>
|
||||
<filter name="activities_upcoming_all" position="after">
|
||||
<separator/>
|
||||
<filter name="no_attachment" string="Missing Attachment" domain="[('has_attachment', '=', False)]"/>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
1
sales_team_usability/__init__.py
Normal file
1
sales_team_usability/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import models
|
||||
27
sales_team_usability/__manifest__.py
Normal file
27
sales_team_usability/__manifest__.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# Copyright 2021 Akretion France (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': 'Sales Teams Usability',
|
||||
'version': '14.0.1.0.0',
|
||||
'category': 'Sales/Sales',
|
||||
'license': 'AGPL-3',
|
||||
'summary': 'Sales Teams usability enhancements',
|
||||
'description': """
|
||||
Sales Teams Usability
|
||||
=====================
|
||||
|
||||
The usability improvements include:
|
||||
|
||||
* set 'name' field of crm.tag un-translatable
|
||||
|
||||
This module has been written by Alexis de Lattre from Akretion
|
||||
<alexis.delattre@akretion.com>.
|
||||
""",
|
||||
'author': 'Akretion',
|
||||
'website': 'http://www.akretion.com',
|
||||
'depends': ['sales_team'],
|
||||
'data': [],
|
||||
'installable': True,
|
||||
}
|
||||
1
sales_team_usability/models/__init__.py
Normal file
1
sales_team_usability/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import crm_tag
|
||||
11
sales_team_usability/models/crm_tag.py
Normal file
11
sales_team_usability/models/crm_tag.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# Copyright 2021 Akretion France (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 CrmTag(models.Model):
|
||||
_inherit = "crm.tag"
|
||||
|
||||
name = fields.Char(translate=False)
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2019-2020 Akretion France (http://www.akretion.com)
|
||||
# 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).
|
||||
|
||||
@@ -15,14 +15,13 @@ Stock Account Usability
|
||||
|
||||
The usability enhancements include:
|
||||
|
||||
NONE
|
||||
- show to_refund on stock.move form view
|
||||
|
||||
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
|
||||
""",
|
||||
'author': 'Akretion',
|
||||
'website': 'http://www.akretion.com',
|
||||
'depends': ['stock_account'],
|
||||
'data': [
|
||||
],
|
||||
'installable': False,
|
||||
'depends': ['stock_account', 'stock_usability'],
|
||||
'data': ['views/stock_move.xml'],
|
||||
'installable': True,
|
||||
}
|
||||
|
||||
23
stock_account_usability/views/stock_move.xml
Normal file
23
stock_account_usability/views/stock_move.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?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_move_form" model="ir.ui.view">
|
||||
<field name="name">stock_account_usability.stock.move.form</field>
|
||||
<field name="model">stock.move</field>
|
||||
<field name="inherit_id" ref="stock_usability.view_move_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="price_unit" position="after">
|
||||
<field name="to_refund" readonly="1"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</odoo>
|
||||
@@ -1,2 +0,0 @@
|
||||
from . import stock_return_picking
|
||||
from . import stock_quantity_history
|
||||
1
stock_picking_type_default_partner/__init__.py
Normal file
1
stock_picking_type_default_partner/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import models
|
||||
25
stock_picking_type_default_partner/__manifest__.py
Normal file
25
stock_picking_type_default_partner/__manifest__.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# Copyright 2014-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': 'Stock Picking Type Default Partner',
|
||||
'version': '14.0.1.0.0',
|
||||
'category': 'Inventory, Logistics, Warehousing',
|
||||
'license': 'AGPL-3',
|
||||
'summary': 'Adds a default partner on types of operation',
|
||||
'description': """
|
||||
Stock Picking Type Default Partner
|
||||
==================================
|
||||
|
||||
This module adds a new field on the Types of Operation (stock.picking.type) : *Default Partner*. This is useful for multi-site companies that create inter-site Type of Operations: all the operations that use this Type of Operation should have the same destination partner.
|
||||
|
||||
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
|
||||
""",
|
||||
'author': 'Akretion',
|
||||
'website': 'http://www.akretion.com',
|
||||
'depends': ['stock'],
|
||||
'data': ['views/stock_picking_type.xml'],
|
||||
'installable': True,
|
||||
}
|
||||
1
stock_picking_type_default_partner/models/__init__.py
Normal file
1
stock_picking_type_default_partner/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import stock_picking
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user