[FIX]Solve issues and bugs with refund tamded

This commit is contained in:
Ali Ammar 2025-12-22 10:22:42 +03:00
parent dd54c2c859
commit 4d1c9f4dd1
9 changed files with 187 additions and 36 deletions

View File

@ -19,7 +19,7 @@ class AccountMove(models.Model):
def action_view_esterdad_id(self): def action_view_esterdad_id(self):
self.ensure_one() # Ensure the method is called on a single record self.ensure_one() # Ensure the method is called on a single record
action = self.env.ref('odex_takaful.view_esterdad_wizard_tree').read()[0] action = self.env.ref('odex_takaful.view_esterdad_wizard_tree').read()[0]
action['domain'] = [('id', '=', self.cancel_record_id.id)] action['domain'] = [('id', '=', self.esterdad_id.id)]
action['context'] = { action['context'] = {
'create': False 'create': False
} }

View File

@ -21,6 +21,7 @@ class DonationsDetailsLines(models.Model):
journal_id = self.env.company.sponsorship_direct_debit_journal_id.id journal_id = self.env.company.sponsorship_direct_debit_journal_id.id
return journal_id if journal_id else False return journal_id if journal_id else False
name = fields.Text(string="Note") name = fields.Text(string="Note")
display_type = fields.Selection([ display_type = fields.Selection([
('line_section', "Section"), ('line_section', "Section"),
@ -55,7 +56,7 @@ class DonationsDetailsLines(models.Model):
family_domain_ids = fields.Many2many('grant.benefit', compute='_compute_family_domain_ids') family_domain_ids = fields.Many2many('grant.benefit', compute='_compute_family_domain_ids')
benefit_id = fields.Many2one('family.member', string='Beneficiary Name', ondelete='restrict', domain="[('id', 'in', members_domain_ids)]", tracking=True) benefit_id = fields.Many2one('family.member', string='Beneficiary Name', ondelete='restrict', domain="[('id', 'in', members_domain_ids)]", tracking=True)
family_id = fields.Many2one('grant.benefit', string='Family', ondelete='restrict', domain="[('id', 'in', family_domain_ids)]", tracking=True) family_id = fields.Many2one('grant.benefit', string='Family', ondelete='restrict', domain="[('id', 'in', family_domain_ids)]", tracking=True)
benefit_ids = fields.Many2many('family.member', string='Beneficiaries Names', tracking=True, domain="[('id', 'in', members_domain_ids) , ('age' , '<' , ages)]") benefit_ids = fields.Many2many('family.member', string='Beneficiaries Names', tracking=True, domain="[('id', 'in', members_domain_ids) ]")
sponsorship_duration = fields.Selection([('temporary', 'Temporary'), ('permanent', 'Permanent')], sponsorship_duration = fields.Selection([('temporary', 'Temporary'), ('permanent', 'Permanent')],
string='Sponsorship Type', default="temporary") string='Sponsorship Type', default="temporary")
start_date = fields.Date(string="Sponsorship Start Date", copy=False, default=fields.Date.today()) start_date = fields.Date(string="Sponsorship Start Date", copy=False, default=fields.Date.today())
@ -79,7 +80,7 @@ class DonationsDetailsLines(models.Model):
sponsor_phone = fields.Char(related='sponsor_id.mobile') sponsor_phone = fields.Char(related='sponsor_id.mobile')
branch_custom_id = fields.Many2one('branch.settings', compute='_compute_branch_custom_id') branch_custom_id = fields.Many2one('branch.settings', compute='_compute_branch_custom_id')
record_type = fields.Selection([('sponsorship', 'Sponsorship'),('donation', 'Donation')], compute='_compute_record_type', store=True, readonly=True) record_type = fields.Selection([('sponsorship', 'Sponsorship'),('donation', 'Donation')], compute='_compute_record_type', store=True, readonly=True)
state = fields.Selection([('draft', 'Draft'),('confirmed', 'Confirmed'),('waiting', 'Waiting'), ('active', 'Active'),('closed', 'Closed'),('extended', 'Extended'),('replace', 'To Replace'), ('paid', 'Paid')], string='State', default='draft') state = fields.Selection([('draft', 'Draft'),('confirmed', 'Confirmed'),('waiting', 'Waiting'), ('active', 'Active'),('closed', 'Closed'),('extended', 'Extended'),('replace', 'To Replace'), ('paid', 'Paid'),('cancel', 'Canceled')], string='State', default='draft')
sponsorship_scheduling_line_ids = fields.One2many('sponsorship.scheduling.line', 'donation_detail_linked_id') sponsorship_scheduling_line_ids = fields.One2many('sponsorship.scheduling.line', 'donation_detail_linked_id')
extension_history_ids = fields.One2many('donation.extension.history', 'donation_detail_id', extension_history_ids = fields.One2many('donation.extension.history', 'donation_detail_id',
string='Extension History') string='Extension History')
@ -147,18 +148,20 @@ class DonationsDetailsLines(models.Model):
store=False store=False
) )
@api.depends() @api.depends('sponsorship_mechanism_id.create_uid')
def _compute_can_edit_benefit(self): def _compute_can_edit_benefit(self):
for rec in self: for rec in self:
user = self.env.user user = self.env.user
print('User , >>>> ' , user )
is_manager = ( is_manager = (
user.has_group('odex_takaful.sponsorship_system_manager_group') or user.has_group('odex_takaful.sponsorship_system_manager_group') or
user.has_group('odex_takaful.branch_manager_group')) user.has_group('odex_takaful.branch_manager_group'))
rec.can_edit_benefit = (rec.create_uid == user and not is_manager) print('is_manager >>>>> ' , is_manager)
print('rec.create_uid >>>>> ' , rec.create_uid)
rec.can_edit_benefit = (rec.create_uid == user and is_manager)
@api.depends('sponsorship_duration', 'payment_month_count', 'direct_debit') @api.depends('sponsorship_duration', 'payment_month_count', 'direct_debit')
def _compute_age_category(self): def _compute_age_category(self):
for rec in self: for rec in self:
print( rec.sponsorship_duration , ' ' ,rec.direct_debit , ' ' , rec.payment_month_count)
if rec.sponsorship_duration == 'permanent': if rec.sponsorship_duration == 'permanent':
rec.age_category = 'all' rec.age_category = 'all'
elif rec.sponsorship_duration != 'permanent' : elif rec.sponsorship_duration != 'permanent' :
@ -714,9 +717,10 @@ class DonationsDetailsLines(models.Model):
domain = [ domain = [
'|', '|',
('state', '=', 'second_approve'), ('state', '=', 'second_approve'),
'&', '&','&',
('state', 'in', ('waiting_approve', 'first_approve')), ('state', 'in', ('waiting_approve', 'first_approve')),
('action_type', '=', 'suspended')] ('action_type', '=', 'suspended'),
('age', '<', rec.ages)]
domain = expression.AND([domain, [ domain = expression.AND([domain, [
('member_status', '=', 'benefit'), ('member_status', '=', 'benefit'),
@ -826,6 +830,7 @@ class DonationsDetailsLines(models.Model):
if record_type == 'donation': if record_type == 'donation':
domain.append(('donation_category', '=', 'donation')) domain.append(('donation_category', '=', 'donation'))
domain.append(('donation_category', '=', 'endowment'))
elif record_type == 'sponsorship': elif record_type == 'sponsorship':
domain.append(('donation_category', '=', 'sponsorship')) domain.append(('donation_category', '=', 'sponsorship'))
@ -836,6 +841,7 @@ class DonationsDetailsLines(models.Model):
'product_template_id': domain} 'product_template_id': domain}
} }
@api.onchange('donation_type') @api.onchange('donation_type')
def onchange_donation_type(self): def onchange_donation_type(self):
for rec in self: for rec in self:

View File

@ -104,7 +104,8 @@ class DonationExtensionHistory(models.Model):
string='New Direct Debit', string='New Direct Debit',
readonly=True readonly=True
) )
state = fields.Selection([ ('active', 'Active'),('cancel', 'Canceled')], string='State', default='active')
canceled = fields.Boolean()
@api.depends('donation_detail_id', 'extension_date') @api.depends('donation_detail_id', 'extension_date')
def _compute_extension_ref(self): def _compute_extension_ref(self):
for rec in self: for rec in self:

View File

@ -309,6 +309,18 @@ class ResPartner(models.Model):
if self.kafel_id: if self.kafel_id:
self.kafel_id.login = vals['mobile'] self.kafel_id.login = vals['mobile']
if 'mobile' in vals and self.mobile != False:
kafeel = self.env['res.users'].with_user(2).create({
'name' : vals['name'],
'branch_custom_id':vals['branch_custom_id'],
'sel_groups_1_9_10' : 9,
'partner_id' : self.id,
'login' : vals['mobile'],
'otp_mobile_phone' : vals['mobile'],
'otp_enabled' : True,
})
self.kafel_id = kafeel
res = super(ResPartner, self).write(vals) res = super(ResPartner, self).write(vals)
return res return res

View File

@ -130,7 +130,12 @@ class TakafulSponsorship(models.Model):
pay_date = fields.Datetime() pay_date = fields.Datetime()
cancel_record_id = fields.Many2one('esterdad.wizard', string="Cancel Record") cancel_record_id = fields.Many2one('esterdad.wizard', string="Cancel Record")
record_url = fields.Char(string="Record URL", readonly=True) record_url = fields.Char(string="Record URL", readonly=True)
is_canceled_refund = fields.Boolean()
@api.depends('is_canceled_refund')
def cancel_refund_tamded(self):
for rec in self:
print('Hi')
def action_quotation_send(self): def action_quotation_send(self):
self.ensure_one() self.ensure_one()

View File

@ -27,7 +27,12 @@
<field name="model">donation.extension.history</field> <field name="model">donation.extension.history</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form create="0" edit="0" delete="0"> <form create="0" edit="0" delete="0">
<header>
<field name="state" widget="statusbar"
statusbar_visible="active,cancel" />
</header>
<sheet> <sheet>
<widget name="web_ribbon" title="Canceld" bg_color="bg-danger" attrs="{'invisible': [('state', '!=', 'cancel')]}"/>
<group> <group>
<group> <group>
<field name="extension_ref"/> <field name="extension_ref"/>

View File

@ -94,7 +94,8 @@
<!-- string="Replacement Processes" class="oe_stat_button" icon="fa-users">--> <!-- string="Replacement Processes" class="oe_stat_button" icon="fa-users">-->
<!-- </button>--> <!-- </button>-->
</div> </div>
<widget name="web_ribbon" title="Canceld" bg_color="bg-danger" attrs="{'invisible': [('state', '!=', 'canceled')]}"/> <widget name="web_ribbon" title="Canceld" bg_color="bg-danger"
attrs="{'invisible': [('state', '!=', 'canceled')]}"/>
<!-- Code badge hidden for now --> <!-- Code badge hidden for now -->
<!-- <div style="position: absolute; top: 70px; right: 15px; z-index: 100;" attrs="{'invisible': [('code', '=', False)]}"> <!-- <div style="position: absolute; top: 70px; right: 15px; z-index: 100;" attrs="{'invisible': [('code', '=', False)]}">
<span class="badge badge-info" style="font-size: 14px; padding: 6px 12px;"> <span class="badge badge-info" style="font-size: 14px; padding: 6px 12px;">
@ -525,7 +526,9 @@
</header> </header>
<group> <group>
<group> <group>
<field name="ages" invisible="1"/> <field name="ages" invisible="0"/>
<field name="members_domain_ids" invisible="0"/>
<field name="waiting_date" invisible="1" widget="date"/> <field name="waiting_date" invisible="1" widget="date"/>
<field name="family_id" <field name="family_id"
attrs="{'invisible': [('sponsorship_type','=','group'), ('parent.record_type','=','sponsorship')], attrs="{'invisible': [('sponsorship_type','=','group'), ('parent.record_type','=','sponsorship')],

View File

@ -3,7 +3,7 @@ from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError, Warning from odoo.exceptions import UserError, ValidationError, Warning
import logging import logging
from odoo import SUPERUSER_ID from odoo import SUPERUSER_ID
from datetime import datetime, date from datetime import datetime, date, timedelta
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -27,8 +27,73 @@ class EsterdadWizard(models.Model):
sponsor_name = fields.Char() sponsor_name = fields.Char()
mobile = fields.Char() mobile = fields.Char()
id_num = fields.Char() id_num = fields.Char()
payment_ids = fields.Many2many('account.payment') payment_ids = fields.Many2many(
'account.payment',
'esterdad_wizard_payment_rel',
'wizard_id',
'payment_id',
string="Payments",
domain="[('id', 'in', allowed_payment_ids)]",
)
allowed_payment_ids = fields.Many2many(
'account.payment',
'esterdad_wizard_allowed_payment_rel',
'wizard_id',
'payment_id',
string="Allowed Payments",
)
confirmed = fields.Boolean() confirmed = fields.Boolean()
@api.onchange('sponsor_id')
def _onchange_sponsor_id_set_payment_domain(self):
"""Limit available payments to same partner within restriction_period days."""
for rec in self:
domain = []
partner = False
invoice_names = []
if rec.sponsor_id:
# Assuming sponsor_id.sponsor_id is the related partner on the sponsorship
partner = getattr(rec.sponsor_id, 'sponsor_id', False) or getattr(rec.sponsor_id, 'partner_id', False)
# Get all invoices from journal_entry_ids where move_type is 'out_invoice'
invoices = rec.sponsor_id.journal_entry_ids.filtered(lambda inv: inv.move_type == 'out_invoice')
# Get all invoice names (numbers) in a list
invoice_names = invoices.mapped('name')
if partner:
# Get restriction period (in days) from config parameters
sudo_conf = self.env['ir.config_parameter'].sudo()
restriction_period = sudo_conf.get_param('odex_takaful.restriction_period')
try:
restriction_period = int(restriction_period or 0)
except (TypeError, ValueError):
restriction_period = 0
if restriction_period and restriction_period > 0:
limit_date = date.today() - timedelta(days=restriction_period)
domain = [
('partner_id', '=', partner.id),
('date', '>=', limit_date),
]
else:
# If no restriction configured, just filter by partner
domain = [('partner_id', '=', partner.id)]
# Add filter for ref field to match invoice names if we have any
if invoice_names:
domain.append(('ref', 'in', invoice_names))
# If we have a domain, fetch the matching payments and store them
# in the helper field, then use their IDs as the domain.
if domain:
payments = self.env['account.payment'].search(domain)
rec.allowed_payment_ids = payments
return {'domain': {'payment_ids': [('id', 'in', payments.ids)]}}
else:
rec.allowed_payment_ids = False
return {'domain': {'payment_ids': []}}
def action_confirm_refund(self): def action_confirm_refund(self):
for rec in self: for rec in self:
user = rec.sponsor_id.sponsor_id.kafel_id user = rec.sponsor_id.sponsor_id.kafel_id
@ -41,6 +106,7 @@ class EsterdadWizard(models.Model):
rec.sponsor_id.write({ rec.sponsor_id.write({
'cancel_record_id': rec.id 'cancel_record_id': rec.id
}) })
context['default_payment_ids'] = [(6, 0, rec.payment_ids.ids)]
view = self.env.ref('odex_takaful.view_otp_wizard_form') view = self.env.ref('odex_takaful.view_otp_wizard_form')
return { return {
'name': _('OTP Confirmation'), 'name': _('OTP Confirmation'),
@ -73,6 +139,10 @@ class OTPWizard(models.TransientModel):
otp_code = fields.Integer() otp_code = fields.Integer()
esterdad_id = fields.Many2one('esterdad.wizard') esterdad_id = fields.Many2one('esterdad.wizard')
user_id = fields.Many2one('res.users') user_id = fields.Many2one('res.users')
payment_ids = fields.Many2many(
'account.payment',
string="Payments"
)
def action_confirm_otp(self): def action_confirm_otp(self):
for rec in self: for rec in self:
@ -80,24 +150,71 @@ class OTPWizard(models.TransientModel):
sponsor_ship = rec.esterdad_id.sponsor_id sponsor_ship = rec.esterdad_id.sponsor_id
rec.esterdad_id.cancel_date = date.today() rec.esterdad_id.cancel_date = date.today()
if sponsor_ship: if sponsor_ship:
# Get ref values from selected payments
payment_refs = rec.payment_ids.mapped('ref')
# Filter out empty/False refs
payment_refs = [ref for ref in payment_refs if ref]
if not payment_refs:
raise UserError("لا توجد مراجع في الدفعات المحددة")
# Search for invoices in account.move matching payment refs
invoices = self.env['account.move'].search([
('name', 'in', payment_refs),
])
if not invoices:
raise UserError("لا توجد فواتير مطابقة للمراجع المحددة")
for invoice in invoices:
credit = self.env['account.move.reversal'].with_company(self.env.user.company_id.id).create({ credit = self.env['account.move.reversal'].with_company(self.env.user.company_id.id).create({
'refund_method': 'refund', 'refund_method': 'refund',
'date': date.today(), 'date': date.today(),
'date_mode': 'custom', 'date_mode': 'custom',
'move_ids': sponsor_ship.journal_entry_ids.ids, 'move_ids': [invoice.id],
}) })
x = credit.reverse_moves() x = credit.reverse_moves()
sponsor_ship.state = 'canceled' sponsor_ship.state = 'canceled'
domain_ids = x.get('res_id')
domain_ids = x.get('domain')[0][2] if domain_ids:
last_id = domain_ids[-1] last_id = domain_ids
sponsor_ship.write({ sponsor_ship.write({
'journal_entry_ids': [(4, last_id)] 'journal_entry_ids': [(4, last_id)]
}) })
credit_note = self.env['account.move'].search([('id' , '=' , last_id)]) credit_note = self.env['account.move'].search([('id', '=', last_id)])
credit_note.action_post() credit_note.action_post()
credit_note.esterdad_id = rec.esterdad_id
rec.esterdad_id.confirmed = True rec.esterdad_id.confirmed = True
rec.esterdad_id.sponsor_id.is_canceled_refund = True
# Get all donation lines from donations_details_lines and donations_details_lines_mechanism_ids
all_donation_lines = sponsor_ship.donations_details_lines | sponsor_ship.donations_details_lines_mechanism_ids
# Set state to 'cancel' for all donation lines
if all_donation_lines:
all_donation_lines.write({'state': 'cancel'})
# Process extension history for each donation line
for donation_line in all_donation_lines:
# Get extension_history_ids for this donation line
extension_histories = donation_line.extension_history_ids
if extension_histories:
# Set state to 'cancel' for all extension histories
extension_histories.write({'state': 'cancel'})
total_extension_months = 0
current_payment_month_count = 0
new_payment_month_count = 0
# Sum all extension_months
total_extension_months = sum(extension_histories.mapped('extension_months'))
# Subtract the sum from payment_month_count
if total_extension_months > 0:
current_payment_month_count = donation_line.payment_month_count or 0
new_payment_month_count = current_payment_month_count - total_extension_months
# Ensure it doesn't go below 0
donation_line.write({
'payment_month_count': max(0, new_payment_month_count)
})
else: else:
raise UserError("الرقم المدخل خاطئ") raise UserError("الرقم المدخل خاطئ")

View File

@ -32,6 +32,8 @@
<field name="another_reason"/> <field name="another_reason"/>
<field name="reason" attrs="{'invisible': [('another_reason', '=', False)], <field name="reason" attrs="{'invisible': [('another_reason', '=', False)],
'required': [('another_reason', '=', True)]}"/> 'required': [('another_reason', '=', True)]}"/>
<field name="sponsor_id" />
<field name="allowed_payment_ids" widget="many2many_tags" />
</group> </group>
<notebook> <notebook>
<page string="بيانات المتبرع"> <page string="بيانات المتبرع">