diff --git a/odex25_sales/dev_membership/i18n/ar_001.po b/odex25_sales/dev_membership/i18n/ar_001.po
index 4b97bdfb5..dc597e7cc 100644
--- a/odex25_sales/dev_membership/i18n/ar_001.po
+++ b/odex25_sales/dev_membership/i18n/ar_001.po
@@ -1280,6 +1280,12 @@ msgstr ""
msgid "Responsible User"
msgstr "المسؤول"
+#. module: dev_membership
+#: model:ir.model.fields,field_description:dev_membership.field_product_product__user_id
+#: model:ir.model.fields,field_description:dev_membership.field_product_template__user_id
+msgid "Responsible"
+msgstr "المسؤول"
+
#. module: dev_membership
#: model:ir.model.fields,field_description:dev_membership.field_dev_membership__user_id
msgid "Resposible"
diff --git a/odex25_sales/dev_membership/models/__init__.py b/odex25_sales/dev_membership/models/__init__.py
index 3eb914a6a..092dcefd4 100644
--- a/odex25_sales/dev_membership/models/__init__.py
+++ b/odex25_sales/dev_membership/models/__init__.py
@@ -15,4 +15,5 @@ from . import res_config_settings
from . import membershib_level
from . import membership_cancel_request
from . import board_membership_nomination
+from . import account_move
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/odex25_sales/dev_membership/models/account_move.py b/odex25_sales/dev_membership/models/account_move.py
new file mode 100644
index 000000000..7d1a91444
--- /dev/null
+++ b/odex25_sales/dev_membership/models/account_move.py
@@ -0,0 +1,102 @@
+from odoo import models, fields,api,_
+from odoo.exceptions import UserError
+from datetime import timedelta
+from dateutil.relativedelta import relativedelta
+
+class AccountMove(models.Model):
+ _inherit = 'account.move'
+
+ @api.depends(
+ 'line_ids.matched_debit_ids.debit_move_id.move_id.payment_id.is_matched',
+ 'line_ids.matched_debit_ids.debit_move_id.move_id.line_ids.amount_residual',
+ 'line_ids.matched_debit_ids.debit_move_id.move_id.line_ids.amount_residual_currency',
+ 'line_ids.matched_credit_ids.credit_move_id.move_id.payment_id.is_matched',
+ 'line_ids.matched_credit_ids.credit_move_id.move_id.line_ids.amount_residual',
+ 'line_ids.matched_credit_ids.credit_move_id.move_id.line_ids.amount_residual_currency',
+ 'line_ids.debit',
+ 'line_ids.credit',
+ 'line_ids.currency_id',
+ 'line_ids.amount_currency',
+ 'line_ids.amount_residual',
+ 'line_ids.amount_residual_currency',
+ 'line_ids.payment_id.state',
+ 'line_ids.full_reconcile_id')
+ def _compute_amount(self):
+ super(AccountMove, self)._compute_amount()
+
+ for move in self:
+ if move.move_type != 'out_invoice' or move.payment_state not in ['paid','in_payment']:
+ continue
+
+ membership_lines = move.invoice_line_ids.filtered(lambda l: l.product_id.is_membership)
+ if not membership_lines:
+ continue
+
+ existing_membership = self.env['dev.membership'].search([
+ ('invoice_id', '=', move.id),
+ ('partner_id', '=', move.partner_id.id),
+ ('state', 'in', ['confirm','active'])
+ ])
+
+ if existing_membership:
+ for membership in existing_membership:
+ membership.action_active_membership()
+ continue
+
+ for line in membership_lines:
+ product = line.product_id
+
+ last_active_membership = self.env['dev.membership'].search([
+ ('partner_id', '=', move.partner_id.id),
+ ('state', 'in', ['draft', 'active', 'confirm'])
+ ], order='to_date desc', limit=1)
+
+ from_date = (last_active_membership.to_date + timedelta(days=1)) if last_active_membership else (
+ move.invoice_date or fields.Date.today())
+ to_date = self._calculate_to_date(from_date, product.interval, int(line.quantity))
+
+ membership_vals = {
+ 'partner_id': move.partner_id.id,
+ 'product_id': product.id,
+ 'membership_fees': line.price_subtotal,
+ 'from_date': from_date,
+ 'to_date': to_date,
+ 'date': from_date,
+ 'duration': int(line.quantity),
+ 'interval': product.interval,
+ 'company_id': move.company_id.id,
+ 'user_id': product.product_tmpl_id.user_id.id,
+ 'invoice_id': move.id,
+ 'state': 'confirm',
+ }
+ membership = self.env['dev.membership'].create(membership_vals)
+ membership.action_active_membership()
+ move.partner_id.is_member = True
+
+ def _calculate_to_date(self, from_date, interval, duration):
+ if interval == 'year':
+ return from_date + relativedelta(years=duration) - timedelta(days=1)
+ elif interval == 'month':
+ return from_date + relativedelta(months=duration) - timedelta(days=1)
+ elif interval == 'days':
+ return from_date + timedelta(days=duration)
+ return from_date
+
+ def button_draft(self):
+ res = super(AccountMove, self).button_draft()
+ self._reset_membership_state()
+ return res
+
+ def button_cancel(self):
+ res = super(AccountMove, self).button_cancel()
+ self._reset_membership_state()
+ return res
+
+ def _reset_membership_state(self):
+ for move in self:
+ memberships = self.env['dev.membership'].search([
+ ('invoice_id', '=', move.id),
+ ('state', '=', 'active')
+ ])
+ for membership in memberships:
+ membership.write({'state': 'confirm'})
diff --git a/odex25_sales/dev_membership/models/dev_membership.py b/odex25_sales/dev_membership/models/dev_membership.py
index cbebad720..681cafbc7 100644
--- a/odex25_sales/dev_membership/models/dev_membership.py
+++ b/odex25_sales/dev_membership/models/dev_membership.py
@@ -180,8 +180,9 @@ class DevMembership(models.Model):
self.partner_id.check_active_membership()
def action_cancel_membership(self):
- self.state = 'cancel'
- self.partner_id.check_active_membership()
+ for rec in self:
+ rec.state = 'cancel'
+ rec.partner_id.check_active_membership()
@api.model
diff --git a/odex25_sales/dev_membership/models/product_template.py b/odex25_sales/dev_membership/models/product_template.py
index 0630d46f9..d4c23e54c 100644
--- a/odex25_sales/dev_membership/models/product_template.py
+++ b/odex25_sales/dev_membership/models/product_template.py
@@ -26,6 +26,7 @@ class ProductTemplate(models.Model):
string="Membership Benefits",
required=False)
is_membership = fields.Boolean(string="Is Membership")
+ user_id = fields.Many2one('res.users', 'Responsible')
duration = fields.Integer(string="Duration")
interval = fields.Selection(string="Interval", selection=([('days', 'Days'),
('month', 'Month'),
diff --git a/odex25_sales/dev_membership/views/product_template.xml b/odex25_sales/dev_membership/views/product_template.xml
index f5c98e931..2602c270a 100644
--- a/odex25_sales/dev_membership/views/product_template.xml
+++ b/odex25_sales/dev_membership/views/product_template.xml
@@ -56,6 +56,7 @@
+