[17.0][ADD] account_asset_force_account: New module account_asset_force_account

This commit is contained in:
bobrador
2024-09-18 12:05:13 +02:00
parent 25c43b2b31
commit 912bd229ce
19 changed files with 1098 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
===================
Asset Force Account
===================
..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:1eb4e22468a624d5f2d627b3ea38ad1b92264324736d1e8071e8e048da712da2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github
:target: https://github.com/OCA/account-financial-tools/tree/17.0/account_asset_force_account
:alt: OCA/account-financial-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/account-financial-tools-17-0/account-financial-tools-17-0-account_asset_force_account
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=17.0
:alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5|
This module enables the ability to override default accounts directly
from the asset form.
**Table of contents**
.. contents::
:local:
Usage
=====
1. | **Create an Asset Profile**:
| Navigate to **Configuration -> Asset Profiles** and create a new
profile.
2. **Create a Vendor Bill**:
- Go to **Vendors -> Bills** and create a new bill.
- Add a product and select the asset profile you just created.
- The Asset Account will be derived from the profile or can be
manually updated at this step (the invoice account will be used as
the Asset Account).
- Set the product price and confirm the bill.
3. | **Asset Creation**:
| Once the bill is confirmed, the asset will be created and populated
with the associated accounts. You can now manually adjust the
**Depreciation Account** and **Depreciation Expense Account** if
necessary.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-tools/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_asset_force_account%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
-------
* Bernat Obrador (APSL-Nagarro)
Contributors
------------
- `APSL-Nagarro <https://apsl.tech>`__:
- Bernat Obrador <bobrador@apsl.net>
Maintainers
-----------
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
.. |maintainer-BernatObrador| image:: https://github.com/BernatObrador.png?size=40px
:target: https://github.com/BernatObrador
:alt: BernatObrador
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-BernatObrador|
This module is part of the `OCA/account-financial-tools <https://github.com/OCA/account-financial-tools/tree/17.0/account_asset_force_account>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -0,0 +1,2 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import models

View File

@@ -0,0 +1,20 @@
# Copyright 2024 Bernat Obrador(APSL-Nagarro)<bobrador@apsl.net>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Asset Force Account",
"summary": "This module allows you to enforce specific accounts for assets, including depreciation and expense accounts, through asset profiles and forms.",
"version": "17.0.1.0.0",
"website": "https://github.com/OCA/account-financial-tools",
"author": "Bernat Obrador (APSL-Nagarro), Odoo Community Association (OCA)",
"category": "Accounting & Finance",
"maintainers": ["BernatObrador"],
"license": "AGPL-3",
"application": False,
"installable": True,
"depends": [
"account_asset_management",
],
"data": [
"views/account_asset.xml",
],
}

View File

@@ -0,0 +1,51 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_asset_force_accounts
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 17.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-09-18 09:41+0000\n"
"PO-Revision-Date: 2024-09-18 09:41+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_asset_force_accounts
#: model:ir.model,name:account_asset_force_accounts.model_account_asset
msgid "Asset"
msgstr "Actiu"
#. module: account_asset_force_accounts
#: model:ir.model.fields,field_description:account_asset_force_accounts.field_account_asset__account_asset_id
msgid "Asset Account"
msgstr "Compte de l'actiu"
#. module: account_asset_force_accounts
#: model:ir.model.fields,field_description:account_asset_force_accounts.field_account_asset__account_depreciation_id
msgid "Depreciation Account"
msgstr "Compte d'amortització"
#. module: account_asset_force_accounts
#: model:ir.model.fields,field_description:account_asset_force_accounts.field_account_asset__account_expense_depreciation_id
msgid "Depreciation Expense Account"
msgstr "Compte de despeses d'amortització"
#. module: account_asset_force_accounts
#: model:ir.model.fields,help:account_asset_force_accounts.field_account_asset__account_depreciation_id
msgid "The account used to record depreciation for the asset."
msgstr "El compte utilitzat per registrar l'amortització de l'actiu."
#. module: account_asset_force_accounts
#: model:ir.model.fields,help:account_asset_force_accounts.field_account_asset__account_expense_depreciation_id
msgid "The account used to record the expense of the depreciation."
msgstr "El compte utilitzat per registrar la despesa per amortització."
#. module: account_asset_force_accounts
#: model:ir.model.fields,help:account_asset_force_accounts.field_account_asset__account_asset_id
msgid "The account used to record the value of the asset."
msgstr "El compte utilitzat per registrar el valor de l'actiu."

View File

@@ -0,0 +1,51 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_asset_force_accounts
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 17.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-09-18 09:43+0000\n"
"PO-Revision-Date: 2024-09-18 09:43+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_asset_force_accounts
#: model:ir.model,name:account_asset_force_accounts.model_account_asset
msgid "Asset"
msgstr "Activo"
#. module: account_asset_force_accounts
#: model:ir.model.fields,field_description:account_asset_force_accounts.field_account_asset__account_asset_id
msgid "Asset Account"
msgstr "Cuenta de activo"
#. module: account_asset_force_accounts
#: model:ir.model.fields,field_description:account_asset_force_accounts.field_account_asset__account_depreciation_id
msgid "Depreciation Account"
msgstr "Cuenta de amortización"
#. module: account_asset_force_accounts
#: model:ir.model.fields,field_description:account_asset_force_accounts.field_account_asset__account_expense_depreciation_id
msgid "Depreciation Expense Account"
msgstr "Cuenta de gastos de amortización"
#. module: account_asset_force_accounts
#: model:ir.model.fields,help:account_asset_force_accounts.field_account_asset__account_depreciation_id
msgid "The account used to record depreciation for the asset."
msgstr "La cuenta utilizada para registrar la depreciación del activo."
#. module: account_asset_force_accounts
#: model:ir.model.fields,help:account_asset_force_accounts.field_account_asset__account_expense_depreciation_id
msgid "The account used to record the expense of the depreciation."
msgstr "La cuenta utilizada para registrar el gasto por depreciación."
#. module: account_asset_force_accounts
#: model:ir.model.fields,help:account_asset_force_accounts.field_account_asset__account_asset_id
msgid "The account used to record the value of the asset."
msgstr "La cuenta utilizada para registrar el valor del activo."

View File

@@ -0,0 +1,3 @@
from . import account_asset
from . import account_asset_line
from . import account_move_line

View File

@@ -0,0 +1,60 @@
# Copyright 2024 Bernat Obrador(APSL-Nagarro)<bobrador@apsl.net>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class AccountAsset(models.Model):
_inherit = "account.asset"
account_asset_id = fields.Many2one(
comodel_name="account.account",
string="Asset Account",
compute="_compute_account_asset_id",
help="The account used to record the value of the asset.",
)
account_depreciation_id = fields.Many2one(
comodel_name="account.account",
string="Depreciation Account",
domain="[('deprecated', '=', False), ('company_id', '=', company_id)]",
help="The account used to record depreciation for the asset.",
required=True,
)
account_expense_depreciation_id = fields.Many2one(
comodel_name="account.account",
string="Depreciation Expense Account",
domain="[('deprecated', '=', False), ('company_id', '=', company_id)]",
help="The account used to record the expense of the depreciation.",
required=True,
)
@api.onchange("profile_id")
def _onchange_profile_id(self):
# To avoid changes when the asset is confirmed
if self.profile_id and self.state == "draft":
self.account_depreciation_id = self.profile_id.account_depreciation_id
self.account_expense_depreciation_id = (
self.profile_id.account_expense_depreciation_id
)
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if vals.get("profile_id"):
profile = self.env["account.asset.profile"].browse(vals["profile_id"])
if not vals.get("account_depreciation_id"):
vals["account_depreciation_id"] = profile.account_depreciation_id.id
if not vals.get("account_expense_depreciation_id"):
vals[
"account_expense_depreciation_id"
] = profile.account_expense_depreciation_id.id
return super().create(vals_list)
def _compute_account_asset_id(self):
if len(self.account_move_line_ids.account_id) != 0:
self.account_asset_id = self.account_move_line_ids.sorted(
lambda line: line.create_date
).account_id[0]
return
self.account_asset_id = self.profile_id.account_asset_id

View File

@@ -0,0 +1,17 @@
# Copyright 2024 Bernat Obrador(APSL-Nagarro)<bobrador@apsl.net>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models
class AccountAssetLine(models.Model):
_inherit = "account.asset.line"
def _setup_move_line_data(self, depreciation_date, account, ml_type, move):
res = super()._setup_move_line_data(depreciation_date, account, ml_type, move)
asset = self.asset_id
if ml_type == "depreciation" and asset.account_depreciation_id:
res["account_id"] = asset.account_depreciation_id.id
if ml_type == "expense" and asset.account_expense_depreciation_id:
res["account_id"] = asset.account_expense_depreciation_id.id
return res

View File

@@ -0,0 +1,13 @@
# Copyright 2024 Bernat Obrador(APSL-Nagarro)<bobrador@apsl.net>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, models
class AccountMoveLine(models.Model):
_inherit = "account.move.line"
@api.onchange("asset_profile_id")
def _onchange_asset_profile_id(self):
if self.account_id and self.account_id.account_type == "asset_fixed":
return
super()._onchange_asset_profile_id()

View File

@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View File

@@ -0,0 +1,2 @@
- [APSL-Nagarro](<https://apsl.tech>):
- Bernat Obrador \<<bobrador@apsl.net>\>

View File

@@ -0,0 +1 @@
This module enables the ability to override default accounts directly from the asset form.

View File

@@ -0,0 +1,11 @@
1. **Create an Asset Profile**:
Navigate to **Configuration -> Asset Profiles** and create a new profile.
2. **Create a Vendor Bill**:
- Go to **Vendors -> Bills** and create a new bill.
- Add a product and select the asset profile you just created.
- The Asset Account will be derived from the profile or can be manually updated at this step (the invoice account will be used as the Asset Account).
- Set the product price and confirm the bill.
3. **Asset Creation**:
Once the bill is confirmed, the asset will be created and populated with the associated accounts. You can now manually adjust the **Depreciation Account** and **Depreciation Expense Account** if necessary.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -0,0 +1,459 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Asset Force Account</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="asset-force-account">
<h1 class="title">Asset Force Account</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:1eb4e22468a624d5f2d627b3ea38ad1b92264324736d1e8071e8e048da712da2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/account-financial-tools/tree/17.0/account_asset_force_account"><img alt="OCA/account-financial-tools" src="https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/account-financial-tools-17-0/account-financial-tools-17-0-account_asset_force_account"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&amp;target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module enables the ability to override default accounts directly
from the asset form.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-2">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-3">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-4">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-5">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-6">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<ol class="arabic">
<li><div class="first line-block">
<div class="line"><strong>Create an Asset Profile</strong>:</div>
<div class="line">Navigate to <strong>Configuration -&gt; Asset Profiles</strong> and create a new
profile.</div>
</div>
</li>
<li><p class="first"><strong>Create a Vendor Bill</strong>:</p>
<ul class="simple">
<li>Go to <strong>Vendors -&gt; Bills</strong> and create a new bill.</li>
<li>Add a product and select the asset profile you just created.</li>
<li>The Asset Account will be derived from the profile or can be
manually updated at this step (the invoice account will be used as
the Asset Account).</li>
<li>Set the product price and confirm the bill.</li>
</ul>
</li>
<li><div class="first line-block">
<div class="line"><strong>Asset Creation</strong>:</div>
<div class="line">Once the bill is confirmed, the asset will be created and populated
with the associated accounts. You can now manually adjust the
<strong>Depreciation Account</strong> and <strong>Depreciation Expense Account</strong> if
necessary.</div>
</div>
</li>
</ol>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_asset_force_account%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-3">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-4">Authors</a></h2>
<ul class="simple">
<li>Bernat Obrador (APSL-Nagarro)</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<ul class="simple">
<li><a class="reference external" href="https://apsl.tech">APSL-Nagarro</a>:<ul>
<li>Bernat Obrador &lt;<a class="reference external" href="mailto:bobrador&#64;apsl.net">bobrador&#64;apsl.net</a>&gt;</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/BernatObrador"><img alt="BernatObrador" src="https://github.com/BernatObrador.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/17.0/account_asset_force_account">OCA/account-financial-tools</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

View File

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

View File

@@ -0,0 +1,188 @@
# Copyright 2024 Bernat Obrador(APSL-Nagarro)<bobrador@apsl.net>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import time
from odoo.tests import tagged
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
@tagged("post_install", "-at_install")
class TestAssetManagement(AccountTestInvoicingCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.asset_model = cls.env["account.asset"]
cls.asset_profile_model = cls.env["account.asset.profile"]
cls.account_depreciation_car = cls.env["account.account"].create(
{
"name": "Fixed Asset - Vehicle",
"code": "151001",
"account_type": "asset_fixed",
}
)
cls.account_expense_laptop = cls.env["account.account"].create(
{
"name": "Depreciation Expense Account - Laptop",
"code": "600001",
"account_type": "expense",
}
)
# Asset Profile 1
cls.ict3Y = cls.asset_profile_model.create(
{
"account_expense_depreciation_id": cls.company_data[
"default_account_expense"
].id,
"account_asset_id": cls.company_data["default_account_assets"].id,
"account_depreciation_id": cls.company_data[
"default_account_assets"
].id,
"journal_id": cls.company_data["default_journal_purchase"].id,
"name": "Hardware - 3 Years",
"method_time": "year",
"method_number": 3,
"method_period": "year",
}
)
# Asset Profile 2
cls.car5y = cls.asset_profile_model.create(
{
"account_expense_depreciation_id": cls.company_data[
"default_account_expense"
].id,
"account_asset_id": cls.company_data["default_account_assets"].id,
"account_depreciation_id": cls.company_data[
"default_account_assets"
].id,
"journal_id": cls.company_data["default_journal_purchase"].id,
"name": "Cars - 5 Years",
"method_time": "year",
"method_number": 5,
"method_period": "year",
}
)
def test_change_asset_accounts(self):
ict0 = self.asset_model.create(
{
"name": "test asset",
"profile_id": self.ict3Y.id,
"purchase_value": 1500,
"date_start": "1901-02-01",
"method_time": "year",
"method_number": 3,
"method_period": "year",
"account_depreciation_id": self.ict3Y.account_depreciation_id.id,
"account_expense_depreciation_id": self.account_expense_laptop.id,
}
)
self.assertEqual(ict0.state, "draft")
self.assertEqual(ict0.purchase_value, 1500)
self.assertEqual(ict0.salvage_value, 0)
self.assertEqual(ict0.depreciation_base, 1500)
self.assertEqual(len(ict0.depreciation_line_ids), 1)
self.assertEqual(ict0.account_asset_id.id, ict0.profile_id.account_asset_id.id)
self.assertEqual(
ict0.account_depreciation_id.id, ict0.profile_id.account_depreciation_id.id
)
self.assertEqual(
ict0.account_expense_depreciation_id.id, self.account_expense_laptop.id
)
vehicle0 = self.asset_model.create(
{
"state": "draft",
"method_time": "year",
"method_number": 5,
"method_period": "year",
"name": "CEO's Car",
"purchase_value": 12000.0,
"salvage_value": 2000.0,
"profile_id": self.car5y.id,
"date_start": time.strftime("%Y-01-01"),
"account_depreciation_id": self.account_depreciation_car.id,
"account_expense_depreciation_id": self.car5y.account_expense_depreciation_id.id,
}
)
self.assertEqual(vehicle0.state, "draft")
self.assertEqual(vehicle0.purchase_value, 12000)
self.assertEqual(vehicle0.salvage_value, 2000)
self.assertEqual(vehicle0.depreciation_base, 10000)
self.assertEqual(len(vehicle0.depreciation_line_ids), 1)
self.assertEqual(
vehicle0.account_asset_id.id, vehicle0.profile_id.account_asset_id.id
)
self.assertEqual(
vehicle0.account_depreciation_id.id, self.account_depreciation_car.id
)
self.assertEqual(
vehicle0.account_expense_depreciation_id.id,
vehicle0.profile_id.account_expense_depreciation_id.id,
)
ict0.compute_depreciation_board()
ict0.invalidate_recordset()
self.assertEqual(len(ict0.depreciation_line_ids), 4)
self.assertEqual(ict0.depreciation_line_ids[1].amount, 500)
vehicle0.compute_depreciation_board()
vehicle0.invalidate_recordset()
self.assertEqual(len(vehicle0.depreciation_line_ids), 6)
self.assertEqual(vehicle0.depreciation_line_ids[1].amount, 2000)
ict0.validate()
ict0_created_moves_ids = ict0.depreciation_line_ids[1].create_move()
ict0.invalidate_recordset()
for move_id in ict0_created_moves_ids:
move = self.env["account.move"].browse(move_id)
# Validate that the profile account is used
depr_line = move.line_ids.filtered(
lambda line: line.account_id == self.ict3Y.account_depreciation_id
)
self.assertTrue(depr_line)
# Validate that the forced expense depreciation account is being used
expense_line = move.line_ids.filtered(
lambda line: line.account_id == self.account_expense_laptop
)
self.assertTrue(expense_line)
# Check that the asset is now open and depreciation is posted correctly
self.assertEqual(ict0.state, "open")
self.assertEqual(ict0.value_depreciated, 500)
self.assertEqual(ict0.value_residual, 1000)
vehicle0.validate()
vehicle0_created_move_ids = vehicle0.depreciation_line_ids[1].create_move()
for move_id in vehicle0_created_move_ids:
move = self.env["account.move"].browse(move_id)
# Validate that the forced depreciation account is being used
depr_line = move.line_ids.filtered(
lambda line: line.account_id == self.account_depreciation_car
)
self.assertTrue(depr_line)
# Validate that the profile account is used
expense_line = move.line_ids.filtered(
lambda line: line.account_id
== self.car5y.account_expense_depreciation_id
)
self.assertTrue(expense_line)
vehicle0.invalidate_recordset()
# Ensure the asset's state and values are correct after depreciation posting
self.assertEqual(vehicle0.state, "open")
self.assertEqual(vehicle0.value_depreciated, 2000)
self.assertEqual(vehicle0.value_residual, 8000)
vehicle0.invalidate_recordset()

View File

@@ -0,0 +1,28 @@
<?xml version='1.0' encoding='utf-8' ?>
<!-- # Copyright 2024 Bernat Obrador(APSL-Nagarro)<bobrador@apsl.net>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="account_asset_view_form_inherit" model="ir.ui.view">
<field name="name">account.asset.form.inherit</field>
<field name="model">account.asset</field>
<field
name="inherit_id"
ref="account_asset_management.account_asset_view_form"
/>
<field name="arch" type="xml">
<xpath expr="//field[@name='group_ids']" position="after">
<field name="account_asset_id" invisible="not profile_id" />
<field
name="account_depreciation_id"
readonly="state in ['open', 'close', 'removed']"
invisible="not profile_id"
/>
<field
name="account_expense_depreciation_id"
readonly="state in ['open', 'close', 'removed']"
invisible="not profile_id"
/>
</xpath>
</field>
</record>
</odoo>