Compare commits

...

65 Commits

Author SHA1 Message Date
clementmbr
c12b496004 account_usability: explicit error msg on unposted reconciliation 2022-03-08 19:21:02 -03:00
Alexis de Lattre
447b0107be account_usability: change the behavior of 'date' on in_invoice/in_refund when the 'invoice_date' is changed 2022-03-08 21:02:55 +01:00
Alexis de Lattre
f9a7983d71 account_usability: update move line search view for reconcile filters 2022-03-01 15:55:03 +01:00
David Beal
870746b965 UPD stk_no_prd_tmpl: make installable 2022-02-28 18:06:05 +01:00
Alexis de Lattre
f22c6522d5 Add industry_id in account.invoice.report 2022-02-23 00:22:54 +01:00
Alexis de Lattre
1ef97629b7 [FIX] account_usability: fix cash in computation of sale_dates 2022-02-22 00:59:48 +01:00
Alexis de Lattre
77a372b3ca account_usability: Add date in outstanding payment widget 2022-02-08 20:39:11 +01:00
Alexis de Lattre
221b090cc8 sale_usability: pivot view by default on sale.report 2022-02-08 07:54:50 +01:00
Raphaël Valyi
e4a2ff5bd4 Merge pull request #153 from akretion/14.0-web_tab_title
[14.0][ADD] web_tab_title
2022-01-26 10:51:31 -03:00
Alexis de Lattre
c1d334b109 account_usability: small code cleanup 2022-01-06 23:34:44 +01:00
Sébastien BEAU
c7c9b2d341 [IMP] add tracking on category 2022-01-04 17:21:46 +01:00
Alexis de Lattre
eddab6020a account_usability: improve view for analytic account and analytic account group 2021-12-31 00:33:48 +01:00
Alexis de Lattre
d1181ca91d account_usability: improve view of account.group
Add group by on group_id in search view of account.account
2021-12-31 00:21:42 +01:00
Alexis de Lattre
bb83765ee2 account_usability: default value for user_type_id on journal accounts 2021-12-19 17:28:03 +01:00
Alexis de Lattre
88615a0774 Add barcode_code128 on product.product 2021-12-19 12:58:22 +01:00
Alexis de Lattre
05e649fa86 account_usability: avoir error when user doesn't have admin rights 2021-12-18 21:40:32 +01:00
Alexis de Lattre
08118ec4f5 Add support for config param usability.line_name_no_product_code
The same ir.config_parameter is used in:
- purchase_usability for purchase.order.line
- sale_usability for sale.order.line
- account_usability for account.move.line
2021-12-03 22:24:59 +01:00
Alexis de Lattre
6d496ba302 Add static legal terms on company for invoice and sale
Add product_supplier_code on purchase.order.line
2021-12-03 17:27:03 +00:00
Kev-Roche
40b79890fe [FIX] stock_reception_usability 2021-12-01 14:31:24 +01:00
Kévin Roche
58b8d300b8 Merge pull request #160 from akretion/14.0_purchase_usability_French_traduction
[TRAD][14.0] French traduction purchase_usability
2021-11-30 15:35:25 +01:00
Kev-Roche
cdcf4eb406 [TRAD][14.0] French traduction purchase_usability 2021-11-30 15:32:37 +01:00
Kevin.roche
a22f79ef44 [ADD] stock_reception_usability 2021-11-29 13:24:24 +01:00
Alexis de Lattre
99dd4de4f7 stock_valuation_xlsx: first port to v14 without price history (when you ask for a past price, you get the current price for the moment) 2021-11-26 23:57:22 +01:00
Alexis de Lattre
f3d6b67043 [MIG] link_tracker_usability from v10 to v14
Prepare port of mass_mailing_usability... but no real port for the moment
2021-11-18 17:18:08 +01:00
Alexis de Lattre
1963af114b mass_mailing_usability: Fix dependencies 2021-11-18 16:51:13 +01:00
Alexis de Lattre
1da4c40927 Add module mass_mailing_usability
Improve module link_tracker_usability
2021-11-18 16:51:13 +01:00
Alexis de Lattre
edc9db5839 New module link_tracker_usability 2021-11-18 16:51:13 +01:00
Alexis de Lattre
882d068f1a [MIG] base_partner_ref from v12 to v14 2021-11-18 16:20:49 +01:00
Alexis de Lattre
878db1d0a1 [MIG] crm_usability from v10 to v14
New module sales_team_usability (remove translation on crm.tag, which
was in crm_usability in v10)
2021-11-18 10:43:53 +01:00
Alexis de Lattre
600acd2f26 Add multi-company ir.rule for crm.lead 2021-11-18 10:21:09 +01:00
Alexis de Lattre
059c3b4a09 Add groupby on partner on opportunity search view 2021-11-18 10:21:09 +01:00
David Beal
895e1d9dd0 FIX branding 2021-11-18 10:21:09 +01:00
Alexis de Lattre
0b3ffc804f translate=False on 'name' field of crm.lead.tag and res.partner.category 2021-11-18 10:21:09 +01:00
Alexis de Lattre
c0a03dbb0e Work on usability of CRM 2021-11-18 10:21:09 +01:00
David Beal
6e5f263283 IMP add icons 2021-11-18 10:21:09 +01:00
Raphaël Valyi
d4ebbb28d9 Merge pull request #150 from akretion/14.0-imp-moves-domain-picking-view
[IMP] StockMoves locations domain in picking view
2021-11-16 13:09:50 -03:00
Raphaël Valyi
7dd204e57e Merge pull request #148 from akretion/14.0-product-usability-filter-domain-supinfo
product_usability: Improve filter domain on supplier product name/reference
2021-11-16 12:34:55 -03:00
Alexis de Lattre
e1a84973da account_usability: FIX display of decimal precision of sale price in product form view 2021-11-12 12:37:42 +01:00
Alexis de Lattre
13e68ac0f5 Remove modules pos_no_product_template_menu and sale_purchase_no_product_template_menu
We won't port those modules to v14
2021-11-04 12:37:34 +01:00
Alexis de Lattre
3b17c2e5fb Improve register payment wizard view 2021-11-04 11:16:24 +01:00
Alexis de Lattre
0be112dc84 Improve pos_usability
Fix FR translation of base_partner_one2many_phone to avoid a crash when loading the FR translation
2021-10-30 00:40:33 +02:00
Raphaël Valyi
ce2255623d [ADD] web_tab_title 2021-10-26 22:06:48 -03:00
Kevin.roche
2854d4fdda [IMP] sale_usability: access to sale orders from invoice view 2021-10-21 22:51:08 +02:00
Alexis de Lattre
6c51a92acc account_usability: delete invoice PDF attachment when putting a customer invoice/refund back to draft
This feature was native up to v12, but was forgotten in the invoice/move merge of v13
2021-10-21 22:48:51 +02:00
Alexis de Lattre
f3910ab528 account_usability: remove field default_move_line_name which we don't use any more 2021-10-20 23:29:04 +02:00
clementmbr
05374c4b4a [FIX] mrp_usability: button action for BoMs needs _for_xml_id()
Avoiding blocking access for users without Admin rigts
2021-10-11 22:16:59 +02:00
clementmbr
279dc7c6c0 [IMP] add domain on origin and destination location for stock.moves in picking view 2021-10-06 14:43:15 +02:00
Alexis de Lattre
f6ddbb48ac [MIG] stock_picking_type_default_partner from v10 to v14 2021-10-01 21:21:31 +02:00
Alexis de Lattre
d3bddf5fda Port stock_picking_type_default_partner to v10 2021-10-01 21:13:11 +02:00
Alexis de Lattre
6f3a468a7c Mass rename from __openerp__.py to __manifest__.py 2021-10-01 21:13:11 +02:00
Alexis de Lattre
0bfa960153 Set all modules as uninstallable 2021-10-01 21:13:11 +02:00
Alexis de Lattre
a520ccff51 Add module stock_picking_type_default_partner 2021-10-01 21:13:11 +02:00
Alexis de Lattre
fa7611eb08 Push missing file 2021-10-01 21:11:30 +02:00
Alexis de Lattre
b2eda2a23b [MIG] sale_confirm_wizard from v10 to v14 2021-10-01 21:10:54 +02:00
Alexis de Lattre
74ff1b5cb5 sale_confirm_wizard: add ability to skip wizard via inherit in some scenarios 2021-10-01 20:52:44 +02:00
Alexis de Lattre
a7b4ed65eb sale_confirm_wizard: don't show main block when sale_warn = block 2021-10-01 20:52:44 +02:00
Alexis de Lattre
7dfb32c2d6 sale_confirm_warning: add sale_warn 2021-10-01 20:52:44 +02:00
Alexis de Lattre
d081bb0fd2 Add module sale_force_invoice_status 2021-10-01 20:52:44 +02:00
Alexis de Lattre
f3fdbec140 Add module sale_confirm_wizard 2021-10-01 20:52:44 +02:00
Alexis de Lattre
ac54c5cc75 Register payment on account.move form view is not highlighted any more 2021-09-30 20:37:00 +02:00
Alexis de Lattre
78c11411c3 Add filter on inventory lines
Always show field prefill_counted_quantity on inventory form
2021-09-26 22:49:24 +02:00
Alexis de Lattre
28ce11b216 stock.inventory improvement 2021-09-26 20:10:58 +02:00
Alexis de Lattre
00e034dacf Show invoice_origin on move form 2021-09-22 14:56:40 +02:00
Alexis de Lattre
8510b9518a Add module hr_contract_usability 2021-09-14 23:45:05 +02:00
Alexis de Lattre
15ef5df155 account_usability: add account_type in res.partner.bank tree view embedded in partner form view 2021-09-09 18:06:56 +00:00
117 changed files with 2625 additions and 492 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -14,16 +14,26 @@
<field name="arch" type="xml">
<tree string="Invoices Analysis">
<field name="move_id"/>
<field name="journal_id" optional="hide"/>
<field name="company_id" optional="hide" groups="base.group_multi_company"/>
<field name="invoice_date"/>
<field name="invoice_date_due"/>
<field name="move_type"/>
<field name="commercial_partner_id"/>
<field name="partner_id" optional="hide"/>
<field name="country_id" optional="hide"/>
<field name="industry_id" optional="hide"/>
<field name="invoice_user_id"/>
<field name="fiscal_position_id" optional="hide"/>
<field name="product_id"/>
<field name="product_categ_id" optional="hide"/>
<field name="account_id" optional="hide"/>
<field name="analytic_account_id" optional="hide" groups="analytic.group_analytic_accounting"/>
<field name="quantity" sum="1"/>
<field name="product_uom_id" groups="uom.group_uom"/>
<field name="price_subtotal" sum="1"/>
<field name="state"/>
<field name="payment_state" optional="hide"/>
</tree>
</field>
</record>

View File

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

View File

@@ -18,6 +18,9 @@
<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>
@@ -26,6 +29,9 @@
</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>
@@ -82,10 +88,11 @@
<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 name="reconciled" string="Fully Reconciled" domain="[('reconciled', '=', True)]"/>
</filter>
<filter name="unreconciled" position="attributes">
<attribute name="string">Unreconciled or Partially Reconciled</attribute>
<attribute name="domain">[('reconciled', '=', False), ('balance', '!=', 0), ('account_id.reconcile', '=', True)]</attribute>
</filter>
<!--
<field name="name" position="attributes">

View File

@@ -27,7 +27,7 @@ Here, we set all those fields on account.group_account_invoice
</field>
<field name="list_price" position="replace">
<div name="list_price">
<field name="list_price" widget='monetary' options="{'currency_field': 'currency_id'}" 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>

View File

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

View File

@@ -16,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>

View 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>

View File

@@ -1,14 +1,14 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * base_partner_one2many_phone
# * base_partner_one2many_phone
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 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 ""

View File

@@ -1,14 +1,14 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * base_partner_one2many_phone
# * base_partner_one2many_phone
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 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"

View File

@@ -14,7 +14,7 @@
<field name="name">res.partner.phone.tree</field>
<field name="model">res.partner.phone</field>
<field name="arch" type="xml">
<tree 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">

View File

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

View File

@@ -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,
}

View File

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

View File

@@ -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
@@ -32,12 +32,13 @@ class ResPartner(models.Model):
# 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'):
@@ -63,5 +65,6 @@ class ResPartner(models.Model):
if name and operator == 'ilike':
recs = self.search([('ref', '=', name)] + args, limit=limit)
if recs:
return recs.name_get()
rec_childs = self.search([('id', 'child_of', recs.ids)])
return rec_childs.name_get()
return super().name_search(name=name, args=args, operator=operator, limit=limit)

View File

@@ -11,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>

View File

@@ -39,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>

View File

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

View 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,
}

View File

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

View 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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View 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>

View File

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

View File

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

View 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,
}

View File

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

View 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)

View 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>

View 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,
}

View 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>

View File

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

View 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,
}

View 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>

View File

@@ -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

View File

@@ -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,
}

View File

@@ -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>

View File

@@ -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,

View 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>

View 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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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"

View File

@@ -73,3 +73,28 @@ class PurchaseOrderLine(models.Model):
# for optional display in tree view
product_barcode = fields.Char(related='product_id.barcode', string="Product Barcode")
product_supplier_code = fields.Char(
compute='_compute_product_supplier_code', string='Vendor Product Code')
def _compute_product_supplier_code(self):
for line in self:
code = False
if not line.display_type and line.product_id and line.order_id:
partner_id = line.order_id.partner_id.commercial_partner_id.id
if partner_id:
for supplier_info in line.product_id.seller_ids:
if supplier_info.name.id == partner_id:
code = supplier_info.product_code
break
line.product_supplier_code = code
def _get_product_purchase_description(self, product_lang):
# This is useful when you want to have the product code in a dedicated
# column in your purchase order report
# The same ir.config_parameter is used in sale_usability,
# purchase_usability and account_usability
no_product_code_param = self.env['ir.config_parameter'].sudo().get_param(
'usability.line_name_no_product_code')
if no_product_code_param and no_product_code_param == 'True':
product_lang = product_lang.with_context(display_default_code=False)
return super()._get_product_purchase_description(product_lang)

View File

@@ -35,6 +35,7 @@
<attribute name="groups">analytic.group_analytic_tags</attribute>
</xpath>
<xpath expr="//field[@name='order_line']/tree//field[@name='product_id']" position="after">
<field name="product_supplier_code" optional="hide"/>
<field name="product_barcode" optional="hide"/>
</xpath>
</field>

View File

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

View 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,
}

View File

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

View 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

View 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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sale_confirm_wizard Full access on sale.confirm wizard model_sale_confirm sales_team.group_sale_salesman 1 1 1 1

View File

@@ -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>

View File

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

View 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

View 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>

View File

@@ -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,
}

View File

@@ -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}"

View File

@@ -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 ""

View File

@@ -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>

View File

@@ -12,6 +12,7 @@
'website': 'http://www.akretion.com',
'depends': [
'sale',
'account_usability', # for company view
'base_view_inheritance_extension',
],
'data': [
@@ -20,6 +21,7 @@
'views/sale_report.xml',
'views/product_pricelist_item.xml',
'views/account_move.xml',
'views/res_company.xml',
],
'installable': True,
}

View File

@@ -2,3 +2,4 @@ from . import sale_order
from . import account_move
from . import product_template
from . import res_partner
from . import res_company

View File

@@ -0,0 +1,13 @@
# Copyright 2021 Akretion France (https://akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ResCompany(models.Model):
_inherit = 'res.company'
# Similar to the field static_invoice_terms in account_usability
static_sale_terms = fields.Text(
translate=True, string="Legal Terms on Quotation")

View File

@@ -124,3 +124,14 @@ class SaleOrderLine(models.Model):
self.env, new_price, currency_obj=pricelist.currency_id))
}
return res
def get_sale_order_line_multiline_description_sale(self, product):
# This is useful when you want to have the product code in a dedicated
# column in your sale order report
# The same ir.config_parameter is used in sale_usability,
# purchase_usability and account_usability
no_product_code_param = self.env['ir.config_parameter'].sudo().get_param(
'usability.line_name_no_product_code')
if no_product_code_param and no_product_code_param == 'True':
product = product.with_context(display_default_code=False)
return super().get_sale_order_line_multiline_description_sale(product)

View File

@@ -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>

View File

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

View File

@@ -54,4 +54,9 @@
</field>
</record>
<record id="sale.action_order_report_all" model="ir.actions.act_window">
<!-- native order is graph,pivot -->
<field name="view_mode">pivot,graph</field>
</record>
</odoo>

View File

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

View 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,
}

View File

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

View 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)

View File

@@ -22,5 +22,5 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
'website': 'http://www.akretion.com',
'depends': ['stock'],
'data': ['view.xml'],
'installable': False,
'installable': True,
}

View File

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

View 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,
}

View File

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

View File

@@ -0,0 +1,31 @@
# 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).
from odoo import models, fields, api
class StockPickingType(models.Model):
_inherit = 'stock.picking.type'
default_partner_id = fields.Many2one(
'res.partner', string='Default Partner', ondelete='restrict',
help="If set, it will be the default partner on this type of "
"pickings.")
class StockPicking(models.Model):
_inherit = 'stock.picking'
@api.model
def _default_partner_id(self):
if self._context.get('default_picking_type_id'):
picktype = self.env['stock.picking.type'].browse(
self._context.get('default_picking_type_id'))
if picktype.default_partner_id:
return picktype.default_partner_id
return False
partner_id = fields.Many2one(
default=lambda self: self._default_partner_id())

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015-2021 Akretion (http://www.akretion.com/)
@author Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_picking_type_form" model="ir.ui.view">
<field name="name">default.partner.stock.picking.type.form</field>
<field name="model">stock.picking.type</field>
<field name="inherit_id" ref="stock.view_picking_type_form"/>
<field name="arch" type="xml">
<field name="default_location_dest_id" position="after">
<field name="default_partner_id"/>
</field>
</field>
</record>
</odoo>

View File

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

View File

@@ -0,0 +1,24 @@
# Copyright 2021 Akretion (https://www.akretion.com).
# @author Kévin Roche <kevin.roche@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Stock relation usability",
"summary": "SUMMARY",
"version": "14.0.1.0.0",
"category": "Inventory, Logistic, Storage",
"website": "http://www.akretion.com",
"author": "Akretion",
"license": "AGPL-3",
"application": False,
"installable": True,
"depends": [
"stock",
"purchase",
],
"data": [
"views/stock_picking.xml",
],
"demo": [],
"qweb": [],
}

View File

@@ -0,0 +1,2 @@
from . import stock_move

View File

@@ -0,0 +1,36 @@
# Copyright (C) 2021 Akretion (<http://www.akretion.com>).
# @author Kévin Roche <kevin.roche@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class StockMove(models.Model):
_inherit = "stock.move"
location_dest_list = fields.Text(
string="Locations", compute="_compute_locations_dest_list"
)
@api.depends(
"move_line_ids", "move_line_ids.location_dest_id", "move_line_ids.qty_done"
)
def _compute_locations_dest_list(self):
for move in self:
data = []
separator = ", "
dest_list = move.move_line_ids.location_dest_id
for dest in dest_list:
lines_qty = move.move_line_ids.search(
[("move_id", "=", move.id), ("location_dest_id", "=", dest.id)]
).mapped("qty_done")
quantity = int(sum(lines_qty))
location = dest.name
data.append("{}: {}".format(quantity, location))
move.location_dest_list = separator.join(data)
def _compute_is_quantity_done_editable(self):
super()._compute_is_quantity_done_editable()
for move in self:
if len(move.move_line_ids) == 1 and move.show_details_visible:
move.is_quantity_done_editable = True

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_picking_form" model="ir.ui.view">
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='product_uom']" position="after">
<field name="location_dest_list" />
</xpath>
<xpath expr="//field[@name='product_uom_qty']" position="attributes">
<attribute
name="attrs"
>{'column_invisible': [('parent.state', '=', 'done')]}</attribute>
</xpath>
</field>
</record>
</odoo>

View File

@@ -2,10 +2,44 @@
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo import api, fields, models, _
from odoo.tools import float_compare, float_is_zero
class StockInventory(models.Model):
_inherit = 'stock.inventory'
prefill_counted_quantity = fields.Selection(
readonly=True, states={'draft': [('readonly', False)]})
class StockInventoryLine(models.Model):
_inherit = 'stock.inventory.line'
product_barcode = fields.Char(related='product_id.barcode', string="Product Barcode")
difference_qty = fields.Float(search="_search_difference_qty_usability")
def _search_difference_qty_usability(self, operator, value):
# Inspired by the method _search_difference_qty() from the
# official stock module
# So a part of this code is copyright Odoo SA under LGPL licence
if not self.env.context.get('default_inventory_id'):
raise NotImplementedError(_('Unsupported search on %s outside of an Inventory Adjustment', 'difference_qty'))
lines = self.search([('inventory_id', '=', self.env.context.get('default_inventory_id'))])
line_ids = []
for line in lines:
if operator == '=':
if float_is_zero(line.difference_qty, line.product_id.uom_id.rounding):
line_ids.append(line.id)
elif operator == '!=':
if not float_is_zero(line.difference_qty, line.product_id.uom_id.rounding):
line_ids.append(line.id)
elif operator == '>':
if float_compare(line.difference_qty, 0, line.product_id.uom_id.rounding) > 0:
line_ids.append(line.id)
elif operator == '<':
if float_compare(line.difference_qty, 0, line.product_id.uom_id.rounding) < 0:
line_ids.append(line.id)
else:
raise NotImplementedError()
return [('id', 'in', line_ids)]

View File

@@ -7,6 +7,20 @@
<odoo>
<record id="view_inventory_form" model="ir.ui.view">
<field name="name">usability.stock.inventory.form</field>
<field name="model">stock.inventory</field>
<field name="inherit_id" ref="stock.view_inventory_form"/>
<field name="arch" type="xml">
<button name="action_open_inventory_lines" states="confirm" position="after">
<button name="action_open_inventory_lines" states="done" string="Show Inventory Lines" type="object"/>
</button>
<field name="prefill_counted_quantity" position="attributes">
<attribute name="attrs">{}</attribute>
</field>
</field>
</record>
<record id="stock_inventory_line_tree" model="ir.ui.view">
<field name="name">usability.stock.inventory.line.tree</field>
<field name="model">stock.inventory.line</field>
@@ -30,4 +44,25 @@
</field>
</record>
<record id="stock_inventory_line_search" model="ir.ui.view">
<field name="name">usability.stock.inventory.line.search</field>
<field name="model">stock.inventory.line</field>
<field name="inherit_id" ref="stock.stock_inventory_line_search"/>
<field name="arch" type="xml">
<field name="product_id" position="after">
<field name="categ_id"/>
</field>
<filter name="difference" position="after">
<filter string="Difference = 0"
name="counted_equal" domain="[('difference_qty', '=', 0)]"/>
<filter string="Counted lower than Theoretical"
name="counted_lower" domain="[('difference_qty', '&lt;', 0)]"/>
<filter string="Counted higher than Theoretical"
name="counted_higher" domain="[('difference_qty', '&gt;', 0)]"/>
<separator/>
<filter string="Counted" name="counted" domain="[('product_qty', '>', 0)]"/>
</filter>
</field>
</record>
</odoo>

View File

@@ -34,8 +34,8 @@
<xpath expr="//field[@name='move_ids_without_package']/tree/field[@name='product_id']" position="after">
<field name="product_barcode" optional="hide"/>
<field name="name" optional="hide"/>
<field name="location_id" groups="stock.group_stock_multi_locations" optional="show"/>
<field name="location_dest_id" groups="stock.group_stock_multi_locations" optional="show"/>
<field name="location_id" groups="stock.group_stock_multi_locations" optional="show" domain="[('id', 'child_of', 'parent.location_id')]" options="{'no_create': True}"/>
<field name="location_dest_id" groups="stock.group_stock_multi_locations" optional="show" domain="[('id', 'child_of', 'parent.location_dest_id')]" options="{'no_create': True}"/>
</xpath>
<xpath expr="//field[@name='move_ids_without_package']/tree/button[@name='action_assign_serial']" position="after">
<button type="object" name="button_do_unreserve" string="Unreserve"
@@ -56,7 +56,7 @@
</field>
</field>
</record>
<record id="view_picking_internal_search" model="ir.ui.view">
<field name="name">stock_usability.view_picking_search</field>
<field name="model">stock.picking</field>

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