Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][MIG] sale_unreconciled #1936

Open
wants to merge 25 commits into
base: 16.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4fc5f89
[14.0][ADD] sale_unreconciled
AaronHForgeFlow Nov 27, 2021
a82ef78
[IMP] sale_unreconciled: black, isort, prettier
AaronHForgeFlow Dec 29, 2021
b4429a2
[15.0][MIG] sale_unreconciled
AaronHForgeFlow Dec 29, 2021
f43a8cb
[FIX] sale_unreconciled: do not create empty write-offs
AaronHForgeFlow Mar 2, 2022
e8d50ab
[15.0][FIX] sale_unreconciled: reconcile exit condition
AaronHForgeFlow May 12, 2022
164c35d
[IMP] sale_unreconciled: allow companies to decide automatic reconcil…
AaronHForgeFlow Jul 13, 2022
6f43b56
[FIX]sale_unreconciled: reconcile by currency
AaronHForgeFlow Aug 23, 2022
e396a93
[IMP] sale_unreconciled: add tolerance parameter
AaronHForgeFlow Oct 29, 2022
efbe2cf
[FIX] sale_unreconciled: if journals have no residual but are full re…
AaronHForgeFlow Nov 7, 2022
d529587
[FIX] sale_unreconciled: multicompany for get unreconciled base domain
AaronHForgeFlow Nov 21, 2022
386baa1
[FIX] sale_unreconciled: action to see unreconciled journal items has…
AaronHForgeFlow Dec 22, 2022
e2f5d41
[IMP] sale_unreconciled: reconcile by groups
AaronHForgeFlow Feb 21, 2023
1723bde
[FIX] sale_unreconcile: bad FW code
AaronHForgeFlow Apr 4, 2023
3fcbc4d
[FIX] sale_unreconciled: sudo in search ir.model
AaronHForgeFlow Jul 17, 2023
91a47b6
[IMP] sale_unreconciled: text
AaronHForgeFlow Oct 10, 2023
22b1c96
[IMP] sale_unreconciled: add hook for custom write-off date
AaronHForgeFlow Oct 26, 2023
a52d16c
[FIX] sale_unreconciled: unreconciled base domain to match standard
AaronHForgeFlow Nov 29, 2023
38a9f54
[IMP]sale_unreconciled: reconcile cancelled SO
AaronHForgeFlow Dec 18, 2023
6ae25c9
fix sale_unrec
AaronHForgeFlow Dec 27, 2023
ea28a40
[FIX]sale_unreconciled: condition when no product
AaronHForgeFlow Dec 28, 2023
fc5afca
[IMP] sale_unreconciled: amount unreconciled in tree view
AaronHForgeFlow Dec 29, 2023
b602120
[FIX] sale_unreconciled: do the write-off on the latest date of the j…
AaronHForgeFlow Jan 8, 2024
b89349a
[FIX] sale_unreconciled: do not show warning unreonciled message when…
AaronHForgeFlow Feb 23, 2024
b4d8e5d
[IMP] sale_unreconciled: black, isort, prettier
AaronHForgeFlow Sep 17, 2024
a246efa
[MIG] sale_unreconciled: Migration to v16
AaronHForgeFlow Sep 17, 2024
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
105 changes: 105 additions & 0 deletions sale_unreconciled/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
=================
Sale Unreconciled
=================

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

.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
:target: https://odoo-community.org/page/development-status
:alt: Alpha
.. |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/16.0/sale_unreconciled
: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-16-0/account-financial-tools-16-0-sale_unreconciled
: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=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module adds a new field "Unreconciled" on Sales Orders, that allows
to find SO's with unreconciled journal items related.

This module allows to reconcile those SO in a single click. In accounting
settings users will be able to set up a specific account for write-off.

.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.
`More details on development status <https://odoo-community.org/page/development-status>`_

**Table of contents**

.. contents::
:local:

Usage
=====

Accountants will be able to find a filter in Sale Orders that shows
outstanding balances in interim accounts. Also there is a link in the SO
to those outstanding journal items.

Locking the SO will automatically reconcile the outstanding balance for the
stock interim accounts.

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:%20sale_unreconciled%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
~~~~~~~

* ForgeFlow S.L.

Contributors
~~~~~~~~~~~~

* ForgeFlow S.L. <[email protected]>

- Aaron Henriquez <[email protected]>

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-AaronHForgeFlow| image:: https://github.com/AaronHForgeFlow.png?size=40px
:target: https://github.com/AaronHForgeFlow
:alt: AaronHForgeFlow

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-AaronHForgeFlow|

This module is part of the `OCA/account-financial-tools <https://github.com/OCA/account-financial-tools/tree/16.0/sale_unreconciled>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions sale_unreconciled/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from . import wizards
21 changes: 21 additions & 0 deletions sale_unreconciled/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2021 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

{
"name": "Sale Unreconciled",
"version": "16.0.1.0.0",
"author": "ForgeFlow S.L., Odoo Community Association (OCA)",
"website": "https://github.com/OCA/account-financial-tools",
"category": "Accounting",
"depends": ["sale_mrp", "account_move_line_sale_info"],
"data": [
"security/ir.model.access.csv",
"views/sale_order_view.xml",
"views/res_config_settings_view.xml",
"wizards/sale_unreconciled_exceeded_view.xml",
],
"license": "AGPL-3",
"installable": True,
"development_status": "Alpha",
"maintainers": ["AaronHForgeFlow"],
}
4 changes: 4 additions & 0 deletions sale_unreconciled/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from . import sale_order
from . import company
from . import res_config_settings
from . import account_move_line
90 changes: 90 additions & 0 deletions sale_unreconciled/models/account_move_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Copyright 2019-21 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from datetime import datetime

from odoo import _, models
from odoo.exceptions import ValidationError


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

def _get_so_writeoff_amounts(self):
precision = self.env["decimal.precision"].precision_get("Account")
writeoff_amount = round(
sum(line["amount_residual"] for line in self), precision
)
writeoff_amount_curr = round(
sum(line["amount_residual_currency"] for line in self), precision
)
if writeoff_amount_curr and not writeoff_amount:
# Data inconsistency, do not create the write-off
return (0.0, 0.0, True)

Check warning on line 23 in sale_unreconciled/models/account_move_line.py

View check run for this annotation

Codecov / codecov/patch

sale_unreconciled/models/account_move_line.py#L23

Added line #L23 was not covered by tests
first_currency = self[0]["currency_id"]
if all([line["currency_id"] == first_currency for line in self]):
same_curr = True
else:
same_curr = False

Check warning on line 28 in sale_unreconciled/models/account_move_line.py

View check run for this annotation

Codecov / codecov/patch

sale_unreconciled/models/account_move_line.py#L28

Added line #L28 was not covered by tests

return (
writeoff_amount,
writeoff_amount_curr,
same_curr,
)

def _create_so_writeoff(self, writeoff_vals):
(
amount_writeoff,
amount_writeoff_curr,
same_curr,
) = self._get_so_writeoff_amounts()
if not amount_writeoff:
return self.env["account.move.line"]

Check warning on line 43 in sale_unreconciled/models/account_move_line.py

View check run for this annotation

Codecov / codecov/patch

sale_unreconciled/models/account_move_line.py#L43

Added line #L43 was not covered by tests
partners = self.mapped("partner_id")
move_date = writeoff_vals.get("date", datetime.now())
write_off_vals = {
"name": _("Automatic writeoff"),
"amount_currency": same_curr and amount_writeoff_curr or amount_writeoff,
"debit": amount_writeoff > 0.0 and amount_writeoff or 0.0,
"credit": amount_writeoff < 0.0 and -amount_writeoff or 0.0,
"partner_id": len(partners) == 1 and partners.id or False,
"account_id": writeoff_vals["account_id"],
"date": move_date,
"sale_order_id": writeoff_vals["sale_order_id"],
"journal_id": writeoff_vals["journal_id"],
"currency_id": writeoff_vals["currency_id"],
"product_id": writeoff_vals["product_id"],
"sale_line_id": writeoff_vals["sale_line_id"],
}
counterpart_account = self.mapped("account_id")
if len(counterpart_account) != 1:
raise ValidationError(_("Cannot write-off more than one account"))

Check warning on line 62 in sale_unreconciled/models/account_move_line.py

View check run for this annotation

Codecov / codecov/patch

sale_unreconciled/models/account_move_line.py#L62

Added line #L62 was not covered by tests
counter_part = write_off_vals.copy()
counter_part["debit"] = write_off_vals["credit"]
counter_part["credit"] = write_off_vals["debit"]
counter_part["amount_currency"] = -write_off_vals["amount_currency"]
counter_part["account_id"] = (counterpart_account.id,)

move = self.env["account.move"].create(
{
"date": move_date,
"journal_id": writeoff_vals["journal_id"],
"currency_id": writeoff_vals["currency_id"],
"line_ids": [(0, 0, write_off_vals), (0, 0, counter_part)],
}
)
if writeoff_vals.get("sale_order_id", False):
# done this way because sale_order_id is a related field and will
# not being assign on create. Cannot assign purchase_line_id because
# it is a generic write-off for the whole SO
self.env.cr.execute(
"""UPDATE account_move_line SET sale_order_id = %s
WHERE id in %s
""",
(writeoff_vals["sale_order_id"], tuple(move.line_ids.ids)),
)
move.action_post()
return move.line_ids.filtered(
lambda l: l.account_id.id == counterpart_account.id
)
29 changes: 29 additions & 0 deletions sale_unreconciled/models/company.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2021 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import fields, models


class ResCompany(models.Model):
_inherit = "res.company"

sale_reconcile_account_id = fields.Many2one(
"account.account",
domain=lambda self: [("deprecated", "=", False)],
string="Write-Off Account On Sales",
ondelete="restrict",
copy=False,
help="Write-off account to reconcile Unreconciled Sale Orders",
)

sale_reconcile_journal_id = fields.Many2one(
"account.journal", string="Writeoff Journal for Sales"
)
sale_lock_auto_reconcile = fields.Boolean()

sale_reconcile_tolerance = fields.Float(
string="Tolerance (%)",
default=0.0,
help="Percentage of tolerance of residual amount vs total amount of the Sales "
"Order. Leave zero to accept all discrepancies",
)
21 changes: 21 additions & 0 deletions sale_unreconciled/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2021 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import fields, models


class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"

sale_reconcile_account_id = fields.Many2one(
related="company_id.sale_reconcile_account_id", readonly=False
)
sale_reconcile_journal_id = fields.Many2one(
related="company_id.sale_reconcile_journal_id", readonly=False
)
sale_lock_auto_reconcile = fields.Boolean(
related="company_id.sale_lock_auto_reconcile", readonly=False
)
sale_reconcile_tolerance = fields.Float(
related="company_id.sale_reconcile_tolerance", readonly=False
)
Loading
Loading