[WIP] compute folio payments from invoices

This commit is contained in:
Darío Lodeiros
2022-01-16 19:13:15 +01:00
parent 6db518adc8
commit c9cd05195d
6 changed files with 114 additions and 153 deletions

View File

@@ -5,7 +5,6 @@
from . import ir_http
from . import ir_config_parameter
# from . import payment_return
from . import pms_board_service_room_type
from . import pms_property
from . import res_users

View File

@@ -4,7 +4,6 @@ import json
from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo.tools import float_is_zero
class AccountMove(models.Model):
@@ -21,12 +20,6 @@ class AccountMove(models.Model):
column2="folio_ids_id",
store=True,
)
outstanding_folios_debits_widget = fields.Text(
compute="_compute_get_outstanding_folios_JSON"
)
has_folios_outstanding = fields.Boolean(
compute="_compute_get_outstanding_folios_JSON"
)
pms_property_id = fields.Many2one(
string="Property",
help="The property associated to the account move",
@@ -56,75 +49,92 @@ class AccountMove(models.Model):
elif move.line_ids and move.line_ids.sale_line_ids:
move.folio_ids = move.mapped("line_ids.sale_line_ids.folio_id.id")
def _compute_get_outstanding_folios_JSON(self):
self.ensure_one()
self.outstanding_folios_debits_widget = json.dumps(False)
if self.from_folio:
payment_ids = self.folio_ids.mapped("payment_ids.id")
if self.state == "open":
account_partner = (
self.env["res.partner"]._find_accounting_partner(self.partner_id).id
def _compute_payments_widget_to_reconcile_info(self):
for move in self:
if not move.line_ids.folio_line_ids:
super(AccountMove, move)._compute_payments_widget_to_reconcile_info()
else:
move.invoice_outstanding_credits_debits_widget = json.dumps(False)
move.invoice_has_outstanding = False
if (
move.state != "posted"
or move.payment_state not in ("not_paid", "partial")
or not move.is_invoice(include_receipts=True)
):
continue
pay_term_lines = move.line_ids.filtered(
lambda line: line.account_id.user_type_id.type
in ("receivable", "payable")
)
domain = [
("account_id", "=", self.account_id.id),
("partner_id", "!=", account_partner),
("account_id", "in", pay_term_lines.account_id.ids),
("parent_state", "=", "posted"),
("reconciled", "=", False),
("payment_id", "in", payment_ids),
"|",
"&",
("amount_residual_currency", "!=", 0.0),
("currency_id", "!=", None),
"&",
("amount_residual_currency", "=", 0.0),
"&",
("currency_id", "=", None),
("amount_residual", "!=", 0.0),
("amount_residual_currency", "!=", 0.0),
"|",
(
"folio_ids",
"in",
move.line_ids.mapped("folio_line_ids.folio_id.id"),
),
("partner_id", "=", move.commercial_partner_id.id),
]
if self.type in ("out_invoice", "in_refund"):
domain.extend([("credit", ">", 0), ("debit", "=", 0)])
type_payment = _("Outstanding credits in Folio")
else:
domain.extend([("credit", "=", 0), ("debit", ">", 0)])
type_payment = _("Outstanding debits")
info = {
"title": "",
payments_widget_vals = {
"outstanding": True,
"content": [],
"move_id": self.id,
"move_id": move.id,
}
lines = self.env["account.move.line"].search(domain)
currency_id = self.currency_id
if len(lines) != 0:
for line in lines:
# get the outstanding residual value in inv. currency
if line.currency_id and line.currency_id == self.currency_id:
amount_to_show = abs(line.amount_residual_currency)
else:
amount_to_show = line.company_id.currency_id.with_context(
date=line.date
).compute(abs(line.amount_residual), self.currency_id)
if float_is_zero(
amount_to_show, precision_rounding=self.currency_id.rounding
):
continue
if line.ref:
title = "{} : {}".format(line.move_id.name, line.ref)
else:
title = line.move_id.name
info["content"].append(
{
"journal_name": line.ref or line.move_id.name,
"title": title,
"amount": amount_to_show,
"currency": currency_id.symbol,
"id": line.id,
"position": currency_id.position,
"digits": [69, self.currency_id.decimal_places],
}
if move.is_inbound():
domain.append(("balance", "<", 0.0))
payments_widget_vals["title"] = _("Outstanding credits")
else:
domain.append(("balance", ">", 0.0))
payments_widget_vals["title"] = _("Outstanding debits")
for line in self.env["account.move.line"].search(domain):
if line.currency_id == move.currency_id:
# Same foreign currency.
amount = abs(line.amount_residual_currency)
else:
# Different foreign currencies.
amount = move.company_currency_id._convert(
abs(line.amount_residual),
move.currency_id,
move.company_id,
line.date,
)
info["title"] = type_payment
self.outstanding_folios_debits_widget = json.dumps(info)
self.has_folio_outstanding = True
if move.currency_id.is_zero(amount):
continue
payments_widget_vals["content"].append(
{
"journal_name": line.ref or line.move_id.name,
"amount": amount,
"currency": move.currency_id.symbol,
"id": line.id,
"move_id": line.move_id.id,
"position": move.currency_id.position,
"digits": [69, move.currency_id.decimal_places],
"payment_date": fields.Date.to_string(line.date),
}
)
if not payments_widget_vals["content"]:
continue
move.invoice_outstanding_credits_debits_widget = json.dumps(
payments_widget_vals
)
move.invoice_has_outstanding = True
def action_folio_payments(self):
self.ensure_one()

View File

@@ -19,11 +19,8 @@ class AccountMoveLine(models.Model):
column2="sale_line_id",
)
folio_ids = fields.Many2many(
related="payment_id.folio_ids",
string="Folios",
comodel_name="pms.folio",
relation="payment_folio_rel",
column1="move_id",
column2="folio_id",
)
name_changed_by_user = fields.Boolean(
string="Custom label",

View File

@@ -1,6 +1,6 @@
# Copyright 2017 Dario Lodeiros
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
from odoo import api, fields, models
class AccountPayment(models.Model):
@@ -11,11 +11,35 @@ class AccountPayment(models.Model):
string="Folios",
comodel_name="pms.folio",
ondelete="cascade",
compute="_compute_folio_ids",
store=True,
readonly=False,
relation="account_payment_folio_rel",
column1="payment_id",
column2="folio_id",
)
@api.depends("reconciled_invoice_ids", "reconciled_bill_ids")
def _compute_folio_ids(self):
for rec in self:
inv_folio_ids = rec.reconciled_invoice_ids.mapped(
"line_ids.folio_line_ids.folio_id.id"
)
bill_folio_ids = rec.reconciled_bill_ids.mapped(
"line_ids.folio_line_ids.folio_id.id"
)
folio_ids = list(set(inv_folio_ids + bill_folio_ids))
if folio_ids:
rec.write({"folio_ids": [(6, 0, folio_ids)]})
elif (
not rec.reconciled_invoice_ids
and not rec.reconciled_bill_ids
and rec.folio_ids
):
rec.folio_ids = rec.folio_ids
else:
rec.folio_ids = False
def _prepare_move_line_default_vals(self, write_off_line_vals=None):
line_vals_list = super(AccountPayment, self)._prepare_move_line_default_vals(
write_off_line_vals
@@ -29,6 +53,16 @@ class AccountPayment(models.Model):
)
return line_vals_list
def _synchronize_to_moves(self, changed_fields):
super(AccountPayment, self)._synchronize_to_moves(changed_fields)
if "folio_ids" in changed_fields:
for pay in self.with_context(skip_account_move_synchronization=True):
pay.move_id.write(
{
"folio_ids": [(6, 0, pay.folio_ids.ids)],
}
)
# Business methods
# def modify(self):

View File

@@ -1,45 +0,0 @@
# Copyright 2017 Dario Lodeiros
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import fields, models
class PaymentReturn(models.Model):
_inherit = "payment.return"
# Fields declaration
folio_id = fields.Many2one(
string="Folio", help="Folio in payment return", comodel_name="pms.folio"
)
pms_property_id = fields.Many2one(
string="Property",
help="Property with access to the element",
store=True,
readonly=True,
comodel_name="pms.property",
related="folio_id.pms_property_id",
)
company_id = fields.Many2one(
string="Company",
help="The company for Payment Return",
check_pms_properties=True,
)
def action_confirm(self):
pay = super(PaymentReturn, self).action_confirm()
if pay:
folio_ids = []
folios = self.env["pms.folio"].browse(folio_ids)
for line in self.line_ids:
payments = self.env["account.payment"].search(
[("move_line_ids", "in", line.move_line_ids.ids)]
)
folios_line = self.env["pms.folio"].browse(
payments.mapped("folio_id.id")
)
# for folio in folios_line:
# if self.id not in folio.return_ids.ids:
# folio.update({"return_ids": [(4, self.id)]})
# msg = _("Return of %s registered") % (line.amount)
# folio.message_post(subject=_("Payment Return"), body=msg)
folios += folios_line
folios.compute_amount()

View File

@@ -110,15 +110,6 @@ class PmsFolio(models.Model):
comodel_name="res.company",
compute="_compute_company_id",
)
move_line_ids = fields.Many2many(
string="Payments",
help="Folio payments",
readonly=True,
comodel_name="account.move.line",
relation="payment_folio_rel",
column1="folio_id",
column2="move_id",
)
analytic_account_id = fields.Many2one(
string="Analytic Account",
help="The analytic account related to a folio.",
@@ -962,10 +953,9 @@ class PmsFolio(models.Model):
"amount_total",
"reservation_type",
"state",
"move_line_ids",
"move_line_ids.parent_state",
"sale_line_ids.invoice_lines",
"sale_line_ids.invoice_lines.move_id.payment_state",
"payment_ids",
)
def _compute_amount(self):
for record in self:
@@ -986,7 +976,7 @@ class PmsFolio(models.Model):
self.env["account.move.line"]
.search(
[
("folio_ids", "in", record.id),
("move_id.folio_ids", "in", record.id),
(
"account_id",
"in",
@@ -1202,30 +1192,6 @@ class PmsFolio(models.Model):
action["context"] = ({"default_reservation_ids": [(6, 0, reservation_ids)]},)
return action
# def action_return_payments(self):
# self.ensure_one()
# return_move_ids = []
# acc_pay_obj = self.env["account.payment"]
# payments = acc_pay_obj.search(
# ["|", ("move_ids", "in", self.move_ids.ids), ("folio_id", "=", self.id)]
# )
# return_move_ids += self.move_ids.filtered(
# lambda invoice: invoice.type == "out_refund"
# ).mapped("payment_move_line_ids.move_id.id")
# return_lines = self.env["payment.return.line"].search(
# [("move_line_ids", "in", payments.mapped("move_line_ids.id")),]
# )
# return_move_ids += return_lines.mapped("return_id.move_id.id")
# return {
# "name": _("Returns"),
# "view_type": "form",
# "view_mode": "tree,form",
# "res_model": "account.move",
# "type": "ir.actions.act_window",
# "domain": [("id", "in", return_move_ids)],
# }
def action_checks(self):
self.ensure_one()
rooms = self.mapped("reservation_ids.id")