partner.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. from datetime import date
  4. from odoo import api, fields, models, _
  5. from odoo.exceptions import UserError, ValidationError
  6. from . import membership
  7. class Partner(models.Model):
  8. _inherit = 'res.partner'
  9. associate_member = fields.Many2one('res.partner', string='Associate Member',
  10. help="A member with whom you want to associate your membership."
  11. "It will consider the membership state of the associated member.")
  12. member_lines = fields.One2many('membership.membership_line', 'partner', string='Membership')
  13. free_member = fields.Boolean(string='Free Member',
  14. help="Select if you want to give free membership.")
  15. membership_amount = fields.Float(string='Membership Amount', digits=(16, 2),
  16. help='The price negotiated by the partner')
  17. membership_state = fields.Selection(membership.STATE, compute='_compute_membership_state',
  18. string='Current Membership Status', store=True, recursive=True,
  19. help='It indicates the membership state.\n'
  20. '-Non Member: A partner who has not applied for any membership.\n'
  21. '-Cancelled Member: A member who has cancelled his membership.\n'
  22. '-Old Member: A member whose membership date has expired.\n'
  23. '-Waiting Member: A member who has applied for the membership and whose invoice is going to be created.\n'
  24. '-Invoiced Member: A member whose invoice has been created.\n'
  25. '-Paying member: A member who has paid the membership fee.')
  26. membership_start = fields.Date(compute='_compute_membership_state',
  27. string ='Membership Start Date', store=True,
  28. help="Date from which membership becomes active.")
  29. membership_stop = fields.Date(compute='_compute_membership_state',
  30. string ='Membership End Date', store=True,
  31. help="Date until which membership remains active.")
  32. membership_cancel = fields.Date(compute='_compute_membership_state',
  33. string ='Cancel Membership Date', store=True,
  34. help="Date on which membership has been cancelled")
  35. @api.depends('member_lines.account_invoice_line',
  36. 'member_lines.account_invoice_line.move_id.state',
  37. 'member_lines.account_invoice_line.move_id.payment_state',
  38. 'member_lines.account_invoice_line.move_id.partner_id',
  39. 'free_member',
  40. 'member_lines.date_to', 'member_lines.date_from',
  41. 'associate_member', 'associate_member.membership_state')
  42. def _compute_membership_state(self):
  43. today = fields.Date.today()
  44. for partner in self:
  45. partner.membership_start = self.env['membership.membership_line'].search([
  46. ('partner', '=', partner.associate_member.id or partner.id), ('date_cancel', '=', False)
  47. ], limit=1, order='date_from').date_from
  48. partner.membership_stop = self.env['membership.membership_line'].search([
  49. ('partner', '=', partner.associate_member.id or partner.id), ('date_cancel', '=', False)
  50. ], limit=1, order='date_to desc').date_to
  51. partner.membership_cancel = self.env['membership.membership_line'].search([
  52. ('partner', '=', partner.id)
  53. ], limit=1, order='date_cancel').date_cancel
  54. if partner.associate_member:
  55. partner.membership_state = partner.associate_member.membership_state
  56. continue
  57. if partner.free_member and partner.membership_state != 'paid':
  58. partner.membership_state = 'free'
  59. continue
  60. for mline in partner.member_lines:
  61. if (mline.date_to or date.min) >= today and (mline.date_from or date.min) <= today:
  62. partner.membership_state = mline.state
  63. break
  64. elif ((mline.date_from or date.min) < today and (mline.date_to or date.min) <= today and \
  65. (mline.date_from or date.min) < (mline.date_to or date.min)):
  66. if mline.account_invoice_id and mline.account_invoice_id.payment_state in ('in_payment', 'paid'):
  67. partner.membership_state = 'old'
  68. elif mline.account_invoice_id and mline.account_invoice_id.state == 'cancel':
  69. partner.membership_state = 'canceled'
  70. break
  71. else:
  72. partner.membership_state = 'none'
  73. @api.constrains('associate_member')
  74. def _check_recursion_associate_member(self):
  75. for partner in self:
  76. level = 100
  77. while partner:
  78. partner = partner.associate_member
  79. if not level:
  80. raise ValidationError(_('You cannot create recursive associated members.'))
  81. level -= 1
  82. @api.model
  83. def _cron_update_membership(self):
  84. partners = self.search([('membership_state', 'in', ['invoiced', 'paid'])])
  85. # mark the field to be recomputed, and recompute it
  86. self.env.add_to_compute(self._fields['membership_state'], partners)
  87. def create_membership_invoice(self, product, amount):
  88. """ Create Customer Invoice of Membership for partners.
  89. """
  90. invoice_vals_list = []
  91. for partner in self:
  92. addr = partner.address_get(['invoice'])
  93. if partner.free_member:
  94. raise UserError(_("Partner is a free Member."))
  95. if not addr.get('invoice', False):
  96. raise UserError(_("Partner doesn't have an address to make the invoice."))
  97. invoice_vals_list.append({
  98. 'move_type': 'out_invoice',
  99. 'partner_id': partner.id,
  100. 'invoice_line_ids': [
  101. (0, None, {'product_id': product.id, 'quantity': 1, 'price_unit': amount, 'tax_ids': [(6, 0, product.taxes_id.ids)]})
  102. ]
  103. })
  104. return self.env['account.move'].create(invoice_vals_list)