Compare commits

..

54 Commits

Author SHA1 Message Date
Alexis de Lattre
819b1370e7 [IMP] product_print_zpl_barcode: remove dep on base_report_to_printer. Use direct print. 2025-03-24 22:34:44 +00:00
Akretion Git Bot
ce7a3a382a [ADD] setup.py 2025-03-15 06:28:32 +00:00
Akretion Git Bot
16e7233adb [ADD] icon.png 2025-03-15 06:28:31 +00:00
Alexis de Lattre
6e54d026a6 [ADD] commission_simple, commission_simple_agent, sale_agent
3 modules backported from v16
2025-03-15 07:28:20 +01:00
Alexis de Lattre
ed1a6641ce [IMP] stock_usability: add index on picking_type_id on stock.picking 2025-03-14 16:40:57 +00:00
Alexis de Lattre
51aa9bb58f [IMP] pos_usability: remove order_id from default measures in report pivot view 2025-03-14 13:44:24 +00:00
Alexis de Lattre
47b7b4a133 [IMP] pos_usability: add filters Today and Yesterday on report.pos.order 2025-03-14 13:37:10 +00:00
Alexis de Lattre
99c1f45951 [IMP] sale_usability: qty by default from Sales Stats from product list view 2025-03-14 12:55:50 +00:00
Alexis de Lattre
e33453c1a5 [IMP] sale_usability: add Sale Statistics in product list view 2025-03-12 23:28:15 +01:00
Akretion Git Bot
4804917f37 [UPD] README.rst 2025-02-25 17:52:15 +00:00
Alexis de Lattre
4b658203cc [IMP] mrp_usability: add lot on mrp production report 2025-02-25 18:51:27 +01:00
Alexis de Lattre
e6d801a43a [FIX] product_usability: fix crash when searching on main supplier 2025-02-17 19:39:43 +01:00
Akretion Bot
8510656382 [ADD] setup.py 2025-01-30 02:36:08 +00:00
Akretion Bot
c35c200ead [ADD] icon.png 2025-01-30 02:36:08 +00:00
Akretion Bot
1b99fedd38 [UPD] README.rst 2025-01-30 02:36:08 +00:00
Benoît
e155a7b821 small fixes on sale_show_transaction views 2025-01-23 15:31:33 +01:00
Alexis de Lattre
cec64f83d8 [IMP] account_usability: add internal_group to account type form/tree views 2025-01-23 09:34:49 +01:00
Alexis de Lattre
3e7298f465 stock_usability: add confirm pop-up on inventory validation 2025-01-07 17:35:59 +01:00
Kévin Roche
82b910491a Merge pull request #228 from akretion/14.0-add-account_default_report_without_paiement
[14.0][ADD] account_default_report_without_paiement
2024-12-21 14:29:33 +01:00
Kev-Roche
7a3f5cd05b [14.0][ADD] account_default_report_without_paiement 2024-12-21 14:26:27 +01:00
Alexis de Lattre
1d96cc4c83 stock_usability: add tracking on important fields of stock.production.lot
Code cleanup
2024-12-19 17:30:14 +01:00
beau sebastien
2ff3ea6dcd Merge pull request #214 from akretion/14.0-fix-product_usability
product_usability: seller_id can not be store as muti-company will be broken
2024-12-12 01:39:21 +01:00
Sébastien BEAU
a1f8ab32dd product_usability: make the field seller_id searcheable 2024-12-12 01:38:25 +01:00
Alexis de Lattre
f3a6cfade6 [IMP] account_bank_reconciliation_summary_xlsx: add block to have difference et justification (entered by user) 2024-10-23 12:20:26 +02:00
Alexis de Lattre
b8203ae42a [IMP] account_bank_reconciliation_summary_xlsx fine-tune config check 2024-10-22 15:11:01 +02:00
Alexis de Lattre
02d9dee32e [IMP] account_bank_reconciliation_summary_xlsx: use native method to compute account balance 2024-10-22 15:05:32 +02:00
Alexis de Lattre
04b363f8a6 [MIG] mass_mailing_usability to v14 2024-10-22 14:39:45 +02:00
Alexis de Lattre
f3b5f85fc9 [IMP] account_bank_reconciliation_summary_xlsx: support bank journals in currency different than company currency
Update fr translation
2024-10-22 14:34:45 +02:00
Alexis de Lattre
d7f6a2b9f8 [IMP] account_payment_line_manual_account: add support for analytic 2024-10-16 17:13:23 +02:00
Florian
2a0b1342e7 Merge pull request #222 from akretion/14-fix-invoice-update-pdf-unlink
[FIX] account_invoice_update_wizard : avoid stacktrace when no pdf is…
2024-10-10 09:18:57 +02:00
Florian da Costa
db33820a57 [FIX] account_invoice_update_wizard : avoid stacktrace when no pdf is found 2024-10-10 09:12:48 +02:00
Alexis de Lattre
4c067fef09 stock_usability: mig method auto unpack on internal locations from v10 2024-10-01 11:02:26 +02:00
Alexis de Lattre
88452b7930 [IMP] account_usability_akretion: simplify code for invoice attach del upon invoice back to draft 2024-09-30 10:56:47 +02:00
Alexis de Lattre
a6305eb581 [FIX] account_usability: fix deletion of PDF invoice attachment when invoice is back to draft 2024-09-30 09:03:30 +02:00
beau sebastien
d2a8b77c22 Merge pull request #221 from akretion/14.0-purge-pdf
account_invoice_update_wizard: purge existing pdf in attachment after update
2024-09-27 17:25:24 +02:00
Sébastien BEAU
467ce47306 account_invoice_update_wizard: purge existing pdf in attachment after update 2024-09-27 17:11:39 +02:00
Alexis de Lattre
ff0bdc1b8d sale_stock_usability: add method to display delivery order on out invoice report 2024-09-23 21:45:30 +00:00
Alexis de Lattre
254a97edd3 base_usability: Add rcs_siren in company header 2024-09-23 20:56:02 +00:00
Alexis de Lattre
162f0b7874 mrp_usability: add tracking on some fields 2024-09-19 16:04:03 +02:00
Alexis de Lattre
ee8bf2ea17 stock_usability: add script to fix reserved_quantity on quants
Filter-out cancelled move lines shown by "reserved" button on quants
2024-09-19 16:03:08 +02:00
Alexis de Lattre
97c20fed73 mrp_subcontracting_usability: add link to subcontrating production order from stock.move form view 2024-09-19 11:22:59 +02:00
Alexis de Lattre
856bca4ccf account_usability: add search on account in account.move search view 2024-09-17 17:53:28 +02:00
Alexis de Lattre
0d5346d856 Add module account_payment_line_manual_account 2024-09-14 00:13:14 +02:00
Alexis de Lattre
940fe43614 [MIG] partner_products_shortcut from v10 to v14 2024-09-12 22:09:25 +02:00
Alexis de Lattre
4e68c48110 stock_usability: Add product_barcode on orderpoint tree view (optional hide) 2024-09-12 21:28:51 +02:00
Alexis de Lattre
7b8c35a384 Add patch in pos_usability 2024-09-10 23:37:46 +02:00
Alexis de Lattre
0bbda6f265 product_detailed_type: improve compatibility with demo/test data
It's still not perfect yet, in particular when you install the "stock"
module and "product_detailed_type_stock" is not installed yet.
2024-09-05 18:21:59 +02:00
Alexis de Lattre
c7c5d9172b pos_usability: add patch pos-always_open_cashbox.diff 2024-07-15 21:57:09 +02:00
Alexis de Lattre
4655e6b739 base_usability: add 2 patches 2024-07-11 13:04:59 +02:00
Alexis de Lattre
8bd83b0975 mrp_average_cost: avoid crash on bad data 2024-06-25 01:10:51 +02:00
Alexis de Lattre
9367f7006e [FIX] mrp_average_cost: fix bad dependency 2024-06-24 18:31:35 +02:00
Alexis de Lattre
29b8ebb779 account_usability: add invoice currency signed fields
Show these fields as optional in tree view without sum=1
2024-06-24 11:24:22 +02:00
Alexis de Lattre
c33835957d sale_usability: add button to send order acknowledgement
This is a forward port of a v12 commit.
2024-06-24 10:03:13 +02:00
Sébastien BEAU
0fa2024dab product_usability: seller_id can not be store as muti-company will be broken
do not store the field as shared product can have different supplier
depending on the company logged
Use compute as related will always pick the first one whatever the
company logged
2024-06-02 22:25:10 +02:00
364 changed files with 4443 additions and 468 deletions

View File

@@ -1,10 +1,10 @@
# Copyright 2017-2023 Akretion France (http://www.akretion.com/)
# Copyright 2017-2024 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": "Bank Reconciliation Report",
"version": "14.0.1.0.0",
"version": "14.0.2.0.0",
"license": "AGPL-3",
"author": "Akretion",
"website": "https://github.com/akretion/odoo-usability",

View File

@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-01-13 10:31+0000\n"
"PO-Revision-Date: 2023-01-13 10:31+0000\n"
"POT-Creation-Date: 2024-10-23 10:04+0000\n"
"PO-Revision-Date: 2024-10-23 10:04+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -17,6 +17,7 @@ msgstr ""
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Amount"
msgstr "Montant"
@@ -27,6 +28,12 @@ msgstr "Montant"
msgid "Balance %s:"
msgstr "Solde %s :"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Bank Balance:"
msgstr "Solde bancaire :"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__journal_ids
msgid "Bank Journals"
@@ -49,7 +56,7 @@ msgstr "Rapport de rapprochement bancaire"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model,name:account_bank_reconciliation_summary_xlsx.model_bank_reconciliation_report_wizard
msgid "Bank Reconciliation Report Wizard"
msgstr "Assistant rapport de rapprochement bancaire"
msgstr "Assistant de rapport de rapprochement bancaire"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.actions.report,name:account_bank_reconciliation_summary_xlsx.bank_reconciliation_xlsx
@@ -96,17 +103,36 @@ msgstr "Créé le"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Currency"
msgstr "Devise"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__date
#, python-format
msgid "Date"
msgstr ""
msgstr "Date"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Description"
msgstr "Description"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Difference:"
msgstr "Écart :"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__display_name
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_report_bank_reconciliation_xlsx__display_name
msgid "Display Name"
msgstr ""
msgstr "Nom affiché"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields.selection,name:account_bank_reconciliation_summary_xlsx.selection__bank_reconciliation_report_wizard__move_state__draft_posted
@@ -123,13 +149,13 @@ msgstr "Écritures"
#. module: account_bank_reconciliation_summary_xlsx
#: model_terms:ir.ui.view,arch_db:account_bank_reconciliation_summary_xlsx.bank_reconciliation_report_wizard_form
msgid "Export XLSX"
msgstr ""
msgstr "Exporter en XLSX"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Generated on %s"
msgstr "Généré le %s"
msgid "Generated from Odoo on %s by %s"
msgstr "Généré par Odoo le %s par %s"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__id
@@ -143,6 +169,18 @@ msgstr ""
msgid "Journal"
msgstr ""
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Journal Entry"
msgstr "Pièce"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Justification:"
msgstr "Justification :"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
@@ -153,23 +191,17 @@ msgstr "Libellé"
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard____last_update
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_report_bank_reconciliation_xlsx____last_update
msgid "Last Modified on"
msgstr ""
msgstr "Dernière modification le"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__write_uid
msgid "Last Updated by"
msgstr ""
msgstr "Dernière mise à jour par"
#. module: account_bank_reconciliation_summary_xlsx
#: model:ir.model.fields,field_description:account_bank_reconciliation_summary_xlsx.field_bank_reconciliation_report_wizard__write_date
msgid "Last Updated on"
msgstr ""
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "Move Number"
msgstr "Numéro de pièce"
msgstr "Dernière mise à jour le"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
@@ -179,10 +211,23 @@ msgstr "Aucun journal de banque sélectionné."
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid "None"
msgstr "Aucun"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid ""
"On bank journal %(journal)s which is configured with currency "
"%(journal_currency)s, the account %(account)s must be configured with the "
"same currency (current account currency: %(account_currency)s)."
msgstr ""
"Sur le journal de banque %(journal)s qui est configuré avec la devise "
"%(journal_currency)s, le compte %(account)s doit être configuré avec la même"
" devise (devise actuelle du compte : %(account_currency)s)."
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
@@ -211,3 +256,13 @@ msgstr "Sous-total :"
#, python-format
msgid "TOTAL:"
msgstr "TOTAL :"
#. module: account_bank_reconciliation_summary_xlsx
#: code:addons/account_bank_reconciliation_summary_xlsx/report/bank_reconciliation_xlsx.py:0
#, python-format
msgid ""
"The are %(count)s journal items in account %(account)s that have a currency "
"other than %(currency)s or where currency is not set."
msgstr ""
"Il y a %(count)s écritures comptables dans le compte %(account)s qui ont une"
" devise autre que %(currency)s ou dont la devise n'est pas définie."

View File

@@ -1,4 +1,4 @@
# Copyright 2017-2023 Akretion France (http://www.akretion.com/)
# Copyright 2017-2024 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).
@@ -14,32 +14,19 @@ class BankReconciliationXlsx(models.AbstractModel):
_description = "Bank Reconciliation XLSX Report"
_inherit = "report.report_xlsx.abstract"
def _domain_add_move_state(self, wizard, domain):
if wizard.move_state == 'posted':
domain.append(('parent_state', '=', 'posted'))
elif wizard.move_state == 'draft_posted':
domain.append(('parent_state', 'in', ('draft', 'posted')))
def _get_account_balance(self, account, wizard):
def _prepare_payment_move_lines(self, jdi, account, unreconciled_only=True):
domain = [
('account_id', '=', account.id),
('date', '<=', wizard.date),
('company_id', '=', wizard.company_id.id),
]
self._domain_add_move_state(wizard, domain)
res_rg = self.env['account.move.line'].read_group(domain, ['balance:sum'], [])
account_bal = res_rg and res_rg[0].get('balance', 0.0) or 0.0
return account_bal
def _prepare_payment_move_lines(self, journal, account, wizard, unreconciled_only=True):
domain = [
("company_id", "=", wizard.company_id.id),
("company_id", "=", jdi['company'].id),
("account_id", "=", account.id),
("journal_id", "=", journal.id),
("date", "<=", wizard.date),
("journal_id", "=", jdi['journal'].id),
("date", "<=", jdi['wizard'].date),
]
if jdi['wizard'].move_state == 'posted':
domain.append(('parent_state', '=', 'posted'))
elif jdi['wizard'].move_state == 'draft_posted':
domain.append(('parent_state', 'in', ('draft', 'posted')))
if unreconciled_only:
limit_datetime_naive = datetime.combine(wizard.date, datetime.max.time())
limit_datetime_naive = datetime.combine(jdi['wizard'].date, datetime.max.time())
tz = pytz.timezone(self.env.user.tz)
limit_datetime_aware = tz.localize(limit_datetime_naive)
limit_datetime_utc = limit_datetime_aware.astimezone(pytz.utc)
@@ -47,7 +34,6 @@ class BankReconciliationXlsx(models.AbstractModel):
domain += [
'|', ('full_reconcile_id', '=', False),
('full_reconcile_id.create_date', '>', limit_datetime)]
self._domain_add_move_state(wizard, domain)
mlines = self.env["account.move.line"].search(domain)
res = []
for mline in mlines:
@@ -60,13 +46,18 @@ class BankReconciliationXlsx(models.AbstractModel):
):
cpart.append(line.account_id.code)
counterpart = " ,".join(cpart)
if jdi['currency'] == mline.currency_id:
amount = mline.amount_currency
else:
amount = mline.currency_id._convert(
mline.amount_currency, jdi['currency'], jdi['company'], mline.date)
res.append(
{
"date": mline.date,
"ref": move.ref or "",
"label": mline.name,
"partner": mline.partner_id.display_name or "",
"amount": mline.balance,
"amount": amount,
"move_name": move.name,
"counterpart": counterpart,
}
@@ -74,27 +65,31 @@ class BankReconciliationXlsx(models.AbstractModel):
return res
def _write_move_lines_block(self, jdi, row, account, add2total=True):
# Returns row
# For suspense lines, it may not add any cells if there are no suspense lines
# => in this case, it doesn't increment row
# If it adds cells, it returns row + 2 to add 2 empty rows at the end
sheet = jdi['sheet']
style = jdi['style']
style_suffix = not add2total and '_warn' or ''
subtotal = 0.0
mlines = self._prepare_payment_move_lines(jdi['journal'], account, jdi['wizard'])
mlines = self._prepare_payment_move_lines(jdi, account)
if mlines or add2total:
sheet.write(row, 0, '%s %s' % (account.name, account.code), style['title' + style_suffix])
sheet.write(row, 1, "", style['title' + style_suffix])
sheet.write(row, 0, '%s %s' % (account.name, account.code), style[f"title{style_suffix}"])
sheet.write(row, 1, "", style[f"title{style_suffix}"])
if not mlines:
if add2total:
sheet.write(row, 2, _("None"), style['none'])
else:
return
return row
else:
row += 1
col_labels = [
_("Date"),
_("Partner"),
_("Amount"),
_("Move Number"),
_("Journal Entry"),
_("Counter-part"),
_("Ref."),
_("Label"),
@@ -108,7 +103,7 @@ class BankReconciliationXlsx(models.AbstractModel):
for mline in mlines:
sheet.write(row, 0, mline["date"], style['regular_date'])
sheet.write(row, 1, mline["partner"], style['regular'])
sheet.write(row, 2, mline["amount"], style['currency'])
sheet.write(row, 2, mline["amount"], style[jdi['currency']])
sheet.write(row, 3, mline["move_name"], style['regular'])
sheet.write(row, 4, mline["counterpart"], style['regular'])
sheet.write(row, 5, mline["ref"], style['regular'])
@@ -118,18 +113,20 @@ class BankReconciliationXlsx(models.AbstractModel):
end_line = row
for col in range(1):
sheet.write(row, col, "", style['title' + style_suffix])
sheet.write(row, 1, _("Sub-total:") + ' ', style['title_right' + style_suffix])
sheet.write(row, col, "", style[f"title{style_suffix}"])
sheet.write(row, 1, _("Sub-total:") + ' ', style[f"title_right{style_suffix}"])
formula = '=SUM(%s%d:%s%d)' % (
jdi['total_col'], start_line, jdi['total_col'], end_line)
sheet.write_formula(row, 2, formula, style['currency_bg' + style_suffix], subtotal)
formula = f"=SUM({jdi['total_col']}{start_line}:{jdi['total_col']}{end_line})"
sheet.write_formula(row, 2, formula, style[f"{jdi['currency']}_bg{style_suffix}"], subtotal)
if add2total:
jdi['total'] += subtotal
jdi['total_formula'] += '+%s%d' % (jdi['total_col'], row + 1)
return row
jdi['total_formula'] += f"+{jdi['total_col']}{row + 1}"
return row + 2
def generate_xlsx_report(self, workbook, data, wizard):
lang = self.env.user.lang
self = self.with_context(lang=lang)
wizard = wizard.with_context(lang=lang)
if not wizard.journal_ids:
raise UserError(_("No bank journal selected."))
date_dt = wizard.date
@@ -137,15 +134,21 @@ class BankReconciliationXlsx(models.AbstractModel):
style = self._get_style(workbook, company)
move_state_label = dict(
wizard.fields_get('move_state', 'selection')['move_state']['selection'])
generated_on_label = _('Generated on %s') % format_datetime(
self.env, datetime.utcnow())
generated_on_label = _('Generated from Odoo on %s by %s') % (
format_datetime(self.env, datetime.utcnow()),
self.env.user.name)
for journal in wizard.journal_ids:
row = 0
sheet = workbook.add_worksheet(journal.code or journal.name)
bank_account = journal.default_account_id
jdi = {
'wizard': wizard,
'company': company,
'journal': journal,
'currency': journal.currency_id or company.currency_id,
'bank_account': bank_account,
'style': style,
'workbook': workbook,
'sheet': sheet,
'total': 0.0,
'total_formula': '=',
@@ -169,7 +172,7 @@ class BankReconciliationXlsx(models.AbstractModel):
sheet.set_column(6, 6, 60)
row += 3
sheet.write(row, 0, _("Company"), style['wizard_field'])
sheet.write(row, 1, wizard.company_id.display_name, style['wizard_value'])
sheet.write(row, 1, company.display_name, style['wizard_value'])
row += 1
sheet.write(row, 0, _("Date"), style['wizard_field'])
sheet.write(row, 1, date_dt, style['wizard_value_date'])
@@ -177,51 +180,121 @@ class BankReconciliationXlsx(models.AbstractModel):
sheet.write(row, 0, _("Journal"), style['wizard_field'])
sheet.write(row, 1, journal.display_name, style['wizard_value'])
row += 1
sheet.write(row, 0, _("Currency"), style['wizard_field'])
sheet.write(row, 1, jdi['currency'].name, style['wizard_value'])
row += 1
sheet.write(row, 0, _("Entries"), style['wizard_field'])
sheet.write(row, 1, move_state_label[wizard.move_state], style['wizard_value'])
# Setup check
if journal.currency_id and journal.currency_id != company.currency_id:
if journal.currency_id != bank_account.currency_id:
raise UserError(_(
"On bank journal %(journal)s which is configured with currency "
"%(journal_currency)s, the account %(account)s must be configured "
"with the same currency (current account currency: %(account_currency)s).",
journal=journal.display_name,
journal_currency=journal.currency_id.name,
account=bank_account.display_name,
account_currency=bank_account.currency_id.name or _('None')))
bad_line_count = self.env['account.move.line'].search_count([
('company_id', '=', company.id),
('journal_id', '=', journal.id),
('account_id', '=', bank_account.id),
('currency_id', '!=', jdi['currency'].id),
])
if bad_line_count:
raise UserError(_(
"The are %(count)s journal items in account %(account)s "
"that have a currency other than %(currency)s or where "
"currency is not set.",
count=bad_line_count,
account=bank_account.display_name,
currency=jdi['currency'].name))
# 1) Show balance of bank account
row += 3
bank_account = journal.default_account_id
for col in range(1):
sheet.write(row, col, "", style['title'])
sheet.write(row, 1, _("Balance %s:") % bank_account.code + ' ', style['title_right'])
account_bal = self._get_account_balance(bank_account, wizard)
if wizard.move_state == 'posted':
domain = [('parent_state', '=', 'posted')]
else:
# by default, the native method _get_journal_bank_account_balance()
# has ('parent_state', '!=', 'cancel')
domain = None
account_bal, nb_lines = journal._get_journal_bank_account_balance(domain=domain)
sheet.write(row, 2, account_bal, style['currency_bg'])
sheet.write(row, 2, account_bal, style[f"{jdi['currency']}_bg"])
jdi['total'] += account_bal
jdi['total_formula'] += '%s%d' % (jdi['total_col'], row + 1)
jdi['total_formula'] += f"{jdi['total_col']}{row + 1}"
row += 2
# 2) Show payment lines IN (debit)
debit_account = journal.payment_debit_account_id
row = self._write_move_lines_block(jdi, row, debit_account)
row += 2
# 3) Show payment lines OUT (credit)
credit_account = journal.payment_credit_account_id
row = self._write_move_lines_block(jdi, row, credit_account)
row += 2
for col in range(1):
sheet.write(row, col, "", style['title'])
sheet.write(row, 1, _("TOTAL:") + ' ', style['title_right'])
sheet.write_formula(
row, 2, jdi['total_formula'], style['currency_bg'], jdi['total'])
row += 3
row, 2, jdi['total_formula'], style[f"{jdi['currency']}_bg"], jdi['total'])
total_row = row
row += 2
# 4) Show suspense account lines
row = self._write_move_lines_block(
jdi, row, journal.suspense_account_id, add2total=False)
# Static cells
for col in range(1):
sheet.write(row, col, "", style['title'])
sheet.write(row, 1, _("Bank Balance:") + ' ', style['title_right'])
sheet.write(row, 2, 0, style[f"{jdi['currency']}_bg_manual"])
bank_bal_row = row
row += 2
for col in range(1):
sheet.write(row, col, "", style['title'])
sheet.write(row, 1, _("Difference:") + ' ', style['title_right'])
sheet.write_formula(
row, 2, f"={jdi['total_col']}{total_row + 1}-{jdi['total_col']}{bank_bal_row + 1}",
style[f"{jdi['currency']}_bg"], jdi['total'])
row += 2
for col in range(1):
sheet.write(row, col, "", style['title'])
sheet.write(row, 1, _("Justification:") + ' ', style['title_right'])
justif_lines = 6
sheet.write_formula(
row, 2, f"=SUM({jdi['total_col']}{row+3}:{jdi['total_col']}{row+3+justif_lines-1})",
style[f"{jdi['currency']}_bg"], 0)
row += 1
col_labels = [
_("Date"),
_("Description"),
_("Amount"),
]
col = 0
for col_label in col_labels:
sheet.write(row, col, col_label, style['col_header'])
col += 1
for x in range(justif_lines):
row += 1
sheet.write(row, 0, "", style['regular_date'])
sheet.write(row, 1, "", style['regular'])
sheet.write(row, 2, "", style[jdi['currency']])
def _get_style(self, workbook, company):
style = {}
font_size = 10
light_grey = "#eeeeee"
title_blue = "#e6e6fa"
light_blue = "#e0edff"
subtotal_orange = "#ffcc00"
title_warn = "#ff9999"
subtotal_warn = "#ffff99"
light_purple = "#ffdeff"
amount_manual = "#ffeeab"
title_warn = "#ff9999"
lang_code = self.env.user.lang
lang = False
if lang_code:
@@ -249,7 +322,7 @@ class BankReconciliationXlsx(models.AbstractModel):
)
title_style = {
"bold": True,
"bg_color": title_blue,
"bg_color": light_blue,
"font_size": font_size,
"align": "left",
}
@@ -257,7 +330,7 @@ class BankReconciliationXlsx(models.AbstractModel):
style['title'] = workbook.add_format(dict(title_style))
style['wizard_field'] = workbook.add_format(dict(title_style, bg_color=light_grey))
wizard_value_style = {
"bg_color": light_purple,
"bg_color": light_blue,
"bold": True,
"font_size": font_size,
"align": "left",
@@ -274,23 +347,29 @@ class BankReconciliationXlsx(models.AbstractModel):
dict(title_style, align="left", bg_color=title_warn))
style['title_right_warn'] = workbook.add_format(
dict(title_style, align="right", bg_color=title_warn))
style['regular'] = workbook.add_format({"font_size": font_size})
style['regular'] = workbook.add_format({"font_size": font_size, "border": 1})
if "%" in xls_date_format:
# fallback
xls_date_format = "yyyy-mm-dd"
style['regular_date'] = workbook.add_format(
{"num_format": xls_date_format, "font_size": font_size, "align": "left"}
{"num_format": xls_date_format, "font_size": font_size, "align": "left", "border": 1}
)
cur_format = "#,##0.00 %s" % (
company.currency_id.symbol or company.currency_id.name
)
# It seems that Excel replaces automatically the decimal
# and thousand separator by those of the language under which
# Excel runs
currency_style = {"num_format": cur_format, "font_size": font_size}
style['currency'] = workbook.add_format(currency_style)
style['currency_bg'] = workbook.add_format(
dict(currency_style, bg_color=subtotal_orange))
style['currency_bg_warn'] = workbook.add_format(
dict(currency_style, bg_color=subtotal_warn))
for currency in self.env['res.currency'].search([]):
symbol = currency.symbol or currency.name
decimals = '0' * currency.decimal_places
if currency.position == 'before':
cur_format = f"{symbol} #,##0.{decimals}"
else:
cur_format = f"#,##0.{decimals} {symbol}"
# It seems that Excel replaces automatically the decimal
# and thousand separator by those of the language under which
# Excel runs
currency_style = {"num_format": cur_format, "font_size": font_size}
style[currency] = workbook.add_format(dict(currency_style, border=1))
style[f'{currency}_bg'] = workbook.add_format(
dict(currency_style, bg_color=subtotal_orange))
style[f'{currency}_bg_warn'] = workbook.add_format(
dict(currency_style, bg_color=subtotal_warn))
style[f'{currency}_bg_manual'] = workbook.add_format(
dict(currency_style, bg_color=amount_manual))
return style

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2017-2023 Akretion France (http://www.akretion.com/)
Copyright 2017-2024 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).
-->
@@ -12,7 +12,6 @@
<field name="report_type">xlsx</field>
<field name="report_name">bank.reconciliation.xlsx</field>
<field name="report_file">bank.reconciliation.xlsx</field>
<!-- print_report_name doesn't work here... -->
<field name="print_report_name">'bank_reconciliation-%s' % (object.date)</field>
</record>
</odoo>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2017-2020 Akretion France (http://www.akretion.com/)
Copyright 2017-2024 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).
-->

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2018-2023 Akretion France (http://www.akretion.com/)
Copyright 2018-2024 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).
-->
@@ -9,7 +9,7 @@
<record id="account_journal_dashboard_kanban_view" model="ir.ui.view">
<field
name="name"
>bank_reconciliation_summarry.account_journal_dashboard</field>
>bank_reconciliation_summary.account_journal_dashboard</field>
<field name="model">account.journal</field>
<field name="inherit_id" ref="account.account_journal_dashboard_kanban_view" />
<field name="arch" type="xml">

View File

@@ -1,4 +1,4 @@
# Copyright 2017-2023 Akretion France (http://www.akretion.com/)
# Copyright 2017-2024 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).

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2017-2023 Akretion France (http://www.akretion.com/)
Copyright 2017-2024 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).
-->

View File

@@ -0,0 +1,68 @@
=======================================
Account Default Report Without Paiement
=======================================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:2035514c3af2d372479b91ca5314fe2f5ff90523f11fb8cc874b4fac8b375f50
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github
:target: https://github.com/akretion/odoo-usability/tree/14.0/account_default_report_without_paiement
:alt: akretion/odoo-usability
|badge1| |badge2| |badge3|
This module switch the default account report to the one without paiement
**Table of contents**
.. contents::
:local:
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/akretion/odoo-usability/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/akretion/odoo-usability/issues/new?body=module:%20account_default_report_without_paiement%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* Akretion
Contributors
~~~~~~~~~~~~
* Kévin Roche <kevin.roche@akretion.com>
Maintainers
~~~~~~~~~~~
.. |maintainer-Kev-Roche| image:: https://github.com/Kev-Roche.png?size=40px
:target: https://github.com/Kev-Roche
:alt: Kev-Roche
Current maintainer:
|maintainer-Kev-Roche|
This module is part of the `akretion/odoo-usability <https://github.com/akretion/odoo-usability/tree/14.0/account_default_report_without_paiement>`_ project on GitHub.
You are welcome to contribute.

View File

@@ -0,0 +1,22 @@
# Copyright 2024 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": "Account Default Report Without Paiement",
"summary": "Account Default Report Without Paiement",
"version": "14.0.1.0.0",
"category": "reports",
"website": "https://github.com/OCA/account",
"author": "Akretion, Odoo Community Association (OCA)",
"license": "AGPL-3",
"maintainers":["Kev-Roche"],
"application": False,
"installable": True,
"depends": [
"account",
],
"data": [
"data/data.xml",
],
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Copyright (C) 2024 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). -->
<odoo>
<record id="account.account_invoices" model="ir.actions.report">
<field name="report_name">account.report_invoice</field>
<field name="report_file">account.report_invoice</field>
</record>
<record id="account.account_invoices_without_payment" model="ir.actions.report">
<field name="name">Factures avec paiement</field>
<field name="report_name">account.report_invoice_with_payments</field>
<field name="report_file">account.report_invoice_with_payments</field>
</record>
</odoo>

View File

@@ -0,0 +1 @@
* Kévin Roche <kevin.roche@akretion.com>

View File

@@ -0,0 +1 @@
This module switch the default account report to the one without paiement

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Purchase Report Date Planned</title>
<title>Account Default Report Without Paiement</title>
<style type="text/css">
/*
@@ -360,17 +360,17 @@ ul.auto-toc {
</style>
</head>
<body>
<div class="document" id="purchase-report-date-planned">
<h1 class="title">Purchase Report Date Planned</h1>
<div class="document" id="account-default-report-without-paiement">
<h1 class="title">Account Default Report Without Paiement</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:5b4d315e1329bf5a241110f6470bdde81407d7bad14c0e687c590a92a80ea414
!! source digest: sha256:2035514c3af2d372479b91ca5314fe2f5ff90523f11fb8cc874b4fac8b375f50
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/purchase-workflow/tree/14.0/purchase_report_date_planned"><img alt="OCA/purchase-workflow" src="https://img.shields.io/badge/github-OCA%2Fpurchase--workflow-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/purchase-workflow-14-0/purchase-workflow-14-0-purchase_report_date_planned"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/purchase-workflow&amp;target_branch=14.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module add the field date_planned on purchase report model, purchase report tree view and add a filter that allows you to display orders that are late for delivery</p>
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/akretion/odoo-usability/tree/14.0/account_default_report_without_paiement"><img alt="akretion/odoo-usability" src="https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github" /></a></p>
<p>This module switch the default account report to the one without paiement</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
@@ -385,10 +385,10 @@ ul.auto-toc {
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/purchase-workflow/issues">GitHub Issues</a>.
<p>Bugs are tracked on <a class="reference external" href="https://github.com/akretion/odoo-usability/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/purchase-workflow/issues/new?body=module:%20purchase_report_date_planned%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<a class="reference external" href="https://github.com/akretion/odoo-usability/issues/new?body=module:%20account_default_report_without_paiement%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
@@ -402,22 +402,15 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
<ul class="simple">
<li>Mathieu Delva &lt;<a class="reference external" href="mailto:mathieu.delva&#64;akretion.com">mathieu.delva&#64;akretion.com</a>&gt;</li>
<li>Kévin Roche &lt;<a class="reference external" href="mailto:kevin.roche&#64;akretion.com">kevin.roche&#64;akretion.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-5">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/mathieudelva"><img alt="mathieudelva" src="https://github.com/mathieudelva.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/purchase-workflow/tree/14.0/purchase_report_date_planned">OCA/purchase-workflow</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
<p>Current maintainer:</p>
<p><a class="reference external image-reference" href="https://github.com/Kev-Roche"><img alt="Kev-Roche" src="https://github.com/Kev-Roche.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/akretion/odoo-usability/tree/14.0/account_default_report_without_paiement">akretion/odoo-usability</a> project on GitHub.</p>
<p>You are welcome to contribute.</p>
</div>
</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -227,6 +227,12 @@ class AccountMoveUpdate(models.TransientModel):
inv.message_post(body=_(
'Non-legal fields of invoice updated via the Invoice Update '
'wizard.'))
# Purge existing PDF
report = self.env.ref("account.account_invoices")
attachment = report.retrieve_attachment(inv)
# attachment may be None
if attachment:
attachment.unlink()
return True

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,25 @@
# Copyright 2024 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': 'Account Payment Line Manual Account',
'version': '14.0.1.0.0',
'category': 'Accounting',
'license': 'AGPL-3',
'summary': 'Ability to select the account on payment lines without journal item',
'description': """
With this module, when you manually create a payment line that is not linked to a journal item, you can select an account (by default, it is set to the payable/receivable account of the partner) : this account will be used as the counter part of the outbound/inbound payment account configured on the bank journal. It covers special needs of a few companies that use SEPA credit transfer for the same partner in different accounting scenarios.
This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'maintainers': ['alexis-via'],
'website': 'https://github.com/akretion/odoo-usability',
'depends': ['account_payment_order'],
'data': [
"views/account_payment_line.xml",
],
'installable': True,
}

View File

@@ -0,0 +1,2 @@
from . import account_payment_line
from . import account_payment_order

View File

@@ -0,0 +1,38 @@
# Copyright 2024 Akretion France (https://www.akretion.com/)
# @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
class AccountPaymentLine(models.Model):
_inherit = "account.payment.line"
account_id = fields.Many2one(
'account.account',
compute="_compute_account_id", store=True, readonly=False, check_company=True,
domain="[('company_id', '=', company_id), ('deprecated', '=', False)]")
analytic_account_id = fields.Many2one(
'account.analytic.account', string='Analytic Account',
domain="[('company_id', 'in', [False, company_id])]",
check_company=True)
@api.depends('move_line_id', 'partner_id')
def _compute_account_id(self):
for line in self:
account_id = False
if not line.move_line_id and line.partner_id:
partner = line.partner_id.with_company(line.order_id.company_id.id)
if line.order_id.payment_type == "inbound":
account_id = partner.property_account_receivable_id.id
else:
account_id = partner.property_account_payable_id.id
line.account_id = account_id
# take info account account_id for grouping
def payment_line_hashcode(self):
hashcode = super().payment_line_hashcode()
account_str = str(self.account_id.id or False)
analytic_account_str = str(self.analytic_account_id.id or False)
hashcode = '-'.join([hashcode, account_str, analytic_account_str])
return hashcode

View File

@@ -0,0 +1,18 @@
# Copyright 2024 Akretion France (https://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import models
class AccountPaymentOrder(models.Model):
_inherit = "account.payment.order"
def _prepare_move_line_partner_account(self, bank_line):
vals = super()._prepare_move_line_partner_account(bank_line)
if not bank_line.payment_line_ids[0].move_line_id:
vals.update({
'account_id': bank_line.payment_line_ids[0].account_id.id,
'analytic_account_id': bank_line.payment_line_ids[0].analytic_account_id.id or False,
})
return vals

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2024 Akretion France (https://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_payment_line_form" model="ir.ui.view">
<field name="model">account.payment.line</field>
<field name="inherit_id" ref="account_payment_order.account_payment_line_form"/>
<field name="arch" type="xml">
<field name="company_id" position="after">
<field name="account_id" attrs="{'invisible': [('move_line_id', '!=', False)], 'required': [('move_line_id', '=', False)]}"/>
<field name="analytic_account_id" attrs="{'invisible': [('move_line_id', '!=', False)]}" groups="analytic.group_analytic_accounting"/>
</field>
</field>
</record>
<record id="account_payment_line_tree" model="ir.ui.view">
<field name="model">account.payment.line</field>
<field name="inherit_id" ref="account_payment_order.account_payment_line_tree"/>
<field name="arch" type="xml">
<field name="move_line_id" position="after">
<field name="account_id" optional="hide"/>
<field name="analytic_account_id" optional="hide" groups="analytic.group_analytic_accounting"/>
</field>
</field>
</record>
</odoo>

View File

@@ -2,10 +2,13 @@
Account Usability
=================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:0a1f18d3ec52ddde3b0ffdb507573d43a38ec1609a578fae0c43f5e5a65026be
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
@@ -14,10 +17,10 @@ Account Usability
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github
:target: https://github.com/akretion/odoo-usability/tree/12.0/account_usability
:target: https://github.com/akretion/odoo-usability/tree/14.0/account_usability
:alt: akretion/odoo-usability
|badge1| |badge2| |badge3|
|badge1| |badge2| |badge3|
This modules adds the following functions:
@@ -52,7 +55,6 @@ This modules adds the following functions:
* don't attach PDF upon invoice report generation on supplier invoices/refunds
* Add filter on debit and credit amount for Move Lines
* Add supplier invoice number in invoice tree view
* Add date in outstanding payment widget on invoice form view (requires `odoo PR 84180 <https://github.com/odoo/odoo/pull/84180>`_)
Together with this module, I recommend the use of the following modules:
@@ -70,8 +72,8 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/akretion/odoo-usability/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/akretion/odoo-usability/issues/new?body=module:%20account_usability%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/akretion/odoo-usability/issues/new?body=module:%20account_usability%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
@@ -92,6 +94,6 @@ Contributors
Maintainers
~~~~~~~~~~~
This module is part of the `akretion/odoo-usability <https://github.com/akretion/odoo-usability/tree/12.0/account_usability>`_ project on GitHub.
This module is part of the `akretion/odoo-usability <https://github.com/akretion/odoo-usability/tree/14.0/account_usability>`_ project on GitHub.
You are welcome to contribute.

View File

@@ -52,6 +52,39 @@ class AccountMove(models.Model):
string="Dispute",
tracking=True,
)
# Having amounts in invoice currency can be useful in tree view of invoices
# We add those fields with optional="hide"
amount_untaxed_invoice_currency_signed = fields.Monetary(
compute="_compute_amount_invoice_currency_signed", store=True,
string="Untaxed Amount Invoice Currency Signed")
amount_tax_invoice_currency_signed = fields.Monetary(
compute="_compute_amount_invoice_currency_signed", store=True,
string="Tax Invoice Currency Signed")
amount_total_invoice_currency_signed = fields.Monetary(
compute="_compute_amount_invoice_currency_signed", store=True,
string="Total Invoice Currency Signed")
amount_residual_invoice_currency_signed = fields.Monetary(
compute="_compute_amount_invoice_currency_signed", store=True,
string="Amount Due Invoice Currency Signed")
# Field search_account_id is just for search view
search_account_id = fields.Many2one(related='line_ids.account_id')
@api.depends('amount_untaxed', 'amount_tax', 'amount_total', 'amount_residual', 'move_type')
def _compute_amount_invoice_currency_signed(self):
for move in self:
amount_untaxed_invoice_currency_signed = move.amount_untaxed
amount_tax_invoice_currency_signed = move.amount_tax
amount_total_invoice_currency_signed = move.amount_total
amount_residual_invoice_currency_signed = move.amount_residual
if move.move_type in ('out_refund', 'in_refund'):
amount_untaxed_invoice_currency_signed *= -1
amount_tax_invoice_currency_signed *= -1
amount_total_invoice_currency_signed *= -1
amount_residual_invoice_currency_signed *= -1
move.amount_untaxed_invoice_currency_signed = amount_untaxed_invoice_currency_signed
move.amount_tax_invoice_currency_signed = amount_tax_invoice_currency_signed
move.amount_total_invoice_currency_signed = amount_total_invoice_currency_signed
move.amount_residual_invoice_currency_signed = amount_residual_invoice_currency_signed
@api.depends("line_ids", "line_ids.blocked")
def _compute_blocked(self):
@@ -225,45 +258,14 @@ class AccountMove(models.Model):
move.suitable_journal_ids = self.env['account.journal'].search(domain)
def button_draft(self):
# Get report name before reset to draft because name can be different.
report_names = self._get_invoice_attachment_name()
super().button_draft()
# Delete attached pdf invoice
if report_names:
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', 'in', report_names[move.id]),
('res_id', '=', move.id),
('res_model', '=', self._name),
('type', '=', 'binary'),
], limit=1)
if attachment:
attachment.unlink()
def _get_invoice_attachment_name(self):
report_names = defaultdict(list)
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')):
report_names[move.id].append(safe_eval(report_invoice.print_report_name, {'object': self, 'time': time}))
try:
report_invoice = self.env['ir.actions.report']._get_report_from_name('account.report_invoice_with_payments')
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')):
report_names[move.id].append(safe_eval(report_invoice.print_report_name, {'object': self, 'time': time}))
return report_names
for move in self.filtered(lambda x: x.move_type in ('out_invoice', 'out_refund')):
for report_xmlid in ('account.account_invoices', 'account.account_invoices_without_payment'):
report = self.env.ref(report_xmlid)
attach = report.retrieve_attachment(move)
if attach:
attach.unlink()
super().button_draft()
def _get_accounting_date(self, invoice_date, has_tax):
# On vendor bills/refunds, we want date = invoice_date unless

View File

@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Account Usability</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
@@ -275,7 +275,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
@@ -301,7 +301,7 @@ span.option {
span.pre {
white-space: pre }
span.problematic {
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
@@ -366,8 +366,10 @@ ul.auto-toc {
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:0a1f18d3ec52ddde3b0ffdb507573d43a38ec1609a578fae0c43f5e5a65026be
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/akretion/odoo-usability/tree/12.0/account_usability"><img alt="akretion/odoo-usability" src="https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github" /></a></p>
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/akretion/odoo-usability/tree/14.0/account_usability"><img alt="akretion/odoo-usability" src="https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github" /></a></p>
<p>This modules adds the following functions:</p>
<ul class="simple">
<li>Add an <em>Overdue</em> filter on invoice search view (this feature was previously
@@ -411,41 +413,41 @@ located in te module <em>account_invoice_overdue_filter</em>)</li>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#bug-tracker" id="id1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id5">Maintainers</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-5">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id1">Bug Tracker</a></h1>
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/akretion/odoo-usability/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/akretion/odoo-usability/issues/new?body=module:%20account_usability%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/akretion/odoo-usability/issues/new?body=module:%20account_usability%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id2">Credits</a></h1>
<h1><a class="toc-backref" href="#toc-entry-2">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id3">Authors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
<ul class="simple">
<li>Akretion</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id4">Contributors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
<ul class="simple">
<li>Alexis de Lattre &lt;<a class="reference external" href="mailto:alexis.delattre&#64;akretion.com">alexis.delattre&#64;akretion.com</a>&gt;</li>
<li>David Beal &lt;<a class="reference external" href="mailto:david.beal&#64;akretion.com">david.beal&#64;akretion.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id5">Maintainers</a></h2>
<p>This module is part of the <a class="reference external" href="https://github.com/akretion/odoo-usability/tree/12.0/account_usability">akretion/odoo-usability</a> project on GitHub.</p>
<h2><a class="toc-backref" href="#toc-entry-5">Maintainers</a></h2>
<p>This module is part of the <a class="reference external" href="https://github.com/akretion/odoo-usability/tree/14.0/account_usability">akretion/odoo-usability</a> project on GitHub.</p>
<p>You are welcome to contribute.</p>
</div>
</div>

View File

@@ -7,12 +7,24 @@
<odoo>
<record id="view_account_type_form" model="ir.ui.view">
<field name="name">account_usability.account_account_type.form</field>
<field name="model">account.account.type</field>
<field name="inherit_id" ref="account.view_account_type_form" />
<field name="arch" type="xml">
<field name="type" position="after">
<field name="internal_group"/>
</field>
</field>
</record>
<record id="view_account_type_tree" model="ir.ui.view">
<field name="name">account_usability.account_type_tree</field>
<field name="name">account_usability.account_account_type_tree</field>
<field name="model">account.account.type</field>
<field name="inherit_id" ref="account.view_account_type_tree" />
<field name="arch" type="xml">
<field name="type" position="after">
<field name="internal_group" optional="show"/>
<field name="include_initial_balance" optional="show"/>
</field>
</field>

View File

@@ -67,6 +67,14 @@
<field name="amount_residual_signed" position="attributes">
<attribute name="optional">show</attribute>
</field>
<field name="amount_untaxed_signed" position="before">
<!-- No sum="1" on the invoice currency fields, because it doesn't make sense
to add amounts in different currencies -->
<field name="amount_untaxed_invoice_currency_signed" string="Tax Excluded Inv. Cur." optional="hide"/>
<field name="amount_tax_invoice_currency_signed" string="Tax Inv. Cur." optional="hide"/>
<field name="amount_total_invoice_currency_signed" string="Total Inv. Cur." optional="hide"/>
<field name="amount_residual_invoice_currency_signed" string="Amount Due Inv. Cur." optional="hide"/>
</field>
</field>
</record>
@@ -93,6 +101,16 @@
</field>
</record>
<record id="view_account_move_filter" model="ir.ui.view">
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_account_move_filter"/>
<field name="arch" type="xml">
<field name="journal_id" position="after">
<field name="search_account_id"/>
</field>
</field>
</record>
<record id="view_move_line_form" model="ir.ui.view">
<field name="model">account.move.line</field>
<field name="inherit_id" ref="account.view_move_line_form"/>

View File

@@ -2,10 +2,13 @@
Base Company Extension
======================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f1f2fb39af0682210c6ac91e106869ab7bfffe1c397becc289eaaf68b707e933
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
@@ -14,24 +17,28 @@ Base Company Extension
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github
:target: https://github.com/akretion/odoo-usability/tree/12.0/base_company_extension
:target: https://github.com/akretion/odoo-usability/tree/14.0/base_company_extension
:alt: akretion/odoo-usability
|badge1| |badge2| |badge3|
This module adds the following fields on the company:
|badge1| |badge2| |badge3|
This module adds the following fields to the ResCompany model:
* Capital Amount
* Legal Type
This is useful to display the legal name of the company in reports.
This is useful to display the legal name of the company in reports
**Table of contents**
.. contents::
:local:
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/akretion/odoo-usability/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/akretion/odoo-usability/issues/new?body=module:%20base_company_extension%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
@@ -52,6 +59,6 @@ Contributors
Maintainers
~~~~~~~~~~~
This module is part of the `akretion/odoo-usability <https://github.com/akretion/odoo-usability/tree/12.0/base_company_extension>`_ project on GitHub.
This module is part of the `akretion/odoo-usability <https://github.com/akretion/odoo-usability/tree/14.0/base_company_extension>`_ project on GitHub.
You are welcome to contribute.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Base Company Extension</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
@@ -275,7 +275,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
@@ -301,7 +301,7 @@ span.option {
span.pre {
white-space: pre }
span.problematic {
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
@@ -366,8 +366,10 @@ ul.auto-toc {
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f1f2fb39af0682210c6ac91e106869ab7bfffe1c397becc289eaaf68b707e933
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/akretion/odoo-usability/tree/12.0/base_company_extension"><img alt="akretion/odoo-usability" src="https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github" /></a></p>
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/akretion/odoo-usability/tree/14.0/base_company_extension"><img alt="akretion/odoo-usability" src="https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github" /></a></p>
<p>This module adds the following fields to the ResCompany model:
* Capital Amount
* Legal Type</p>
@@ -375,40 +377,40 @@ ul.auto-toc {
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#bug-tracker" id="id1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id5">Maintainers</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-5">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id1">Bug Tracker</a></h1>
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/akretion/odoo-usability/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/akretion/odoo-usability/issues/new?body=module:%20base_company_extension%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/akretion/odoo-usability/issues/new?body=module:%20base_company_extension%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id2">Credits</a></h1>
<h1><a class="toc-backref" href="#toc-entry-2">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id3">Authors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
<ul class="simple">
<li>Akretion</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id4">Contributors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
<ul class="simple">
<li>Alexis de Lattre &lt;<a class="reference external" href="mailto:alexis.delattre&#64;akretion.com">alexis.delattre&#64;akretion.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id5">Maintainers</a></h2>
<p>This module is part of the <a class="reference external" href="https://github.com/akretion/odoo-usability/tree/12.0/base_company_extension">akretion/odoo-usability</a> project on GitHub.</p>
<h2><a class="toc-backref" href="#toc-entry-5">Maintainers</a></h2>
<p>This module is part of the <a class="reference external" href="https://github.com/akretion/odoo-usability/tree/14.0/base_company_extension">akretion/odoo-usability</a> project on GitHub.</p>
<p>You are welcome to contribute.</p>
</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -2,10 +2,13 @@
Base Usability
==============
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:34b38099c08b1967a5082dd802765b1b34015403159badf256ee845648d9e6da
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
@@ -14,10 +17,10 @@ Base Usability
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github
:target: https://github.com/akretion/odoo-usability/tree/12.0/base_usability
:target: https://github.com/akretion/odoo-usability/tree/14.0/base_usability
:alt: akretion/odoo-usability
|badge1| |badge2| |badge3|
|badge1| |badge2| |badge3|
This module adds the following functions:
@@ -55,8 +58,8 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/akretion/odoo-usability/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/akretion/odoo-usability/issues/new?body=module:%20base_usability%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/akretion/odoo-usability/issues/new?body=module:%20base_usability%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
@@ -72,11 +75,12 @@ Contributors
~~~~~~~~~~~~
* Alexis de Lattre <alexis.delattre@akretion.com>
* Raphaël Valyi <rvalyi@akretion.com>
* David Beal <david.beal@akretion.com>
Maintainers
~~~~~~~~~~~
This module is part of the `akretion/odoo-usability <https://github.com/akretion/odoo-usability/tree/12.0/base_usability>`_ project on GitHub.
This module is part of the `akretion/odoo-usability <https://github.com/akretion/odoo-usability/tree/14.0/base_usability>`_ project on GitHub.
You are welcome to contribute.

View File

@@ -0,0 +1,13 @@
diff --git a/odoo/tools/mimetypes.py b/odoo/tools/mimetypes.py
index d104198a4ae..6eeabcc63a3 100644
--- a/odoo/tools/mimetypes.py
+++ b/odoo/tools/mimetypes.py
@@ -123,7 +123,7 @@ _mime_mappings = (
_Entry('image/png', [b'\x89PNG\r\n\x1A\n'], []),
_Entry('image/gif', [b'GIF87a', b'GIF89a'], []),
_Entry('image/bmp', [b'BM'], []),
- _Entry('image/svg+xml', [b'<'], [
+ _Entry('application/xml', [b'<'], [
_check_svg,
]),
_Entry('image/x-icon', [b'\x00\x00\x01\x00'], []),

View File

@@ -69,6 +69,10 @@ class ResCompany(models.Model):
'value': hasattr(self, 'siren') and self.siren or False,
'label': _('SIREN:'),
},
'rcs_siren': {
'value': hasattr(self, 'siren') and self.siren and self.company_registry and f"{self.company_registry} {self.siren}",
'label': 'RCS',
},
'eori': {
'value': self._get_eori(),
'label': _('EORI:'),
@@ -102,7 +106,7 @@ class ResCompany(models.Model):
"""This method is designed to be inherited"""
# I decided not to put email in the default header because only a few very small
# companies have a generic company email address
line_details = [['phone', 'website', 'capital'], ['vat', 'siret', 'eori', 'ape']]
line_details = [['phone', 'website', 'rcs_siren', 'capital'], ['vat', 'siret', 'eori', 'ape']]
return line_details
# for reports

View File

@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Base Usability</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
@@ -275,7 +275,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
@@ -301,7 +301,7 @@ span.option {
span.pre {
white-space: pre }
span.problematic {
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
@@ -366,8 +366,10 @@ ul.auto-toc {
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:34b38099c08b1967a5082dd802765b1b34015403159badf256ee845648d9e6da
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/akretion/odoo-usability/tree/12.0/base_usability"><img alt="akretion/odoo-usability" src="https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github" /></a></p>
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/akretion/odoo-usability/tree/14.0/base_usability"><img alt="akretion/odoo-usability" src="https://img.shields.io/badge/github-akretion%2Fodoo--usability-lightgray.png?logo=github" /></a></p>
<p>This module adds the following functions:</p>
<ul class="simple">
<li>Adds <em>track_visibility=onchange</em> on all the important fields of the Partner object</li>
@@ -397,41 +399,42 @@ ul.auto-toc {
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#bug-tracker" id="id1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id5">Maintainers</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-1">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-2">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-3">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-4">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-5">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id1">Bug Tracker</a></h1>
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/akretion/odoo-usability/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/akretion/odoo-usability/issues/new?body=module:%20base_usability%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/akretion/odoo-usability/issues/new?body=module:%20base_usability%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id2">Credits</a></h1>
<h1><a class="toc-backref" href="#toc-entry-2">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id3">Authors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-3">Authors</a></h2>
<ul class="simple">
<li>Akretion</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id4">Contributors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
<ul class="simple">
<li>Alexis de Lattre &lt;<a class="reference external" href="mailto:alexis.delattre&#64;akretion.com">alexis.delattre&#64;akretion.com</a>&gt;</li>
<li>Raphaël Valyi &lt;<a class="reference external" href="mailto:rvalyi&#64;akretion.com">rvalyi&#64;akretion.com</a>&gt;</li>
<li>David Beal &lt;<a class="reference external" href="mailto:david.beal&#64;akretion.com">david.beal&#64;akretion.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id5">Maintainers</a></h2>
<p>This module is part of the <a class="reference external" href="https://github.com/akretion/odoo-usability/tree/12.0/base_usability">akretion/odoo-usability</a> project on GitHub.</p>
<h2><a class="toc-backref" href="#toc-entry-5">Maintainers</a></h2>
<p>This module is part of the <a class="reference external" href="https://github.com/akretion/odoo-usability/tree/14.0/base_usability">akretion/odoo-usability</a> project on GitHub.</p>
<p>You are welcome to contribute.</p>
</div>
</div>

View File

@@ -0,0 +1,16 @@
diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js
index e4c1b187169..ccd8110478f 100644
--- a/addons/web/static/src/js/views/form/form_renderer.js
+++ b/addons/web/static/src/js/views/form/form_renderer.js
@@ -516,7 +516,10 @@ var FormRenderer = BasicRenderer.extend({
* @returns {integer}
*/
_renderButtonBoxNbButtons: function () {
- return [2, 2, 2, 4][config.device.size_class] || 7;
+ /* AKRETION HACK 24/04/2024
+ * show 14 buttons before adding 'More' dropdown list (instead of 7 by default
+ */
+ return [2, 2, 2, 4][config.device.size_class] || 14;
},
/**
* Do not render a field widget if it is always invisible.

View File

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

View File

@@ -0,0 +1,46 @@
# Copyright 2019-2025 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': 'Commission Simple',
'version': '14.0.1.0.0',
'category': 'Sales',
'license': 'AGPL-3',
'summary': 'Compute commissions for salesman',
'description': """
Commission Simple
=================
This module is a **simple** module to compute commission for salesman. From my experience, companies often use very specific methods to compute commissions and it's impossible to develop a module that can support all of them. So the goal of this module is just to have a simple base to build the company-specific commissionning system by inheriting this simple module.
Here is a short description of this module:
* create commission profiles using rules (per product category, per product, per product and customer, etc.),
* the commission rules can have a start and end date (optional),
* commissionning can happen on invoicing or on payment,
* each invoice line can only be commissionned to one salesman,
* commission reports are stored in Odoo.
This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'https://github.com/akretion/odoo-usability',
'depends': [
'account',
'date_range',
],
'data': [
'security/ir.model.access.csv',
'security/rule.xml',
'data/decimal_precision.xml',
'views/commission_profile.xml',
'views/commission_rule.xml',
'views/commission_result.xml',
'views/account_move_line.xml',
'views/res_config_settings.xml',
'wizards/commission_compute_view.xml',
],
'installable': True,
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<record forcecreate="True" id="commission_rate" model="decimal.precision">
<field name="name">Commission Rate</field>
<field name="digits">2</field>
</record>
</odoo>

View File

@@ -0,0 +1,640 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * commission_simple
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-29 23:38+0000\n"
"PO-Revision-Date: 2024-11-29 23:38+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: commission_simple
#: model:ir.model.constraint,message:commission_simple.constraint_commission_result_salesman_period_company_unique
msgid ""
"A commission result already exists for this salesman/agent for the same "
"period."
msgstr ""
"Un état des commissions existe déjà pour ce vendeur/agent pour la même "
"période."
#. module: commission_simple
#. odoo-python
#: code:addons/commission_simple/models/commission_profile.py:0
#, python-format
msgid "A salesman must be selected when the assignment type is 'Salesman'."
msgstr ""
"Un vendeur doit être sélectionné lorsque le type d'affectation est "
"\"Vendeur\"."
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__message_needaction
msgid "Action Needed"
msgstr "Action requise"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__active
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__active
msgid "Active"
msgstr "Actif"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__activity_ids
msgid "Activities"
msgstr "Activités"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__activity_exception_decoration
msgid "Activity Exception Decoration"
msgstr "Style d'affichage de l'activité-alerte"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__activity_state
msgid "Activity State"
msgstr "État de l'activité"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__activity_type_icon
msgid "Activity Type Icon"
msgstr "Îcone du type d'activité"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__applied_on
msgid "Apply On"
msgstr "Conditions"
#. module: commission_simple
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_profile_form
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_rule_search
msgid "Archived"
msgstr "Archivé"
#. module: commission_simple
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_result_form
msgid "Are you sure you want to go back to draft?"
msgstr "Êtes-vous sûr de vouloir revenir à l'état brouillon ?"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__assign_type
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_result_search
msgid "Assign Type"
msgstr "Type d'affectation"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__assign_ids
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_profile_form
msgid "Assignments"
msgstr "Assignations"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__message_attachment_count
msgid "Attachment Count"
msgstr "Nombre de pièces jointes"
#. module: commission_simple
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_result_form
msgid "Back to Draft"
msgstr "Remettre en brouillon"
#. module: commission_simple
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_compute_form
msgid "Cancel"
msgstr "Annuler"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_account_move_line__commission_amount
msgid "Commission Amount"
msgstr "Montant de la commission"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_account_move_line__commission_base
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__base
msgid "Commission Base"
msgstr "Base de la commission"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__line_ids
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_result_form
msgid "Commission Lines"
msgstr "Lignes commission"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_compute__date_range_type_id
#: model:ir.model.fields,field_description:commission_simple.field_res_company__commission_date_range_type_id
#: model:ir.model.fields,field_description:commission_simple.field_res_config_settings__commission_date_range_type_id
msgid "Commission Periodicity"
msgstr "Périodicité de commission"
#. module: commission_simple
#: model:ir.model,name:commission_simple.model_commission_profile
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__profile_id
msgid "Commission Profile"
msgstr "Profil de commission"
#. module: commission_simple
#: model:ir.model,name:commission_simple.model_commission_profile_assignment
msgid "Commission Profile Assignment"
msgstr "Affectation du profil de commission"
#. module: commission_simple
#: model:ir.actions.act_window,name:commission_simple.commission_profile_action
#: model:ir.ui.menu,name:commission_simple.commission_profile_menu
msgid "Commission Profiles"
msgstr "Profils de commission"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_account_move_line__commission_rate
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__rate
msgid "Commission Rate"
msgstr "Taux de commission"
#. module: commission_simple
#: model:ir.model,name:commission_simple.model_commission_result
#: model:ir.model.fields,field_description:commission_simple.field_account_move_line__commission_result_id
msgid "Commission Result"
msgstr "État des commissions"
#. module: commission_simple
#: model:ir.model,name:commission_simple.model_commission_rule
msgid "Commission Rule"
msgstr "Règle de commission"
#. module: commission_simple
#: model:ir.actions.act_window,name:commission_simple.commission_rule_action
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__rule_ids
#: model:ir.ui.menu,name:commission_simple.commission_rule_menu
msgid "Commission Rules"
msgstr "Règles de commission"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__amount_total
msgid "Commission Total"
msgstr "Total des commissions"
#. module: commission_simple
#: model:ir.actions.act_window,name:commission_simple.commission_result_action
#: model:ir.ui.menu,name:commission_simple.commission_config_root
#: model:ir.ui.menu,name:commission_simple.commission_result_menu
#: model:ir.ui.menu,name:commission_simple.commission_root
#: model_terms:ir.ui.view,arch_db:commission_simple.res_config_settings_view_form
msgid "Commissions"
msgstr ""
#. module: commission_simple
#. odoo-python
#: code:addons/commission_simple/wizards/commission_compute.py:0
#, python-format
msgid "Commissions already exist for %(period)s in company %(company)s."
msgstr ""
"Des commissions existent déjà pour %(period)s dans la société %(company)s."
#. module: commission_simple
#: model:ir.model,name:commission_simple.model_res_company
msgid "Companies"
msgstr "Sociétés"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_compute__company_id
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__company_id
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile_assignment__company_id
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__company_id
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__company_id
msgid "Company"
msgstr "Société"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__company_currency_id
msgid "Company Currency"
msgstr "Devise de la société"
#. module: commission_simple
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_compute_form
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_rule_form
msgid "Compute"
msgstr "Calculer"
#. module: commission_simple
#: model:ir.actions.act_window,name:commission_simple.commission_compute_action
#: model:ir.model,name:commission_simple.model_commission_compute
#: model:ir.ui.menu,name:commission_simple.commission_compute_menu
msgid "Compute Commissions"
msgstr "Calculer les commissions"
#. module: commission_simple
#: model:ir.model,name:commission_simple.model_res_config_settings
msgid "Config Settings"
msgstr "Configuration"
#. module: commission_simple
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_result_form
msgid "Confirm"
msgstr "Confirmer"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_compute__create_uid
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__create_uid
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile_assignment__create_uid
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__create_uid
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__create_uid
msgid "Created by"
msgstr "Créé par"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_compute__create_date
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__create_date
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile_assignment__create_date
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__create_date
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__create_date
msgid "Created on"
msgstr "Créé le"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__partner_ids
msgid "Customers"
msgstr "Clients"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_compute__display_name
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__display_name
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile_assignment__display_name
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__display_name
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__display_name
msgid "Display Name"
msgstr "Nom affiché"
#. module: commission_simple
#: model:ir.model.fields.selection,name:commission_simple.selection__commission_result__state__done
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_result_search
msgid "Done"
msgstr "Validé"
#. module: commission_simple
#: model:ir.model.fields.selection,name:commission_simple.selection__commission_result__state__draft
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_result_search
msgid "Draft"
msgstr "Brouillon"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__date_end
msgid "End Date"
msgstr "Date de fin"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_compute__date_end
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__date_end
msgid "End date"
msgstr "Date de fin"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__message_follower_ids
msgid "Followers"
msgstr "Abonnés"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__message_partner_ids
msgid "Followers (Partners)"
msgstr "Abonnés (partenaires)"
#. module: commission_simple
#: model:ir.model.fields,help:commission_simple.field_commission_result__activity_type_icon
msgid "Font awesome icon e.g. fa-tasks"
msgstr "Îcone font-awesome, par exemple fa-task"
#. module: commission_simple
#: model:ir.model.fields.selection,name:commission_simple.selection__commission_rule__applied_on__4_global
msgid "Global"
msgstr ""
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__has_message
msgid "Has Message"
msgstr "A un message"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_compute__id
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__id
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile_assignment__id
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__id
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__id
msgid "ID"
msgstr ""
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__activity_exception_icon
msgid "Icon"
msgstr "Îcone"
#. module: commission_simple
#: model:ir.model.fields,help:commission_simple.field_commission_result__activity_exception_icon
msgid "Icon to indicate an exception activity."
msgstr "Îcone pour indiquer une activité-alerte"
#. module: commission_simple
#: model:ir.model.fields,help:commission_simple.field_commission_result__message_needaction
msgid "If checked, new messages require your attention."
msgstr "Si activé, de nouveaux messages nécessitent votre attention."
#. module: commission_simple
#: model:ir.model.fields,help:commission_simple.field_commission_result__message_has_error
msgid "If checked, some messages have a delivery error."
msgstr "Si activé, des messages ont une erreur d'envoi."
#. module: commission_simple
#: model:ir.model.fields.selection,name:commission_simple.selection__commission_profile__trigger_type__in_payment
msgid "In Payment and Paid"
msgstr "En paiement et payé"
#. module: commission_simple
#: model:ir.model.fields.selection,name:commission_simple.selection__commission_profile__trigger_type__invoice
msgid "Invoiced"
msgstr "Facturé"
#. module: commission_simple
#: model:ir.model.fields.selection,name:commission_simple.selection__commission_rule__base__invoiced
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_result_form
msgid "Invoiced Amount"
msgstr "Montant facturé"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__message_is_follower
msgid "Is Follower"
msgstr "Est abonné"
#. module: commission_simple
#: model:ir.model,name:commission_simple.model_account_move_line
msgid "Journal Item"
msgstr "Écriture comptable"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_compute____last_update
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile____last_update
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile_assignment____last_update
#: model:ir.model.fields,field_description:commission_simple.field_commission_result____last_update
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule____last_update
msgid "Last Modified on"
msgstr "Dernière modification le"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_compute__write_uid
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__write_uid
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile_assignment__write_uid
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__write_uid
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__write_uid
msgid "Last Updated by"
msgstr "Dernière mise à jour par"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_compute__write_date
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__write_date
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile_assignment__write_date
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__write_date
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__write_date
msgid "Last Updated on"
msgstr "Dernière mise à jour le"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__message_main_attachment_id
msgid "Main Attachment"
msgstr "Pièce jointe principale"
#. module: commission_simple
#: model:ir.model.fields.selection,name:commission_simple.selection__commission_rule__base__margin
msgid "Margin"
msgstr "Marge"
#. module: commission_simple
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_rule_form
msgid "Match"
msgstr ""
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_account_move_line__commission_rule_id
msgid "Matched Commission Rule"
msgstr "Règle de commission associée"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__message_has_error
msgid "Message Delivery error"
msgstr "Erreur d'envoi du message"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__message_ids
msgid "Messages"
msgstr ""
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__my_activity_date_deadline
msgid "My Activity Deadline"
msgstr "Date butoir de l'activité"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__name
msgid "Name of the Profile"
msgstr "Nom du profil"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__activity_calendar_event_id
msgid "Next Activity Calendar Event"
msgstr "Prochaine activité du calendrier"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__activity_date_deadline
msgid "Next Activity Deadline"
msgstr "Date butoir de l'activité suivante"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__activity_summary
msgid "Next Activity Summary"
msgstr "Résumé de l'activité suivante"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__activity_type_id
msgid "Next Activity Type"
msgstr "Type de l'activité suivante"
#. module: commission_simple
#. odoo-python
#: code:addons/commission_simple/wizards/commission_compute.py:0
#, python-format
msgid "No commissions generated."
msgstr "Aucune commission n'a été générée."
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__message_needaction_counter
msgid "Number of Actions"
msgstr "Nombre d'actions"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__message_has_error_counter
msgid "Number of errors"
msgstr "Nombre d'erreurs"
#. module: commission_simple
#: model:ir.model.fields,help:commission_simple.field_commission_result__message_needaction_counter
msgid "Number of messages requiring action"
msgstr "Nombre de messages nécessitant une action"
#. module: commission_simple
#: model:ir.model.fields,help:commission_simple.field_commission_result__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr "Nombre de messages en échec d'envoi"
#. module: commission_simple
#: model:ir.model.fields.selection,name:commission_simple.selection__commission_profile__trigger_type__paid
msgid "Paid"
msgstr "Payé"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_compute__date_range_id
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__date_range_id
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_result_search
msgid "Period"
msgstr "Période"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__product_categ_ids
#: model:ir.model.fields.selection,name:commission_simple.selection__commission_rule__applied_on__3_product_category
msgid "Product Categories"
msgstr "Catégories de produits"
#. module: commission_simple
#: model:ir.model.fields.selection,name:commission_simple.selection__commission_rule__applied_on__1_customer_product_category
msgid "Product Categories and Customers"
msgstr "Catégories de produits et clients"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_account_move_line__product_categ_id
msgid "Product Category"
msgstr "Catégorie de produit"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__product_ids
#: model:ir.model.fields.selection,name:commission_simple.selection__commission_rule__applied_on__2_product
msgid "Products"
msgstr "Produits"
#. module: commission_simple
#: model:ir.model.fields.selection,name:commission_simple.selection__commission_rule__applied_on__0_customer_product
msgid "Products and Customers"
msgstr "Produits et clients"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile_assignment__profile_id
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__profile_id
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_rule_search
msgid "Profile"
msgstr "Profil"
#. module: commission_simple
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_result_form
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_rule_tree
msgid "Rate (%)"
msgstr "Taux (%)"
#. module: commission_simple
#: model:ir.model.constraint,message:commission_simple.constraint_commission_rule_rate_positive
msgid "Rate must be positive !"
msgstr "Le taux doit être positif !"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__activity_user_id
msgid "Responsible User"
msgstr "Utilisateur responsable"
#. module: commission_simple
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_profile_form
msgid "Rules"
msgstr "Règles"
#. module: commission_simple
#. odoo-python
#: code:addons/commission_simple/models/commission_profile.py:0
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile_assignment__user_id
#: model_terms:ir.ui.view,arch_db:commission_simple.commission_result_search
#, python-format
msgid "Salesman"
msgstr "Vendeur"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__partner_id
msgid "Salesman/Agent"
msgstr "Vendeur/Agent"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__sequence
msgid "Sequence"
msgstr "Séquence"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_rule__date_start
msgid "Start Date"
msgstr "Date de début"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_compute__date_start
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__date_start
msgid "Start date"
msgstr "Date de début"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__state
msgid "State"
msgstr "État"
#. module: commission_simple
#: model:ir.model.fields,help:commission_simple.field_commission_result__activity_state
msgid ""
"Status based on activities\n"
"Overdue: Due date is already passed\n"
"Today: Activity date is today\n"
"Planned: Future activities."
msgstr ""
"Statut basé sur les activités\n"
"En retard : La date d'échéance est déjà dépassée\n"
"Aujourd'hui : La date de l'activité est aujourd'hui\n"
"Planifié : Activités futures."
#. module: commission_simple
#: model:ir.model.constraint,message:commission_simple.constraint_commission_profile_assignment_company_user_uniq
msgid "This salesman already has an assignment in this company."
msgstr "Ce vendeur a déjà une assignation dans cette société."
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile__trigger_type
msgid "Trigger"
msgstr "Déclencheur"
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_profile_assignment__assign_type
msgid "Type"
msgstr ""
#. module: commission_simple
#: model:ir.model.fields,help:commission_simple.field_commission_result__activity_exception_decoration
msgid "Type of the exception activity on record."
msgstr "Type de l'activité-alerte sur l'enregistrement."
#. module: commission_simple
#: model:ir.model.fields,field_description:commission_simple.field_commission_result__website_message_ids
msgid "Website Messages"
msgstr "Messages du site Web"
#. module: commission_simple
#: model:ir.model.fields,help:commission_simple.field_commission_result__website_message_ids
msgid "Website communication history"
msgstr "Historique des échanges sur le site Web"
#. module: commission_simple
#. odoo-python
#: code:addons/commission_simple/models/commission_result.py:0
#, python-format
msgid "You cannot delete commission result %s because it is in done state."
msgstr ""
"Vous ne pouvez pas supprimer l'état de commission %s parce qu'il est à "
"l'état \"validé\"."

View File

@@ -0,0 +1,5 @@
from . import commission_profile
from . import commission_rule
from . import commission_result
from . import res_company
from . import account_move_line

View File

@@ -0,0 +1,90 @@
# Copyright 2019-2024 Akretion France (http://www.akretion.com/)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.tools import float_is_zero
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
commission_result_id = fields.Many2one(
'commission.result', string='Commission Result', check_company=True)
commission_rule_id = fields.Many2one(
'commission.rule', 'Matched Commission Rule', ondelete='restrict', check_company=True)
commission_base = fields.Monetary('Commission Base', currency_field='company_currency_id')
commission_rate = fields.Float('Commission Rate', digits='Commission Rate')
commission_amount = fields.Monetary(
string='Commission Amount', currency_field='company_currency_id',
readonly=True, compute='_compute_commission_amount', store=True)
# to display on commission line
product_categ_id = fields.Many2one(
related='product_id.product_tmpl_id.categ_id')
@api.depends('commission_rate', 'commission_base')
def _compute_commission_amount(self):
for line in self:
commission_amount = False
if not line.display_type:
commission_amount = line.company_currency_id.round(
line.commission_rate * line.commission_base / 100.0)
line.commission_amount = commission_amount
def _match_commission_rule(self, rules):
# commission rules are already in the right order
self.ensure_one()
for rule in rules:
if rule['date_start'] and rule['date_start'] > self.date:
continue
if rule['date_end'] and rule['date_end'] < self.date:
continue
if rule['applied_on'] == '0_customer_product':
if (
self.partner_id.id in
rule['partner_ids'] and
self.product_id.id in rule['product_ids']):
return rule
elif rule['applied_on'] == '1_customer_product_category':
if (
self.partner_id.id in
rule['partner_ids'] and
self.product_categ_id.id in rule['product_categ_ids']):
return rule
elif rule['applied_on'] == '2_product':
if self.product_id.id in rule['product_ids']:
return rule
elif rule['applied_on'] == '3_product_category':
if self.product_categ_id.id in rule['product_categ_ids']:
return rule
elif rule['applied_on'] == '4_global':
return rule
return False
def _prepare_commission_data(self, rule):
self.ensure_one()
rate_prec = self.env['decimal.precision'].precision_get('Commission Rate')
lvals = {
'commission_rule_id': rule['id'],
# company currency
# inherit this method to change the value below if you want to base on margin
# or something else
'commission_rate': rule['rate'],
}
if rule['base'] == 'margin':
# What do we do if it's negative ? For the moment, it adds a negative commission line
cost = 0
if self.product_id and self.product_uom_id:
# if the module account_invoice_margin from akretion/odoo-usability is installed
if hasattr(self, 'margin_company_currency'):
cost = self.margin_company_currency
else:
sign = self.move_id.move_type == 'out_refund' and -1 or 1
cost = self.product_id.standard_price * self.product_uom_id._compute_quantity(self.quantity, self.product_id.uom_id) * sign
lvals['commission_base'] = self.balance * -1 - cost
else:
lvals['commission_base'] = self.balance * -1
if float_is_zero(lvals['commission_rate'], precision_digits=rate_prec) or self.company_currency_id.is_zero(lvals['commission_base']):
return False
return lvals

View File

@@ -0,0 +1,125 @@
# Copyright Akretion France (http://www.akretion.com/)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models, api, _
from odoo.exceptions import ValidationError
class CommissionProfile(models.Model):
_name = 'commission.profile'
_description = 'Commission Profile'
_order = 'sequence, id'
name = fields.Char(string='Name of the Profile', required=True)
active = fields.Boolean(string='Active', default=True)
sequence = fields.Integer()
company_id = fields.Many2one(
'res.company', string='Company', ondelete='cascade',
required=False, default=lambda self: self.env.company)
assign_ids = fields.One2many(
'commission.profile.assignment', 'profile_id', string="Assignments")
rule_ids = fields.One2many(
'commission.rule', 'profile_id', string='Commission Rules')
trigger_type = fields.Selection([
('invoice', 'Invoiced'),
('paid', 'Paid'),
('in_payment', 'In Payment and Paid'),
], default='paid', string='Trigger', required=True)
class CommissionProfileAssignment(models.Model):
_name = "commission.profile.assignment"
_description = "Commission Profile Assignment"
profile_id = fields.Many2one('commission.profile', ondelete='cascade')
company_id = fields.Many2one(
'res.company', string='Company', ondelete='cascade',
required=True, default=lambda self: self.env.company)
assign_type = fields.Selection(
'_assign_type_selection', default='user', required=True, string="Type")
user_id = fields.Many2one(
'res.users', compute="_compute_user_id", store=True, readonly=False,
ondelete="restrict", string="Salesman",
)
_sql_constraints = [
(
'company_user_uniq',
'unique(user_id, company_id)',
'This salesman already has an assignment in this company.')]
@api.model
def _assign_type_selection(self):
return [('user', _('Salesman'))]
@api.constrains('assign_type', 'user_id')
def _check_user(self):
for assignment in self:
if assignment.assign_type == 'user' and not assignment.user_id:
raise ValidationError(_("A salesman must be selected when the assignment type is 'Salesman'."))
@api.depends('assign_type')
def _compute_user_id(self):
for assign in self:
if assign.assign_type != 'user':
assign.user_id = False
def _get_partner(self):
self.ensure_one()
if self.assign_type == 'user':
return self.user_id.partner_id
return False
def _prepare_move_line_domain(self, date_range):
self.ensure_one()
domain = [
('display_type', '=', False),
('move_id.move_type', 'in', ('out_invoice', 'out_refund')),
('date', '<=', date_range.date_end),
('company_id', '=', self.company_id.id),
('commission_result_id', '=', False),
('parent_state', '=', 'posted'),
]
if self.assign_type == 'user':
domain.append(('move_id.invoice_user_id', '=', self.user_id.id))
# TODO : for trigger 'paid' and 'in_payment', we would need to filter
# out the invoices paid after the end date of the commission period
if self.profile_id.trigger_type == 'paid':
domain.append(('move_id.payment_state', 'in', ('paid', 'reversed')))
elif self.profile_id.trigger_type == 'in_payment':
domain.append(('move_id.payment_state', 'in', ('in_payment', 'paid', 'reversed')))
elif self.profile_id.trigger_type == 'invoice':
domain.append(('date', '>=', date_range.date_start))
return domain
def _prepare_commission_result(self, date_range):
vals = {
'partner_id': self._get_partner().id,
'profile_id': self.profile_id.id,
'date_range_id': date_range.id,
'assign_type': self.assign_type,
'company_id': self.company_id.id,
}
return vals
def _generate_commission_result(self, date_range, rules):
self.ensure_one()
ilines = self.env['account.move.line'].search(
self._prepare_move_line_domain(date_range), order='date, move_id, sequence, id')
profile = self.profile_id
ilines2write = {}
for iline in ilines:
rule = iline._match_commission_rule(rules[profile.id])
if rule:
lvals = iline._prepare_commission_data(rule)
if lvals:
ilines2write[iline] = lvals
if ilines2write:
com_result = self.env['commission.result'].create(self._prepare_commission_result(date_range))
for iline, vals in ilines2write.items():
iline.write(dict(vals, commission_result_id=com_result.id))
return com_result
else:
return False

View File

@@ -0,0 +1,77 @@
# Copyright Akretion France (http://www.akretion.com/)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models, api, _
from odoo.exceptions import UserError
class CommissionResult(models.Model):
_name = 'commission.result'
_description = "Commission Result"
_order = 'date_start desc'
_inherit = ['mail.thread', 'mail.activity.mixin']
partner_id = fields.Many2one(
'res.partner', string='Salesman/Agent', required=True, ondelete='restrict',
readonly=True, tracking=True)
profile_id = fields.Many2one(
'commission.profile', string='Commission Profile', readonly=True, tracking=True)
assign_type = fields.Selection('_assign_type_selection', readonly=True, tracking=True)
company_id = fields.Many2one(
'res.company', string='Company', ondelete='cascade',
required=True, readonly=True, default=lambda self: self.env.company, tracking=True)
company_currency_id = fields.Many2one(
related='company_id.currency_id', string='Company Currency', store=True)
date_range_id = fields.Many2one(
'date.range', required=True, string='Period', readonly=True, tracking=True)
date_start = fields.Date(related='date_range_id.date_start', store=True)
date_end = fields.Date(related='date_range_id.date_end', store=True)
line_ids = fields.One2many(
'account.move.line', 'commission_result_id', string='Commission Lines',
states={'done': [('readonly', True)]})
amount_total = fields.Monetary(
string='Commission Total', currency_field='company_currency_id',
compute='_compute_amount_total', store=True, tracking=True)
state = fields.Selection([
('draft', 'Draft'),
('done', 'Done'),
], default='draft', tracking=True)
# TODO copy amount to another field
# help='This is the total amount at the date of the computation of the commission')
@api.model
def _assign_type_selection(self):
return self.env['commission.profile.assignment']._assign_type_selection()
@api.depends('line_ids.commission_amount')
def _compute_amount_total(self):
rg_res = self.env['account.move.line'].read_group([('commission_result_id', 'in', self.ids)], ['commission_result_id', 'commission_amount:sum'], ['commission_result_id'])
mapped_data = dict([(x['commission_result_id'][0], x['commission_amount']) for x in rg_res])
for rec in self:
rec.amount_total = mapped_data.get(rec.id, 0)
def unlink(self):
for result in self:
if result.state == 'done':
raise UserError(_(
"You cannot delete commission result %s because it is in done state.") % result.display_name)
return super().unlink()
def draft2done(self):
self.write({'state': 'done'})
def backtodraft(self):
self.write({'state': 'draft'})
def name_get(self):
res = []
for result in self:
name = '%s (%s)' % (result.partner_id.name, result.date_range_id.name)
res.append((result.id, name))
return res
_sql_constraints = [(
'salesman_period_company_unique',
'unique(company_id, partner_id, date_range_id)',
'A commission result already exists for this salesman/agent for the same period.')]

View File

@@ -0,0 +1,52 @@
# Copyright Akretion France (http://www.akretion.com/)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models, api
class CommissionRule(models.Model):
_name = 'commission.rule'
_description = 'Commission Rule'
_order = 'profile_id, applied_on'
partner_ids = fields.Many2many(
'res.partner', string='Customers', domain=[('parent_id', '=', False)])
product_categ_ids = fields.Many2many(
'product.category', string="Product Categories")
product_ids = fields.Many2many('product.product', string='Products')
date_start = fields.Date('Start Date')
date_end = fields.Date('End Date')
profile_id = fields.Many2one(
'commission.profile', string='Profile', ondelete='cascade')
company_id = fields.Many2one(related='profile_id.company_id', store=True)
rate = fields.Float('Commission Rate', digits="Commission Rate", copy=False)
base = fields.Selection([
('invoiced', 'Invoiced Amount'),
('margin', 'Margin'),
], default='invoiced', required=True, string="Commission Base")
applied_on = fields.Selection([
('0_customer_product', 'Products and Customers'),
('1_customer_product_category', "Product Categories and Customers"),
('2_product', "Products"),
('3_product_category', "Product Categories"),
('4_global', 'Global')],
string='Apply On', default='4_global', required=True)
active = fields.Boolean(string='Active', default=True)
@api.model
def load_all_rules(self):
rules = self.search_read([('profile_id', '!=', False)])
res = {} # key = profile, value = [rule1 recordset, rule2]
for rule in rules:
if rule['profile_id'][0] not in res:
res[rule['profile_id'][0]] = [rule]
else:
res[rule['profile_id'][0]].append(rule)
return res
_sql_constraints = [(
'rate_positive',
'CHECK(rate >= 0)',
'Rate must be positive !')]

View File

@@ -0,0 +1,13 @@
# Copyright 2019-2024 Akretion France (https://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 ResCompany(models.Model):
_inherit = 'res.company'
commission_date_range_type_id = fields.Many2one(
'date.range.type', string='Commission Periodicity', ondelete='restrict')

View File

@@ -0,0 +1,11 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_commission_profile_read,Read access on commission.profile for employees,model_commission_profile,base.group_user,1,0,0,0
access_commission_profile_full,Full access on commission.profile for financial manager,model_commission_profile,account.group_account_manager,1,1,1,1
access_commission_profile_assignment_full,Full access on commission.profile.assignment for financial manager,model_commission_profile_assignment,account.group_account_manager,1,1,1,1
access_commission_rule_full,Full access on commission.rule for financial manager,model_commission_rule,account.group_account_manager,1,1,1,1
access_commission_rule_read,Read access on commission.rule for invoicing group,model_commission_rule,account.group_account_invoice,1,0,0,0
access_commission_rule_audit,Read access on commission.rule for viewer group,model_commission_rule,account.group_account_readonly,1,0,0,0
access_commission_result_full,Full access on commission.result to accountant,model_commission_result,account.group_account_user,1,1,1,1
access_commission_result_read,Read access on commission.result to invoicing grp,model_commission_result,account.group_account_invoice,1,0,0,0
access_commission_result_audit,Read access on commission.result to viewer grp,model_commission_result,account.group_account_readonly,1,0,0,0
access_commission_compute_full,Full access to wizard commission.compute,model_commission_compute,account.group_account_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_commission_profile_read Read access on commission.profile for employees model_commission_profile base.group_user 1 0 0 0
3 access_commission_profile_full Full access on commission.profile for financial manager model_commission_profile account.group_account_manager 1 1 1 1
4 access_commission_profile_assignment_full Full access on commission.profile.assignment for financial manager model_commission_profile_assignment account.group_account_manager 1 1 1 1
5 access_commission_rule_full Full access on commission.rule for financial manager model_commission_rule account.group_account_manager 1 1 1 1
6 access_commission_rule_read Read access on commission.rule for invoicing group model_commission_rule account.group_account_invoice 1 0 0 0
7 access_commission_rule_audit Read access on commission.rule for viewer group model_commission_rule account.group_account_readonly 1 0 0 0
8 access_commission_result_full Full access on commission.result to accountant model_commission_result account.group_account_user 1 1 1 1
9 access_commission_result_read Read access on commission.result to invoicing grp model_commission_result account.group_account_invoice 1 0 0 0
10 access_commission_result_audit Read access on commission.result to viewer grp model_commission_result account.group_account_readonly 1 0 0 0
11 access_commission_compute_full Full access to wizard commission.compute model_commission_compute account.group_account_manager 1 1 1 1

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019-2024 Akretion France (https://www.akretion.com)
@author Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
-->
<odoo noupdate="1">
<record id="commission_profile_rule" model="ir.rule">
<field name="name">Commission Profile multi-company</field>
<field name="model_id" ref="model_commission_profile"/>
<field name="domain_force">[('company_id', 'in', company_ids + [False])]</field>
</record>
<record id="commission_rule_rule" model="ir.rule">
<field name="name">Commission Rule multi-company</field>
<field name="model_id" ref="model_commission_rule"/>
<field name="domain_force">[('company_id', 'in', company_ids + [False])]</field>
</record>
<record id="commission_result_rule" model="ir.rule">
<field name="name">Commission Result multi-company</field>
<field name="model_id" ref="model_commission_result"/>
<field name="domain_force">[('company_id', 'in', company_ids)]</field>
</record>
</odoo>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2024 Akretion France (https://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_move_line_form" model="ir.ui.view">
<field name="model">account.move.line</field>
<field name="inherit_id" ref="account.view_move_line_form"/>
<field name="arch" type="xml">
<notebook position="inside">
<page name="commission" string="Commission" attrs="{'invisible': [('display_type', '!=', False)]}">
<group name="commission_grp">
<field name="commission_base"/>
<label for="commission_rate"/>
<div name="commission_rate">
<field name="commission_rate" class="oe_inline"/> %
</div>
<field name="commission_amount"/>
<field name="commission_rule_id"/>
<field name="display_type" invisible="1"/>
<field name="company_currency_id" invisible="1"/>
</group>
</page>
</notebook>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,206 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 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>
<menuitem id="commission_root" name="Commissions" parent="account.menu_finance" sequence="11"/>
<menuitem id="commission_config_root" name="Commissions" parent="account.menu_finance_configuration" sequence="110"/>
<!-- PROFILE -->
<record id="commission_profile_form" model="ir.ui.view">
<field name="name">commission.profile.form</field>
<field name="model">commission.profile</field>
<field name="arch" type="xml">
<form>
<sheet>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<group name="main">
<field name="name"/>
<field name="active" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="trigger_type"/>
</group>
<group name="lines" string="Rules">
<field name="line_ids" nolabel="1" colspan="2"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="commission_profile_tree" model="ir.ui.view">
<field name="name">commission.profile.tree</field>
<field name="model">commission.profile</field>
<field name="arch" type="xml">
<tree>
<field name="sequence" widget="handle"/>
<field name="name" decoration-bf="1"/>
<field name="trigger_type" optional="show"/>
<field name="company_id" groups="base.group_multi_company"/>
</tree>
</field>
</record>
<record id="commission_profile_action" model="ir.actions.act_window">
<field name="name">Commission Profiles</field>
<field name="res_model">commission.profile</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="commission_profile_menu" action="commission_profile_action" parent="commission_config_root" sequence="18"/>
<!-- RULE -->
<record id="commission_rule_form" model="ir.ui.view">
<field name="name">commission.rule.form</field>
<field name="model">commission.rule</field>
<field name="arch" type="xml">
<form>
<sheet>
<group name="main">
<field name="profile_id" invisible="not context.get('commission_rule_main_view')"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="company_id" invisible="1"/>
<field name="applied_on" widget="radio"/>
</group>
<group name="match" string="Match">
<field name="partner_ids" attrs="{'invisible': [('applied_on', 'not in', ('0_customer_product', '1_customer_product_category'))], 'required': [('applied_on', 'in', ('0_customer_product', '1_customer_product_category'))]}"/>
<field name="product_categ_ids" attrs="{'invisible': [('applied_on', 'not in', ('1_customer_product_category', '3_product_category'))], 'required': [('applied_on', 'in', ('1_customer_product_category', '3_product_category'))]}"/>
<field name="product_ids" attrs="{'invisible': [('applied_on', 'not in', ('0_customer_product', '2_product'))], 'required': [('applied_on', 'in', ('0_customer_product', '2_product'))]}"/>
<field name="date_start"/>
<field name="date_end"/>
</group>
<group name="compute" string="Compute">
<label for="rate"/>
<div name="rate">
<field name="rate" class="oe_inline"/> %
</div>
</group>
</sheet>
</form>
</field>
</record>
<record id="commission_rule_tree" model="ir.ui.view">
<field name="name">commission.rule.tree</field>
<field name="model">commission.rule</field>
<field name="arch" type="xml">
<tree>
<field name="profile_id" invisible="not context.get('commission_rule_main_view')"/>
<field name="applied_on"/>
<field name="date_start"/>
<field name="date_end"/>
<field name="rate" string="Rate (%)"/>
</tree>
</field>
</record>
<record id="commission_rule_search" model="ir.ui.view">
<field name="name">commission.rule.search</field>
<field name="model">commission.rule</field>
<field name="arch" type="xml">
<search>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<group name="groupby">
<filter name="profile_groupby" string="Profile" context="{'group_by': 'profile_id'}"/>
</group>
</search>
</field>
</record>
<record id="commission_rule_action" model="ir.actions.act_window">
<field name="name">Commission Rules</field>
<field name="res_model">commission.rule</field>
<field name="view_mode">tree,form</field>
<field name="context">{'commission_rule_main_view': True}</field>
</record>
<menuitem id="commission_rule_menu" action="commission_rule_action" parent="commission_config_root" sequence="20"/>
<!-- RESULT -->
<record id="commission_result_form" model="ir.ui.view">
<field name="name">commission.result.form</field>
<field name="model">commission.result</field>
<field name="arch" type="xml">
<form>
<group name="main">
<group name="main-left">
<field name="partner_id"/>
<field name="profile_id" groups="account.group_account_manager"/>
<field name="company_currency_id" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="amount_total"/>
</group>
<group name="main-right">
<field name="date_range_id"/>
<field name="date_start"/>
<field name="date_end"/>
</group>
</group>
<group name="lines" string="Commission Lines">
<field nolabel="1" name="line_ids" colspan="2">
<tree>
<field name="move_id"/>
<field name="move_line_id"/>
<field name="base"/>
<field name="rate" string="Rate (%)"/>
<field name="amount" sum="1"/>
<field name="rule_id"/>
<field name="company_currency_id" invisible="1"/>
</tree>
</field>
</group>
</form>
</field>
</record>
<record id="commission_result_tree" model="ir.ui.view">
<field name="name">commission.result.tree</field>
<field name="model">commission.result</field>
<field name="arch" type="xml">
<tree>
<field name="date_range_id" optional="show"/>
<field name="date_start" optional="hide"/>
<field name="date_end" optional="hide"/>
<field name="partner_id"/>
<field name="profile_id" groups="account.group_account_manager"/>
<field name="company_currency_id" invisible="1"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="amount_total" sum="1" optional="show"/>
</tree>
</field>
</record>
<record id="commission_result_search" model="ir.ui.view">
<field name="name">commission.result.search</field>
<field name="model">commission.result</field>
<field name="arch" type="xml">
<search>
<field name="partner_id"/>
<field name="date_range_id"/>
<group name="groupby">
<filter name="partner_groupby" string="Salesman" context="{'group_by': 'partner_id'}"/>
<filter name="date_range_groupby" string="Period" context="{'group_by': 'date_range_id'}"/>
</group>
</search>
</field>
</record>
<record id="commission_result_action" model="ir.actions.act_window">
<field name="name">Commissions</field>
<field name="res_model">commission.result</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="commission_result_menu" action="commission_result_action" parent="commission_root" sequence="10"/>
</odoo>

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019-2024 Akretion France (http://www.akretion.com)
@author Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
-->
<odoo>
<menuitem id="commission_root" name="Commissions" parent="account.menu_finance" sequence="11"/>
<menuitem id="commission_config_root" name="Commissions" parent="account.menu_finance_configuration" sequence="110"/>
<record id="commission_profile_form" model="ir.ui.view">
<field name="name">commission.profile.form</field>
<field name="model">commission.profile</field>
<field name="arch" type="xml">
<form>
<sheet>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<group name="main">
<group name="main-left">
<field name="name"/>
<field name="active" invisible="1"/>
<field name="trigger_type" widget="radio"/>
</group>
<group name="main-right">
<field name="company_id" invisible="1"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
</group>
<notebook>
<page name="assignments" string="Assignments">
<field name="assign_ids">
<tree editable="bottom">
<field name="assign_type"/>
<field name="user_id" attrs="{'required': [('assign_type', '=', 'user')], 'readonly': [('assign_type', '!=', 'user')]}"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="company_id" invisible="1"/>
</tree>
</field>
</page>
<page name="rules" string="Rules">
<field name="rule_ids"/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="commission_profile_tree" model="ir.ui.view">
<field name="name">commission.profile.tree</field>
<field name="model">commission.profile</field>
<field name="arch" type="xml">
<tree>
<field name="sequence" widget="handle"/>
<field name="name" decoration-bf="1"/>
<field name="trigger_type" optional="show"/>
<field name="company_id" groups="base.group_multi_company"/>
</tree>
</field>
</record>
<record id="commission_profile_action" model="ir.actions.act_window">
<field name="name">Commission Profiles</field>
<field name="res_model">commission.profile</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="commission_profile_menu" action="commission_profile_action" parent="commission_config_root" sequence="18"/>
</odoo>

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2024 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="commission_result_form" model="ir.ui.view">
<field name="name">commission.result.form</field>
<field name="model">commission.result</field>
<field name="arch" type="xml">
<form>
<header>
<button name="draft2done" type="object" states="draft" string="Confirm" class="btn-primary"/>
<button name="backtodraft" type="object" states="done" string="Back to Draft" confirm="Are you sure you want to go back to draft?"/>
<field name="state" widget="statusbar"/>
</header>
<group name="main">
<group name="main-left">
<field name="partner_id"/>
<field name="date_range_id"/>
<field name="date_start"/>
<field name="date_end"/>
<field name="amount_total"/>
<field name="company_currency_id" invisible="1"/>
<field name="company_id" invisible="1"/>
</group>
<group name="main-right">
<field name="profile_id" groups="account.group_account_manager"/>
<field name="assign_type"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
</group>
<group name="lines" string="Commission Lines">
<field nolabel="1" name="line_ids" colspan="2">
<tree>
<field name="move_id"/>
<field name="date" optional="hide"/>
<field name="partner_id"/>
<field name="product_id"/>
<field name="product_categ_id" optional="hide"/>
<field name="name" optional="hide"/>
<field name="price_subtotal" optional="hide" string="Invoiced Amount"/>
<field name="commission_base"/>
<field name="commission_rate" string="Rate (%)"/>
<field name="commission_amount" sum="1"/>
<field name="commission_rule_id" optional="hide"/>
<field name="company_currency_id" invisible="1"/>
<field name="currency_id" invisible="1"/>
</tree>
</field>
</group>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="activity_ids" widget="mail_activity"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<record id="commission_result_tree" model="ir.ui.view">
<field name="name">commission.result.tree</field>
<field name="model">commission.result</field>
<field name="arch" type="xml">
<tree decoration-info="state == 'draft'">
<field name="date_range_id" optional="show"/>
<field name="date_start" optional="hide"/>
<field name="date_end" optional="hide"/>
<field name="partner_id"/>
<field name="profile_id" groups="account.group_account_manager"/>
<field name="assign_type" optional="hide" widget="badge" decoration-warning="assign_type == 'user'"/>
<field name="company_currency_id" invisible="1"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="amount_total" sum="1" optional="show"/>
<field name="state" decoration-info="state == 'draft'" decoration-success="state == 'done'" widget="badge"/>
</tree>
</field>
</record>
<record id="commission_result_search" model="ir.ui.view">
<field name="name">commission.result.search</field>
<field name="model">commission.result</field>
<field name="arch" type="xml">
<search>
<field name="partner_id"/>
<field name="date_range_id"/>
<separator/>
<filter name="draft" domain="[('state', '=', 'draft')]" string="Draft"/>
<filter name="done" domain="[('state', '=', 'done')]" string="Done"/>
<separator/>
<filter name="user" domain="[('assign_type', '=', 'user')]" string="Salesman"/>
<group name="groupby">
<filter name="partner_groupby" string="Salesman" context="{'group_by': 'partner_id'}"/>
<filter name="date_range_groupby" string="Period" context="{'group_by': 'date_range_id'}"/>
<filter name="assign_type_groupby" string="Assign Type" context="{'group_by': 'assign_type'}"/>
</group>
</search>
</field>
</record>
<record id="commission_result_action" model="ir.actions.act_window">
<field name="name">Commissions</field>
<field name="res_model">commission.result</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="commission_result_menu" action="commission_result_action" parent="commission_root" sequence="10"/>
</odoo>

View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 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>
<record id="commission_rule_form" model="ir.ui.view">
<field name="name">commission.rule.form</field>
<field name="model">commission.rule</field>
<field name="arch" type="xml">
<form>
<sheet>
<group name="main">
<field name="profile_id" invisible="not context.get('commission_rule_main_view')"/>
<field name="applied_on" widget="radio"/>
<field name="company_id" invisible="1"/>
</group>
<group name="match" string="Match">
<field name="partner_ids" attrs="{'invisible': [('applied_on', 'not in', ('0_customer_product', '1_customer_product_category'))], 'required': [('applied_on', 'in', ('0_customer_product', '1_customer_product_category'))]}"/>
<field name="product_categ_ids" attrs="{'invisible': [('applied_on', 'not in', ('1_customer_product_category', '3_product_category'))], 'required': [('applied_on', 'in', ('1_customer_product_category', '3_product_category'))]}"/>
<field name="product_ids" attrs="{'invisible': [('applied_on', 'not in', ('0_customer_product', '2_product'))], 'required': [('applied_on', 'in', ('0_customer_product', '2_product'))]}"/>
<field name="date_start"/>
<field name="date_end"/>
</group>
<group name="compute" string="Compute">
<label for="rate"/>
<div name="rate">
<field name="rate" class="oe_inline"/> %
</div>
<field name="base" widget="radio"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="commission_rule_tree" model="ir.ui.view">
<field name="name">commission.rule.tree</field>
<field name="model">commission.rule</field>
<field name="arch" type="xml">
<tree>
<field name="profile_id" invisible="not context.get('commission_rule_main_view')"/>
<field name="applied_on"/>
<field name="date_start"/>
<field name="date_end"/>
<field name="rate" string="Rate (%)"/>
<field name="base"/>
</tree>
</field>
</record>
<record id="commission_rule_search" model="ir.ui.view">
<field name="name">commission.rule.search</field>
<field name="model">commission.rule</field>
<field name="arch" type="xml">
<search>
<field name="profile_id"/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<group name="groupby">
<filter name="profile_groupby" string="Profile" context="{'group_by': 'profile_id'}"/>
</group>
</search>
</field>
</record>
<record id="commission_rule_action" model="ir.actions.act_window">
<field name="name">Commission Rules</field>
<field name="res_model">commission.rule</field>
<field name="view_mode">tree,form</field>
<field name="context">{'commission_rule_main_view': True}</field>
</record>
<menuitem id="commission_rule_menu" action="commission_rule_action" parent="commission_config_root" sequence="20"/>
</odoo>

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019-2025 Akretion France (https://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="res_config_settings_view_form" model="ir.ui.view">
<field name="name">commission.res.config.settings.form</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="account.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//div[@id='analytic']" position="after">
<h2>Commissions</h2>
<div class="row mt16 o_settings_container" id="commission_simple">
<div class="col-12 col-lg-12 o_setting_box" id="commission_simple-settings">
<div class="o_setting_left_pane" />
<div class="o_setting_right_pane">
<div class="row" id="commission_date_range_type_id">
<label
for="commission_date_range_type_id"
class="col-md-5"
/>
<field name="commission_date_range_type_id" />
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,2 @@
from . import commission_compute
from . import res_config_settings

View File

@@ -0,0 +1,77 @@
# Copyright 2019-2024 Akretion France (http://www.akretion.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models, _
from dateutil.relativedelta import relativedelta
from odoo.exceptions import UserError
import logging
logger = logging.getLogger(__name__)
class CommissionCompute(models.TransientModel):
_name = 'commission.compute'
_description = 'Compute Commissions'
company_id = fields.Many2one('res.company', required=True, default=lambda self: self.env.company)
date_range_type_id = fields.Many2one(related='company_id.commission_date_range_type_id')
date_range_id = fields.Many2one(
'date.range', required=True, string='Period',
compute='_compute_date_range_id', store=True, readonly=False,
domain="[('type_id', '=', date_range_type_id)]")
date_start = fields.Date(related='date_range_id.date_start')
date_end = fields.Date(related='date_range_id.date_end')
@api.depends('company_id')
def _compute_date_range_id(self):
for wiz in self:
date_range_id = False
company = wiz.company_id
if company and company.commission_date_range_type_id:
type_id = company.commission_date_range_type_id.id
last_commission_result = self.env['commission.result'].search([
('company_id', '=', company.id),
], order='date_end desc', limit=1)
limit_date = last_commission_result and last_commission_result.date_end or (fields.Date.context_today(self) + relativedelta(months=-2, day=31))
date_range = self.env['date.range'].search([
('company_id', 'in', (company.id, False)),
('type_id', '=', type_id),
('date_start', '>', limit_date)
], order='date_start', limit=1)
date_range_id = date_range and date_range.id or False
wiz.date_range_id = date_range_id
def run(self):
self.ensure_one()
creso = self.env['commission.result']
date_range = self.date_range_id
existing_commissions = creso.search([
('date_range_id', '=', date_range.id),
('company_id', '=', self.company_id.id),
])
if existing_commissions:
raise UserError(_(
'Commissions already exist for %(period)s in company %(company)s.',
period=date_range.display_name, company=self.company_id.display_name))
com_result_ids = self._core_compute()
if not com_result_ids:
raise UserError(_('No commissions generated.'))
action = self.env['ir.actions.actions']._for_xml_id(
'commission_simple.commission_result_action')
action.update({
'views': False,
'domain': f"[('id', 'in', {com_result_ids})]",
})
return action
def _core_compute(self):
rules = self.env['commission.rule'].load_all_rules()
com_result_ids = []
assignments = self.env['commission.profile.assignment'].search([('company_id', '=', self.company_id.id)])
for assignment in assignments:
com_result = assignment._generate_commission_result(self.date_range_id, rules)
if com_result:
com_result_ids.append(com_result.id)
else:
logger.info("No commission for %s", assignment._get_partner().display_name)
return com_result_ids

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2019-2024 Akretion France (https://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="commission_compute_form" model="ir.ui.view">
<field name="name">commission.compute.form</field>
<field name="model">commission.compute</field>
<field name="arch" type="xml">
<form>
<group name="main">
<field name="company_id" groups="base.group_multi_company"/>
<field name="company_id" invisible="1"/>
<field name="date_range_type_id" invisible="1"/>
<field name="date_range_id"/>
<field name="date_start"/>
<field name="date_end"/>
</group>
<footer>
<button name="run" type="object" string="Compute"
class="btn-primary"/>
<button special="cancel" string="Cancel"/>
</footer>
</form>
</field>
</record>
<record id="commission_compute_action" model="ir.actions.act_window">
<field name="name">Compute Commissions</field>
<field name="res_model">commission.compute</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem id="commission_compute_menu" action="commission_compute_action" parent="commission_root" sequence="15" groups="account.group_account_user"/>
</odoo>

View File

@@ -0,0 +1,12 @@
# Copyright 2019-2024 Akretion France (https://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 ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
commission_date_range_type_id = fields.Many2one(
related='company_id.commission_date_range_type_id', readonly=False)

View File

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

View File

@@ -0,0 +1,22 @@
# Copyright 2019-2025 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': 'Commission Simple Agent',
'version': '14.0.1.0.0',
'category': 'Sales',
'license': 'AGPL-3',
'summary': 'Glue module between commission_simple and sale_agent',
'author': 'Akretion',
'website': 'https://github.com/akretion/odoo-usability',
'depends': [
'commission_simple',
'sale_agent',
],
'data': [
'views/commission_profile.xml',
'views/commission_result.xml',
],
'installable': True,
}

View File

@@ -0,0 +1,44 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * commission_simple_agent
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-29 23:32+0000\n"
"PO-Revision-Date: 2024-11-29 23:32+0000\n"
"Last-Translator: Alexis de Lattre <alexis.delattre@akretion.com>\n"
"Language-Team: \n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: commission_simple_agent
#. odoo-python
#: code:addons/commission_simple_agent/models/commission_profile_assignment.py:0
#: model:ir.model.fields,field_description:commission_simple_agent.field_commission_profile_assignment__agent_id
#: model_terms:ir.ui.view,arch_db:commission_simple_agent.commission_result_search
#, python-format
msgid "Agent"
msgstr "Agent"
#. module: commission_simple_agent
#. odoo-python
#: code:addons/commission_simple_agent/models/commission_profile_assignment.py:0
#, python-format
msgid "An agent must be selected when the assignment type is 'Agent'."
msgstr ""
"Un agent doit être sélectionné lorsque le type d'affectation est \"Agent\"."
#. module: commission_simple_agent
#: model:ir.model,name:commission_simple_agent.model_commission_profile_assignment
msgid "Commission Profile Assignment"
msgstr "Affectation du profil de commission"
#. module: commission_simple_agent
#: model:ir.model.constraint,message:commission_simple_agent.constraint_commission_profile_assignment_company_agent_uniq
msgid "This agent already has an assignment in this company."
msgstr "Cet agent a déjà une affectation dans cette société."

View File

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

View File

@@ -0,0 +1,51 @@
# Copyright Akretion France (http://www.akretion.com/)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class CommissionProfileAssignment(models.Model):
_inherit = "commission.profile.assignment"
agent_id = fields.Many2one(
'res.partner', ondelete='restrict',
compute="_compute_agent_id", store=True, readonly=False,
domain=[('agent', '=', True)])
_sql_constraints = [
(
'company_agent_uniq',
'unique(agent_id, company_id)',
'This agent already has an assignment in this company.')]
@api.model
def _assign_type_selection(self):
sel = super()._assign_type_selection()
sel.append(('agent', _('Agent')))
return sel
@api.constrains('assign_type', 'agent_id')
def _check_agent(self):
for assignment in self:
if assignment.assign_type == 'agent' and not assignment.agent_id:
raise ValidationError(_("An agent must be selected when the assignment type is 'Agent'."))
@api.depends('assign_type')
def _compute_agent_id(self):
for assign in self:
if assign.assign_type != 'agent':
assign.agent_id = False
def _prepare_move_line_domain(self, date_range):
domain = super()._prepare_move_line_domain(date_range)
if self.assign_type == 'agent':
domain.append(('move_id.invoice_agent_id', '=', self.agent_id.id))
return domain
def _get_partner(self):
self.ensure_one()
if self.assign_type == 'agent':
return self.agent_id
return super()._get_partner()

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2024 Akretion France (https://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="commission_profile_form" model="ir.ui.view">
<field name="model">commission.profile</field>
<field name="inherit_id" ref="commission_simple.commission_profile_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='assign_ids']/tree/field[@name='user_id']" position="after">
<field name="agent_id" attrs="{'required': [('assign_type', '=', 'agent')], 'readonly': [('assign_type', '!=', 'agent')]}"/>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2024 Akretion France (https://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="commission_result_tree" model="ir.ui.view">
<field name="model">commission.result</field>
<field name="inherit_id" ref="commission_simple.commission_result_tree"/>
<field name="arch" type="xml">
<field name="assign_type" position="attributes">
<attribute name="decoration-danger">assign_type == 'agent'</attribute>
</field>
</field>
</record>
<record id="commission_result_search" model="ir.ui.view">
<field name="model">commission.result</field>
<field name="inherit_id" ref="commission_simple.commission_result_search"/>
<field name="arch" type="xml">
<filter name="user" position="after">
<filter name="agent" domain="[('assign_type', '=', 'agent')]" string="Agent"/>
</filter>
</field>
</record>
</odoo>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -20,10 +20,10 @@ This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>.
""",
'author': 'Akretion',
'website': 'http://www.akretion.com',
'website': 'https://github.com/akretion/odoo-usability',
'depends': ['mass_mailing', 'link_tracker_usability'],
'data': [
# 'views/link_tracker.xml',
'views/link_tracker.xml',
],
'installable': False,
'installable': True,
}

View File

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

View File

@@ -0,0 +1,14 @@
# Copyright 2023 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class MassMailing(models.Model):
_inherit = 'mailing.mailing'
def action_view_clicked(self):
action = super().action_view_clicked()
action["view_mode"] = "tree,form"
return action

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -8,39 +8,13 @@
<odoo>
<record id="view_link_tracker_click_tree" model="ir.ui.view">
<record id="link_tracker_click_view_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="inherit_id" ref="mass_mailing.link_tracker_click_view_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 name="mass_mailing_id" position="after">
<field name="mailing_trace_id" optional="hide"/>
</field>
</field>
</record>

View File

@@ -22,7 +22,7 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
""",
'author': 'Akretion',
'website': 'https://github.com/akretion/odoo-usability',
'depends': ['mrp'],
'depends': ['mrp_account'],
'data': [
'security/mrp_average_cost_security.xml',
'security/ir.model.access.csv',

View File

@@ -165,7 +165,9 @@ class MrpProduction(models.Model):
company_currency_id = fields.Many2one(
related='company_id.currency_id', string='Company Currency')
# extra_cost is per unit in the UoM of the mrp.production (product_uom_id)
# extra_cost is a native field of mrp_account
# we convert it to a computed field
# extra_cost is per unit in the UoM of mrp.production (product_uom_id)
extra_cost = fields.Float(
compute='_compute_extra_cost', store=True, readonly=False,
help="For a regular production order, it takes into account the labor cost "
@@ -178,7 +180,7 @@ class MrpProduction(models.Model):
def _compute_extra_cost(self):
for prod in self:
bom = prod.bom_id
if bom and bom.type == 'normal':
if bom and bom.type == 'normal' and bom.product_uom_id.category_id == prod.product_uom_id.category_id:
extra_cost_bom_qty_uom = bom.extra_cost + bom.total_labour_cost
extra_cost_per_unit_in_prod_uom = 0
qty_prod_uom = bom.product_uom_id._compute_quantity(bom.product_qty, prod.product_uom_id)

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

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

View File

@@ -10,9 +10,11 @@
'summary': 'Usability improvements on mrp_subcontracting',
'author': 'Akretion',
'website': 'https://github.com/akretion/odoo-usability',
'depends': ['mrp_subcontracting'],
'depends': ['mrp_subcontracting', 'stock_usability'],
'data': [
'views/mrp_bom.xml',
'views/stock_move.xml',
'views/stock_picking.xml',
],
'installable': True,
}

View File

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

View File

@@ -0,0 +1,21 @@
# Copyright 2024 Akretion France (https://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class StockMove(models.Model):
_inherit = 'stock.move'
subcontracting_production_id = fields.Many2one(
'mrp.production',
compute='_compute_subcontracting_production_id',
)
def _compute_subcontracting_production_id(self):
for move in self:
subcontracting_production_id = False
if move.is_subcontract and move.move_orig_ids.production_id:
subcontracting_production_id = move.move_orig_ids.production_id[-1:].id
move.subcontracting_production_id = subcontracting_production_id

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2023 Akretion France (http://www.akretion.com/)
Copyright 2024 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).
-->

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