From 99affd40957c76e202f725ede48781a8a2fdd867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dar=C3=ADo=20Lodeiros?= Date: Fri, 4 Nov 2022 13:38:44 +0100 Subject: [PATCH] [RFC]pms_api_rest: payments to transactions --- pms_api_rest/datamodels/__init__.py | 2 +- .../datamodels/pms_account_payment.py | 59 ------ pms_api_rest/datamodels/pms_transaction.py | 41 +++++ pms_api_rest/models/__init__.py | 1 + pms_api_rest/models/account_payment.py | 36 ++++ pms_api_rest/services/pms_folio_service.py | 12 +- pms_api_rest/services/pms_partner_service.py | 7 +- ..._service.py => pms_transaction_service.py} | 170 +++++++++++++----- 8 files changed, 213 insertions(+), 115 deletions(-) delete mode 100644 pms_api_rest/datamodels/pms_account_payment.py create mode 100644 pms_api_rest/datamodels/pms_transaction.py create mode 100644 pms_api_rest/models/account_payment.py rename pms_api_rest/services/{pms_account_payment_service.py => pms_transaction_service.py} (64%) diff --git a/pms_api_rest/datamodels/__init__.py b/pms_api_rest/datamodels/__init__.py index 25586a00a..bba5766fd 100644 --- a/pms_api_rest/datamodels/__init__.py +++ b/pms_api_rest/datamodels/__init__.py @@ -14,7 +14,7 @@ from . import pms_partner from . import pms_property from . import pms_account_journal -from . import pms_account_payment +from . import pms_transaction from . import pms_invoice from . import pms_user diff --git a/pms_api_rest/datamodels/pms_account_payment.py b/pms_api_rest/datamodels/pms_account_payment.py deleted file mode 100644 index 190ac8369..000000000 --- a/pms_api_rest/datamodels/pms_account_payment.py +++ /dev/null @@ -1,59 +0,0 @@ -from marshmallow import fields - -from odoo.addons.datamodel.core import Datamodel -from odoo.addons.datamodel.fields import NestedModel - - -class PmsPaymentInfo(Datamodel): - _name = "pms.payment.info" - id = fields.Integer(required=False, allow_none=True) - name = fields.String(required=False, allow_none=True) - amount = fields.Float(required=False, allow_none=True) - journalId = fields.Integer(required=False, allow_none=True) - date = fields.String(required=False, allow_none=True) - partnerName = fields.String(required=False, allow_none=True) - partnerId = fields.Integer(required=False, allow_none=True) - paymentType = fields.String(required=False, allow_none=True) - partnerType = fields.String(required=False, allow_none=True) - isTransfer = fields.Boolean(required=False, allow_none=True) - reference = fields.String(required=False, allow_none=True) - createUid = fields.Integer(required=False, allow_none=True) - - -class PmsPaymentSearchParam(Datamodel): - _name = "pms.payment.search.param" - _inherit = "pms.rest.metadata" - pmsPropertyId = fields.Integer(required=True, allow_none=False) - filter = fields.String(required=False, allow_none=True) - dateStart = fields.String(required=False, allow_none=True) - dateEnd = fields.String(required=False, allow_none=True) - paymentMethodId = fields.Integer(required=False, allow_none=True) - # TODO: paymentTypes filter - paymentTypes = fields.List(fields.Integer(required=False, allow_none=True)) - paymentType = fields.String(required=False, allow_none=True) - partnerType = fields.String(required=False, allow_none=True) - isTransfer = fields.Boolean(required=False, allow_none=True) - - -class PmsPaymentResults(Datamodel): - _name = "pms.payment.results" - payments = fields.List(NestedModel("pms.payment.info")) - total = fields.Float(required=False, allow_none=True) - totalPayments = fields.Integer(required=False, allow_none=True) - - -class PmsTransactionInfo(Datamodel): - _name = "pms.transaction.info" - id = fields.Integer(required=False, allow_none=True) - date = fields.String(required=False, allow_none=True) - journalId = fields.Integer(required=False, allow_none=True) - amount = fields.Float(required=False, allow_none=True) - partnerId = fields.Integer(required=False, allow_none=True) - reservationIds = fields.List(fields.Integer(), required=False) - folioId = fields.Integer(required=False, allow_none=True) - - transactionType = fields.String(required=False, allow_none=True) - destinationJournalId = fields.Integer(required=False, allow_none=True) - reference = fields.String(required=False, allow_none=True) - pmsPropertyId = fields.Integer(required=False, allow_none=True) - createUid = fields.Integer(required=False, allow_none=True) diff --git a/pms_api_rest/datamodels/pms_transaction.py b/pms_api_rest/datamodels/pms_transaction.py new file mode 100644 index 000000000..28465f816 --- /dev/null +++ b/pms_api_rest/datamodels/pms_transaction.py @@ -0,0 +1,41 @@ +from marshmallow import fields + +from odoo.addons.datamodel.core import Datamodel +from odoo.addons.datamodel.fields import NestedModel + + +class PmsTransactionSearchParam(Datamodel): + _name = "pms.transaction.search.param" + _inherit = "pms.rest.metadata" + pmsPropertyId = fields.Integer(required=True, allow_none=False) + filter = fields.String(required=False, allow_none=True) + dateStart = fields.String(required=False, allow_none=True) + dateEnd = fields.String(required=False, allow_none=True) + transactionMethodId = fields.Integer(required=False, allow_none=True) + transactionType = fields.String(required=False, allow_none=True) + # REVIEW: Fields to avoid?: + + +class PmsTransactionsResults(Datamodel): + _name = "pms.transaction.results" + transactions = fields.List(NestedModel("pms.transaction.info")) + total = fields.Float(required=False, allow_none=True) + totalTransactions = fields.Integer(required=False, allow_none=True) + + +class PmsTransactionInfo(Datamodel): + _name = "pms.transaction.info" + id = fields.Integer(required=False, allow_none=True) + date = fields.String(required=False, allow_none=True) + journalId = fields.Integer(required=False, allow_none=True) + amount = fields.Float(required=False, allow_none=True) + partnerId = fields.Integer(required=False, allow_none=True) + reservationIds = fields.List(fields.Integer(), required=False) + folioId = fields.Integer(required=False, allow_none=True) + destinationJournalId = fields.Integer(required=False, allow_none=True) + reference = fields.String(required=False, allow_none=True) + pmsPropertyId = fields.Integer(required=False, allow_none=True) + createUid = fields.Integer(required=False, allow_none=True) + transactionType = fields.String(required=False, allow_none=True) + # REVIEW: Fields to avoid?: + partnerName = fields.String(required=False, allow_none=True) diff --git a/pms_api_rest/models/__init__.py b/pms_api_rest/models/__init__.py index 49652c702..495168b21 100644 --- a/pms_api_rest/models/__init__.py +++ b/pms_api_rest/models/__init__.py @@ -1,2 +1,3 @@ from . import pms_property from . import res_users +from . import account_payment diff --git a/pms_api_rest/models/account_payment.py b/pms_api_rest/models/account_payment.py new file mode 100644 index 000000000..f6c3be67a --- /dev/null +++ b/pms_api_rest/models/account_payment.py @@ -0,0 +1,36 @@ +from odoo import api, fields, models + + +class AccountPayment(models.Model): + _inherit = "account.payment" + + pms_api_transaction_type = fields.Selection( + selection=[ + ("customer_inbound", "Customer Payment"), + ("customer_outbound", "Customer Refund"), + ("supplier_outbound", "Supplier Payment"), + ("supplier_inbound", "Supplier Refund"), + ("internal_transfer", "Internal Transfer"), + ], + string="PMS API Transaction Type", + help="Transaction type for PMS API", + compute="_compute_pms_api_transaction_type", + store=True, + ) + + @api.depends("payment_type", "partner_type") + def _compute_pms_api_transaction_type(self): + for record in self: + if record.is_internal_transfer: + return "internal_transfer" + if record.partner_type == "customer": + if record.payment_type == "inbound": + return "customer_payment" + else: + return "customer_refund" + if record.partner_type == "supplier": + if record.payment_type == "inbound": + return "supplier_payment" + else: + return "supplier_refund" + return False diff --git a/pms_api_rest/services/pms_folio_service.py b/pms_api_rest/services/pms_folio_service.py index 1dc409521..69403a867 100644 --- a/pms_api_rest/services/pms_folio_service.py +++ b/pms_api_rest/services/pms_folio_service.py @@ -173,7 +173,7 @@ class PmsFolioService(Component): ) ], input_param=Datamodel("pms.search.param"), - output_param=Datamodel("pms.payment.info", is_list=True), + output_param=Datamodel("pms.transaction.info", is_list=True), auth="jwt_api_pms", ) def get_folio_payments(self, folio_id, pms_search_param): @@ -183,7 +183,7 @@ class PmsFolioService(Component): domain.append(("pms_property_id", "=", pms_search_param.pmsPropertyId)) folio = self.env["pms.folio"].search(domain) payments = [] - PmsPaymentInfo = self.env.datamodels["pms.payment.info"] + PmsTransactiontInfo = self.env.datamodels["pms.transaction.info"] if not folio: pass else: @@ -193,14 +193,14 @@ class PmsFolioService(Component): if folio.payment_ids: for payment in folio.payment_ids: payments.append( - PmsPaymentInfo( + PmsTransactiontInfo( id=payment.id, amount=round(payment.amount, 2), journalId=payment.journal_id.id, date=datetime.combine( payment.date, datetime.min.time() ).isoformat(), - paymentType=payment.payment_type, + transactionTypeCode=payment.pms_api_transaction_type, ) ) return payments @@ -214,7 +214,7 @@ class PmsFolioService(Component): "POST", ) ], - input_param=Datamodel("pms.payment.info", is_list=False), + input_param=Datamodel("pms.transaction.info", is_list=False), auth="jwt_api_pms", ) def create_folio_charge(self, folio_id, pms_account_payment_info): @@ -249,7 +249,7 @@ class PmsFolioService(Component): "POST", ) ], - input_param=Datamodel("pms.payment.info", is_list=False), + input_param=Datamodel("pms.transaction.info", is_list=False), auth="jwt_api_pms", ) def create_folio_refund(self, folio_id, pms_account_payment_info): diff --git a/pms_api_rest/services/pms_partner_service.py b/pms_api_rest/services/pms_partner_service.py index 08cff7a6a..44d0c1603 100644 --- a/pms_api_rest/services/pms_partner_service.py +++ b/pms_api_rest/services/pms_partner_service.py @@ -216,23 +216,24 @@ class PmsPartnerService(Component): "GET", ) ], - output_param=Datamodel("pms.payment.info", is_list=True), + output_param=Datamodel("pms.transaction.info", is_list=True), auth="jwt_api_pms", ) def get_partner_payments(self, partner_id): partnerPayments = self.env["account.payment"].search( [("partner_id", "=", partner_id)] ) - PmsPaymentInfo = self.env.datamodels["pms.payment.info"] + PmsTransactiontInfo = self.env.datamodels["pms.transaction.info"] payments = [] for payment in partnerPayments: payments.append( - PmsPaymentInfo( + PmsTransactiontInfo( id=payment.id, amount=round(payment.amount, 2), journalId=payment.journal_id.id, date=payment.date.strftime("%d/%m/%Y"), reference=payment.ref, + transactionTypeCode=payment.pms_api_transaction_type, ) ) return payments diff --git a/pms_api_rest/services/pms_account_payment_service.py b/pms_api_rest/services/pms_transaction_service.py similarity index 64% rename from pms_api_rest/services/pms_account_payment_service.py rename to pms_api_rest/services/pms_transaction_service.py index 43f7051d3..2d4cd298c 100644 --- a/pms_api_rest/services/pms_account_payment_service.py +++ b/pms_api_rest/services/pms_transaction_service.py @@ -11,10 +11,10 @@ from odoo.addons.base_rest_datamodel.restapi import Datamodel from odoo.addons.component.core import Component -class PmsAccountPaymentService(Component): +class PmsTransactionService(Component): _inherit = "base.rest.service" - _name = "pms.account.payment.service" - _usage = "payments" + _name = "pms.transaction.service" + _usage = "transactions" _collection = "pms.services" @restapi.method( @@ -26,37 +26,42 @@ class PmsAccountPaymentService(Component): "GET", ) ], - input_param=Datamodel("pms.payment.search.param", is_list=False), - output_param=Datamodel("pms.payment.results", is_list=False), + input_param=Datamodel("pms.transaction.search.param", is_list=False), + output_param=Datamodel("pms.transaction.results", is_list=False), auth="jwt_api_pms", ) - def get_payments(self, pms_payments_search_param): - result_payments = [] + def get_transactions(self, pms_transactions_search_param): + result_transactions = [] domain_fields = [("state", "=", "posted")] available_journals = () - if pms_payments_search_param.pmsPropertyId: + if pms_transactions_search_param.pmsPropertyId: available_journals = self.env["account.journal"].search( [ - "&", - ("pms_property_ids", "in", pms_payments_search_param.pmsPropertyId), - ("pms_property_ids", "!=", False), + ( + "pms_property_ids", + "in", + pms_transactions_search_param.pmsPropertyId, + ), ] ) domain_fields.append(("journal_id", "in", available_journals.ids)) domain_filter = list() - if pms_payments_search_param.filter: + if pms_transactions_search_param.filter: # TODO: filter by folio and invoice - for search in pms_payments_search_param.filter.split(" "): + for search in pms_transactions_search_param.filter.split(" "): subdomains = [ [("name", "ilike", search)], - # [("folio_id.name", "ilike", search)], + [("ref", "ilike", search)], [("partner_id.display_name", "ilike", search)], ] domain_filter.append(expression.OR(subdomains)) - if pms_payments_search_param.dateStart and pms_payments_search_param.dateEnd: - date_from = fields.Date.from_string(pms_payments_search_param.dateStart) - date_to = fields.Date.from_string(pms_payments_search_param.dateEnd) + if ( + pms_transactions_search_param.dateStart + and pms_transactions_search_param.dateEnd + ): + date_from = fields.Date.from_string(pms_transactions_search_param.dateStart) + date_to = fields.Date.from_string(pms_transactions_search_param.dateEnd) domain_fields.extend( [ "&", @@ -64,26 +69,33 @@ class PmsAccountPaymentService(Component): ("date", "<", date_to), ] ) - if pms_payments_search_param.paymentMethodId: + if pms_transactions_search_param.transactionMethodId: domain_fields.append( - ("journal_id", "=", pms_payments_search_param.paymentMethodId) + ("journal_id", "=", pms_transactions_search_param.transactionMethodId) ) - # TODO: payment tyope filter (partner_type, payment_type, is_transfer) + + if pms_transactions_search_param.transactionType: + domain_fields.append( + "pms_api_transaction_type", + "=", + pms_transactions_search_param.transactionType, + ) + if domain_filter: domain = expression.AND([domain_fields, domain_filter[0]]) else: domain = domain_fields - PmsPaymentResults = self.env.datamodels["pms.payment.results"] - PmsPaymentInfo = self.env.datamodels["pms.payment.info"] + PmsTransactionResults = self.env.datamodels["pms.transaction.results"] + PmsTransactiontInfo = self.env.datamodels["pms.transaction.info"] - total_payments = self.env["account.payment"].search_count(domain) - group_payments = self.env["account.payment"].read_group( + total_transactions = self.env["account.payment"].search_count(domain) + group_transactions = self.env["account.payment"].read_group( domain=domain, fields=["amount:sum"], groupby=["payment_type"] ) amount_result = 0 - if group_payments: - for item in group_payments: + if group_transactions: + for item in group_transactions: total_inbound = ( item["amount"] if item["payment_type"] == "inbound" else 0 ) @@ -91,33 +103,99 @@ class PmsAccountPaymentService(Component): item["amount"] if item["payment_type"] == "outbound" else 0 ) amount_result = total_inbound - total_outbound - for payment in self.env["account.payment"].search( + for transaction in self.env["account.payment"].search( domain, - order=pms_payments_search_param.orderBy, - limit=pms_payments_search_param.limit, - offset=pms_payments_search_param.offset, + order=pms_transactions_search_param.orderBy, + limit=pms_transactions_search_param.limit, + offset=pms_transactions_search_param.offset, ): - result_payments.append( - PmsPaymentInfo( - id=payment.id, - name=payment.name if payment.name else None, - amount=payment.amount, - journalId=payment.journal_id.id if payment.journal_id else None, - date=payment.date.strftime("%d/%m/%Y"), - partnerId=payment.partner_id.id if payment.partner_id else None, - partnerName=payment.partner_id.name if payment.partner_id else None, - paymentType=payment.payment_type, - partnerType=payment.partner_type, - isTransfer=payment.is_internal_transfer, - reference=payment.ref if payment.ref else None, - createUid=payment.create_uid if payment.create_uid else None, + result_transactions.append( + PmsTransactiontInfo( + id=transaction.id, + name=transaction.name if transaction.name else None, + amount=transaction.amount, + journalId=transaction.journal_id.id + if transaction.journal_id + else None, + date=transaction.date.strftime("%d/%m/%Y"), + partnerId=transaction.partner_id.id + if transaction.partner_id + else None, + partnerName=transaction.partner_id.name + if transaction.partner_id + else None, + reference=transaction.ref if transaction.ref else None, + createUid=transaction.create_uid + if transaction.create_uid + else None, + transactionType=transaction.pms_api_transaction_type, ) ) - return PmsPaymentResults( - payments=result_payments, total=amount_result, totalPayments=total_payments + return PmsTransactionResults( + payments=result_transactions, + total=amount_result, + totalPayments=total_transactions, ) + @restapi.method( + [ + ( + [ + "/", + ], + "GET", + ) + ], + output_param=Datamodel("pms.transaction.info", is_list=False), + auth="jwt_api_pms", + ) + def get_transaction(self, transaction_id): + PmsTransactiontInfo = self.env.datamodels["pms.transaction.info"] + transaction = self.env["account.payment"].browse(transaction_id) + return PmsTransactiontInfo( + id=transaction.id, + name=transaction.name if transaction.name else None, + amount=transaction.amount, + journalId=transaction.journal_id.id if transaction.journal_id else None, + date=transaction.date.strftime("%d/%m/%Y"), + partnerId=transaction.partner_id.id if transaction.partner_id else None, + partnerName=transaction.partner_id.name if transaction.partner_id else None, + reference=transaction.ref if transaction.ref else None, + createUid=transaction.create_uid.id if transaction.create_uid else None, + transactionType=transaction.pms_api_transaction_type, + ) + + @restapi.method( + [ + ( + [ + "/", + ], + "POST", + ) + ], + input_param=Datamodel("pms.transaction.info", is_list=False), + auth="jwt_api_pms", + ) + def create_transaction(self): + return True + + @restapi.method( + [ + ( + [ + "/p/", + ], + "PATCH", + ) + ], + input_param=Datamodel("pms.transaction.info", is_list=False), + auth="jwt_api_pms", + ) + def update_transaction(self, transaction_id): + return True + @restapi.method( [ (