Skip to content

16.0 #230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 47 commits into
base: 16.0
Choose a base branch
from
Open

16.0 #230

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d2b6323
Fix stripe installation issue due to wrong account_type on transfert …
hparfr Apr 29, 2020
614c1a7
Remove dead file
alexis-via Dec 2, 2020
2a3ca2d
sale_usability: up-port warning on price update when qty is changed
alexis-via Dec 4, 2020
4076946
mrp_usability: add location_dest_id in the tree view of finished prod…
alexis-via Dec 4, 2020
05ac567
Show location_id in tree view of stock.move.line in raw materials tab
alexis-via Jan 11, 2021
aa804e2
Add track_visibility='onchange' on all importants fields of mrp.bom
alexis-via Jan 13, 2021
2fe0ad5
mrp_usability: add source and dest loc on stock.move.line form view o…
alexis-via Jan 29, 2021
09b73d1
mrp_usability: remove readonly on location field
alexis-via Jan 29, 2021
872801f
stock_valuation_xlsx: add stock.variation.xlsx report (Up-port from v10)
alexis-via Feb 26, 2021
93272fb
Update menu_view.xml
bealdav Mar 9, 2021
97fe8b4
mrp_usability: add tracking on date fields
alexis-via Mar 12, 2021
9b89661
Fix crash in sale_down_payment
alexis-via Mar 22, 2021
e566540
Merge pull request #116 from akretion/12.0-fix_account_type_liquidity…
PierrickBrun Apr 26, 2021
592a82a
fix message_post v12 API in unreserve (#145)
rvalyi May 12, 2021
dbbd14f
sale_down_payment: add a hook that can be used for notifications
alexis-via May 27, 2021
25a177e
Add module sale_mrp_usability (backport of a feature of v14)
alexis-via May 27, 2021
8e01d32
Add tracking on some fields
alexis-via Jul 20, 2021
9a67836
Improve stock inventory tree view
alexis-via Jul 20, 2021
8da01d0
Add script to fix old rounding data bug
alexis-via Sep 13, 2021
bb4e5d3
[ADD] mail_usability module for improvements on mails
bguillot Jun 23, 2016
81b78b8
Set all modules as uninstallable
alexis-via Oct 11, 2016
6dbbb98
Mass rename from __openerp__.py to __manifest__.py
alexis-via Oct 11, 2016
453b6ba
IMP add icons
bealdav Nov 18, 2016
1a8588e
Port mail_usability to v10
alexis-via Dec 2, 2016
d34f273
mail_usability: add intermediary level to notify_email parameter of r…
alexis-via Jun 22, 2017
c3f4775
UPD Branding
bealdav Nov 22, 2017
b26b3de
[IMP] improve the wizard for testing email, allow to search on object…
sebastienbeau Sep 4, 2018
7f64d3c
[IMP] add readme, remove auto following when sending an email, use li…
sebastienbeau Dec 4, 2018
0f35f8e
[REF] refactor the code to make it simplifier and avoid hacking the _…
sebastienbeau Jan 8, 2019
aec5bb9
[IMP] remove the fucking auto_delete!!!
sebastienbeau Jan 8, 2019
39bee6e
[IMP] add some extra style css support and add a debugger mode. Updat…
sebastienbeau Jan 8, 2019
e644b27
[IMP] add record_id on mail.message to be able to access to the record
sebastienbeau Jan 11, 2019
39855d7
[REF] refactor the code in order to split it in several file
sebastienbeau Jan 11, 2019
b62f3a3
[IMP] by default do not send an email when user_id is fill on object
sebastienbeau Feb 19, 2019
ea4c6df
[FIX] fix helper
sebastienbeau Feb 25, 2019
70d7cbd
New module link_tracker_usability
alexis-via May 17, 2019
f752fbc
[12.0][MIG] mail_usability
chafique-delli Oct 26, 2020
8449c3d
[FIX] remove notify_email option in README.rst
chafique-delli Oct 26, 2020
d05b75d
fix migraiton of mail_usability
bguillot Feb 18, 2021
49226e8
stock_valuation_xlsx: add depreciation ratios
alexis-via Sep 26, 2021
b72d8c4
stock_valuation_xlsx: fix crash with using depreciation rules
alexis-via Nov 15, 2021
af806f7
stock_usability: usability improvements on inventory and picking form…
alexis-via Jan 21, 2022
38a6b12
account_usability: add name_search on account.incoterms
alexis-via Mar 4, 2022
3b2efaa
[ADD] module base_dynamic_list
alexis-via May 6, 2022
8fe2cac
sale_report: add button to send order acknowledgement
alexis-via May 6, 2022
0d689b1
stock_valuation_xlsx: improve multi-company support
alexis-via May 13, 2022
0cd6ecd
purchase_usability: warning when price and/or delay is auto-updated f…
alexis-via Jun 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 82 additions & 1 deletion account_usability/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models, fields, api, _
from odoo.tools import float_compare, float_is_zero
from odoo.tools import float_compare, float_is_zero, float_round
from odoo.tools.misc import formatLang
from odoo.exceptions import UserError, ValidationError
from odoo.osv import expression
Expand Down Expand Up @@ -407,6 +407,58 @@ def _compute_default_credit_debit(self):
move.default_credit = default_credit
move.default_debit = default_debit

@api.model
def _fix_debit_credit_round_bug(self):
logger.info('START script _fix_debit_credit_round_bug')
moves = self.sudo().search([]) # sudo to search in all companies
bug_move_ids = []
for move in moves:
buggy = False
for l in move.line_ids:
if not float_is_zero(l.debit, precision_digits=2):
debit_rounded = float_round(l.debit, precision_digits=2)
if float_compare(l.debit, debit_rounded, precision_digits=6):
logger.info('Bad move to fix ID %d company_id %d name %s ref %s date %s journal %s (line ID %d debit=%s)', move.id, move.company_id.id, move.name, move.ref, move.date, move.journal_id.code, l.id, l.debit)
buggy = True
break
else:
credit_rounded = float_round(l.credit, precision_digits=2)
if float_compare(l.credit, credit_rounded, precision_digits=6):
logger.info('Bad move to fix ID %d company_id %d name %s ref %s date %s journal %s (line ID %d credit=%s)', move.id, move.company_id.id, move.name, move.ref, move.date, move.journal_id.code, l.id, l.credit)
buggy = True
break
if buggy:
bug_move_ids.append(move.id)
bal = 0.0
max_credit = (False, 0)
for l in move.line_ids:
if not float_is_zero(l.debit, precision_digits=2):
new_debit = float_round(l.debit, precision_digits=2)
self._cr.execute(
'UPDATE account_move_line set debit=%s, balance=%s where id=%s',
(new_debit, new_debit, l.id))
bal -= new_debit
elif not float_is_zero(l.credit, precision_digits=2):
new_credit = float_round(l.credit, precision_digits=2)
self._cr.execute(
'UPDATE account_move_line set credit=%s, balance=%s where id=%s',
(new_credit, new_credit * -1, l.id))
bal += new_credit
if new_credit > max_credit[1]:
max_credit = (l, new_credit)
if not float_is_zero(bal, precision_digits=2):
assert abs(bal) < 0.05
l = max_credit[0]
new_credit = max_credit[1]
new_new_credit = float_round(new_credit - bal, precision_digits=2)
assert new_new_credit > 0
self._cr.execute(
'UPDATE account_move_line set credit=%s, balance=%s where id=%s',
(new_new_credit, new_new_credit * -1, l.id))
logger.info('Move ID %d fixed', move.id)
logger.info('%d buggy moves fixed (IDs: %s)', len(bug_move_ids), bug_move_ids)
logger.info('END _fix_debit_credit_round_bug')


class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
Expand Down Expand Up @@ -672,6 +724,16 @@ def name_get(self):
res.append((rec.id, '[%s] %s' % (rec.code, rec.name)))
return res

@api.model
def name_search(self, name='', args=None, operator='ilike', limit=80):
if args is None:
args = []
if name and operator == 'ilike':
recs = self.search([('code', '=', name)] + args, limit=limit)
if recs:
return recs.name_get()
return super().name_search(name=name, args=args, operator=operator, limit=limit)


class AccountReconciliation(models.AbstractModel):
_inherit = 'account.reconciliation.widget'
Expand Down Expand Up @@ -704,3 +766,22 @@ class ResConfigSettings(models.TransientModel):

transfer_account_id = fields.Many2one(
related='company_id.transfer_account_id', readonly=False)


class AccountChartTemplate(models.Model):
_inherit = "account.chart.template"

@api.model
def _prepare_transfer_account_template(self):
"""Change the type of default account in order to be
compliant with _check_account_type_on_bank_journal
Used at installation of payment modules like stripe
See https://github.com/akretion/odoo-usability/issues/115
"""
vals = super()._prepare_transfer_account_template()
current_assets_type = self.env.ref(
'account.data_account_type_liquidity', raise_if_not_found=False)
vals.update({
'user_type_id': current_assets_type and current_assets_type.id or False,
})
return vals
1 change: 1 addition & 0 deletions account_usability/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,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
* Change type from current_assets to liquidity for transfert account template.

Together with this module, I recommend the use of the following modules:

Expand Down
1 change: 1 addition & 0 deletions base_dynamic_list/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
62 changes: 62 additions & 0 deletions base_dynamic_list/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright 2020-2022 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
'name': 'Base Dynamic List',
'version': '12.0.1.0.0',
'category': 'Tools',
'license': 'AGPL-3',
'summary': 'Dynamic lists',
'description': """
Base Dynamic List
=================

Very often during an Odoo implementation, we need to add selection fields on a native objet, and we don't want to have a hard-coded selection list (fields.Selection), but a selection list that can be changed by users (Many2one field). For that, the developper needs to add a new object (with just a 'name' and 'sequence' field) with a form/tree view. The goal of this module is to speed-up this process by defining a dynamic list object that already has all the required views.

This module provides several ready-to-go objects:

* simple list : fields *name*, *sequence* and *active*
* translatable list : fields *name* with translate=True, *sequence* and *active*
* code list : fields *code* (unique), *name*, *sequence* and *active*
* translatable code list : fields *code* (unique), *name* with translate=True, *sequence* and *active*

These objects are readable by the employee group. The system group has full rights on it.

To use it, you need to do 2 or 3 things :

1) Add an entry in the domain field and the object you selected:

domain = fields.Selection(selection_add=[('risk.type', "Risk Type")], ondelete={"risk.type": "cascade"})

2) Add the many2one field on your object:

risk_type_id = fields.Many2one(
'dynamic.list', string="Risk Type",
ondelete='restrict', domain=[('domain', '=', 'risk.type')])


3) Optionally, you can add a dedicated action and a menu entry (otherwize, you can use the generic menu entry under *Settings > Technical > Dynamic Lists*:

<record id="dynamic_list_risk_type_action" model="ir.actions.act_window">
<field name="name">Risk Type</field>
<field name="res_model">dynamic.list</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('domain', '=', 'risk.type')]</field>
<field name="context">{'default_domain': 'risk.type'}</field>
</record>

<menuitem id="dynamic_list_risk_type_menu" action="dynamic_list_risk_type_action"
parent="parent_menu_xmlid"/>

Limitation: when you want to have different access rights on these lists depending on the source object, you should prefer to use dedicated objects.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'depends': ['base'],
'data': [
'security/ir.model.access.csv',
'views/dynamic_list.xml',
],
'installable': True,
}
1 change: 1 addition & 0 deletions base_dynamic_list/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import dynamic_list
115 changes: 115 additions & 0 deletions base_dynamic_list/models/dynamic_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Copyright 2020-2022 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import api, fields, models


class DynamicList(models.Model):
_name = 'dynamic.list'
_description = 'Dynamic List (non translatable)'
_order = 'sequence, id'

name = fields.Char(required=True)
sequence = fields.Integer(default=10)
active = fields.Boolean(default=True)
domain = fields.Selection([], string='Domain', required=True, index=True)

_sql_constraint = [(
'domain_name_uniq',
'unique(domain, name)',
'This entry already exists!'
)]


class DynamicListTranslate(models.Model):
_name = 'dynamic.list.translate'
_description = 'Translatable Dynamic List'
_order = 'sequence, id'

name = fields.Char(translate=True, required=True)
sequence = fields.Integer(default=10)
active = fields.Boolean(default=True)
domain = fields.Selection([], string='Domain', required=True, index=True)

_sql_constraint = [(
'domain_name_uniq',
'unique(domain, name)',
'This entry already exists!'
)]


class DynamicListCode(models.Model):
_name = 'dynamic.list.code'
_description = 'Dynamic list with code'
_order = 'sequence, id'

code = fields.Char(required=True)
name = fields.Char(translate=True, required=True)
sequence = fields.Integer(default=10)
active = fields.Boolean(default=True)
domain = fields.Selection([], string='Domain', required=True, index=True)

_sql_constraint = [(
'domain_code_uniq',
'unique(domain, code)',
'This code already exists!'
)]

@api.depends('code', 'name')
def name_get(self):
res = []
for rec in self:
res.append((rec.id, '[%s] %s' % (rec.code, rec.name)))
return res

@api.model
def name_search(
self, name='', args=None, operator='ilike', limit=80):
if args is None:
args = []
if name and operator == 'ilike':
recs = self.search(
[('code', '=', name)] + args, limit=limit)
if recs:
return recs.name_get()
return super().name_search(
name=name, args=args, operator=operator, limit=limit)


class DynamicListCodeTranslate(models.Model):
_name = 'dynamic.list.code.translate'
_description = 'Translatable dynamic list with code'
_order = 'sequence, id'

code = fields.Char(required=True)
name = fields.Char(translate=True, required=True)
sequence = fields.Integer(default=10)
active = fields.Boolean(default=True)
domain = fields.Selection([], string='Domain', required=True, index=True)

_sql_constraint = [(
'domain_code_uniq',
'unique(domain, code)',
'This code already exists!'
)]

@api.depends('code', 'name')
def name_get(self):
res = []
for rec in self:
res.append((rec.id, '[%s] %s' % (rec.code, rec.name)))
return res

@api.model
def name_search(
self, name='', args=None, operator='ilike', limit=80):
if args is None:
args = []
if name and operator == 'ilike':
recs = self.search(
[('code', '=', name)] + args, limit=limit)
if recs:
return recs.name_get()
return super().name_search(
name=name, args=args, operator=operator, limit=limit)
9 changes: 9 additions & 0 deletions base_dynamic_list/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_dynamic_list_read,Read access on dynamic.list to employees,model_dynamic_list,base.group_user,1,0,0,0
access_dynamic_list_full,Full access to dynamic.list to System group,model_dynamic_list,base.group_system,1,1,1,1
access_dynamic_list_translate_read,Read access on dynamic.list.translate to employees,model_dynamic_list_translate,base.group_user,1,0,0,0
access_dynamic_list_translate_full,Full access to dynamic.list.translate to System group,model_dynamic_list_translate,base.group_system,1,1,1,1
access_dynamic_list_code_read,Read access on dynamic.list.code to employees,model_dynamic_list_code,base.group_user,1,0,0,0
access_dynamic_list_code_full,Full access to dynamic.list.code to System group,model_dynamic_list_code,base.group_system,1,1,1,1
access_dynamic_list_code_translate_read,Read access on dynamic.list.code.translate to employees,model_dynamic_list_code_translate,base.group_user,1,0,0,0
access_dynamic_list_code_translate_full,Full access to dynamic.list.code.translate to System group,model_dynamic_list_code_translate,base.group_system,1,1,1,1
Loading