mirror of
https://github.com/OCA/account-financial-tools.git
synced 2025-02-02 12:47:26 +02:00
4
account_asset_stock_move/__init__.py
Normal file
4
account_asset_stock_move/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# Copyright 2021 Ecosoft Co., Ltd. <http://ecosoft.co.th>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import models
|
||||
17
account_asset_stock_move/__manifest__.py
Normal file
17
account_asset_stock_move/__manifest__.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# Copyright 2021 Ecosoft Co., Ltd. <http://ecosoft.co.th>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
{
|
||||
"name": "Assets Management - Create asset during stock move",
|
||||
"version": "14.0.1.0.0",
|
||||
"license": "AGPL-3",
|
||||
"depends": ["account_asset_management", "stock_account"],
|
||||
"author": "Ecosoft, Odoo Community Association (OCA)",
|
||||
"website": "https://github.com/OCA/account-financial-tools",
|
||||
"category": "Accounting & Finance",
|
||||
"data": [
|
||||
"views/stock.xml",
|
||||
],
|
||||
"development_status": "Alpha",
|
||||
"maintainers": ["kittiu"],
|
||||
}
|
||||
5
account_asset_stock_move/models/__init__.py
Normal file
5
account_asset_stock_move/models/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
# Copyright 2021 Ecosoft Co., Ltd. <http://ecosoft.co.th>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import stock_move
|
||||
from . import stock_picking
|
||||
90
account_asset_stock_move/models/stock_move.py
Normal file
90
account_asset_stock_move/models/stock_move.py
Normal file
@@ -0,0 +1,90 @@
|
||||
# Copyright 2021 Ecosoft Co., Ltd. <http://ecosoft.co.th>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import _, models
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tests.common import Form
|
||||
|
||||
|
||||
class StockMove(models.Model):
|
||||
_inherit = "stock.move"
|
||||
|
||||
def _generate_valuation_lines_data(
|
||||
self,
|
||||
partner_id,
|
||||
qty,
|
||||
debit_value,
|
||||
credit_value,
|
||||
debit_account_id,
|
||||
credit_account_id,
|
||||
description,
|
||||
):
|
||||
"""
|
||||
Assign Account's Asset Profile (if any)
|
||||
"""
|
||||
rslt = super()._generate_valuation_lines_data(
|
||||
partner_id,
|
||||
qty,
|
||||
debit_value,
|
||||
credit_value,
|
||||
debit_account_id,
|
||||
credit_account_id,
|
||||
description,
|
||||
)
|
||||
for entry in rslt.values():
|
||||
account = self.env["account.account"].browse(entry["account_id"])
|
||||
entry["asset_profile_id"] = account.asset_profile_id.id
|
||||
return rslt
|
||||
|
||||
def _create_account_move_line(
|
||||
self,
|
||||
credit_account_id,
|
||||
debit_account_id,
|
||||
journal_id,
|
||||
qty,
|
||||
description,
|
||||
svl_id,
|
||||
cost,
|
||||
):
|
||||
"""
|
||||
Create Asset (if asset_profile_id exists)
|
||||
"""
|
||||
res = super()._create_account_move_line(
|
||||
credit_account_id,
|
||||
debit_account_id,
|
||||
journal_id,
|
||||
qty,
|
||||
description,
|
||||
svl_id,
|
||||
cost,
|
||||
)
|
||||
for move in self.env["account.move"].search([("stock_move_id", "=", self.id)]):
|
||||
for aml in move.line_ids.filtered("asset_profile_id"):
|
||||
vals = move._prepare_asset_vals(aml)
|
||||
if not aml.name:
|
||||
raise UserError(
|
||||
_("Asset name must be set in the label of the line.")
|
||||
)
|
||||
asset_form = Form(
|
||||
self.env["account.asset"]
|
||||
.with_company(move.company_id)
|
||||
.with_context(create_asset_from_move_line=True, move_id=move.id)
|
||||
)
|
||||
for key, val in vals.items():
|
||||
setattr(asset_form, key, val)
|
||||
asset = asset_form.save()
|
||||
asset.analytic_tag_ids = aml.analytic_tag_ids
|
||||
aml.with_context(allow_asset=True).asset_id = asset.id
|
||||
refs = [
|
||||
"<a href=# data-oe-model=account.asset data-oe-id=%s>%s</a>"
|
||||
% tuple(name_get)
|
||||
for name_get in move.line_ids.filtered(
|
||||
"asset_profile_id"
|
||||
).asset_id.name_get()
|
||||
]
|
||||
if refs:
|
||||
message = _("This journal entry created the asset(s): %s") % ", ".join(
|
||||
refs
|
||||
)
|
||||
move.message_post(body=message)
|
||||
return res
|
||||
40
account_asset_stock_move/models/stock_picking.py
Normal file
40
account_asset_stock_move/models/stock_picking.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# Copyright 2021 Ecosoft Co., Ltd. <http://ecosoft.co.th>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class StockPicking(models.Model):
|
||||
_inherit = "stock.picking"
|
||||
|
||||
asset_count = fields.Integer(compute="_compute_asset_count")
|
||||
|
||||
def _compute_asset_count(self):
|
||||
for rec in self:
|
||||
moves = self.env["account.move"].search(
|
||||
[("stock_move_id", "in", rec.move_lines.ids)]
|
||||
)
|
||||
rec.asset_count = sum(moves.mapped("asset_count"))
|
||||
|
||||
def action_view_assets(self):
|
||||
moves = self.env["account.move"].search(
|
||||
[("stock_move_id", "in", self.move_lines.ids)]
|
||||
)
|
||||
assets = (
|
||||
self.env["account.asset.line"]
|
||||
.search([("move_id", "in", moves.ids)])
|
||||
.mapped("asset_id")
|
||||
)
|
||||
action = self.env.ref("account_asset_management.account_asset_action")
|
||||
action_dict = action.sudo().read()[0]
|
||||
if len(assets) == 1:
|
||||
res = self.env.ref(
|
||||
"account_asset_management.account_asset_view_form", False
|
||||
)
|
||||
action_dict["views"] = [(res and res.id or False, "form")]
|
||||
action_dict["res_id"] = assets.id
|
||||
elif assets:
|
||||
action_dict["domain"] = [("id", "in", assets.ids)]
|
||||
else:
|
||||
action_dict = {"type": "ir.actions.act_window_close"}
|
||||
return action_dict
|
||||
6
account_asset_stock_move/readme/CONFIGURE.rst
Normal file
6
account_asset_stock_move/readme/CONFIGURE.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
For Product to create as asset (during stock move), setup on product category,
|
||||
|
||||
* Inventory Valuation = Automated (realtime)
|
||||
* Stock Valuation Account = Asset Profile's Asset Account
|
||||
|
||||
With this setup, account move created during picking in will set asset profile, and result in asset creation.
|
||||
3
account_asset_stock_move/readme/CONTRIBUTORS.rst
Normal file
3
account_asset_stock_move/readme/CONTRIBUTORS.rst
Normal file
@@ -0,0 +1,3 @@
|
||||
* `Ecosoft <http://ecosoft.co.th>`_:
|
||||
|
||||
* Kitti U. <kittiu@ecosoft.co.th
|
||||
5
account_asset_stock_move/readme/DESCRIPTION.rst
Normal file
5
account_asset_stock_move/readme/DESCRIPTION.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
By standard, asset is created when vendor bill is confirmed (asset profile was set on invoice line)
|
||||
|
||||
But in case real time stock is used, account moves created on stock moves, and it is possible to create asset on confirm of stock picking.
|
||||
|
||||
This should be useful for organization that want to create asset during stock in and not when confirm vendor bill.
|
||||
3
account_asset_stock_move/readme/USAGE.rst
Normal file
3
account_asset_stock_move/readme/USAGE.rst
Normal file
@@ -0,0 +1,3 @@
|
||||
1. Create Picking In (either by direct creation or from purchase order)
|
||||
2. Select product (to create asset) and confirm the transfer
|
||||
3. Check journal entry created by the transfer, asset is created and linked.
|
||||
BIN
account_asset_stock_move/static/description/icon.png
Normal file
BIN
account_asset_stock_move/static/description/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
4
account_asset_stock_move/tests/__init__.py
Normal file
4
account_asset_stock_move/tests/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# Copyright 2021 Ecosoft Co., Ltd. <http://ecosoft.co.th>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import test_account_asset_stock_move
|
||||
@@ -0,0 +1,77 @@
|
||||
# Copyright 2021 Ecosoft Co., Ltd. <http://ecosoft.co.th>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo.tests import common
|
||||
from odoo.tests.common import Form
|
||||
|
||||
|
||||
class TestAccountAssetStockMove(common.TransactionCase):
|
||||
def setUp(self):
|
||||
super(TestAccountAssetStockMove, self).setUp()
|
||||
# Asset Profile
|
||||
self.account_expense = self.env["account.account"].search(
|
||||
[
|
||||
(
|
||||
"user_type_id",
|
||||
"=",
|
||||
self.env.ref("account.data_account_type_expenses").id,
|
||||
)
|
||||
],
|
||||
limit=1,
|
||||
)
|
||||
self.account_asset = self.env["account.account"].search(
|
||||
[
|
||||
(
|
||||
"user_type_id",
|
||||
"=",
|
||||
self.env.ref("account.data_account_type_current_assets").id,
|
||||
)
|
||||
],
|
||||
limit=1,
|
||||
)
|
||||
self.journal_purchase = self.env["account.journal"].search(
|
||||
[("type", "=", "purchase")], limit=1
|
||||
)
|
||||
self.asset_profile = self.env["account.asset.profile"].create(
|
||||
{
|
||||
"account_expense_depreciation_id": self.account_expense.id,
|
||||
"account_asset_id": self.account_asset.id,
|
||||
"account_depreciation_id": self.account_asset.id,
|
||||
"journal_id": self.journal_purchase.id,
|
||||
"name": "Furniture - 3 Years",
|
||||
"method_time": "year",
|
||||
"method_number": 3,
|
||||
"method_period": "year",
|
||||
}
|
||||
)
|
||||
# Realtime valuation product
|
||||
self.product_categ = self.env.ref("product.product_category_5")
|
||||
self.product_categ.property_valuation = "real_time"
|
||||
self.product_categ.property_stock_valuation_account_id = self.account_asset
|
||||
self.product_desk = self.env.ref("product.product_product_4")
|
||||
self.product_desk.categ_id = self.product_categ
|
||||
self.picking_type_in = self.env.ref("stock.picking_type_in")
|
||||
|
||||
def test_account_asset_stock_move(self):
|
||||
"""Create Picking In with realtime valuation product,
|
||||
If account_asset_id in account move, asset profile will be set,
|
||||
and asset will be created when stock move is done"""
|
||||
with Form(self.env["stock.picking"]) as f:
|
||||
f.picking_type_id = self.picking_type_in
|
||||
with f.move_ids_without_package.new() as line:
|
||||
line.product_id = self.product_desk
|
||||
line.product_uom_qty = 1
|
||||
picking = f.save()
|
||||
picking.action_confirm()
|
||||
picking.move_lines[0].quantity_done = 1
|
||||
picking.button_validate()
|
||||
self.assertEqual(picking.state, "done")
|
||||
move = self.env["account.move"].search(
|
||||
[("stock_move_id", "=", picking.move_lines[0].id)]
|
||||
)
|
||||
move_line = move.line_ids.filtered(lambda l: l.debit)
|
||||
self.assertEqual(move_line.account_id, self.account_asset)
|
||||
self.assertEqual(picking.asset_count, 1)
|
||||
res = picking.action_view_assets()
|
||||
asset = self.env[res["res_model"]].browse(res["res_id"])
|
||||
self.assertEqual(asset.profile_id, self.asset_profile)
|
||||
28
account_asset_stock_move/views/stock.xml
Normal file
28
account_asset_stock_move/views/stock.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<odoo>
|
||||
|
||||
<record id="view_picking_form" model="ir.ui.view">
|
||||
<field name="name">stock.picking.form</field>
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_form" />
|
||||
<field name="groups_id" eval="[(4, ref('account.group_account_invoice'))]" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('oe_button_box')]" position="inside">
|
||||
<button
|
||||
name="action_view_assets"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-cube"
|
||||
attrs="{'invisible': [('asset_count', '=', 0)]}"
|
||||
>
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_value">
|
||||
<field name="asset_count" />
|
||||
</span>
|
||||
<span class="o_stat_text"> Asset(s)</span>
|
||||
</div>
|
||||
</button>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -0,0 +1 @@
|
||||
../../../../account_asset_stock_move
|
||||
6
setup/account_asset_stock_move/setup.py
Normal file
6
setup/account_asset_stock_move/setup.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['setuptools-odoo'],
|
||||
odoo_addon=True,
|
||||
)
|
||||
Reference in New Issue
Block a user