Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions purchase_deposit_preserve_amount/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
================================
Purchase Deposit Preserve Amount
================================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:dec5ee036437249ea0cd05823cc27d012220374d3b2d2473cd92f6cfee5c5b7e
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |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-qrtl%2Faxls--custom-lightgray.png?logo=github
:target: https://github.com/qrtl/axls-custom/tree/16.0/purchase_deposit_preserve_amount
:alt: qrtl/axls-custom

|badge1| |badge2| |badge3|

This module preserves the original deposit invoice amount on deposit
lines when creating vendor bills from purchase orders in a
multi-currency environment, ensuring that stock valuation layer
differences are calculated based on the preserved deposit amount.

**Table of contents**

.. contents::
:local:

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/qrtl/axls-custom/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/qrtl/axls-custom/issues/new?body=module:%20purchase_deposit_preserve_amount%0Aversion:%2016.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
-------

* Quartile

Maintainers
-----------

This module is part of the `qrtl/axls-custom <https://github.com/qrtl/axls-custom/tree/16.0/purchase_deposit_preserve_amount>`_ project on GitHub.

You are welcome to contribute.
1 change: 1 addition & 0 deletions purchase_deposit_preserve_amount/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
13 changes: 13 additions & 0 deletions purchase_deposit_preserve_amount/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2025 Quartile (https://www.quartile.co)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

{
"name": "Purchase Deposit Preserve Amount",
"version": "16.0.1.0.0",
"author": "Quartile",
"website": "https://www.quartile.co",
"category": "Purchase Management",
"license": "AGPL-3",
"depends": ["purchase_deposit"],
"installable": True,
}
3 changes: 3 additions & 0 deletions purchase_deposit_preserve_amount/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import account_move_line
from . import account_move
from . import uom_uom
92 changes: 92 additions & 0 deletions purchase_deposit_preserve_amount/models/account_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Copyright 2025 Quartile (https://www.quartile.co)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import api, fields, models


class AccountMove(models.Model):
_inherit = "account.move"

is_deposit = fields.Boolean(compute="_compute_is_deposit")

def _compute_is_deposit(self):
for rec in self:
rec.is_deposit = any(
rec.invoice_line_ids.filtered(
lambda line: line.purchase_line_id.is_deposit and line.quantity > 0
)
)

def _adjust_journal_item_balances_for_deposit(self):
Comment thread
AungKoKoLin1997 marked this conversation as resolved.
"""Reconcile deposit and stock received balances when the move currency
differs from the company currency by resetting deposit lines to the
original deposit bill amount and redistributing the difference over
non-deposit product lines.
"""
for rec in self:
deposit_lines = rec.line_ids.filtered(
lambda line: line.display_type == "product"
and line.purchase_line_id.is_deposit
)
Comment thread
AungKoKoLin1997 marked this conversation as resolved.
if not deposit_lines:
continue
amount_diff = 0.0
for line in deposit_lines:
balance = sum(
line.purchase_line_id.invoice_lines.filtered(
lambda l: l.move_id.state == "posted" and l.move_id.is_deposit
).mapped("balance")
)
amount_diff += balance + line.balance
line.with_context(skip_deposit_adjustment=True).balance = -1 * balance
Comment thread
AungKoKoLin1997 marked this conversation as resolved.
if not amount_diff:
continue
product_lines = rec.line_ids.filtered(
lambda line: line.display_type == "product"
and line.purchase_line_id
and not line.purchase_line_id.is_deposit
)
if not product_lines:
continue
line_count = len(product_lines)
total_balance = sum(product_lines.mapped("balance"))
remaining = amount_diff
for idx, line in enumerate(product_lines):
if idx < line_count - 1:
if total_balance:
raw_share = amount_diff * (line.balance / total_balance)
else:
raw_share = amount_diff / line_count
share = rec.currency_id.round(raw_share)
remaining -= share
else:
# last line gets whatever remains, to keep sums exact
share = rec.currency_id.round(remaining)
line.with_context(skip_deposit_adjustment=True).balance = (
line.balance + share
)

# Expect to extend as necessary for other move types
def _moves_needing_deposit_adjustment(self):
return self.filtered(
lambda m: (
m.move_type == "in_invoice"
and not m.is_deposit
and m.line_ids.filtered(
lambda l: l.purchase_line_id and l.purchase_line_id.is_deposit
)
)
)

@api.model_create_multi
def create(self, vals_list):
moves = super().create(vals_list)
moves._moves_needing_deposit_adjustment()._adjust_journal_item_balances_for_deposit()
return moves

def write(self, vals):
res = super().write(vals)
if self.env.context.get("skip_deposit_adjustment"):
return res
self._moves_needing_deposit_adjustment()._adjust_journal_item_balances_for_deposit()
return res
17 changes: 17 additions & 0 deletions purchase_deposit_preserve_amount/models/account_move_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2025 Quartile (https://www.quartile.co)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import models


class AccountMoveLine(models.Model):
_inherit = "account.move.line"

def _generate_price_difference_vals(self, layers):
self.ensure_one()
if not self.move_id.line_ids.filtered(
lambda line: line.purchase_line_id.is_deposit
):
return super()._generate_price_difference_vals(layers)
self = self.with_context(need_deposit_adj_aml=self)
return super()._generate_price_difference_vals(layers)
19 changes: 19 additions & 0 deletions purchase_deposit_preserve_amount/models/uom_uom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2025 Quartile (https://www.quartile.co)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import models
from odoo.tools import float_round


class UOM(models.Model):
_inherit = "uom.uom"

def _compute_price(self, price, to_unit):
self.ensure_one()
aml = self.env.context.get("need_deposit_adj_aml")
if aml and aml.quantity:
price = float_round(
aml.balance / aml.quantity,
precision_rounding=aml.company_currency_id.rounding,
)
return super()._compute_price(price, to_unit)
3 changes: 3 additions & 0 deletions purchase_deposit_preserve_amount/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
This module preserves the original deposit invoice amount on deposit lines when creating
vendor bills from purchase orders in a multi-currency environment, ensuring that stock
valuation layer differences are calculated based on the preserved deposit amount.
Loading
Loading