[I18N] odex_takaful: automatic update

Auto-generated commit based on local changes.
This commit is contained in:
maltayyar2 2026-01-06 02:29:10 +03:00
parent e64a78d370
commit c81cfa3b53
10 changed files with 248 additions and 10 deletions

View File

@ -80,6 +80,7 @@
'views/preferred_communication.xml',
'views/takaful_payment_method.xml',
'views/product_views.xml',
'views/payment_machine_views.xml',
'views/takaful_menus_actions.xml',
'data/message_template_data.xml',
'data/server_actions.xml',

View File

@ -4642,7 +4642,7 @@ msgstr "فواتير المدفوعات"
#: model_terms:ir.ui.view,arch_db:odex_takaful.view_account_payment_register_form
#, python-format
msgid "Payment Method"
msgstr "طريقة الدفع"
msgstr "طريقة السداد"
#. module: odex_takaful
#: model:ir.model.fields,field_description:odex_takaful.field_donations_details_lines__payment_month_count

View File

@ -28,3 +28,4 @@ from . import donation_extension_history
from . import family_member
from . import sponsorship_scheduling_line
from . import donation_replacement_log
from . import payment_machine

View File

@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
class PaymentMachine(models.Model):
"""Payment Machine Model for POS Terminals like Gidea, Neoleap, etc."""
_name = 'payment.machine'
_description = 'Payment Machine'
_order = 'name'
_rec_name = 'name'
name = fields.Char(
string='Machine Name',
required=True,
help='Name or identifier of the payment machine'
)
code = fields.Char(
string='Machine Code',
help='Serial number or code of the payment machine'
)
machine_type = fields.Selection([
('neoleap', 'Neoleap'),
('gidea', 'Gidea'),
('other', 'Other'),
], string='Machine Type', required=True, default='neoleap')
machine_type_other = fields.Char(
string='Other Machine Type',
help='Specify the machine type if not listed above'
)
branch_custom_id = fields.Many2one(
'branch.settings',
string='Branch',
required=True,
help='Branch where this payment machine is located'
)
journal_id = fields.Many2one(
'account.journal',
string='Journal',
required=True,
domain="[('type', '=', 'bank')]",
help='Bank journal associated with this payment machine'
)
active = fields.Boolean(
string='Active',
default=True,
help='If unchecked, the machine will be archived and hidden'
)
notes = fields.Text(
string='Notes',
help='Additional notes or information about the machine'
)
_sql_constraints = [
('code_unique', 'UNIQUE(code)', 'Machine code must be unique!'),
]
@api.depends('name', 'code')
def name_get(self):
"""Display name with code if available"""
result = []
for record in self:
if record.code:
name = f"{record.name} [{record.code}]"
else:
name = record.name
result.append((record.id, name))
return result

View File

@ -211,10 +211,15 @@ class ResPartner(models.Model):
if not args:
args = []
# If no name is provided, use standard Odoo search behavior
# This fixes the issue where empty name causes invalid domain
if not name:
return super()._name_search(name, args=args, operator=operator, limit=limit, name_get_uid=name_get_uid)
# Build search domains for the raw name and (optionally) the name
# without leading zero, to "ignore" a starting 0 in the search term.
search_terms = [name] if name else []
if name and name.startswith('0'):
search_terms = [name]
if name.startswith('0'):
search_terms.append(name[1:])
domain = []
@ -562,9 +567,10 @@ class ResPartner(models.Model):
def name_get(self):
result = []
for sponsor in self:
name = sponsor.name
# Ensure name is always a string, never False or None
name = sponsor.name or ''
if sponsor.mobile:
name = sponsor.name + " - " + str(sponsor.mobile)
name = (sponsor.name or '') + " - " + str(sponsor.mobile)
result.append((sponsor.id, name))
return result

View File

@ -1892,6 +1892,7 @@ class TakafulSponsorship(models.Model):
'sponsorship_payment_skip_compute_amount': True,
'default_sponsorship_payment': True,
'force_sponsorship_line_partner_id': self.sponsor_id.id,
'default_takaful_sponsorship_id': self.id,
},
'target': 'new',
'type': 'ir.actions.act_window',

View File

@ -59,3 +59,5 @@ access_replace_benefit_wizard,replace.benefit.wizard.access,model_replace_benefi
access_group_esterdad_wizard,access_group_esterdad_wizard,model_esterdad_wizard,,1,1,1,0
access_group_otp_confirmation_wizard,access_group_otp_confirmation_wizard,model_otp_confirmation_wizard,,1,1,1,0
access_payment_machine,access_payment_machine,model_payment_machine,odex_takaful.group_kufula_user,1,1,1,1
access_payment_machine_manager,access_payment_machine_manager,model_payment_machine,odex_takaful.sponsorship_system_manager_group,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
59
60
61
62
63

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Payment Machine Tree View -->
<record id="payment_machine_view_tree" model="ir.ui.view">
<field name="name">payment.machine.view.tree</field>
<field name="model">payment.machine</field>
<field name="arch" type="xml">
<tree string="Payment Machines">
<field name="name"/>
<field name="code"/>
<field name="machine_type"/>
<field name="branch_custom_id"/>
<field name="journal_id"/>
<field name="active" widget="boolean_toggle"/>
</tree>
</field>
</record>
<!-- Payment Machine Form View -->
<record id="payment_machine_view_form" model="ir.ui.view">
<field name="name">payment.machine.view.form</field>
<field name="model">payment.machine</field>
<field name="arch" type="xml">
<form string="Payment Machine">
<sheet>
<div class="oe_button_box" name="button_box">
</div>
<div class="oe_title">
<label for="name"/>
<h1>
<field name="name" placeholder="Machine Name"/>
</h1>
</div>
<group>
<group name="main_info" string="Machine Information">
<field name="code"/>
<field name="machine_type"/>
<field name="machine_type_other"
attrs="{'invisible': [('machine_type', '!=', 'other')],
'required': [('machine_type', '=', 'other')]}"/>
</group>
<group name="branch_info" string="Branch &amp; Journal">
<field name="branch_custom_id" options="{'no_create': True}"/>
<field name="journal_id" options="{'no_create': True}"/>
<field name="active" widget="boolean_toggle"/>
</group>
</group>
<group name="notes_group" string="Notes">
<field name="notes" nolabel="1" placeholder="Additional notes..."/>
</group>
</sheet>
</form>
</field>
</record>
<!-- Payment Machine Search View -->
<record id="payment_machine_view_search" model="ir.ui.view">
<field name="name">payment.machine.view.search</field>
<field name="model">payment.machine</field>
<field name="arch" type="xml">
<search string="Search Payment Machines">
<field name="name"/>
<field name="code"/>
<field name="branch_custom_id"/>
<separator/>
<filter string="Neoleap" name="filter_neoleap"
domain="[('machine_type', '=', 'neoleap')]"/>
<filter string="Gidea" name="filter_gidea"
domain="[('machine_type', '=', 'gidea')]"/>
<filter string="Other" name="filter_other"
domain="[('machine_type', '=', 'other')]"/>
<separator/>
<filter string="Archived" name="filter_archived"
domain="[('active', '=', False)]"/>
<group expand="0" string="Group By">
<filter string="Branch" name="group_branch"
context="{'group_by': 'branch_custom_id'}"/>
<filter string="Machine Type" name="group_type"
context="{'group_by': 'machine_type'}"/>
</group>
</search>
</field>
</record>
<!-- Payment Machine Action -->
<record id="action_payment_machine" model="ir.actions.act_window">
<field name="name">Payment Machines</field>
<field name="res_model">payment.machine</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="payment_machine_view_search"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first payment machine
</p>
<p>
Payment machines are used to track POS terminals like Gidea, Neoleap, etc.
</p>
</field>
</record>
<!-- Menu Item under Global Settings -->
<menuitem id="menu_payment_machine"
name="Payment Machines"
parent="odex_takaful.sponsor_setting_menu"
action="action_payment_machine"
sequence="9"/>
</odoo>

View File

@ -8,6 +8,24 @@ _logger = logging.getLogger(__name__)
class AccountRegisterPayment(models.TransientModel):
_inherit = 'account.payment.register'
@api.model
def default_get(self, fields_list):
res = super(AccountRegisterPayment, self).default_get(fields_list)
if 'machine_id' in res and res['machine_id']:
machine = self.env['payment.machine'].browse(res['machine_id'])
if machine.exists() and machine.journal_id:
res['journal_id'] = machine.journal_id.id
elif not res.get('machine_id'):
# Fallback if default_get didn't catch the field default (though it usually does for computed defaults)
# Let's explicitly check our custom default logic if not present
machine_id = self._default_machine_id()
if machine_id:
res['machine_id'] = machine_id
machine = self.env['payment.machine'].browse(machine_id)
if machine.exists() and machine.journal_id:
res['journal_id'] = machine.journal_id.id
return res
@api.model
def _default_payment_method_id(self):
payment_method = self.env['takaful.payment.method'].sudo().search(
@ -30,7 +48,29 @@ class AccountRegisterPayment(models.TransientModel):
transaction_file_attachment = fields.Binary(string='Transaction Attachment', attachment=False)
transaction_attachment_file_name = fields.Char('Transaction File Name', required=False)
payment_method = fields.Selection(selection=[("cash", "Cash"), ("bank", "Bank Transfer"), ("check", "Check")], string="Payment Method", required=True, default="cash")
machine_id = fields.Many2one('geidea.terminals', string=_('Machine'))
@api.model
def _default_machine_id(self):
sponsorship_id = self.env.context.get('default_takaful_sponsorship_id') or self.env.context.get('active_id')
if sponsorship_id:
sponsorship = self.env['takaful.sponsorship'].browse(sponsorship_id)
if sponsorship.exists() and sponsorship.branch_custom_id:
return self.env['payment.machine'].search([
('branch_custom_id', '=', sponsorship.branch_custom_id.id),
('active', '=', True)
], limit=1).id
return False
machine_id = fields.Many2one(
'payment.machine',
string='Payment Machine',
default=_default_machine_id
)
sponsorship_branch_id = fields.Many2one(
'branch.settings',
string='Sponsorship Branch',
related='takaful_sponsorship_id.branch_custom_id',
store=False,
)
check_number = fields.Char(string='Check Number')
check_due_date = fields.Date(string='Check Due Date')
sponsorship_payment = fields.Boolean(string='Sponsorship Payment', default=False)

View File

@ -76,24 +76,35 @@
</xpath>
<xpath expr="//field[@name='journal_id']" position="before">
<field name="takaful_payment_method_id" string="Payment Method" attrs="{'invisible': [('sponsorship_payment', '=', False)]}" options="{'no_create': True, 'no_create_edit': True}"/>
<field name="takaful_payment_method_id" string="Payment Method" attrs="{'invisible': [('sponsorship_payment', '=', False)]}" options="{'no_create': True, 'no_create_edit': True, 'no_open': True}"/>
<field name="takaful_sponsorship_id" invisible="1"/>
<field name="sponsorship_branch_id" invisible="1"/>
<field name="machine_id"
options="{'no_create': True, 'no_create_edit': True, 'no_open': True}"
domain="[('branch_custom_id', '=', sponsorship_branch_id)]"
attrs="{'invisible': ['|', ('sponsorship_payment', '=', False), ('takaful_payment_method', '!=', 'network')], 'required': [('sponsorship_payment', '=', True), ('takaful_payment_method', '=', 'network')]}"/>
</xpath>
<xpath expr="//field[@name='partner_bank_id']" position="after">
<xpath expr="//field[@name='journal_id']" position="attributes">
<attribute name="attrs">{'readonly':[('is_refund_sponsorship','=',True)], 'invisible': [('takaful_payment_method', '=', 'network')]}</attribute>
<attribute name="string">Association Journal</attribute>
</xpath>
<xpath expr="//field[@name='partner_bank_id']" position="after">
<field name="sponsorship_payment" invisible="1"/>
<field name="takaful_payment_method" invisible="1"/>
<!-- <field name="payment_method" attrs="{'invisible': [('sponsorship_payment', '=', False)]}"/>-->
<field name="payment_method" invisible="1"/>
<field name="check_number" attrs="{'invisible': ['|', ('sponsorship_payment', '=', False), ('takaful_payment_method','!=','check')], 'required': [('sponsorship_payment', '=', True), ('takaful_payment_method','=','check')]}"/>
<field name="check_due_date" attrs="{'invisible': ['|', ('sponsorship_payment', '=', False), ('takaful_payment_method','!=','check')], 'required': [('sponsorship_payment', '=', True), ('takaful_payment_method','=','check')]}"/>
<field name="partner_bank_id" string="Donor Bank Account" options="{'skip_disable_quick_create': True}" context="{'form_view_ref': 'odex_takaful.res_partner_bank_view_form_quick_create', 'default_partner_id': context.get('force_sponsorship_line_partner_id')}" attrs="{'required': [('sponsorship_payment', '=', True), ('takaful_payment_method','not in',('bank','check'))], 'invisible': ['|', ('sponsorship_payment', '=', False), ('takaful_payment_method','not',('bank','check'))]}" create="1" edit="1"/>
<field name="partner_bank_id" string="Donor Bank Account" options="{'skip_disable_quick_create': True}" context="{'form_view_ref': 'odex_takaful.res_partner_bank_view_form_quick_create', 'default_partner_id': context.get('force_sponsorship_line_partner_id')}" attrs="{'required': [('sponsorship_payment', '=', True), ('takaful_payment_method','in',['bank','check'])], 'invisible': ['|', ('sponsorship_payment', '=', False), ('takaful_payment_method','not in',['bank','check'])]}" create="1" edit="1"/>
<field name="transaction_file_attachment" widget="binary"
filename="transaction_attachment_file_name"
attrs="{'invisible': ['|', ('sponsorship_payment', '=', False), ('takaful_payment_method','not in',['bank', 'check'])], 'required': [('sponsorship_payment', '=', True), ('takaful_payment_method','=','bank')]}"/>
<field name="transaction_attachment_file_name" invisible="1"/>
<field name="payment_date" attrs="{'readonly': [('sponsorship_payment', '=', True)]}"/>
<field name="communication"/>
</xpath>
</xpath>
<xpath expr="//footer/button[2]" position="replace">
<!-- <field name="show_cancel_button" invisible="1"/>-->
<button string="Cancel"