Compare commits
17 Commits
13.0-accou
...
14.0
Author | SHA1 | Date | |
---|---|---|---|
71e3188383 | |||
2d7a37f65a | |||
b4b007c1ae | |||
|
2d799eaf8c | ||
|
5074244aa6 | ||
|
2c3a647c17 | ||
|
6dea772ace | ||
|
4e448a4dd9 | ||
|
77bdc39e32 | ||
|
758592128e | ||
|
58235d3b51 | ||
|
b265056ed7 | ||
|
1143d83184 | ||
|
d76796bfa7 | ||
|
96fd3ae674 | ||
|
1883014efc | ||
|
0cb6311966 |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
*.*~
|
||||||
|
*.pyc
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
"name": "account_budget_forecast",
|
"name": "account_budget_forecast",
|
||||||
"version": "13.0.1.3.0",
|
"version": "14.0.1.4.0",
|
||||||
"author": "Elabore",
|
"author": "Elabore",
|
||||||
"maintainer": "False",
|
"maintainer": "False",
|
||||||
"website": "False",
|
"website": "False",
|
||||||
@@ -65,6 +65,7 @@ This module is maintained by ELABORE.
|
|||||||
"product",
|
"product",
|
||||||
"project",
|
"project",
|
||||||
"sale",
|
"sale",
|
||||||
|
"sale_crm",
|
||||||
"stock",
|
"stock",
|
||||||
],
|
],
|
||||||
"external_dependencies": {
|
"external_dependencies": {
|
||||||
@@ -76,7 +77,6 @@ This module is maintained by ELABORE.
|
|||||||
"wizard/budget_forecast_model_choice.xml",
|
"wizard/budget_forecast_model_choice.xml",
|
||||||
"views/account_analytic_account.xml",
|
"views/account_analytic_account.xml",
|
||||||
"views/account_analytic_account_categories.xml",
|
"views/account_analytic_account_categories.xml",
|
||||||
"views/account_invoice.xml",
|
|
||||||
"views/sale_order.xml",
|
"views/sale_order.xml",
|
||||||
"views/budget_forecast.xml",
|
"views/budget_forecast.xml",
|
||||||
"views/budget_coefficient.xml",
|
"views/budget_coefficient.xml",
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
from . import account_analytic_account
|
from . import account_analytic_account
|
||||||
from . import account_analytic_line
|
from . import account_analytic_line
|
||||||
from . import account_move
|
|
||||||
from . import budget_forecast
|
from . import budget_forecast
|
||||||
from . import budget_forecast_model
|
from . import budget_forecast_model
|
||||||
from . import sale_order
|
from . import sale_order
|
||||||
|
@@ -12,43 +12,43 @@ class AccountAnalyticAccount(models.Model):
|
|||||||
"budget.forecast",
|
"budget.forecast",
|
||||||
"analytic_id",
|
"analytic_id",
|
||||||
domain=[("budget_category", "=", "manpower")],
|
domain=[("budget_category", "=", "manpower")],
|
||||||
copy=True,
|
copy=False,
|
||||||
)
|
)
|
||||||
budget_forecast_material_ids = fields.One2many(
|
budget_forecast_material_ids = fields.One2many(
|
||||||
"budget.forecast",
|
"budget.forecast",
|
||||||
"analytic_id",
|
"analytic_id",
|
||||||
domain=[("budget_category", "=", "material")],
|
domain=[("budget_category", "=", "material")],
|
||||||
copy=True,
|
copy=False,
|
||||||
)
|
)
|
||||||
budget_forecast_equipment_ids = fields.One2many(
|
budget_forecast_equipment_ids = fields.One2many(
|
||||||
"budget.forecast",
|
"budget.forecast",
|
||||||
"analytic_id",
|
"analytic_id",
|
||||||
domain=[("budget_category", "=", "equipment")],
|
domain=[("budget_category", "=", "equipment")],
|
||||||
copy=True,
|
copy=False,
|
||||||
)
|
)
|
||||||
budget_forecast_subcontractors_ids = fields.One2many(
|
budget_forecast_subcontractors_ids = fields.One2many(
|
||||||
"budget.forecast",
|
"budget.forecast",
|
||||||
"analytic_id",
|
"analytic_id",
|
||||||
domain=[("budget_category", "=", "subcontractors")],
|
domain=[("budget_category", "=", "subcontractors")],
|
||||||
copy=True,
|
copy=False,
|
||||||
)
|
)
|
||||||
budget_forecast_delivery_ids = fields.One2many(
|
budget_forecast_delivery_ids = fields.One2many(
|
||||||
"budget.forecast",
|
"budget.forecast",
|
||||||
"analytic_id",
|
"analytic_id",
|
||||||
domain=[("budget_category", "=", "delivery")],
|
domain=[("budget_category", "=", "delivery")],
|
||||||
copy=True,
|
copy=False,
|
||||||
)
|
)
|
||||||
budget_forecast_miscellaneous_ids = fields.One2many(
|
budget_forecast_miscellaneous_ids = fields.One2many(
|
||||||
"budget.forecast",
|
"budget.forecast",
|
||||||
"analytic_id",
|
"analytic_id",
|
||||||
domain=[("budget_category", "=", "miscellaneous")],
|
domain=[("budget_category", "=", "miscellaneous")],
|
||||||
copy=True,
|
copy=False,
|
||||||
)
|
)
|
||||||
budget_forecast_unplanned_ids = fields.One2many(
|
budget_forecast_unplanned_ids = fields.One2many(
|
||||||
"budget.forecast",
|
"budget.forecast",
|
||||||
"analytic_id",
|
"analytic_id",
|
||||||
domain=[("budget_category", "=", "unplanned")],
|
domain=[("budget_category", "=", "unplanned")],
|
||||||
copy=True,
|
copy=False,
|
||||||
)
|
)
|
||||||
project_section_budget_ids = fields.One2many(
|
project_section_budget_ids = fields.One2many(
|
||||||
"budget.forecast",
|
"budget.forecast",
|
||||||
@@ -146,15 +146,15 @@ class AccountAnalyticAccount(models.Model):
|
|||||||
domain = [
|
domain = [
|
||||||
("analytic_account_id", "=", record.id),
|
("analytic_account_id", "=", record.id),
|
||||||
("parent_state", "in", ["draft", "posted"]),
|
("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)
|
invoice_lines = self.env["account.move.line"].search(domain)
|
||||||
for invoice_line in invoice_lines:
|
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 = (
|
||||||
record.total_incomes + invoice_line.price_subtotal
|
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 = (
|
||||||
record.total_incomes - invoice_line.price_subtotal
|
record.total_incomes - invoice_line.price_subtotal
|
||||||
)
|
)
|
||||||
|
@@ -6,4 +6,16 @@ from odoo import models, fields, api
|
|||||||
class AccountAnalyticLine(models.Model):
|
class AccountAnalyticLine(models.Model):
|
||||||
_inherit = "account.analytic.line"
|
_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
|
||||||
|
@@ -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
|
|
@@ -1,6 +1,8 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import logging
|
import logging
|
||||||
from odoo import models, fields, api, _
|
from odoo import models, fields, api, _
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -19,6 +21,13 @@ class BudgetForecast(models.Model):
|
|||||||
index=True,
|
index=True,
|
||||||
copy=True,
|
copy=True,
|
||||||
)
|
)
|
||||||
|
analytic_tag = fields.Many2one(
|
||||||
|
"account.analytic.tag",
|
||||||
|
"Analytic tag",
|
||||||
|
index=True,
|
||||||
|
copy=False,
|
||||||
|
ondelete="cascade",
|
||||||
|
)
|
||||||
|
|
||||||
budget_category = fields.Selection(
|
budget_category = fields.Selection(
|
||||||
[
|
[
|
||||||
@@ -61,16 +70,6 @@ class BudgetForecast(models.Model):
|
|||||||
copy=False,
|
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(
|
actual_amount = fields.Float(
|
||||||
"Expenses",
|
"Expenses",
|
||||||
compute="_calc_actual",
|
compute="_calc_actual",
|
||||||
@@ -114,6 +113,9 @@ class BudgetForecast(models.Model):
|
|||||||
"line_subsection",
|
"line_subsection",
|
||||||
]:
|
]:
|
||||||
record._create_category_sections()
|
record._create_category_sections()
|
||||||
|
record.analytic_tag = self.env["account.analytic.tag"].create(
|
||||||
|
{"name": record._calculate_name()}
|
||||||
|
)
|
||||||
return records
|
return records
|
||||||
|
|
||||||
def _create_category_sections(self):
|
def _create_category_sections(self):
|
||||||
@@ -173,24 +175,32 @@ class BudgetForecast(models.Model):
|
|||||||
return val
|
return val
|
||||||
return ""
|
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")
|
@api.onchange("description", "product_id")
|
||||||
def _compute_name(self):
|
def _compute_name(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
if record.product_id:
|
if record.product_id:
|
||||||
name = (
|
values = {"name": record._calculate_name()}
|
||||||
record.description
|
|
||||||
+ " - "
|
|
||||||
+ record.product_id.name
|
|
||||||
+ " - "
|
|
||||||
+ record._get_budget_category_label()
|
|
||||||
+ " - "
|
|
||||||
+ record.analytic_id.name
|
|
||||||
)
|
|
||||||
values = {
|
|
||||||
"name": name,
|
|
||||||
}
|
|
||||||
record.write(values, False)
|
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):
|
def _sync_sections_data(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
if record.display_type in ["line_section", "line_subsection"]:
|
if record.display_type in ["line_section", "line_subsection"]:
|
||||||
@@ -330,69 +340,102 @@ class BudgetForecast(models.Model):
|
|||||||
@api.depends("analytic_id.line_ids.amount")
|
@api.depends("analytic_id.line_ids.amount")
|
||||||
def _calc_actual(self):
|
def _calc_actual(self):
|
||||||
for record in 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:
|
if record.child_ids:
|
||||||
# Actual expenses are calculated with the child lines
|
# Addition of the childs values
|
||||||
record.actual_qty = sum(record.mapped("child_ids.actual_qty"))
|
|
||||||
record.actual_amount = sum(record.mapped("child_ids.actual_amount"))
|
record.actual_amount = sum(record.mapped("child_ids.actual_amount"))
|
||||||
# Incomes are calculated with the analytic lines
|
record.incomes = sum(record.mapped("child_ids.incomes"))
|
||||||
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"))
|
|
||||||
|
|
||||||
# Add Invoice lines ids
|
# Retrieve all the analytics lines linked to the current budget line
|
||||||
domain = [
|
analytic_lines = (
|
||||||
("analytic_account_id", "=", record.analytic_id.id),
|
self.env["account.analytic.line"]
|
||||||
("parent_state", "in", ["draft", "posted"]),
|
.search([])
|
||||||
("budget_forecast_id", "=", record.id),
|
.filtered(lambda x: record.analytic_tag in x.tag_ids)
|
||||||
("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"]
|
|
||||||
)
|
)
|
||||||
record.actual_qty = abs(sum(line_ids.mapped("unit_amount")))
|
for line in analytic_lines:
|
||||||
record.actual_amount = -sum(line_ids.mapped("amount"))
|
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 = [
|
domain = [
|
||||||
("analytic_account_id", "=", record.analytic_id.id),
|
("analytic_account_id", "=", record.analytic_id.id),
|
||||||
("parent_state", "in", ["draft", "posted"]),
|
("parent_state", "in", ["draft"]),
|
||||||
("budget_forecast_id", "=", record.id),
|
|
||||||
("move_id.type", "in", ["in_invoice", "in_refund"]),
|
|
||||||
]
|
]
|
||||||
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:
|
for invoice_line in invoice_lines:
|
||||||
if invoice_line.move_id.type == "in_invoice":
|
if invoice_line.move_id.move_type == "out_invoice":
|
||||||
record.actual_qty = record.actual_qty + invoice_line.quantity
|
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 = (
|
||||||
record.actual_amount + invoice_line.price_subtotal
|
record.actual_amount + invoice_line.price_subtotal
|
||||||
)
|
)
|
||||||
elif invoice_line.move_id.type == "in_refund":
|
elif invoice_line.move_id.move_type == "in_refund":
|
||||||
record.actual_qty = record.actual_qty - invoice_line.quantity
|
|
||||||
record.actual_amount = (
|
record.actual_amount = (
|
||||||
record.actual_amount - invoice_line.price_subtotal
|
record.actual_amount - invoice_line.price_subtotal
|
||||||
)
|
)
|
||||||
|
|
||||||
record.incomes = None
|
record.balance = record.incomes - record.actual_amount
|
||||||
record.balance = None
|
|
||||||
|
|
||||||
record.diff_expenses = record.plan_amount_with_coeff - 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")
|
||||||
|
)
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
from odoo import models, fields, _, api
|
from odoo import models, fields, _, api
|
||||||
from odoo.exceptions import Warning
|
from odoo.exceptions import Warning
|
||||||
|
import logging
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class SaleOrder(models.Model):
|
class SaleOrder(models.Model):
|
||||||
@@ -49,9 +51,12 @@ class SaleOrder(models.Model):
|
|||||||
name = self.analytic_account_id.name.replace(self.name, record.name)
|
name = self.analytic_account_id.name.replace(self.name, record.name)
|
||||||
else:
|
else:
|
||||||
name = "%s: %s" % (self.analytic_account_id.name, record.name)
|
name = "%s: %s" % (self.analytic_account_id.name, record.name)
|
||||||
record.analytic_account_id = self.analytic_account_id.copy(
|
try:
|
||||||
default=dict(name=name)
|
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
|
return record
|
||||||
|
|
||||||
|
|
||||||
|
@@ -24,7 +24,6 @@
|
|||||||
<field name="note" optional="hide" />
|
<field name="note" optional="hide" />
|
||||||
<field name="plan_price" />
|
<field name="plan_price" />
|
||||||
<field name="plan_qty" />
|
<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_without_coeff" string="Plan Amount before Coeff" />
|
||||||
<field name="plan_amount_with_coeff" string="Plan Amount after 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)]}" />
|
<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="note" optional="hide" />
|
||||||
<field name="plan_price" />
|
<field name="plan_price" />
|
||||||
<field name="plan_qty" />
|
<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_without_coeff" string="Plan Amount before Coeff" />
|
||||||
<field name="plan_amount_with_coeff" string="Plan Amount after 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)]}" />
|
<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="note" optional="hide" />
|
||||||
<field name="plan_price" />
|
<field name="plan_price" />
|
||||||
<field name="plan_qty" />
|
<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_without_coeff" string="Plan Amount before Coeff" />
|
||||||
<field name="plan_amount_with_coeff" string="Plan Amount after 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)]}" />
|
<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="note" optional="hide" />
|
||||||
<field name="plan_price" />
|
<field name="plan_price" />
|
||||||
<field name="plan_qty" />
|
<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_without_coeff" string="Plan Amount before Coeff" />
|
||||||
<field name="plan_amount_with_coeff" string="Plan Amount after 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)]}" />
|
<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="note" optional="hide" />
|
||||||
<field name="plan_price" />
|
<field name="plan_price" />
|
||||||
<field name="plan_qty" />
|
<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_without_coeff" string="Plan Amount before Coeff" />
|
||||||
<field name="plan_amount_with_coeff" string="Plan Amount after 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)]}" />
|
<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="note" optional="hide" />
|
||||||
<field name="plan_price" />
|
<field name="plan_price" />
|
||||||
<field name="plan_qty" />
|
<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_without_coeff" string="Plan Amount before Coeff" />
|
||||||
<field name="plan_amount_with_coeff" string="Plan Amount after 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)]}" />
|
<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="note" optional="hide" />
|
||||||
<field name="plan_price" />
|
<field name="plan_price" />
|
||||||
<field name="plan_qty" />
|
<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_without_coeff" string="Plan Amount before Coeff" />
|
||||||
<field name="plan_amount_with_coeff" string="Plan Amount after 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)]}" />
|
<field name="actual_amount" string="Actual Amount" attrs="{'column_invisible' : [('parent.display_actual_amounts', '=', False)]}" />
|
||||||
|
@@ -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>
|
|
@@ -8,11 +8,12 @@
|
|||||||
<form>
|
<form>
|
||||||
<sheet>
|
<sheet>
|
||||||
<group>
|
<group>
|
||||||
<group>
|
<group string="Identification">
|
||||||
<field name="product_id" />
|
<field name="product_id" />
|
||||||
<field name="description" />
|
<field name="description" />
|
||||||
|
<field name="analytic_tag" />
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group string="Properties">
|
||||||
<field name="analytic_id" />
|
<field name="analytic_id" />
|
||||||
<field name="is_summary" />
|
<field name="is_summary" />
|
||||||
<field name="budget_category" />
|
<field name="budget_category" />
|
||||||
@@ -22,30 +23,32 @@
|
|||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<group string="Unit prices">
|
<group string="Planned">
|
||||||
<field name="plan_price" />
|
<field name="plan_price" string="Unit price" />
|
||||||
</group>
|
<field name="plan_qty" string="Quantities" />
|
||||||
<group string="Quantities">
|
|
||||||
<field name="plan_qty" />
|
|
||||||
<field name="actual_qty" />
|
|
||||||
</group>
|
|
||||||
<group string="Totals">
|
|
||||||
<field name="plan_amount_without_coeff" />
|
<field name="plan_amount_without_coeff" />
|
||||||
<field name="plan_amount_with_coeff" />
|
<field name="plan_amount_with_coeff" />
|
||||||
|
</group>
|
||||||
|
<group string="Expenses">
|
||||||
<field name="actual_amount" />
|
<field name="actual_amount" />
|
||||||
|
<field name="diff_expenses" />
|
||||||
|
</group>
|
||||||
|
<group string="Incomes">
|
||||||
|
<field name="incomes" />
|
||||||
|
<field name="balance" />
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group string="Analytic Lines">
|
<group string="Expenses and Incomes lists">
|
||||||
<field name="analytic_line_ids" nolabel="1">
|
<group string="Analytic Lines">
|
||||||
<tree>
|
<button class="oe_highlight" type="object" name="action_view_analytic_lines">
|
||||||
<field name="date" />
|
List analytics lines
|
||||||
<field name="employee_id" />
|
</button>
|
||||||
<field name="product_id" />
|
</group>
|
||||||
<field name="name" />
|
<group string="Draft invoice lines">
|
||||||
<field name="unit_amount" string="Quantity" />
|
<button class="oe_highlight" type="object" name="action_view_draft_invoice_lines">
|
||||||
<field name="amount" />
|
List draft invoce lines
|
||||||
</tree>
|
</button>
|
||||||
</field>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group string="Childs" attrs="{'invisible' : [('child_ids','=', False)]}">
|
<group string="Childs" attrs="{'invisible' : [('child_ids','=', False)]}">
|
||||||
<field name="child_ids" nolabel="1">
|
<field name="child_ids" nolabel="1">
|
||||||
@@ -55,7 +58,6 @@
|
|||||||
<field name="budget_category" />
|
<field name="budget_category" />
|
||||||
<field name="plan_price" sum="total" />
|
<field name="plan_price" sum="total" />
|
||||||
<field name="plan_qty" 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_without_coeff" sum="total" />
|
||||||
<field name="plan_amount_with_coeff" sum="total" />
|
<field name="plan_amount_with_coeff" sum="total" />
|
||||||
<field name="actual_amount" sum="total" />
|
<field name="actual_amount" sum="total" />
|
||||||
@@ -82,7 +84,6 @@
|
|||||||
<field name="budget_category" />
|
<field name="budget_category" />
|
||||||
<field name="plan_price" sum="total" />
|
<field name="plan_price" sum="total" />
|
||||||
<field name="plan_qty" 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_without_coeff" sum="total" />
|
||||||
<field name="plan_amount_with_coeff" sum="total" />
|
<field name="plan_amount_with_coeff" sum="total" />
|
||||||
<field name="actual_amount" sum="total" />
|
<field name="actual_amount" sum="total" />
|
||||||
|
@@ -15,10 +15,10 @@
|
|||||||
<field name="model">budget.forecast.model.line</field>
|
<field name="model">budget.forecast.model.line</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree editable="top">
|
<tree editable="top">
|
||||||
<field name="budget_model" />
|
<field name="budget_model" required="True" />
|
||||||
<field name="display_type" />
|
<field name="display_type" required="True" />
|
||||||
<field name="product_id" />
|
<field name="product_id" required="True" />
|
||||||
<field name="name" />
|
<field name="name" required="True" />
|
||||||
<field name="parent_id" />
|
<field name="parent_id" />
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
<field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_tree" />
|
<field name="inherit_id" ref="hr_timesheet.hr_timesheet_line_tree" />
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath expr="//field[@name='task_id']" position="after">
|
<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>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
<field name="inherit_id" ref="hr_timesheet.view_task_form2_inherited" />
|
<field name="inherit_id" ref="hr_timesheet.view_task_form2_inherited" />
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath expr="//field[@name='timesheet_ids']/tree/field[@name='name']" position="after">
|
<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>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
3
account_mooncard_receipt_lost_transfer/__init__.py
Normal file
3
account_mooncard_receipt_lost_transfer/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import models
|
63
account_mooncard_receipt_lost_transfer/__manifest__.py
Normal file
63
account_mooncard_receipt_lost_transfer/__manifest__.py
Normal 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": [],
|
||||||
|
}
|
@@ -0,0 +1,4 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import account_move
|
||||||
|
from . import newgen_payment_card_transaction
|
@@ -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)
|
@@ -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
|
@@ -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>
|
3
account_partner_account_number/__init__.py
Normal file
3
account_partner_account_number/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import models
|
63
account_partner_account_number/__manifest__.py
Normal file
63
account_partner_account_number/__manifest__.py
Normal 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": [],
|
||||||
|
}
|
61
account_partner_account_number/i18n/fr.po
Normal file
61
account_partner_account_number/i18n/fr.po
Normal 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"
|
3
account_partner_account_number/models/__init__.py
Normal file
3
account_partner_account_number/models/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from . import res_partner
|
||||||
|
from . import account_move_line
|
20
account_partner_account_number/models/account_move_line.py
Normal file
20
account_partner_account_number/models/account_move_line.py
Normal 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 = ''
|
||||||
|
|
13
account_partner_account_number/models/res_partner.py
Normal file
13
account_partner_account_number/models/res_partner.py
Normal 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!')
|
||||||
|
]
|
14
account_partner_account_number/views/account_move_views.xml
Normal file
14
account_partner_account_number/views/account_move_views.xml
Normal 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>
|
17
account_partner_account_number/views/partner_views.xml
Normal file
17
account_partner_account_number/views/partner_views.xml
Normal 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>
|
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Account Quotation Sale Order Invoice Title",
|
"name": "Account Quotation Sale Order Invoice Title",
|
||||||
"category": "Account",
|
"category": "Account",
|
||||||
"version": "13.0.1.0",
|
"version": "14.0.1.0",
|
||||||
"summary": "Transfer the Receipt Lost value in invoices and account move lines",
|
"summary": "Transfer the Receipt Lost value in invoices and account move lines",
|
||||||
"author": "Elabore",
|
"author": "Elabore",
|
||||||
"website": "https://elabore.coop/",
|
"website": "https://elabore.coop/",
|
||||||
|
@@ -1,7 +1,18 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<record id="view_move_title_tree" model="ir.ui.view">
|
<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="model">account.move</field>
|
||||||
<field name="inherit_id" ref="account.view_invoice_tree" />
|
<field name="inherit_id" ref="account.view_invoice_tree" />
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
@@ -16,7 +27,7 @@
|
|||||||
<field name="model">account.move</field>
|
<field name="model">account.move</field>
|
||||||
<field name="inherit_id" ref="account.view_move_form" />
|
<field name="inherit_id" ref="account.view_move_form" />
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath expr="//field[@name='name']/../.." position="inside">
|
<xpath expr="//div[hasclass('oe_title')]" position="after">
|
||||||
<h1 class="mt0">
|
<h1 class="mt0">
|
||||||
<field name="move_title" placeholder="Title..." />
|
<field name="move_title" placeholder="Title..." />
|
||||||
</h1>
|
</h1>
|
||||||
|
@@ -11,7 +11,4 @@ class SaleAdvancePaymentInv(models.TransientModel):
|
|||||||
order, name, amount, so_line
|
order, name, amount, so_line
|
||||||
)
|
)
|
||||||
res["move_title"] = order.so_title
|
res["move_title"] = order.so_title
|
||||||
import pdb
|
|
||||||
|
|
||||||
pdb.set_trace()
|
|
||||||
return res
|
return res
|
||||||
|
1
import_chart_of_accounts/__init__.py
Normal file
1
import_chart_of_accounts/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import wizard
|
66
import_chart_of_accounts/__manifest__.py
Normal file
66
import_chart_of_accounts/__manifest__.py
Normal 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': {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
168
import_chart_of_accounts/i18n/fr.po
Normal file
168
import_chart_of_accounts/i18n/fr.po
Normal 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 ""
|
2
import_chart_of_accounts/security/ir.model.access.csv
Normal file
2
import_chart_of_accounts/security/ir.model.access.csv
Normal 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
import_chart_of_accounts/wizard/__init__.py
Normal file
1
import_chart_of_accounts/wizard/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import import_coa_wizard
|
50
import_chart_of_accounts/wizard/import_coa_wizard.py
Normal file
50
import_chart_of_accounts/wizard/import_coa_wizard.py
Normal 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)
|
66
import_chart_of_accounts/wizard/import_coa_wizard_views.xml
Normal file
66
import_chart_of_accounts/wizard/import_coa_wizard_views.xml
Normal 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>
|
Reference in New Issue
Block a user