17 Commits

Author SHA1 Message Date
71e3188383 [FIX]account_budget_forecast:odoo cant copy multiple times on the same record One2many fields that all point to analic_id, so pass them to copy=False 2025-04-14 16:13:29 +02:00
2d7a37f65a [IMP]import_chart_of_accounts:manage final zero in account code 2024-06-19 16:31:42 +02:00
b4b007c1ae [MIG]import_chart_of_accounts 2024-05-30 15:00:23 +02:00
clementthomas
2d799eaf8c [IMP] account_partner_account_code : changes on field account_number
rename field account_number to account_code
field is now unique
2023-06-09 09:44:46 +02:00
clementthomas
5074244aa6 [ADD] account_partner_account_number:
new module to add account number on partner, visible in account move lines payable and receivable
2023-06-08 14:47:40 +02:00
clementthomas
2c3a647c17 [IMP] account_quotation_sale_order_invoice_title: add title in account move tree 2023-03-30 14:09:07 +02:00
Stéphan Sainléger
6dea772ace [FIX] account_budget_forecast: budget model line fields now required 2023-01-31 09:34:14 +01:00
Stéphan Sainléger
4e448a4dd9 [UPD] Enhance budget forecast form view 2022-06-30 14:14:58 +02:00
Stéphan Sainléger
77bdc39e32 [UPD] Add button to list draft invoice lines linked to budget line 2022-06-30 14:14:58 +02:00
Stéphan Sainléger
758592128e [UPD] Add User error if no analytic lines to display
from the budget forecast form view
2022-06-30 14:14:58 +02:00
Stéphan Sainléger
58235d3b51 [UPD] Refectoring of _calc_actual function for budget_lines
- expenses and incomes are calculated for both section, sub-section
and article lines
- for budget lines with child, the amounts are now always considering
both child values and analytic lines linked to the budget line
2022-06-30 14:14:58 +02:00
Stéphan Sainléger
b265056ed7 [UPD] Remove actual_quantity field
useless field as it mixes several kind of units
2022-06-30 14:14:58 +02:00
Stéphan Sainléger
1143d83184 [UPD] Add button to list budget line's linked analytic lines 2022-06-30 14:14:58 +02:00
Stéphan Sainléger
d76796bfa7 [UPD] Use analytic tags to link incomes/expenses to budget lines
instead of a direct budget_forecast field
2022-06-30 14:14:58 +02:00
Stéphan Sainléger
96fd3ae674 [UPD] Modify budget line name calculation method 2022-06-30 14:14:58 +02:00
Stéphan Sainléger
1883014efc [MIG] Migration account_budget_forecast addons to v14.0 2022-06-30 14:14:58 +02:00
Stéphan Sainléger
0cb6311966 [NEW] Addons creation - Account Quotation Sale Order Invoice Title 2022-06-24 14:35:59 +02:00
38 changed files with 881 additions and 157 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*.*~
*.pyc

View File

@@ -3,7 +3,7 @@
{
"name": "account_budget_forecast",
"version": "13.0.1.3.0",
"version": "14.0.1.4.0",
"author": "Elabore",
"maintainer": "False",
"website": "False",
@@ -65,6 +65,7 @@ This module is maintained by ELABORE.
"product",
"project",
"sale",
"sale_crm",
"stock",
],
"external_dependencies": {
@@ -76,7 +77,6 @@ This module is maintained by ELABORE.
"wizard/budget_forecast_model_choice.xml",
"views/account_analytic_account.xml",
"views/account_analytic_account_categories.xml",
"views/account_invoice.xml",
"views/sale_order.xml",
"views/budget_forecast.xml",
"views/budget_coefficient.xml",

View File

@@ -2,7 +2,6 @@
from . import account_analytic_account
from . import account_analytic_line
from . import account_move
from . import budget_forecast
from . import budget_forecast_model
from . import sale_order

View File

@@ -12,43 +12,43 @@ class AccountAnalyticAccount(models.Model):
"budget.forecast",
"analytic_id",
domain=[("budget_category", "=", "manpower")],
copy=True,
copy=False,
)
budget_forecast_material_ids = fields.One2many(
"budget.forecast",
"analytic_id",
domain=[("budget_category", "=", "material")],
copy=True,
copy=False,
)
budget_forecast_equipment_ids = fields.One2many(
"budget.forecast",
"analytic_id",
domain=[("budget_category", "=", "equipment")],
copy=True,
copy=False,
)
budget_forecast_subcontractors_ids = fields.One2many(
"budget.forecast",
"analytic_id",
domain=[("budget_category", "=", "subcontractors")],
copy=True,
copy=False,
)
budget_forecast_delivery_ids = fields.One2many(
"budget.forecast",
"analytic_id",
domain=[("budget_category", "=", "delivery")],
copy=True,
copy=False,
)
budget_forecast_miscellaneous_ids = fields.One2many(
"budget.forecast",
"analytic_id",
domain=[("budget_category", "=", "miscellaneous")],
copy=True,
copy=False,
)
budget_forecast_unplanned_ids = fields.One2many(
"budget.forecast",
"analytic_id",
domain=[("budget_category", "=", "unplanned")],
copy=True,
copy=False,
)
project_section_budget_ids = fields.One2many(
"budget.forecast",
@@ -146,15 +146,15 @@ class AccountAnalyticAccount(models.Model):
domain = [
("analytic_account_id", "=", record.id),
("parent_state", "in", ["draft", "posted"]),
("move_id.type", "in", ["out_invoice", "out_refund"]),
("move_id.move_type", "in", ["out_invoice", "out_refund"]),
]
invoice_lines = self.env["account.move.line"].search(domain)
for invoice_line in invoice_lines:
if invoice_line.move_id.type == "out_invoice":
if invoice_line.move_id.move_type == "out_invoice":
record.total_incomes = (
record.total_incomes + invoice_line.price_subtotal
)
elif invoice_line.move_id.type == "out_refund":
elif invoice_line.move_id.move_type == "out_refund":
record.total_incomes = (
record.total_incomes - invoice_line.price_subtotal
)

View File

@@ -6,4 +6,16 @@ from odoo import models, fields, api
class AccountAnalyticLine(models.Model):
_inherit = "account.analytic.line"
budget_forecast_id = fields.Many2one("budget.forecast")
timesheet_entry = fields.Boolean(
help="Technical field to identify analytic lines created from timesheet vies",
store=True,
default=False,
)
@api.model_create_multi
def create(self, vals_list):
lines = super(AccountAnalyticLine, self).create(vals_list)
for line, values in zip(lines, vals_list):
if line.project_id: # applied only for timesheet
line.timesheet_entry = True
return lines

View File

@@ -1,14 +0,0 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class AccountMoveLine(models.Model):
_inherit = "account.move.line"
budget_forecast_id = fields.Many2one("budget.forecast")
@api.depends("budget_forecast_id")
def _transfer_budget_forecast_line(self):
for record in self:
record.analytic_line_ids.budget_forecast_id = record.budget_forecast_id.id

View File

@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
import logging
from odoo import models, fields, api, _
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
@@ -19,6 +21,13 @@ class BudgetForecast(models.Model):
index=True,
copy=True,
)
analytic_tag = fields.Many2one(
"account.analytic.tag",
"Analytic tag",
index=True,
copy=False,
ondelete="cascade",
)
budget_category = fields.Selection(
[
@@ -61,16 +70,6 @@ class BudgetForecast(models.Model):
copy=False,
)
analytic_line_ids = fields.One2many(
"account.analytic.line", "budget_forecast_id", copy=False
)
actual_qty = fields.Float(
"Actual Quantity",
compute="_calc_actual",
store=True,
compute_sudo=True,
copy=False,
)
actual_amount = fields.Float(
"Expenses",
compute="_calc_actual",
@@ -114,6 +113,9 @@ class BudgetForecast(models.Model):
"line_subsection",
]:
record._create_category_sections()
record.analytic_tag = self.env["account.analytic.tag"].create(
{"name": record._calculate_name()}
)
return records
def _create_category_sections(self):
@@ -173,24 +175,32 @@ class BudgetForecast(models.Model):
return val
return ""
def _calculate_name(self):
for record in self:
name = (
record.description
+ " - "
+ record.product_id.name
+ " - "
+ record._get_budget_category_label()
+ " - "
+ record.analytic_id.name
)
return name
@api.onchange("description", "product_id")
def _compute_name(self):
for record in self:
if record.product_id:
name = (
record.description
+ " - "
+ record.product_id.name
+ " - "
+ record._get_budget_category_label()
+ " - "
+ record.analytic_id.name
)
values = {
"name": name,
}
values = {"name": record._calculate_name()}
record.write(values, False)
@api.onchange("name")
def _compute_analytic_tag_name(self):
for record in self:
if record.analytic_tag:
record.analytic_tag.name = record.name
def _sync_sections_data(self):
for record in self:
if record.display_type in ["line_section", "line_subsection"]:
@@ -330,69 +340,102 @@ class BudgetForecast(models.Model):
@api.depends("analytic_id.line_ids.amount")
def _calc_actual(self):
for record in self:
if record.display_type in ["line_section", "line_subsection"]:
record.actual_amount = 0.00
record.incomes = 0.00
if record.display_type in [
"line_section",
"line_subsection",
"line_article",
]:
if record.child_ids:
# Actual expenses are calculated with the child lines
record.actual_qty = sum(record.mapped("child_ids.actual_qty"))
# Addition of the childs values
record.actual_amount = sum(record.mapped("child_ids.actual_amount"))
# Incomes are calculated with the analytic lines
line_ids = record.analytic_line_ids.filtered(
lambda x: x.move_id.move_id.type
in ["out_invoice", "out_refund"]
)
record.incomes = sum(line_ids.mapped("amount"))
record.incomes = sum(record.mapped("child_ids.incomes"))
# Add Invoice lines ids
domain = [
("analytic_account_id", "=", record.analytic_id.id),
("parent_state", "in", ["draft", "posted"]),
("budget_forecast_id", "=", record.id),
("move_id.type", "in", ["out_invoice", "out_refund"]),
]
invoice_lines = self.env["account.move.line"].search(domain)
for invoice_line in invoice_lines:
if invoice_line.move_id.type == "out_invoice":
record.incomes = (
record.incomes + invoice_line.price_subtotal
)
elif invoice_line.move_id.type == "out_refund":
record.incomes = (
record.incomes - invoice_line.price_subtotal
)
record.balance = record.incomes - record.actual_amount
elif record.display_type == "line_note":
record.actual_qty = 0
record.actual_amount = 0.00
else:
line_ids = record.analytic_line_ids.filtered(
lambda x: x.move_id.move_id.type
not in ["out_invoice", "out_refund"]
# Retrieve all the analytics lines linked to the current budget line
analytic_lines = (
self.env["account.analytic.line"]
.search([])
.filtered(lambda x: record.analytic_tag in x.tag_ids)
)
record.actual_qty = abs(sum(line_ids.mapped("unit_amount")))
record.actual_amount = -sum(line_ids.mapped("amount"))
for line in analytic_lines:
if line.move_id:
if line.move_id.move_id.move_type in [
"out_invoice",
"out_refund",
"out_receipt",
]:
record.incomes = record.incomes + line.amount
elif line.move_id.move_id.move_type in [
"in_invoice",
"in_refund",
"in_receipt",
]:
record.actual_amount = record.actual_amount - line.amount
elif line.timesheet_entry:
record.actual_amount = record.actual_amount - line.amount
# Add Invoice lines ids
# Retrieve all the DRAFT invoices linked to the current budget line
domain = [
("analytic_account_id", "=", record.analytic_id.id),
("parent_state", "in", ["draft", "posted"]),
("budget_forecast_id", "=", record.id),
("move_id.type", "in", ["in_invoice", "in_refund"]),
("parent_state", "in", ["draft"]),
]
invoice_lines = self.env["account.move.line"].search(domain)
invoice_lines = (
self.env["account.move.line"]
.search(domain)
.filtered(lambda x: record.analytic_tag in x.analytic_tag_ids)
)
for invoice_line in invoice_lines:
if invoice_line.move_id.type == "in_invoice":
record.actual_qty = record.actual_qty + invoice_line.quantity
if invoice_line.move_id.move_type == "out_invoice":
record.incomes = record.incomes + invoice_line.price_subtotal
elif invoice_line.move_id.move_type == "out_refund":
record.incomes = record.incomes - invoice_line.price_subtotal
elif invoice_line.move_id.move_type == "in_invoice":
record.actual_amount = (
record.actual_amount + invoice_line.price_subtotal
)
elif invoice_line.move_id.type == "in_refund":
record.actual_qty = record.actual_qty - invoice_line.quantity
elif invoice_line.move_id.move_type == "in_refund":
record.actual_amount = (
record.actual_amount - invoice_line.price_subtotal
)
record.incomes = None
record.balance = None
record.balance = record.incomes - record.actual_amount
record.diff_expenses = record.plan_amount_with_coeff - record.actual_amount
def action_view_analytic_lines(self):
self.ensure_one()
analytic_lines = (
self.env["account.analytic.line"]
.search([])
.filtered(lambda x: self.analytic_tag in x.tag_ids)
)
if len(analytic_lines) > 0:
action = self.env["ir.actions.actions"]._for_xml_id(
"analytic.account_analytic_line_action_entries"
)
action["domain"] = [("tag_ids", "ilike", self.analytic_tag.id)]
return action
else:
raise UserError(_("There is no analytic lines linked to this budget line"))
def action_view_draft_invoice_lines(self):
self.ensure_one()
invoice_lines = (
self.env["account.move.line"]
.search([("parent_state", "in", ["draft"])])
.filtered(lambda x: self.analytic_tag in x.analytic_tag_ids)
)
if len(invoice_lines) > 0:
action = self.env["ir.actions.actions"]._for_xml_id(
"account.action_account_moves_all_tree"
)
action["domain"] = [
("analytic_tag_ids", "ilike", self.analytic_tag.id),
("parent_state", "in", ["draft"]),
]
return action
else:
raise UserError(
_("There is no draft invoice lines linked to this budget line")
)

View File

@@ -2,6 +2,8 @@
from odoo import models, fields, _, api
from odoo.exceptions import Warning
import logging
_logger = logging.getLogger(__name__)
class SaleOrder(models.Model):
@@ -49,9 +51,12 @@ class SaleOrder(models.Model):
name = self.analytic_account_id.name.replace(self.name, record.name)
else:
name = "%s: %s" % (self.analytic_account_id.name, record.name)
record.analytic_account_id = self.analytic_account_id.copy(
default=dict(name=name)
)
try:
copied_account = self.analytic_account_id.copy(default={"name": name})
if copied_account:
record.analytic_account_id = copied_account
except Exception as e:
_logger.error("Failed to copy analytic account for sale order %s: %s", self.name, e)
return record

View File

@@ -24,7 +24,6 @@
<field name="note" optional="hide" />
<field name="plan_price" />
<field name="plan_qty" />
<field name="actual_qty" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
<field name="plan_amount_without_coeff" string="Plan Amount before Coeff" />
<field name="plan_amount_with_coeff" string="Plan Amount after Coeff" />
<field name="actual_amount" string="Actual Amount" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
@@ -51,7 +50,6 @@
<field name="note" optional="hide" />
<field name="plan_price" />
<field name="plan_qty" />
<field name="actual_qty" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
<field name="plan_amount_without_coeff" string="Plan Amount before Coeff" />
<field name="plan_amount_with_coeff" string="Plan Amount after Coeff" />
<field name="actual_amount" string="Actual Amount" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
@@ -78,7 +76,6 @@
<field name="note" optional="hide" />
<field name="plan_price" />
<field name="plan_qty" />
<field name="actual_qty" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
<field name="plan_amount_without_coeff" string="Plan Amount before Coeff" />
<field name="plan_amount_with_coeff" string="Plan Amount after Coeff" />
<field name="actual_amount" string="Actual Amount" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
@@ -105,7 +102,6 @@
<field name="note" optional="hide" />
<field name="plan_price" />
<field name="plan_qty" />
<field name="actual_qty" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
<field name="plan_amount_without_coeff" string="Plan Amount before Coeff" />
<field name="plan_amount_with_coeff" string="Plan Amount after Coeff" />
<field name="actual_amount" string="Actual Amount" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
@@ -132,7 +128,6 @@
<field name="note" optional="hide" />
<field name="plan_price" />
<field name="plan_qty" />
<field name="actual_qty" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
<field name="plan_amount_without_coeff" string="Plan Amount before Coeff" />
<field name="plan_amount_with_coeff" string="Plan Amount after Coeff" />
<field name="actual_amount" string="Actual Amount" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
@@ -159,7 +154,6 @@
<field name="note" optional="hide" />
<field name="plan_price" />
<field name="plan_qty" />
<field name="actual_qty" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
<field name="plan_amount_without_coeff" string="Plan Amount before Coeff" />
<field name="plan_amount_with_coeff" string="Plan Amount after Coeff" />
<field name="actual_amount" string="Actual Amount" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
@@ -186,7 +180,6 @@
<field name="note" optional="hide" />
<field name="plan_price" />
<field name="plan_qty" />
<field name="actual_qty" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
<field name="plan_amount_without_coeff" string="Plan Amount before Coeff" />
<field name="plan_amount_with_coeff" string="Plan Amount after Coeff" />
<field name="actual_amount" string="Actual Amount" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="invoice_budget_form" model="ir.ui.view">
<field name="name">account.invoice.budget.form</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='analytic_tag_ids']" position="after">
<field name="budget_forecast_id" domain="[('analytic_id', '=', analytic_account_id), ('product_id', '=', product_id)]" />
</xpath>
</field>
</record>
</odoo>

View File

@@ -8,11 +8,12 @@
<form>
<sheet>
<group>
<group>
<group string="Identification">
<field name="product_id" />
<field name="description" />
<field name="analytic_tag" />
</group>
<group>
<group string="Properties">
<field name="analytic_id" />
<field name="is_summary" />
<field name="budget_category" />
@@ -22,30 +23,32 @@
</group>
</group>
<group>
<group string="Unit prices">
<field name="plan_price" />
</group>
<group string="Quantities">
<field name="plan_qty" />
<field name="actual_qty" />
</group>
<group string="Totals">
<group string="Planned">
<field name="plan_price" string="Unit price" />
<field name="plan_qty" string="Quantities" />
<field name="plan_amount_without_coeff" />
<field name="plan_amount_with_coeff" />
</group>
<group string="Expenses">
<field name="actual_amount" />
<field name="diff_expenses" />
</group>
<group string="Incomes">
<field name="incomes" />
<field name="balance" />
</group>
</group>
<group string="Analytic Lines">
<field name="analytic_line_ids" nolabel="1">
<tree>
<field name="date" />
<field name="employee_id" />
<field name="product_id" />
<field name="name" />
<field name="unit_amount" string="Quantity" />
<field name="amount" />
</tree>
</field>
<group string="Expenses and Incomes lists">
<group string="Analytic Lines">
<button class="oe_highlight" type="object" name="action_view_analytic_lines">
List analytics lines
</button>
</group>
<group string="Draft invoice lines">
<button class="oe_highlight" type="object" name="action_view_draft_invoice_lines">
List draft invoce lines
</button>
</group>
</group>
<group string="Childs" attrs="{'invisible' : [('child_ids','=', False)]}">
<field name="child_ids" nolabel="1">
@@ -55,7 +58,6 @@
<field name="budget_category" />
<field name="plan_price" sum="total" />
<field name="plan_qty" sum="total" />
<field name="actual_qty" sum="total" />
<field name="plan_amount_without_coeff" sum="total" />
<field name="plan_amount_with_coeff" sum="total" />
<field name="actual_amount" sum="total" />
@@ -82,7 +84,6 @@
<field name="budget_category" />
<field name="plan_price" sum="total" />
<field name="plan_qty" sum="total" />
<field name="actual_qty" sum="total" />
<field name="plan_amount_without_coeff" sum="total" />
<field name="plan_amount_with_coeff" sum="total" />
<field name="actual_amount" sum="total" />

View File

@@ -15,10 +15,10 @@
<field name="model">budget.forecast.model.line</field>
<field name="arch" type="xml">
<tree editable="top">
<field name="budget_model" />
<field name="display_type" />
<field name="product_id" />
<field name="name" />
<field name="budget_model" required="True" />
<field name="display_type" required="True" />
<field name="product_id" required="True" />
<field name="name" required="True" />
<field name="parent_id" />
</tree>
</field>

View File

@@ -8,7 +8,7 @@
<field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_tree" />
<field name="arch" type="xml">
<xpath expr="//field[@name='task_id']" position="after">
<field name="budget_forecast_id" domain="[('display_type', '=', 'line_article')]" />
<field name="tag_ids" widget="many2many_tags" /> <!--domain="[('display_type', '=', 'line_article')]" />-->
</xpath>
</field>
</record>

View File

@@ -6,7 +6,7 @@
<field name="inherit_id" ref="hr_timesheet.view_task_form2_inherited" />
<field name="arch" type="xml">
<xpath expr="//field[@name='timesheet_ids']/tree/field[@name='name']" position="after">
<field name="budget_forecast_id" domain="[('display_type', '=', 'line_article')]" />
<field name="tag_ids" /> <!--domain="[('display_type', '=', 'line_article')]" />-->
</xpath>
</field>
</record>

View File

@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import models

View File

@@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
{
"name": "Account Mooncard Receipt Lost Transfer",
"category": "Account",
"version": "14.0.1.0",
"summary": "Transfer the Receipt Lost value in invoices and account move lines",
"author": "Elabore",
"website": "https://elabore.coop/",
"installable": True,
"application": False,
"auto_install": False,
"description": """
======================================
Account Mooncard Receipt Lost Transfer
======================================
This module allows the transfer of the Receipt Lost field value from model newgen.payment.card.transaction in invoices and account.move.line
Installation
============
Before the installation, please ensure that the addons of the repository `Odoo Mooncard Connector <https://github.com/akretion/odoo-mooncard-connector>` are available in your Odoo
Just install account_mooncard_receipt_lost_transfer, all dependencies will be installed by default.
Known issues / Roadmap
======================
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/elabore-coop/.../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.
Credits
=======
Images
------
* Elabore: `Icon <https://elabore.coop/web/image/res.company/1/logo?unique=f3db262>`_.
Contributors
------------
* Stéphan Sainléger <https://github.com/stephansainleger>
Funders
-------
The development of this module has been financially supported by:
* Elabore (https://elabore.coop)
Maintainer
----------
This module is maintained by ELABORE.
""",
"depends": [
"base",
"account",
"base_newgen_payment_card",
],
"data": [
"views/account_move_views.xml",
],
"qweb": [],
}

View File

@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import account_move
from . import newgen_payment_card_transaction

View File

@@ -0,0 +1,15 @@
from odoo import fields, models, _
class AccountMove(models.Model):
_inherit = "account.move"
receipt_lost = fields.Boolean(string=_("Receipt lost"), store=True)
mooncard_record = fields.Boolean(store=True)
class AccountMoveLine(models.Model):
_inherit = "account.move.line"
receipt_lost = fields.Boolean(string=_("Receipt lost"), store=True)
mooncard_record = fields.Boolean(store=True)

View File

@@ -0,0 +1,29 @@
from odoo import models
class NewgenPaymentCardTransaction(models.Model):
_inherit = "newgen.payment.card.transaction"
def process_line(self):
res = super(NewgenPaymentCardTransaction, self).process_line()
if res:
for line in self:
if line.invoice_id:
line.invoice_id.receipt_lost = line.receipt_lost
line.invoice_id.mooncard_record = True
move_lines = line.invoice_id.line_ids
for move_line in move_lines:
move_line.receipt_lost = line.receipt_lost
move_line.mooncard_record = True
return res
def generate_bank_journal_move(self):
bank_move = super(
NewgenPaymentCardTransaction, self
).generate_bank_journal_move()
if bank_move:
for line in bank_move.line_ids:
line.receipt_lost = self.receipt_lost
line.mooncard_record = True
return bank_move

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_move_form_recipt_lost" model="ir.ui.view">
<field name="name">view.move.form.receipt.lost</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form" />
<field name="arch" type="xml">
<div name="journal_div" position="after">
<field name="mooncard_record" invisible="1" />
<field name="receipt_lost" attrs="{'invisible': [('mooncard_record','=',False)]}" />
</div>
</field>
</record>
<record id="view_move_line_form_recipt_lost" model="ir.ui.view">
<field name="name">view.move.line.form.recipt.lost</field>
<field name="model">account.move.line</field>
<field name="inherit_id" ref="account.view_move_line_form" />
<field name="arch" type="xml">
<field name="blocked" position="after">
<field name="mooncard_record" invisible="1" />
<field name="receipt_lost" attrs="{'invisible': [('mooncard_record','=',False)]}" />
</field>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import models

View File

@@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
{
"name": "Account partner account number",
"category": "Account",
"version": "14.0.1.0",
"summary": "Add account number in partner",
"author": "Elabore",
"website": "https://elabore.coop/",
"installable": True,
"application": False,
"auto_install": False,
"description": """
======================================
Account partner account number
======================================
This module add a new field in partner, visible in account move lines for payable and receivable accounts
Installation
============
Just install account_partner_account_number, all dependencies will be installed by default.
Known issues / Roadmap
======================
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/elabore-coop/.../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.
Credits
=======
Images
------
* Elabore: `Icon <https://elabore.coop/web/image/res.company/1/logo?unique=f3db262>`_.
Contributors
------------
* Clément Thoams
Funders
-------
The development of this module has been financially supported by:
* Elabore (https://elabore.coop)
* Rovalterre
Maintainer
----------
This module is maintained by ELABORE.
""",
"depends": [
"base",
"account",
],
"data": [
"views/account_move_views.xml",
"views/partner_views.xml",
],
"qweb": [],
}

View File

@@ -0,0 +1,61 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_partner_account_number
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-09 07:37+0000\n"
"PO-Revision-Date: 2023-06-09 07:37+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: account_partner_account_number
#: model:ir.model.fields,field_description:account_partner_account_number.field_account_move_line__account_code
msgid "Account code"
msgstr "Code comptable"
#. module: account_partner_account_number
#: model:ir.model.fields,field_description:account_partner_account_number.field_res_partner__account_code
#: model:ir.model.fields,field_description:account_partner_account_number.field_res_users__account_code
#: model_terms:ir.ui.view,arch_db:account_partner_account_number.view_partner_property_form_account_code
msgid "Account code"
msgstr "Code comptable"
#. module: account_partner_account_number
#: model:ir.model.constraint,message:account_partner_account_number.constraint_res_partner_account_coder_unique
msgid "Choose another value of account code - it has to be unique!"
msgstr "Choisissez une autre valeur de code comptable - il doit être unique !"
#. module: account_partner_account_number
#: model:ir.model,name:account_partner_account_number.model_res_partner
msgid "Contact"
msgstr ""
#. module: account_partner_account_number
#: model:ir.model.fields,field_description:account_partner_account_number.field_account_move_line__display_name
#: model:ir.model.fields,field_description:account_partner_account_number.field_res_partner__display_name
msgid "Display Name"
msgstr "Nom affiché"
#. module: account_partner_account_number
#: model:ir.model.fields,field_description:account_partner_account_number.field_account_move_line__id
#: model:ir.model.fields,field_description:account_partner_account_number.field_res_partner__id
msgid "ID"
msgstr "Identifiant"
#. module: account_partner_account_number
#: model:ir.model,name:account_partner_account_number.model_account_move_line
msgid "Journal Item"
msgstr "Écriture comptable"
#. module: account_partner_account_number
#: model:ir.model.fields,field_description:account_partner_account_number.field_account_move_line____last_update
#: model:ir.model.fields,field_description:account_partner_account_number.field_res_partner____last_update
msgid "Last Modified on"
msgstr "Dernière modification le"

View File

@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import res_partner
from . import account_move_line

View File

@@ -0,0 +1,20 @@
from odoo import fields, models, _, api
class AccountMoveLine(models.Model):
_inherit = "account.move.line"
account_code = fields.Char(compute='get_account_code', string="Account code")
@api.depends('partner_id','account_id')
def get_account_code(self):
"""
assign account number of partner if move line is receivable (Customers) or payable (Suppliers)
"""
for account_move_line in self:
if account_move_line.account_id.id == account_move_line.partner_id.commercial_partner_id.property_account_receivable_id.id or \
account_move_line.account_id.id == account_move_line.partner_id.commercial_partner_id.property_account_payable_id.id:
account_move_line.account_code = account_move_line.partner_id.commercial_partner_id.account_code
else:
account_move_line.account_code = ''

View File

@@ -0,0 +1,13 @@
from odoo import fields, models, _
class ResPartner(models.Model):
_inherit = "res.partner"
account_code = fields.Char('Account code')
_sql_constraints = [
('account_coder_unique',
'unique(account_code)',
'Choose another value of account code - it has to be unique!')
]

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_move_line_tree_inherit_account_code" model="ir.ui.view">
<field name="name">account.move.line.tree.inherit.account.number</field>
<field name="model">account.move.line</field>
<field eval="100" name="priority"/>
<field name="inherit_id" ref="account.view_move_line_tree" />
<field name="arch" type="xml">
<xpath expr="//field[@name='partner_id']" position="after">
<field name="account_code" />
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_partner_property_form_account_code" model="ir.ui.view">
<field name="name">res.partner.property.form.inherit.account.number</field>
<field name="model">res.partner</field>
<field name="priority">2</field>
<field name="inherit_id" ref="account.view_partner_property_form"/>
<field name="groups_id" eval="[(5,)]"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='accounting']/group" position="inside">
<group string="Account code" name="account_code" groups="account.group_account_readonly">
<field name="account_code" />
</group>
</xpath>
</field>
</record>
</odoo>

View File

@@ -2,7 +2,7 @@
{
"name": "Account Quotation Sale Order Invoice Title",
"category": "Account",
"version": "13.0.1.0",
"version": "14.0.1.0",
"summary": "Transfer the Receipt Lost value in invoices and account move lines",
"author": "Elabore",
"website": "https://elabore.coop/",

View File

@@ -1,7 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_move_title_tree" model="ir.ui.view">
<field name="name">amove_title.move.tree</field>
<field name="name">move_title.move.tree</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_tree" />
<field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="after">
<field name="move_title" />
</xpath>
</field>
</record>
<record id="view_invoice_title_tree" model="ir.ui.view">
<field name="name">invoice_title.move.tree</field>
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_invoice_tree" />
<field name="arch" type="xml">
@@ -16,7 +27,7 @@
<field name="model">account.move</field>
<field name="inherit_id" ref="account.view_move_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='name']/../.." position="inside">
<xpath expr="//div[hasclass('oe_title')]" position="after">
<h1 class="mt0">
<field name="move_title" placeholder="Title..." />
</h1>

View File

@@ -11,7 +11,4 @@ class SaleAdvancePaymentInv(models.TransientModel):
order, name, amount, so_line
)
res["move_title"] = order.so_title
import pdb
pdb.set_trace()
return res

View File

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

View File

@@ -0,0 +1,66 @@
{
'name': 'Import chart of accounts',
'version': '14.0.1.1.0',
'summary': 'while importing the accounts chart, only update account name of existing accounts and automatise settings for new accounts',
'description': """
Installation
============
Install import_chart_of_accounts, all dependencies will be installed by default.
Description
=============
Pendant l'import, chaque ligne est comparée aux comptes comptables présents dans Odoo
- Si le compte comptable existe déjà dans bdd, seul le nom du compte comptable est mis à jour
- Un compte comptable est déjà existant si les 6 premiers chiffres du code comptable sont identique (par ex: le compte 120000 et 12000000 sont les mêmes comptes)
- Si le compte comptable n'existe pas dans bdd, il est créé.
- Un compte similaire est recherché dans la bdd à partir des 3 premier chiffres du code comptable.
- On recherche tous les comptes qui ont les 3 premiers chiffres de son code en commun avec celui du compte nouvellement créé
- Parmi ces comptes, le compte du lequel les paramètres seront copiés sur le nouveau compte est celui au numéro de code le plus bas.
- On enregistre la valeur des variables 'type' et 'reconcilition' du compte "similaire" dans le nouveau compte comptable
- S'il n'existe "compte similaire" pour ce nouveau compte, aucun paramétrage n'est ajouté lors de l'import
Exemple :
J'importe le compte comptable 607730 Epicerie divers
Ce compte comptable n'existe pas déjà dans Odoo, il est créé.
Pour le configurer automatiquement, on se fonde sur un compte similaire dans Odoo et avec le code le plus bas parmis les comptes similaires
Ici il s'agit de 607000 Achats de marchandise:
Il a pour Type Charges car c'est une compte de charges et Autoriser le lettrage est à False.
Le compte 607730 Epicerie divers sera donc enregistré dans Odoo avec le même paramétrage.
Usage
=====
Pour importer le plan comptable :
Aller dans l'App Facturation
Menu Configuration > Comptabilité > Importer le plan comptable
Un assistant permettant le téléversement d'un plan comptable apparaît.
Le fichier téléversé doit être au format CSV uniquement.
Il ne doit comporter que deux colonnes :
- La première colonne doit s'appeler 'code' pour le numéro de compte comptable
- La deuxième colonne doit s'appeler 'name' pour le nom du compte comptable
""",
'author': '',
'website': '',
'license': 'AGPL-3',
'category': '',
'depends': [
'account'
],
'data': [
'wizard/import_coa_wizard_views.xml',
'security/ir.model.access.csv'
],
'installable': True,
'application': False,
'assets': {
}
}

View File

@@ -0,0 +1,168 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * import_chart_of_accounts
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-05-29 10:27+0000\n"
"PO-Revision-Date: 2024-05-29 10:27+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid "<strong>Exemple :</strong>"
msgstr ""
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid "Accounts chart CSV Import Wizard"
msgstr "Importer un plan comptable"
#. module: import_chart_of_accounts
#: model:ir.model.fields,field_description:import_chart_of_accounts.field_import_coa_wizard__coa_file
msgid "CSV File"
msgstr "Fichier CSV"
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid "Cancel"
msgstr "Annuler"
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid "Ce compte comptable n'existe pas déjà dans Odoo, il est créé."
msgstr ""
#. module: import_chart_of_accounts
#: model:ir.model.fields,field_description:import_chart_of_accounts.field_import_coa_wizard__create_uid
msgid "Created by"
msgstr ""
#. module: import_chart_of_accounts
#: model:ir.model.fields,field_description:import_chart_of_accounts.field_import_coa_wizard__create_date
msgid "Created on"
msgstr ""
#. module: import_chart_of_accounts
#: model:ir.model.fields,field_description:import_chart_of_accounts.field_import_coa_wizard__display_name
msgid "Display Name"
msgstr ""
#. module: import_chart_of_accounts
#: model:ir.model.fields,field_description:import_chart_of_accounts.field_import_coa_wizard__filename
msgid "Filename"
msgstr ""
#. module: import_chart_of_accounts
#: model:ir.model.fields,field_description:import_chart_of_accounts.field_import_coa_wizard__id
msgid "ID"
msgstr ""
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid ""
"Ici il s'agit de <strong>607000 Achats de marchandise</strong>:<br/>\n"
" Il a pour <strong>Type</strong> Charges car c'est une compte de charges et <strong>Autoriser le lettrage</strong> est à False.<br/>\n"
" Le compte 607730 Epicerie divers sera donc enregistré dans Odoo avec le même paramétrage,<br/>\n"
" c'est-à-dire avec un type Charge et une non autorisation du lettrage"
msgstr ""
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid "Il ne doit comporter que <strong>deux colonnes</strong>"
msgstr ""
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid "Import"
msgstr "Importer"
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid "J'importe le compte comptable <strong>607730 Epicerie divers</strong>"
msgstr ""
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid ""
"La deuxième colonne doit s'appeler <strong>name</strong> pour le nom du "
"compte comptable"
msgstr ""
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid ""
"La première colonne doit s'appeler <strong>code</strong> pour le numéro de "
"compte comptable"
msgstr ""
#. module: import_chart_of_accounts
#: model:ir.model.fields,field_description:import_chart_of_accounts.field_import_coa_wizard____last_update
msgid "Last Modified on"
msgstr ""
#. module: import_chart_of_accounts
#: model:ir.model.fields,field_description:import_chart_of_accounts.field_import_coa_wizard__write_uid
msgid "Last Updated by"
msgstr ""
#. module: import_chart_of_accounts
#: model:ir.model.fields,field_description:import_chart_of_accounts.field_import_coa_wizard__write_date
msgid "Last Updated on"
msgstr ""
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid "Le fichier téléversé doit être au <strong>format CSV</strong>"
msgstr ""
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid ""
"Pendant l'import, chaque ligne est comparée aux comptes comptables présents "
"dans Odoo"
msgstr ""
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid "Pour importer le plan comptable :"
msgstr ""
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid ""
"Pour le configurer automatiquement, on se fonde sur le compte le plus proche"
" dans Odoo"
msgstr ""
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid ""
"Si le compte comptable existe déjà dans bdd, seul le nom du compte comptable"
" est mis à jour"
msgstr ""
#. module: import_chart_of_accounts
#: model_terms:ir.ui.view,arch_db:import_chart_of_accounts.import_coa_wizard_view
msgid ""
"Si le compte comptable n'existe pas dans bdd, il est créé. Puis un compte similaire est recherché dans la bdd,\n"
" <br/>le compte comptable nouvellement créé aura le même type et la même autorisation de lettrage."
msgstr ""
#. module: import_chart_of_accounts
#: model:ir.actions.act_window,name:import_chart_of_accounts.action_import_coa_wizard
#: model:ir.ui.menu,name:import_chart_of_accounts.import_coa_menu
msgid "Upload Chart Of Accounts"
msgstr "Importer un plan comptable"
#. module: import_chart_of_accounts
#: model:ir.model,name:import_chart_of_accounts.model_import_coa_wizard
msgid "import.coa.wizard"
msgstr ""

View File

@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_import_coa_wizard,access.import.coa.wizard,model_import_coa_wizard,account.group_account_manager,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_import_coa_wizard access.import.coa.wizard model_import_coa_wizard account.group_account_manager 1 1 1 0

View File

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

View File

@@ -0,0 +1,50 @@
from odoo import models, fields, api, exceptions, _
import csv
import base64
from io import StringIO
from odoo.exceptions import UserError
class ImportCoaWizard(models.TransientModel):
_name = 'import.coa.wizard'
coa_file = fields.Binary(string='CSV File', required=True)
filename = fields.Char(string='Filename')
def import_plan_comptable(self):
self.ensure_one()
if not self.coa_file:
raise UserError("Please upload a file.")
if self.filename and not self.filename.lower().endswith('.csv'):
raise UserError("Import COA Wizard only supports CSV")
file_content = base64.b64decode(self.coa_file).decode('utf-8')
csv_file = StringIO(file_content)
csv_reader = csv.DictReader(csv_file)
required_columns = ['code', 'name']
if not all(column in csv_reader.fieldnames for column in required_columns):
raise UserError(f"The CSV file must contain the following columns: {', '.join(required_columns)}")
data_to_import = [row for row in csv_reader]
for record_data in data_to_import:
# the account is already existing in Odoo if the 6 first digits are identicales
existing_line = self.find_account_with_same_firsts_digits(record_data['code'][:6])
if existing_line:
existing_line.write(record_data)
else:
# the closest account already existing in Odoo has the first tree digits identicales
closest_account = self.find_account_with_same_firsts_digits(record_data['code'][:3])
if closest_account :
record_data['user_type_id'] = closest_account.user_type_id.id
record_data['reconcile'] = closest_account.reconcile
new_account = self.env['account.account'].create(record_data)
return {
"type": "ir.actions.act_window",
"res_model": "account.account",
"view_mode": "list"
}
def find_account_with_same_firsts_digits(self, code_prefix):
return self.env['account.account'].search([('code', '=like', f'{code_prefix}%')],limit=1)

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="import_coa_wizard_view" model="ir.ui.view">
<field name="name">import.coa.wizard.view</field>
<field name="model">import.coa.wizard</field>
<field name="arch" type="xml">
<form string="Accounts chart CSV Import Wizard">
<group name="help-import" colspan="1" col="1">
<div colspan="2">
<p>Pour importer le plan comptable :
<ul>
<li>Le fichier téléversé doit être au <strong>format CSV</strong></li>
<li>Il ne doit comporter que <strong>deux colonnes</strong></li>
<li>La première colonne doit s'appeler <strong>code</strong> pour le numéro de compte comptable</li>
<li>La deuxième colonne doit s'appeler <strong>name</strong> pour le nom du compte comptable</li>
</ul>
</p>
<br/>
<p>Pendant l'import, chaque ligne est comparée aux comptes comptables présents dans Odoo
<ul>
<li>Si le compte comptable existe déjà dans bdd, seul le nom du compte comptable est mis à jour</li>
<li>Un compte comptable est déjà existant si les 6 premiers chiffres du code comptable sont identique (par ex: le compte 120000 et 12000000 sont les mêmes comptes)</li>
<li>Si le compte comptable n'existe pas dans bdd, il est créé. Puis un compte similaire est recherché dans la bdd,
<br/>le compte comptable nouvellement créé aura le même type et la même autorisation de lettrage.</li>
</ul>
</p>
<br/>
<p><strong>Exemple :</strong>
<ul>
<li>J'importe le compte comptable <strong>607730 Epicerie divers</strong></li>
<li>Ce compte comptable n'existe pas déjà dans Odoo, il est créé.</li>
<li>Pour le configurer automatiquement, on se fonde sur le compte le plus proche dans Odoo</li>
<li>Ici il s'agit de <strong>607000 Achats de marchandise</strong>:<br/>
Il a pour <strong>Type</strong> Charges car c'est une compte de charges et <strong>Autoriser le lettrage</strong> est à False.<br/>
Le compte 607730 Epicerie divers sera donc enregistré dans Odoo avec le même paramétrage,<br/>
c'est-à-dire avec un type Charge et une non autorisation du lettrage</li>
</ul>
</p>
</div>
</group>
<group name="import">
<field name="coa_file" filename="filename" />
<field name="filename" invisible="1"/>
</group>
<footer>
<button name="import_plan_comptable" type="object"
class="btn-primary" string="Import"/>
<button special="cancel" string="Cancel" class="btn-default"/>
</footer>
</form>
</field>
</record>
<record id="action_import_coa_wizard" model="ir.actions.act_window">
<field name="name">Upload Chart Of Accounts</field>
<field name="res_model">import.coa.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem
id="import_coa_menu"
action="action_import_coa_wizard"
sequence="1"
parent="account.account_account_menu"
/>
</odoo>