Skip to content

Commit

Permalink
Merge PR #604 into 16.0
Browse files Browse the repository at this point in the history
Signed-off-by AaronHForgeFlow
  • Loading branch information
OCA-git-bot committed Oct 26, 2023
2 parents ed0c352 + 54eec0f commit 153767d
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 3 deletions.
5 changes: 5 additions & 0 deletions account_mass_reconcile/models/base_reconciliation.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ def _get_rec_date(self, lines, based_on="end_period_last_credit"):
def last_date(mlines):
return max(mlines, key=itemgetter("date"))

def oldest_date(mlines):
return min(mlines, key=itemgetter("date"))

def credit(mlines):
return [line for line in mlines if line["credit"] > 0]

Expand All @@ -136,6 +139,8 @@ def debit(mlines):

if based_on == "newest":
return last_date(lines)["date"]
elif based_on == "oldest":
return oldest_date(lines)["date"]
elif based_on == "newest_credit":
return last_date(credit(lines))["date"]
elif based_on == "newest_debit":
Expand Down
6 changes: 5 additions & 1 deletion account_mass_reconcile/models/mass_reconcile.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ class MassReconcileOptions(models.AbstractModel):

@api.model
def _get_rec_base_date(self):
return [("newest", "Most recent move line"), ("actual", "Today")]
return [
("newest", "Most recent move line"),
("actual", "Today"),
("oldest", "Oldest move line"),
]

write_off = fields.Float("Write off allowed", default=0.0)
account_lost_id = fields.Many2one("account.account", string="Account Lost")
Expand Down
7 changes: 6 additions & 1 deletion account_mass_reconcile/models/simple_reconciliation.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ def rec_auto_lines_simple(self, lines):
return res

def _simple_order(self, *args, **kwargs):
return "ORDER BY account_move_line.%s" % self._key_field
ret = "ORDER BY account_move_line.%s" % self._key_field
if self.date_base_on == "oldest":
ret += ", date"
elif self.date_base_on == "newest":
ret += ", date desc"
return ret

def _action_rec(self):
"""Match only 2 move lines, do not allow partial reconcile"""
Expand Down
5 changes: 4 additions & 1 deletion account_mass_reconcile/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ in order to provide:
in this module, the simple reconciliations works
on 2 lines (1 debit / 1 credit) and do not allow
partial reconciliation, they also match on 1 key,
partner or Journal item name.
partner or Journal item name. There is also an
option for 'most recent move line' or
'oldest move line' which is used to choose the
move to be reconciled if more than one is found.
119 changes: 119 additions & 0 deletions account_mass_reconcile/tests/test_scenario_reconcile.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# © 2014-2016 Camptocamp SA (Damien Crier)
# © 2023 FactorLibre - Aritz Olea <aritz.olea@factorlibre.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from datetime import timedelta
Expand Down Expand Up @@ -67,6 +68,124 @@ def test_scenario_reconcile(self):
mass_rec.run_reconcile()
self.assertEqual("paid", invoice.payment_state)

def test_scenario_reconcile_newest(self):
invoice = self.create_invoice()
self.assertEqual("posted", invoice.state)

receivalble_account_id = invoice.partner_id.property_account_receivable_id.id
# create payments
payment_old = self.env["account.payment"].create(
{
"partner_type": "customer",
"payment_type": "inbound",
"partner_id": invoice.partner_id.id,
"destination_account_id": receivalble_account_id,
"amount": 50.0,
"journal_id": self.bank_journal.id,
"date": fields.Date.from_string("2023-10-01"),
}
)
payment_new = self.env["account.payment"].create(
{
"partner_type": "customer",
"payment_type": "inbound",
"partner_id": invoice.partner_id.id,
"destination_account_id": receivalble_account_id,
"amount": 50.0,
"journal_id": self.bank_journal.id,
"date": fields.Date.from_string("2023-10-20"),
}
)
payment_old.action_post()
payment_new.action_post()

# create the mass reconcile record
mass_rec = self.mass_rec_obj.create(
{
"name": "mass_reconcile_1",
"account": invoice.partner_id.property_account_receivable_id.id,
"reconcile_method": [
(
0,
0,
{
"name": "mass.reconcile.simple.partner",
"date_base_on": "newest",
},
)
],
}
)
# call the automatic reconciliation method
mass_rec.run_reconcile()
self.assertEqual("paid", invoice.payment_state)
self.assertTrue(mass_rec.last_history)
payment_new_line = payment_new.move_id.line_ids.filtered(lambda l: l.credit)
payment_old_line = payment_old.move_id.line_ids.filtered(lambda l: l.credit)
self.assertTrue(payment_new_line in mass_rec.last_history.reconcile_line_ids)
self.assertTrue(payment_new_line.reconciled)
self.assertFalse(payment_old_line in mass_rec.last_history.reconcile_line_ids)
self.assertFalse(payment_old_line.reconciled)

def test_scenario_reconcile_oldest(self):
invoice = self.create_invoice()
self.assertEqual("posted", invoice.state)

receivalble_account_id = invoice.partner_id.property_account_receivable_id.id
# create payments
payment_old = self.env["account.payment"].create(
{
"partner_type": "customer",
"payment_type": "inbound",
"partner_id": invoice.partner_id.id,
"destination_account_id": receivalble_account_id,
"amount": 50.0,
"journal_id": self.bank_journal.id,
"date": fields.Date.from_string("2023-10-01"),
}
)
payment_new = self.env["account.payment"].create(
{
"partner_type": "customer",
"payment_type": "inbound",
"partner_id": invoice.partner_id.id,
"destination_account_id": receivalble_account_id,
"amount": 50.0,
"journal_id": self.bank_journal.id,
"date": fields.Date.from_string("2023-10-20"),
}
)
payment_old.action_post()
payment_new.action_post()

# create the mass reconcile record
mass_rec = self.mass_rec_obj.create(
{
"name": "mass_reconcile_1",
"account": invoice.partner_id.property_account_receivable_id.id,
"reconcile_method": [
(
0,
0,
{
"name": "mass.reconcile.simple.partner",
"date_base_on": "oldest",
},
)
],
}
)
# call the automatic reconciliation method
mass_rec.run_reconcile()
self.assertEqual("paid", invoice.payment_state)
self.assertTrue(mass_rec.last_history)
payment_new_line = payment_new.move_id.line_ids.filtered(lambda l: l.credit)
payment_old_line = payment_old.move_id.line_ids.filtered(lambda l: l.credit)
self.assertFalse(payment_new_line in mass_rec.last_history.reconcile_line_ids)
self.assertFalse(payment_new_line.reconciled)
self.assertTrue(payment_old_line in mass_rec.last_history.reconcile_line_ids)
self.assertTrue(payment_old_line.reconciled)

def test_scenario_reconcile_currency(self):
currency_rate = (
self.env["res.currency.rate"]
Expand Down

0 comments on commit 153767d

Please sign in to comment.