Compare commits

...

24 Commits

Author SHA1 Message Date
Kevin Khao
df673718e5 [14.0][ADD] shopinvader_usability 2021-12-27 16:30:11 +03: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
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
45500f5bd8 product_usability: Improve filter domain on supplier product names 2021-09-03 15:25:55 +02:00
50 changed files with 770 additions and 397 deletions

View File

@@ -31,6 +31,7 @@
'views/account_report.xml',
'wizard/account_invoice_mark_sent_view.xml',
'wizard/account_group_generate_view.xml',
'wizard/account_payment_register_views.xml',
'security/ir.model.access.csv',
],
'installable': True,

View File

@@ -11,8 +11,6 @@ from odoo.osv import expression
class AccountMove(models.Model):
_inherit = 'account.move'
default_move_line_name = fields.Char(
string='Default Label', states={'posted': [('readonly', True)]})
# By default, we can still modify "ref" when account move is posted
# which seems a bit lazy for me...
ref = fields.Char(states={'posted': [('readonly', True)]})
@@ -180,6 +178,35 @@ 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')
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'

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

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

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

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

@@ -0,0 +1,18 @@
# Copyright 2021 Akretion
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Shopinvader Usability",
"description": """
Shopinvader Usability""",
"version": "14.0.1.0.0",
"license": "AGPL-3",
"author": "Akretion",
"website": "https://github.com/OCA/odoo-usability",
"depends": [
"shopinvader",
"sale_usability",
],
"data": ["views/sale_views.xml"],
"auto_install": True,
}

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2021 Akretion
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="sale.action_quotations" model="ir.actions.act_window">
<field
name="domain"
>['&amp;', ('state', 'in', ('draft', 'sent', 'cancel')), ('typology', '=', 'sale')]</field>
</record>
<record id="sale.action_quotations_with_onboarding" model="ir.actions.act_window">
<field
name="domain"
>['&amp;', ('state', 'in', ('draft', 'sent', 'cancel')), ('typology', '=', 'sale')]</field>
</record>
<record id="sale.action_quotations_salesteams" model="ir.actions.act_window">
<field
name="domain"
>['&amp;', ('state', 'in', ('draft', 'sent', 'cancel')), ('typology', '=', 'sale')]</field>
</record>
</odoo>

View File

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

View File

@@ -5,7 +5,7 @@
{
'name': 'Stock Valuation XLSX',
'version': '12.0.1.0.0',
'version': '14.0.1.0.0',
'category': 'Tools',
'license': 'AGPL-3',
'summary': 'Generate XLSX reports for past or present stock levels',
@@ -37,8 +37,11 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
'website': 'http://www.akretion.com',
'depends': ['stock_account'],
'data': [
'security/ir.model.access.csv',
'wizard/stock_valuation_xlsx_view.xml',
'wizard/stock_variation_xlsx_view.xml',
'views/stock_inventory.xml',
'views/stock_expiry_depreciation_rule.xml',
],
'installable': False,
'installable': True,
}

View File

@@ -16,7 +16,7 @@
<button name="action_validate" position="after">
<button name="%(stock_valuation_xlsx_action)d" type="action"
states="done" string="XLSX Valuation Report"
context="{'default_source': 'inventory', 'default_inventory_id': active_id, 'default_location_id': location_id}"/>
context="{'default_source': 'inventory', 'default_inventory_id': active_id}"/>
</button>
</field>
</record>

View File

@@ -1 +1,2 @@
from . import stock_valuation_xlsx
from . import stock_variation_xlsx

View File

@@ -4,6 +4,7 @@
from odoo import models, fields, api, _
from odoo.exceptions import UserError
from dateutil.relativedelta import relativedelta
from odoo.tools import float_is_zero, float_round
from io import BytesIO
from datetime import datetime
@@ -18,7 +19,7 @@ class StockValuationXlsx(models.TransientModel):
_name = 'stock.valuation.xlsx'
_description = 'Generate XLSX report for stock valuation'
export_file = fields.Binary(string='XLSX Report', readonly=True)
export_file = fields.Binary(string='XLSX Report', readonly=True, attachment=True)
export_filename = fields.Char(readonly=True)
# I don't use ir.actions.url on v12, because it renders
# the wizard unusable after the first report generation, which creates
@@ -38,8 +39,10 @@ class StockValuationXlsx(models.TransientModel):
help="The childen locations of the selected locations will "
u"be taken in the valuation.")
categ_ids = fields.Many2many(
'product.category', string='Product Categories',
states={'done': [('readonly', True)]})
'product.category', string='Product Category Filter',
help="Leave this field empty to have a stock valuation for all your products.",
states={'done': [('readonly', True)]},
)
source = fields.Selection([
('inventory', 'Physical Inventory'),
('stock', 'Stock Levels'),
@@ -59,17 +62,33 @@ class StockValuationXlsx(models.TransientModel):
categ_subtotal = fields.Boolean(
string='Subtotals per Categories', default=True,
states={'done': [('readonly', True)]},
help="Show a subtotal per product category")
help="Show a subtotal per product category.")
standard_price_date = fields.Selection([
('past', 'Past Date or Inventory Date'),
('present', 'Current'),
], default='past', string='Cost Price Date',
states={'done': [('readonly', True)]})
# I can't put a compute field for has_expiry_date
# because I want to have the value when the wizard is started,
# and not wait until run
has_expiry_date = fields.Boolean(
default=lambda self: self._default_has_expiry_date(), readonly=True)
apply_depreciation = fields.Boolean(
string='Apply Depreciation Rules', default=True,
states={'done': [('readonly', True)]})
split_by_lot = fields.Boolean(
string='Display Lots', states={'done': [('readonly', True)]})
split_by_location = fields.Boolean(
string='Display Stock Locations', states={'done': [('readonly', True)]})
@api.model
def _default_has_expiry_date(self):
splo = self.env['stock.production.lot']
has_expiry_date = False
if hasattr(splo, 'expiry_date'):
has_expiry_date = True
return has_expiry_date
@api.model
def _default_location(self):
wh = self.env.ref('stock.warehouse0')
@@ -123,6 +142,17 @@ class StockValuationXlsx(models.TransientModel):
def _prepare_product_fields(self):
return ['uom_id', 'name', 'default_code', 'categ_id']
def _prepare_expiry_depreciation_rules(self, company_id, past_date):
rules = self.env['stock.expiry.depreciation.rule'].search_read([('company_id', '=', company_id)], ['start_limit_days', 'ratio'], order='start_limit_days desc')
if past_date:
date_dt = past_date
else:
date_dt = fields.Date.context_today(self)
for rule in rules:
rule['start_date'] = date_dt - relativedelta(days=rule['start_limit_days'])
logger.debug('depreciation_rules=%s', rules)
return rules
def compute_product_data(
self, company_id, in_stock_product_ids, standard_price_past_date=False):
self.ensure_one()
@@ -156,38 +186,56 @@ class StockValuationXlsx(models.TransientModel):
logger.debug('End compute_product_data')
return product_id2data
def id2name(self, product_ids):
logger.debug('Start id2name')
@api.model
def product_categ_id2name(self, categories):
pco = self.env['product.category']
splo = self.env['stock.production.lot']
slo = self.env['stock.location'].with_context(active_test=False)
puo = self.env['uom.uom'].with_context(active_test=False)
categ_id2name = {}
categ_domain = []
if self.categ_ids:
categ_domain = [('id', 'child_of', self.categ_ids.ids)]
if categories:
categ_domain = [('id', 'child_of', categories.ids)]
for categ in pco.search_read(categ_domain, ['display_name']):
categ_id2name[categ['id']] = categ['display_name']
return categ_id2name
@api.model
def uom_id2name(self):
puo = self.env['uom.uom'].with_context(active_test=False)
uom_id2name = {}
uoms = puo.search_read([], ['name'])
for uom in uoms:
uom_id2name[uom['id']] = uom['name']
return uom_id2name
@api.model
def prodlot_id2data(self, product_ids, has_expiry_date, depreciation_rules):
splo = self.env['stock.production.lot']
lot_id2data = {}
lot_fields = ['name']
if hasattr(splo, 'expiry_date'):
if has_expiry_date:
lot_fields.append('expiry_date')
lots = splo.search_read(
[('product_id', 'in', product_ids)], lot_fields)
for lot in lots:
lot_id2data[lot['id']] = lot
lot_id2data[lot['id']]['depreciation_ratio'] = 0
if depreciation_rules and lot.get('expiry_date'):
expiry_date = lot['expiry_date']
for rule in depreciation_rules:
if expiry_date <= rule['start_date']:
lot_id2data[lot['id']]['depreciation_ratio'] = rule['ratio'] / 100.0
break
return lot_id2data
@api.model
def stock_location_id2name(self, location):
slo = self.env['stock.location'].with_context(active_test=False)
loc_id2name = {}
locs = slo.search_read(
[('id', 'child_of', self.location_id.id)], ['display_name'])
for loc in locs:
loc_id2name[loc['id']] = loc['display_name']
logger.debug('End id2name')
return categ_id2name, uom_id2name, lot_id2data, loc_id2name
return loc_id2name
def compute_data_from_inventory(self, product_ids, prec_qty):
self.ensure_one()
@@ -275,7 +323,7 @@ class StockValuationXlsx(models.TransientModel):
def stringify_and_sort_result(
self, product_ids, product_id2data, data,
prec_qty, prec_price, prec_cur_rounding, categ_id2name,
uom_id2name, lot_id2data, loc_id2name):
uom_id2name, lot_id2data, loc_id2name, apply_depreciation):
logger.debug('Start stringify_and_sort_result')
res = []
for l in data:
@@ -284,17 +332,27 @@ class StockValuationXlsx(models.TransientModel):
standard_price = float_round(
product_id2data[product_id]['standard_price'],
precision_digits=prec_price)
subtotal = float_round(
subtotal_before_depreciation = float_round(
standard_price * qty, precision_rounding=prec_cur_rounding)
depreciation_ratio = 0
if apply_depreciation and l['lot_id']:
depreciation_ratio = lot_id2data[l['lot_id']].get('depreciation_ratio', 0)
subtotal = float_round(
subtotal_before_depreciation * (1 - depreciation_ratio),
precision_rounding=prec_cur_rounding)
else:
subtotal = subtotal_before_depreciation
res.append(dict(
product_id2data[product_id],
product_name=product_id2data[product_id]['name'],
loc_name=l['location_id'] and loc_id2name[l['location_id']] or '',
lot_name=l['lot_id'] and lot_id2data[l['lot_id']]['name'] or '',
expiry_date=l['lot_id'] and lot_id2data[l['lot_id']].get('expiry_date'),
depreciation_ratio=depreciation_ratio,
qty=qty,
uom_name=uom_id2name[product_id2data[product_id]['uom_id']],
standard_price=standard_price,
subtotal_before_depreciation=subtotal_before_depreciation,
subtotal=subtotal,
categ_name=categ_id2name[product_id2data[product_id]['categ_id']],
))
@@ -313,6 +371,12 @@ class StockValuationXlsx(models.TransientModel):
prec_cur_rounding = company.currency_id.rounding
self._check_config(company_id)
apply_depreciation = self.apply_depreciation
if (
(self.source == 'stock' and self.stock_date_type == 'past') or
not self.split_by_lot or
not self.has_expiry_date):
apply_depreciation = False
product_ids = self.get_product_ids()
if not product_ids:
raise UserError(_("There are no products to analyse."))
@@ -335,15 +399,25 @@ class StockValuationXlsx(models.TransientModel):
standard_price_past_date = past_date
if not (self.source == 'stock' and self.stock_date_type == 'present') and self.standard_price_date == 'present':
standard_price_past_date = False
depreciation_rules = []
if apply_depreciation:
depreciation_rules = self._prepare_expiry_depreciation_rules(company_id, past_date)
if not depreciation_rules:
raise UserError(_(
"The are not stock depreciation rule for company '%s'.")
% company.display_name)
in_stock_product_ids = list(in_stock_products.keys())
product_id2data = self.compute_product_data(
company_id, in_stock_product_ids,
standard_price_past_date=standard_price_past_date)
data_res = self.group_result(data, split_by_lot, split_by_location)
categ_id2name, uom_id2name, lot_id2data, loc_id2name = self.id2name(product_ids)
categ_id2name = self.product_categ_id2name(self.categ_ids)
uom_id2name = self.uom_id2name()
lot_id2data = self.prodlot_id2data(in_stock_product_ids, self.has_expiry_date, depreciation_rules)
loc_id2name = self.stock_location_id2name(self.location_id)
res = self.stringify_and_sort_result(
product_ids, product_id2data, data_res, prec_qty, prec_price, prec_cur_rounding,
categ_id2name, uom_id2name, lot_id2data, loc_id2name)
categ_id2name, uom_id2name, lot_id2data, loc_id2name, apply_depreciation)
logger.debug('Start create XLSX workbook')
file_data = BytesIO()
@@ -356,12 +430,15 @@ class StockValuationXlsx(models.TransientModel):
if not split_by_lot:
cols.pop('lot_name', None)
cols.pop('expiry_date', None)
if not hasattr(splo, 'expiry_date'):
if not self.has_expiry_date:
cols.pop('expiry_date', None)
if not split_by_location:
cols.pop('loc_name', None)
if not categ_subtotal:
cols.pop('categ_subtotal', None)
if not apply_depreciation:
cols.pop('depreciation_ratio', None)
cols.pop('subtotal_before_depreciation', None)
j = 0
for col, col_vals in sorted(cols.items(), key=lambda x: x[1]['sequence']):
@@ -417,6 +494,9 @@ class StockValuationXlsx(models.TransientModel):
letter_qty = cols['qty']['pos_letter']
letter_price = cols['standard_price']['pos_letter']
letter_subtotal = cols['subtotal']['pos_letter']
if apply_depreciation:
letter_subtotal_before_depreciation = cols['subtotal_before_depreciation']['pos_letter']
letter_depreciation_ratio = cols['depreciation_ratio']['pos_letter']
crow = 0
lines = res
for categ_id in categ_ids:
@@ -432,12 +512,20 @@ class StockValuationXlsx(models.TransientModel):
total += l['subtotal']
ctotal += l['subtotal']
categ_has_line = True
subtotal_formula = '=%s%d*%s%d' % (letter_qty, i + 1, letter_price, i + 1)
qty_by_price_formula = '=%s%d*%s%d' % (letter_qty, i + 1, letter_price, i + 1)
if apply_depreciation:
sheet.write_formula(i, cols['subtotal_before_depreciation']['pos'], qty_by_price_formula, styles['regular_currency'], l['subtotal_before_depreciation'])
subtotal_formula = '=%s%d*(1 - %s%d)' % (letter_subtotal_before_depreciation, i + 1, letter_depreciation_ratio, i + 1)
else:
subtotal_formula = qty_by_price_formula
sheet.write_formula(i, cols['subtotal']['pos'], subtotal_formula, styles['regular_currency'], l['subtotal'])
for col_name, col in cols.items():
if not col.get('formula'):
if col.get('type') == 'date' and l[col_name]:
l[col_name] = fields.Date.from_string(l[col_name])
if col.get('type') == 'date':
if l[col_name]:
l[col_name] = fields.Date.from_string(l[col_name])
else:
l[col_name] = '' # to avoid display of 31/12/1899
sheet.write(i, col['pos'], l[col_name], styles[col['style']])
if categ_subtotal:
if categ_has_line:
@@ -503,6 +591,7 @@ class StockValuationXlsx(models.TransientModel):
'regular_date': workbook.add_format({'num_format': 'dd/mm/yyyy'}),
'regular_currency': workbook.add_format({'num_format': currency_num_format}),
'regular_price_currency': workbook.add_format({'num_format': price_currency_num_format}),
'regular_int_percent': workbook.add_format({'num_format': u'0.%'}),
'regular': workbook.add_format({}),
'regular_small': workbook.add_format({'font_size': regular_font_size - 2}),
'categ_title': workbook.add_format({
@@ -527,8 +616,10 @@ class StockValuationXlsx(models.TransientModel):
'qty': {'width': 8, 'style': 'regular', 'sequence': 60, 'title': _('Qty')},
'uom_name': {'width': 5, 'style': 'regular_small', 'sequence': 70, 'title': _('UoM')},
'standard_price': {'width': 14, 'style': 'regular_price_currency', 'sequence': 80, 'title': _('Cost Price')},
'subtotal': {'width': 16, 'style': 'regular_currency', 'sequence': 90, 'title': _('Sub-total'), 'formula': True},
'categ_subtotal': {'width': 16, 'style': 'regular_currency', 'sequence': 100, 'title': _('Categ Sub-total'), 'formula': True},
'categ_name': {'width': 40, 'style': 'regular_small', 'sequence': 110, 'title': _('Product Category')},
'subtotal_before_depreciation': {'width': 16, 'style': 'regular_currency', 'sequence': 90, 'title': _('Sub-total'), 'formula': True},
'depreciation_ratio': {'width': 10, 'style': 'regular_int_percent', 'sequence': 100, 'title': _('Depreciation')},
'subtotal': {'width': 16, 'style': 'regular_currency', 'sequence': 110, 'title': _('Sub-total'), 'formula': True},
'categ_subtotal': {'width': 16, 'style': 'regular_currency', 'sequence': 120, 'title': _('Categ Sub-total'), 'formula': True},
'categ_name': {'width': 40, 'style': 'regular_small', 'sequence': 130, 'title': _('Product Category')},
}
return cols

View File

@@ -27,8 +27,10 @@
<field name="past_date" attrs="{'invisible': ['|', ('source', '!=', 'stock'), ('stock_date_type', '!=', 'past')], 'required': [('source', '=', 'stock'), ('stock_date_type', '=', 'past')]}"/>
<field name="standard_price_date" attrs="{'invisible': [('source', '=', 'stock'), ('stock_date_type', '=', 'present')]}" widget="radio"/>
<field name="categ_subtotal" />
<field name="has_expiry_date" invisible="1"/>
<field name="split_by_lot" attrs="{'invisible': [('source', '=', 'stock'), ('stock_date_type', '=', 'past')]}" groups="stock.group_production_lot"/>
<field name="split_by_location" attrs="{'invisible': [('source', '=', 'stock'), ('stock_date_type', '=', 'past')]}"/>
<field name="apply_depreciation" groups="stock.group_production_lot" attrs="{'invisible': ['|', '|', ('split_by_lot', '=', False), ('has_expiry_date', '=', False), '&amp;', ('source', '=', 'stock'), ('stock_date_type', '=', 'past')]}"/>
</group>
<group name="done" states="done" string="Result">
<field name="export_file" filename="export_filename"/>
@@ -55,6 +57,7 @@
<record id="stock_account.menu_valuation" model="ir.ui.menu">
<field name="action" ref="stock_valuation_xlsx.stock_valuation_xlsx_action"/>
<field name="name">Stock Valuation XLSX</field>
<field name="sequence">0</field>
</record>
</odoo>