diff --git a/addons/membership/models/partner.py b/addons/membership/models/partner.py index d720fd5ec02..5528d7ada53 100644 --- a/addons/membership/models/partner.py +++ b/addons/membership/models/partner.py @@ -63,8 +63,9 @@ class Partner(models.Model): partner.membership_state = 'free' if partner.free_member else 'canceled' continue if partner.membership_stop and today > partner.membership_stop: - partner.membership_state = 'free' if partner.free_member else 'old' - continue + if partner.free_member: + partner.membership_state = 'free' + continue if partner.associate_member: partner.associate_member._compute_membership_state() partner.membership_state = partner.associate_member.membership_state @@ -89,7 +90,7 @@ class Partner(models.Model): # if there is an old invoice paid, set the state to 'old' if ((mline.date_from or date.min) < today and (mline.date_to or date.min) < today and \ (mline.date_from or date.min) <= (mline.date_to or date.min) and \ - mline.account_invoice_id and mline.account_invoice_id.state == 'paid'): + mline.account_invoice_id and mline.account_invoice_id.payment_state in ('in_payment', 'paid')): state = 'old' break diff --git a/addons/membership/tests/test_membership.py b/addons/membership/tests/test_membership.py index d8427923299..0b4abbbebd0 100644 --- a/addons/membership/tests/test_membership.py +++ b/addons/membership/tests/test_membership.py @@ -4,6 +4,7 @@ import datetime from dateutil.relativedelta import relativedelta from unittest.mock import patch +import time from odoo.addons.membership.tests.common import TestMembershipCommon from odoo.tests import tagged from odoo import fields @@ -12,6 +13,17 @@ from odoo import fields @tagged('post_install', '-at_install') class TestMembership(TestMembershipCommon): + def test_none_membership(self): + self.membership_1.write({ + 'membership_date_from': datetime.date.today() + relativedelta(years=-2), + 'membership_date_to': datetime.date.today() + relativedelta(years=-1), + }) + + self.partner_1.create_membership_invoice(self.membership_1, 75.0) + self.assertEqual( + self.partner_1.membership_state, 'none', + 'membership: outdated non paid subscription should keep in non-member state') + def test_old_membership(self): self.membership_1.write({ 'membership_date_from': datetime.date.today() + relativedelta(years=-2), @@ -19,9 +31,66 @@ class TestMembership(TestMembershipCommon): }) self.partner_1.create_membership_invoice(self.membership_1, 75.0) + self.assertEqual( + self.partner_1.membership_state, 'none', + 'membership: outdated non paid subscription should keep in non-member state') + + # subscribes to a membership + self.partner_1.create_membership_invoice(self.membership_1, 75.0) + + # checks for invoices + invoice = self.env['account.move'].search([('partner_id', '=', self.partner_1.id)], limit=1) + self.assertEqual( + invoice.state, 'draft', + 'membership: new subscription should create a draft invoice') + self.assertEqual( + invoice.invoice_line_ids[0].product_id, self.membership_1, + 'membership: new subscription should create a line with the membership as product') + self.assertEqual( + invoice.invoice_line_ids[0].price_unit, 75.0, + 'membership: new subscription should create a line with the given price instead of product price') + + self.assertEqual( + self.partner_1.membership_state, 'none', + 'membership: old membership unpaid should be in non-member state') + + # the invoice is open -> customer goes to invoiced status + invoice.action_post() + + self.assertEqual( + self.partner_1.membership_state, 'none', + 'membership: after opening the invoice for old membership, it should remain in non paid status') + + # payment process + payment = self.env['account.payment'].create({ + 'destination_account_id': invoice.line_ids.account_id.filtered(lambda account: account.internal_type == 'receivable').id, + 'payment_method_id': self.env['account.payment.method'].search([], limit=1).id, + 'payment_type': 'inbound', + 'partner_type': 'customer', + 'partner_id': invoice.partner_id.id, + 'amount': 500, + 'company_id': self.env.company.id, + 'currency_id': self.env.company.currency_id.id, + }) + payment.action_post() + inv1_receivable = invoice.line_ids.filtered(lambda l: l.account_id.internal_type == 'receivable') + pay_receivable = payment.move_id.line_ids.filtered(lambda l: l.account_id.internal_type == 'receivable') + + (inv1_receivable + pay_receivable).reconcile() + + # the invoice is paid -> customer goes to paid status self.assertEqual( self.partner_1.membership_state, 'old', - 'membership: outdated subscription should put member in old state') + 'membership: after paying the invoice, customer should be in old status') + + # check second partner then associate them + self.assertEqual( + self.partner_2.membership_state, 'free', + 'membership: free member customer should be in free state') + self.partner_2.write({'free_member': False, 'associate_member': self.partner_1.id}) + self.assertEqual( + self.partner_2.membership_state, 'old', + 'membership: associated customer should be in old state') def test_paid_membership(self): self.assertEqual(