Skip to content

Commit 9c2d4ce

Browse files
committed
[IMP] l10n_it_asset_management: Recharge asset
1 parent 9f6c1ad commit 9c2d4ce

15 files changed

+435
-20
lines changed

l10n_it_asset_management/README.rst

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ Depreciations can be generated by using the related wizard found in
5050
Assets -> Assets Management -> Generate Depreciations, or by triggering
5151
the same wizard from a single asset form view.
5252

53+
When an asset is returned, it is possible to recharge its purchase and
54+
fund amounts choosing "Partial Recharge" in the "Link to Asset" wizard
55+
of the credit note. The wizard will allow to link to the credit note
56+
only the assets of the refunded invoice.
57+
5358
**Italiano**
5459

5560
È possibile creare e gestire cespiti dalla sezione contabilità di Odoo.
@@ -63,6 +68,11 @@ contabili. Gli ammortamenti possono essere generati utilizzando
6368
l'apposito wizard in Cespiti -> Gestione Cestpiti -> Genera
6469
Ammortamenti, o aprendo quello stesso wizard dalla scheda del cespite.
6570

71+
Quando un cespite viene restituito, è possibile ricaricare gli importi
72+
di acquisto e di fondo scegliendo "Ricarica parziale" nella procedura
73+
"Collega a cespite" della nota di credito. La procedura consentirà di
74+
collegare alla nota di credito solo i cespiti della fattura rimborsata.
75+
6676
Bug Tracker
6777
===========
6878

@@ -99,8 +109,7 @@ Contributors
99109
- Nextev Srl <[email protected]>
100110

101111
Base icon made by `surang <https://www.flaticon.com/authors/surang>`__
102-
from
103-
[`www.flaticon.com](https://www.flaticon.com/) <http://www.flaticon.com](https://www.flaticon.com/)>`__.
112+
from `www.flaticon.com <http://www.flaticon.com>`__.
104113

105114
Maintainers
106115
-----------

l10n_it_asset_management/models/account_move.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ def open_wizard_manage_asset(self):
107107
{
108108
"default_company_id": self.company_id.id,
109109
"default_dismiss_date": self.invoice_date or self.invoice_date_due,
110+
"default_recharge_date": self.invoice_date or self.invoice_date_due,
110111
"default_move_ids": [Command.set(self.ids)],
111112
"default_move_line_ids": [Command.set(lines.ids)],
112113
"default_purchase_date": self.invoice_date or self.invoice_date_due,

l10n_it_asset_management/models/asset_accounting_info.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class AssetAccountingInfo(models.Model):
5151
relation_type = fields.Selection(
5252
[
5353
("create", "Asset Creation"),
54+
("partial_recharge", "Partial Recharge"),
5455
("update", "Asset Update"),
5556
("partial_dismiss", "Asset Partial Dismissal"),
5657
("dismiss", "Asset Dismissal"),

l10n_it_asset_management/models/asset_depreciation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ def _compute_last_depreciation_date(self):
296296
for dep in self:
297297
dep_lines = dep.line_ids.filtered(
298298
lambda line: line.move_type == "depreciated"
299-
and not line.partial_dismissal
299+
and not (line.partial_dismissal or line.partial_recharge)
300300
)
301301
if dep_lines:
302302
dep.last_depreciation_date = max(dep_lines.mapped("date"))

l10n_it_asset_management/models/asset_depreciation_line.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class AssetDepreciationLine(models.Model):
100100
)
101101

102102
partial_dismissal = fields.Boolean()
103+
partial_recharge = fields.Boolean()
103104

104105
percentage = fields.Float(string="%")
105106

@@ -265,9 +266,8 @@ def get_update_move_types(self):
265266
def is_depreciation_nr_required(self):
266267
"""Defines if a line requires to be numbered"""
267268
self.ensure_one()
268-
return (
269-
self.move_type in self.get_numbered_move_types()
270-
and not self.partial_dismissal
269+
return self.move_type in self.get_numbered_move_types() and not (
270+
self.partial_dismissal or self.partial_recharge
271271
)
272272

273273
def make_name(self):
@@ -398,15 +398,22 @@ def get_depreciated_account_move_line_vals(self):
398398
self.ensure_one()
399399

400400
# Asset depreciation
401-
if not self.partial_dismissal:
401+
if not (self.partial_dismissal or self.partial_recharge):
402402
credit_account_id = self.asset_id.category_id.fund_account_id.id
403403
debit_account_id = self.depreciation_id.depreciation_account_id.id
404404

405-
# Asset partial dismissal
406405
else:
406+
# Asset partial dismissal
407407
debit_account_id = self.asset_id.category_id.fund_account_id.id
408408
credit_account_id = self.asset_id.category_id.asset_account_id.id
409409

410+
# Asset partial recharge
411+
if self.partial_recharge:
412+
credit_account_id, debit_account_id = (
413+
debit_account_id,
414+
credit_account_id,
415+
)
416+
410417
amt = abs(self.amount)
411418
credit_line_vals = {
412419
"account_id": credit_account_id,
@@ -499,3 +506,6 @@ def post_partial_dismiss_asset(self):
499506
)
500507
if to_create_move:
501508
to_create_move.generate_account_move()
509+
510+
def post_partial_recharge_asset(self):
511+
return self.post_partial_dismiss_asset()

l10n_it_asset_management/readme/USAGE.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Depreciations can be generated by using the related wizard found in
1010
Assets -\> Assets Management -\> Generate Depreciations, or by
1111
triggering the same wizard from a single asset form view.
1212

13+
When an asset is returned, it is possible to recharge its purchase and fund amounts choosing "Partial Recharge" in the "Link to Asset" wizard of the credit note.
14+
The wizard will allow to link to the credit note only the assets of the refunded invoice.
15+
1316
**Italiano**
1417

1518
È possibile creare e gestire cespiti dalla sezione contabilità di Odoo.
@@ -22,3 +25,6 @@ I cespiti possono essere creati manualmente o da fatture e registrazioni
2225
contabili. Gli ammortamenti possono essere generati utilizzando
2326
l'apposito wizard in Cespiti -\> Gestione Cestpiti -\> Genera
2427
Ammortamenti, o aprendo quello stesso wizard dalla scheda del cespite.
28+
29+
Quando un cespite viene restituito, è possibile ricaricare gli importi di acquisto e di fondo scegliendo "Ricarica parziale" nella procedura "Collega a cespite" della nota di credito.
30+
La procedura consentirà di collegare alla nota di credito solo i cespiti della fattura rimborsata.

l10n_it_asset_management/report/asset_journal.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ def get_report_dep_line_year_data(self):
728728
line.amount
729729
for line in self.dep_line_ids.filtered(
730730
lambda line: line.move_type == "depreciated"
731-
and not line.partial_dismissal
731+
and not (line.partial_dismissal or line.partial_recharge)
732732
)
733733
]
734734
)
@@ -737,7 +737,7 @@ def get_report_dep_line_year_data(self):
737737
line.amount
738738
for line in self.dep_line_ids.filtered(
739739
lambda line: line.move_type == "depreciated"
740-
and line.partial_dismissal
740+
and (line.partial_dismissal or line.partial_recharge)
741741
)
742742
]
743743
)

l10n_it_asset_management/report/asset_previsional.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,9 @@ def generate_structure(self):
245245
if fyear.date_to >= dep.date_start:
246246
prev = not lines or not any(
247247
line.move_type == "depreciated"
248-
and not line.partial_dismissal
248+
and not (
249+
line.partial_dismissal or line.partial_recharge
250+
)
249251
for line in lines
250252
)
251253
sequence += 1
@@ -797,7 +799,7 @@ def get_report_dep_line_year_data(self):
797799
line.amount
798800
for line in self.dep_line_ids.filtered(
799801
lambda line: line.move_type == "depreciated"
800-
and not line.partial_dismissal
802+
and not (line.partial_dismissal or line.partial_recharge)
801803
)
802804
]
803805
)
@@ -806,7 +808,7 @@ def get_report_dep_line_year_data(self):
806808
line.amount
807809
for line in self.dep_line_ids.filtered(
808810
lambda line: line.move_type == "depreciated"
809-
and line.partial_dismissal
811+
and (line.partial_dismissal or line.partial_recharge)
810812
)
811813
]
812814
)

l10n_it_asset_management/static/description/index.html

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,10 @@ <h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
394394
Depreciations can be generated by using the related wizard found in
395395
Assets -&gt; Assets Management -&gt; Generate Depreciations, or by triggering
396396
the same wizard from a single asset form view.</p>
397+
<p>When an asset is returned, it is possible to recharge its purchase and
398+
fund amounts choosing “Partial Recharge” in the “Link to Asset” wizard
399+
of the credit note. The wizard will allow to link to the credit note
400+
only the assets of the refunded invoice.</p>
397401
<p><strong>Italiano</strong></p>
398402
<p>È possibile creare e gestire cespiti dalla sezione contabilità di Odoo.</p>
399403
<p>La configurazione dei cespiti dev’essere fatta andando in Cespiti -&gt;
@@ -403,6 +407,10 @@ <h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
403407
contabili. Gli ammortamenti possono essere generati utilizzando
404408
l’apposito wizard in Cespiti -&gt; Gestione Cestpiti -&gt; Genera
405409
Ammortamenti, o aprendo quello stesso wizard dalla scheda del cespite.</p>
410+
<p>Quando un cespite viene restituito, è possibile ricaricare gli importi
411+
di acquisto e di fondo scegliendo “Ricarica parziale” nella procedura
412+
“Collega a cespite” della nota di credito. La procedura consentirà di
413+
collegare alla nota di credito solo i cespiti della fattura rimborsata.</p>
406414
</div>
407415
<div class="section" id="bug-tracker">
408416
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
@@ -438,8 +446,7 @@ <h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
438446
<li>Nextev Srl &lt;<a class="reference external" href="mailto:odoo&#64;nextev.it">odoo&#64;nextev.it</a>&gt;</li>
439447
</ul>
440448
<p>Base icon made by <a class="reference external" href="https://www.flaticon.com/authors/surang">surang</a>
441-
from
442-
[<a class="reference external" href="http://www.flaticon.com](https://www.flaticon.com/)">www.flaticon.com](https://www.flaticon.com/)</a>.</p>
449+
from <a class="reference external" href="http://www.flaticon.com">www.flaticon.com</a>.</p>
443450
</div>
444451
<div class="section" id="maintainers">
445452
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>

l10n_it_asset_management/tests/common.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,27 @@ def _create_entry(self, account, amount, post=True):
312312
self.assertEqual(entry.move_type, "entry")
313313
return entry
314314

315+
def _refund_move(self, move, method="cancel", ref_date=None):
316+
reverse_context = {
317+
"active_model": move._name,
318+
"active_ids": move.ids,
319+
}
320+
refund_wizard_form = Form(
321+
self.env["account.move.reversal"].with_context(**reverse_context)
322+
)
323+
refund_wizard_form.reason = "test"
324+
if ref_date:
325+
refund_wizard_form.date_mode = "custom"
326+
refund_wizard_form.date = ref_date
327+
refund_wizard_form.refund_method = method
328+
refund_wizard = refund_wizard_form.save()
329+
330+
refund_action = refund_wizard.reverse_moves()
331+
refund_move = self.env[refund_action["res_model"]].browse(
332+
refund_action["res_id"]
333+
)
334+
return refund_move
335+
315336
def _civil_depreciate_asset(self, asset):
316337
# Keep only one civil depreciation
317338
civil_depreciation_type = self.env.ref(

l10n_it_asset_management/tests/test_assets_management.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# Copyright 2022 Simone Rubino - TAKOBI
33
# Copyright 2023 Simone Rubino - Aion Tech
44
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
5+
6+
import datetime
57
from datetime import date
68

79
from odoo import fields
@@ -816,3 +818,132 @@ def test_open_manage_asset_wiz(self):
816818
asset_wiz.with_user(forbidden_user).link_asset()
817819
asset_wiz.with_user(manager_user).link_asset()
818820
asset_wiz.with_user(account_user).link_asset()
821+
822+
def test_purchase_sale_refund_recharge(self):
823+
"""A sale refund can be used to restore asset value."""
824+
# Create with purchase
825+
purchase_amount = 2500
826+
purchase_invoice = self._create_purchase_invoice(
827+
datetime.date(2020, month=1, day=1), amount=purchase_amount
828+
)
829+
asset = self._link_asset_move(
830+
purchase_invoice,
831+
"create",
832+
{
833+
"category_id": self.asset_category_1,
834+
"name": "Test recharge asset",
835+
},
836+
)
837+
civ_depreciation = asset.depreciation_ids.filtered(
838+
lambda x: x.type_id
839+
== self.env.ref("l10n_it_asset_management.ad_type_civilistico")
840+
)
841+
self.assertEqual(civ_depreciation.amount_depreciable_updated, purchase_amount)
842+
843+
# Partial dismiss with sale
844+
asset_account_amount = asset_fund_amount = 1000
845+
sale_invoice = self._create_sale_invoice(
846+
asset, amount=8000, invoice_date=datetime.date(2020, month=3, day=1)
847+
)
848+
self._link_asset_move(
849+
sale_invoice,
850+
"partial_dismiss",
851+
wiz_values={
852+
"asset_id": asset,
853+
"depreciated_fund_amount": asset_account_amount,
854+
"asset_purchase_amount": asset_fund_amount,
855+
},
856+
)
857+
civ_depreciation_lines = civ_depreciation.line_ids
858+
self.assertRecordValues(
859+
civ_depreciation_lines.sorted("move_type"),
860+
[
861+
{
862+
"move_type": "depreciated",
863+
"amount": -1000.0,
864+
},
865+
{
866+
"move_type": "gain",
867+
"amount": 8000.0,
868+
},
869+
{
870+
"move_type": "out",
871+
"amount": 1000.0,
872+
},
873+
],
874+
)
875+
civ_depreciation_move_lines = civ_depreciation_lines.filtered(
876+
lambda cdl: cdl.move_type == "depreciated"
877+
).move_id.line_ids
878+
self.assertRecordValues(
879+
civ_depreciation_move_lines.sorted("balance"),
880+
[
881+
{
882+
"account_id": asset.category_id.asset_account_id.id,
883+
"balance": -1000,
884+
},
885+
{
886+
"account_id": asset.category_id.fund_account_id.id,
887+
"balance": 1000,
888+
},
889+
],
890+
)
891+
self.assertEqual(
892+
civ_depreciation.amount_depreciable_updated,
893+
purchase_amount - asset_account_amount,
894+
)
895+
896+
# Refund and recharge
897+
sale_refund = self._refund_move(
898+
sale_invoice, ref_date=datetime.date(2020, month=7, day=1)
899+
)
900+
recharge_purchase_amount = recharge_fund_amount = 1000
901+
wizard = self._get_move_asset_wizard(
902+
sale_refund,
903+
"partial_recharge",
904+
wiz_values={
905+
"recharge_purchase_amount": recharge_purchase_amount,
906+
"recharge_fund_amount": recharge_fund_amount,
907+
},
908+
)
909+
wizard.link_asset()
910+
self.assertEqual(wizard.asset_id, asset)
911+
self.assertEqual(wizard.allowed_asset_ids, asset)
912+
civ_depreciation_lines = civ_depreciation.line_ids - civ_depreciation_lines
913+
self.assertRecordValues(
914+
civ_depreciation_lines.sorted("move_type"),
915+
[
916+
{
917+
"move_type": "depreciated",
918+
"amount": 1000.0,
919+
},
920+
{
921+
"move_type": "in",
922+
"amount": 1000.0,
923+
},
924+
{
925+
"move_type": "loss",
926+
"amount": 8000.0,
927+
},
928+
],
929+
)
930+
civ_depreciation_move_lines = civ_depreciation_lines.filtered(
931+
lambda cdl: cdl.move_type == "depreciated"
932+
).move_id.line_ids
933+
self.assertRecordValues(
934+
civ_depreciation_move_lines.sorted("balance"),
935+
[
936+
{
937+
"account_id": asset.category_id.fund_account_id.id,
938+
"balance": -1000,
939+
},
940+
{
941+
"account_id": asset.category_id.asset_account_id.id,
942+
"balance": 1000,
943+
},
944+
],
945+
)
946+
self.assertEqual(
947+
civ_depreciation.amount_depreciable_updated,
948+
purchase_amount,
949+
)

l10n_it_asset_management/views/account_move.xml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,19 @@
100100
/>
101101
<field name="force_dep_nr" invisible="1" />
102102
<field name="partial_dismissal" invisible="1" />
103+
<field name="partial_recharge" invisible="1" />
103104
<field
104105
name="depreciation_nr"
105-
attrs="{'invisible': [('force_dep_nr', '=', False), '|', ('partial_dismissal', '=', True), ('move_type', 'not in', ('depreciated', 'historical'))]}"
106+
attrs="{
107+
'invisible': [
108+
('force_dep_nr', '=', False),
109+
'|',
110+
'|',
111+
('partial_dismissal', '=', True),
112+
('partial_recharge', '=', True),
113+
('move_type', 'not in', ('depreciated', 'historical')),
114+
],
115+
}"
106116
/>
107117
<field name="amount" widget="monetary" />
108118
<field name="requires_account_move" invisible="1" />

0 commit comments

Comments
 (0)