commit
fdf798e9c5
|
|
@ -17540,4 +17540,69 @@ msgid ""
|
||||||
"%s"
|
"%s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"طلبات الخدمة التالية ليس لديها جهة الدفع محددة:\n"
|
"طلبات الخدمة التالية ليس لديها جهة الدفع محددة:\n"
|
||||||
"%s"
|
"%s"
|
||||||
|
|
||||||
|
#. module: odex_benefit
|
||||||
|
#: model:ir.model.fields,field_description:odex_benefit.field_service_request__related_information_html
|
||||||
|
#: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_form
|
||||||
|
#: model_terms:ir.ui.view,arch_db:odex_benefit.services_settings_form
|
||||||
|
msgid "Related Information"
|
||||||
|
msgstr "المعلومات المرتبطة"
|
||||||
|
|
||||||
|
#. module: odex_benefit
|
||||||
|
#: code:addons/odex_benefit/models/service_request.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Family Information"
|
||||||
|
msgstr "معلومات الأسرة"
|
||||||
|
|
||||||
|
#. module: odex_benefit
|
||||||
|
#: code:addons/odex_benefit/models/service_request.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Member Information"
|
||||||
|
msgstr "معلومات الأفراد"
|
||||||
|
|
||||||
|
#. module: odex_benefit
|
||||||
|
#: code:addons/odex_benefit/models/service_request.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Unnamed file"
|
||||||
|
msgstr "ملف بدون اسم"
|
||||||
|
|
||||||
|
#. module: odex_benefit
|
||||||
|
#: model:ir.model.fields,field_description:odex_benefit.field_services_settings__family_related_fields
|
||||||
|
msgid "Related Family Fields"
|
||||||
|
msgstr "الحقول المرتبطة بالأسرة"
|
||||||
|
|
||||||
|
#. module: odex_benefit
|
||||||
|
#: model:ir.model.fields,field_description:odex_benefit.field_services_settings__member_related_fields
|
||||||
|
msgid "Related Member Fields"
|
||||||
|
msgstr "الحقول المرتبطة بالفرد"
|
||||||
|
|
||||||
|
#. module: odex_benefit
|
||||||
|
#: code:addons/odex_benefit/models/service_request.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "No service selected"
|
||||||
|
msgstr "لم يتم اختيار خدمة"
|
||||||
|
|
||||||
|
#. module: odex_benefit
|
||||||
|
#: code:addons/odex_benefit/models/service_request.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Please select a service category to view related information."
|
||||||
|
msgstr "رجاءً اختر خدمة لعرض المعلومات المرتبطة."
|
||||||
|
|
||||||
|
#. module: odex_benefit
|
||||||
|
#: code:addons/odex_benefit/models/service_request.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Field Name"
|
||||||
|
msgstr "اسم الحقل"
|
||||||
|
|
||||||
|
#. module: odex_benefit
|
||||||
|
#: code:addons/odex_benefit/models/service_request.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "Value"
|
||||||
|
msgstr "القيمة"
|
||||||
|
|
||||||
|
#. module: odex_benefit
|
||||||
|
#: code:addons/odex_benefit/models/service_request.py:0
|
||||||
|
#, python-format
|
||||||
|
msgid "No information available for this section."
|
||||||
|
msgstr "لا توجد معلومات متاحة."
|
||||||
|
|
@ -628,9 +628,9 @@ class GrantBenefitProfile(models.Model):
|
||||||
|
|
||||||
def _compute_total_families(self):
|
def _compute_total_families(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
record.total_father_families = self.search_count([('father_id_number','=',self.father_id_number),('id','!=',self.id)])
|
record.total_father_families = self.search_count([('father_id_number','=',record.father_id_number),('id','!=',record.id)])
|
||||||
record.total_mother_families = self.search_count([('mother_id_number','=',self.mother_id_number),('id','!=',self.id)])
|
record.total_mother_families = self.search_count([('mother_id_number','=',record.mother_id_number),('id','!=',record.id)])
|
||||||
record.total_replacement_mother_families = self.search_count([('replacement_mother_id_number','=',self.replacement_mother_id_number),('id','!=',self.id)])
|
record.total_replacement_mother_families = self.search_count([('replacement_mother_id_number','=',record.replacement_mother_id_number),('id','!=',record.id)])
|
||||||
|
|
||||||
def action_open_related_father_families(self):
|
def action_open_related_father_families(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
|
|
@ -827,6 +827,7 @@ class GrantBenefitProfile(models.Model):
|
||||||
record.required_attach = 'true'
|
record.required_attach = 'true'
|
||||||
|
|
||||||
def get_attached_domain(self):
|
def get_attached_domain(self):
|
||||||
|
self.ensure_one()
|
||||||
visit_location = self.env['visit.location'].search([('benefit_id', '=', self.id)]).ids
|
visit_location = self.env['visit.location'].search([('benefit_id', '=', self.id)]).ids
|
||||||
service_requests = self.env['service.request'].search([('family_id', '=', self.id)]).ids
|
service_requests = self.env['service.request'].search([('family_id', '=', self.id)]).ids
|
||||||
family_complaints = self.env['family.complaints'].search([('family_id', '=', self.id)]).ids
|
family_complaints = self.env['family.complaints'].search([('family_id', '=', self.id)]).ids
|
||||||
|
|
@ -865,7 +866,7 @@ class GrantBenefitProfile(models.Model):
|
||||||
def _compute_attached_docs_count(self):
|
def _compute_attached_docs_count(self):
|
||||||
Attachment = self.env['ir.attachment']
|
Attachment = self.env['ir.attachment']
|
||||||
for benefit in self:
|
for benefit in self:
|
||||||
benefit.doc_count = Attachment.search_count(self.get_attached_domain())
|
benefit.doc_count = Attachment.search_count(benefit.get_attached_domain())
|
||||||
|
|
||||||
def view_attachments(self):
|
def view_attachments(self):
|
||||||
action = self.env['ir.actions.act_window']._for_xml_id('base.action_attachment')
|
action = self.env['ir.actions.act_window']._for_xml_id('base.action_attachment')
|
||||||
|
|
@ -1881,20 +1882,21 @@ class GrantBenefitProfile(models.Model):
|
||||||
|
|
||||||
@api.depends('name')
|
@api.depends('name')
|
||||||
def _compute_qr_code(self):
|
def _compute_qr_code(self):
|
||||||
qr = qrcode.QRCode(
|
for rec in self:
|
||||||
version=1,
|
qr = qrcode.QRCode(
|
||||||
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
version=1,
|
||||||
box_size=15,
|
error_correction=qrcode.constants.ERROR_CORRECT_L,
|
||||||
border=4,
|
box_size=15,
|
||||||
)
|
border=4,
|
||||||
name = self.name
|
)
|
||||||
qr.add_data(name)
|
name = rec.name
|
||||||
qr.make(fit=True)
|
qr.add_data(name)
|
||||||
img = qr.make_image()
|
qr.make(fit=True)
|
||||||
temp = BytesIO()
|
img = qr.make_image()
|
||||||
img.save(temp, format="PNG")
|
temp = BytesIO()
|
||||||
qr_image = base64.b64encode(temp.getvalue())
|
img.save(temp, format="PNG")
|
||||||
self.qr_code = qr_image
|
qr_image = base64.b64encode(temp.getvalue())
|
||||||
|
rec.qr_code = qr_image
|
||||||
|
|
||||||
@api.onchange('bank_id')
|
@api.onchange('bank_id')
|
||||||
def _compute_prefix_iban(self):
|
def _compute_prefix_iban(self):
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ from odoo import fields, models, api, _
|
||||||
from odoo.exceptions import UserError, ValidationError
|
from odoo.exceptions import UserError, ValidationError
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
from odoo.tools import html_escape
|
||||||
|
|
||||||
|
|
||||||
class ServiceRequest(models.Model):
|
class ServiceRequest(models.Model):
|
||||||
|
|
@ -185,8 +186,8 @@ class ServiceRequest(models.Model):
|
||||||
car_owner_id = fields.Many2one('family.member', domain="[('benefit_id','=',family_id)]", string="Car Owner")
|
car_owner_id = fields.Many2one('family.member', domain="[('benefit_id','=',family_id)]", string="Car Owner")
|
||||||
car_model_id = fields.Many2one('benefit.vehicle.model', string='Car model')
|
car_model_id = fields.Many2one('benefit.vehicle.model', string='Car model')
|
||||||
car_price = fields.Float(string='Car Price')
|
car_price = fields.Float(string='Car Price')
|
||||||
car_remaining_amount = fields.Float(string='Remaining Amount',compute='_compute_remaining_amount',store=True,)
|
car_remaining_amount = fields.Float(string='Remaining Amount', compute='_compute_remaining_amount', store=True, )
|
||||||
show_car_remaining_amount = fields.Boolean(string='Show Car Remaining Amount',compute='_compute_remaining_amount')
|
show_car_remaining_amount = fields.Boolean(string='Show Car Remaining Amount', compute='_compute_remaining_amount')
|
||||||
application_form = fields.Many2many('ir.attachment', 'request_application_form_rel', 'request_id', 'attachment_id',
|
application_form = fields.Many2many('ir.attachment', 'request_application_form_rel', 'request_id', 'attachment_id',
|
||||||
string="Application Form")
|
string="Application Form")
|
||||||
driving_license = fields.Many2many('ir.attachment', 'request_driving_license_rel', 'request_id', 'attachment_id',
|
driving_license = fields.Many2many('ir.attachment', 'request_driving_license_rel', 'request_id', 'attachment_id',
|
||||||
|
|
@ -204,6 +205,135 @@ class ServiceRequest(models.Model):
|
||||||
total_moves = fields.Integer(string="Total Move", compute='_get_total_move_lines')
|
total_moves = fields.Integer(string="Total Move", compute='_get_total_move_lines')
|
||||||
return_reason_id = fields.Many2one("return.reason", string="Return Reason")
|
return_reason_id = fields.Many2one("return.reason", string="Return Reason")
|
||||||
agree_terms = fields.Boolean(string="I agree to the Terms and Conditions", default=False, )
|
agree_terms = fields.Boolean(string="I agree to the Terms and Conditions", default=False, )
|
||||||
|
related_information_html = fields.Html(string="Related Information",
|
||||||
|
compute='_compute_related_information_html', store=True, )
|
||||||
|
|
||||||
|
@api.depends('service_cat', 'family_id', 'member_id', 'benefit_type')
|
||||||
|
def _compute_related_information_html(self):
|
||||||
|
for rec in self:
|
||||||
|
if not rec.service_cat:
|
||||||
|
no_service_title = _("No service selected")
|
||||||
|
no_service_desc = _("Please select a service category to view related information.")
|
||||||
|
rec.related_information_html = f"""
|
||||||
|
<div class="o_form_sheet_not_found">
|
||||||
|
<div class="o_form_sheet_not_found_icon">📋</div>
|
||||||
|
<h4>{no_service_title}</h4>
|
||||||
|
<p>{no_service_desc}</p>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
continue
|
||||||
|
|
||||||
|
family_rows = []
|
||||||
|
member_rows = []
|
||||||
|
family_title = _("Family Information")
|
||||||
|
member_title = _("Member Information")
|
||||||
|
|
||||||
|
for ir_field in rec.service_cat.family_related_fields:
|
||||||
|
row = rec._get_field_display_value(rec.family_id, ir_field)
|
||||||
|
if row:
|
||||||
|
family_rows.append(row)
|
||||||
|
if rec.benefit_type == 'member' and rec.member_id:
|
||||||
|
for ir_field in rec.service_cat.member_related_fields:
|
||||||
|
row = rec._get_field_display_value(rec.member_id, ir_field)
|
||||||
|
if row:
|
||||||
|
member_rows.append(row)
|
||||||
|
family_table = rec._build_info_table(family_title, family_rows)
|
||||||
|
member_table = rec._build_info_table(member_title, member_rows) if member_rows else ""
|
||||||
|
|
||||||
|
rec.related_information_html = f"""
|
||||||
|
<div class="info-container">
|
||||||
|
{family_table}
|
||||||
|
{member_table}
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _build_info_table(self, title, rows):
|
||||||
|
field_name_label = _("Field Name")
|
||||||
|
value_label = _("Value")
|
||||||
|
no_info_text = _("No information available for this section.")
|
||||||
|
if not rows:
|
||||||
|
return f"""
|
||||||
|
<div class="info-section">
|
||||||
|
<h3>{title}</h3>
|
||||||
|
<div class="info-empty">{no_info_text}</div>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
return f"""
|
||||||
|
<div class="info-section">
|
||||||
|
<h3>{title}</h3>
|
||||||
|
<table class="table info-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{field_name_label}</th>
|
||||||
|
<th>{value_label}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{''.join(rows)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _get_field_display_value(self, record, ir_field):
|
||||||
|
if not record or not ir_field:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
field_name = ir_field.name
|
||||||
|
field = record._fields.get(field_name)
|
||||||
|
if not field:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
value = record[field_name]
|
||||||
|
label = html_escape(ir_field.field_description or field_name)
|
||||||
|
|
||||||
|
if value in (False, None, '') or (hasattr(value, '__len__') and len(value) == 0):
|
||||||
|
display = '<span class="info-empty">—</span>'
|
||||||
|
elif field.type == 'boolean':
|
||||||
|
display = f"<span class='badge badge-success'>✓ {_('Yes')}</span>" if value else f"<span class='badge badge-danger'>✗ {_('No')}</span>"
|
||||||
|
elif field.type == 'selection':
|
||||||
|
sel_dict = dict(field._description_selection(record.env))
|
||||||
|
display_val = sel_dict.get(value, value)
|
||||||
|
display = f'<span class="badge">{html_escape(str(display_val or "—"))}</span>'
|
||||||
|
elif field.type == 'many2one':
|
||||||
|
display = f'<strong>{html_escape(value.name or "—")}</strong>'
|
||||||
|
elif field.type == 'many2many':
|
||||||
|
if field.comodel_name == 'ir.attachment':
|
||||||
|
if not value:
|
||||||
|
display = '<span class="info-empty">—</span>'
|
||||||
|
else:
|
||||||
|
links = []
|
||||||
|
for attach in value:
|
||||||
|
filename = attach.name or _("Unnamed file")
|
||||||
|
url = f"/web/content/{attach.id}?download=true"
|
||||||
|
links.append(f'<a class="file-link" href="{url}" target="_blank">📎 {html_escape(filename)}</a>')
|
||||||
|
display = '<br/>'.join(links)
|
||||||
|
else:
|
||||||
|
badges = [f'<span class="badge badge-secondary">{html_escape(r.name or "-")}</span>' for r in value]
|
||||||
|
display = ' '.join(badges) or '<span class="info-empty">—</span>'
|
||||||
|
elif field.type == 'one2many':
|
||||||
|
items = [
|
||||||
|
f'<div style="margin:8px 0; padding:6px 0; border-bottom:1px dotted #ddd;">• {html_escape(r.display_name or r.name or "-")}</div>'
|
||||||
|
for r in value[:20]]
|
||||||
|
more = f'<div style="color:#875A92; font-weight:600; margin-top:10px;">... {_("and")} {len(value) - 20} {_("more records")}</div>' if len(
|
||||||
|
value) > 20 else ""
|
||||||
|
display = ''.join(items) + more or '<span class="info-empty">—</span>'
|
||||||
|
elif field.type == 'binary':
|
||||||
|
if value:
|
||||||
|
filename = getattr(record, f"{field_name}_fname", None) or _("Download file")
|
||||||
|
url = f"/web/content/{record._name}/{record.id}/{field_name}?download=true"
|
||||||
|
display = f'<a class="file-link" href="{url}" target="_blank">📎 {html_escape(filename)}</a>'
|
||||||
|
else:
|
||||||
|
display = '<span class="info-empty">—</span>'
|
||||||
|
else:
|
||||||
|
display = html_escape(str(value))
|
||||||
|
|
||||||
|
return f"""
|
||||||
|
<tr>
|
||||||
|
<td class="info-label">{label}</td>
|
||||||
|
<td class="info-value">{display}</td>
|
||||||
|
</tr>
|
||||||
|
"""
|
||||||
|
|
||||||
@api.depends('payment_order_ids')
|
@api.depends('payment_order_ids')
|
||||||
def _compute_payment_order(self):
|
def _compute_payment_order(self):
|
||||||
|
|
@ -641,9 +771,9 @@ class ServiceRequest(models.Model):
|
||||||
if rec.service_cat.service_type == 'recruiting_driver':
|
if rec.service_cat.service_type == 'recruiting_driver':
|
||||||
if not rec.family_id.has_car:
|
if not rec.family_id.has_car:
|
||||||
raise ValidationError(_("You cannot request this service because you do not have a car"))
|
raise ValidationError(_("You cannot request this service because you do not have a car"))
|
||||||
#son_members_above_age = rec.family_id.member_ids.filtered(
|
# son_members_above_age = rec.family_id.member_ids.filtered(
|
||||||
# lambda x: x.relationn.relation_type == 'son' and x.age > 18)
|
# lambda x: x.relationn.relation_type == 'son' and x.age > 18)
|
||||||
#daughter_members_above_age = rec.family_id.member_ids.filtered(
|
# daughter_members_above_age = rec.family_id.member_ids.filtered(
|
||||||
# lambda x: x.relationn.relation_type == 'daughter' and x.age > 18)
|
# lambda x: x.relationn.relation_type == 'daughter' and x.age > 18)
|
||||||
|
|
||||||
children_above_18_living_with_family = rec.family_id.member_ids.filtered(
|
children_above_18_living_with_family = rec.family_id.member_ids.filtered(
|
||||||
|
|
@ -662,10 +792,11 @@ class ServiceRequest(models.Model):
|
||||||
work_mother = rec.family_id.member_ids.filtered(
|
work_mother = rec.family_id.member_ids.filtered(
|
||||||
lambda x: x.relationn.relation_type == 'mother' and x.is_work)
|
lambda x: x.relationn.relation_type == 'mother' and x.is_work)
|
||||||
disable_replacement_mother = rec.family_id.member_ids.filtered(
|
disable_replacement_mother = rec.family_id.member_ids.filtered(
|
||||||
lambda x: x.relationn.relation_type == 'replacement_mother' and bool(x.disabilities_attachment_ids))
|
lambda x: x.relationn.relation_type == 'replacement_mother' and bool(
|
||||||
|
x.disabilities_attachment_ids))
|
||||||
work_replacement_mother = rec.family_id.member_ids.filtered(
|
work_replacement_mother = rec.family_id.member_ids.filtered(
|
||||||
lambda x: x.relationn.relation_type == 'replacement_mother' and x.is_work)
|
lambda x: x.relationn.relation_type == 'replacement_mother' and x.is_work)
|
||||||
#if son_members_above_age or daughter_members_above_age:
|
# if son_members_above_age or daughter_members_above_age:
|
||||||
# raise ValidationError(
|
# raise ValidationError(
|
||||||
# _("You cannot request this service because children above 18 years"))
|
# _("You cannot request this service because children above 18 years"))
|
||||||
if rec.family_id.add_replacement_mother and not disable_replacement_mother and not work_replacement_mother:
|
if rec.family_id.add_replacement_mother and not disable_replacement_mother and not work_replacement_mother:
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,30 @@ class ServicesSettings(models.Model):
|
||||||
('payment_order', 'Payment Order'),
|
('payment_order', 'Payment Order'),
|
||||||
('invoice', 'Invoice'),
|
('invoice', 'Invoice'),
|
||||||
], string='Payment Method',default="payment_order")
|
], string='Payment Method',default="payment_order")
|
||||||
|
family_related_fields = fields.Many2many(
|
||||||
|
comodel_name='ir.model.fields',
|
||||||
|
relation='services_settings_family_field_rel',
|
||||||
|
column1='services_settings_id',
|
||||||
|
column2='field_id',
|
||||||
|
string='Related Family Fields',
|
||||||
|
domain="[('model_id.model', '=', 'grant.benefit')]",
|
||||||
|
help="Select fields from the Family profile (grant.benefit) to display in the service request."
|
||||||
|
)
|
||||||
|
|
||||||
|
member_related_fields = fields.Many2many(
|
||||||
|
comodel_name='ir.model.fields',
|
||||||
|
relation='services_settings_member_field_rel',
|
||||||
|
column1='services_settings_id',
|
||||||
|
column2='field_id',
|
||||||
|
string='Related Member Fields',
|
||||||
|
domain="[('model_id.model', '=', 'family.member')]",
|
||||||
|
help="Select fields from the Member profile to display only when the service is for a member."
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.onchange('benefit_type')
|
||||||
|
def _onchange_benefit_type(self):
|
||||||
|
if self.benefit_type != 'member':
|
||||||
|
self.member_related_fields = [(5, 0, 0)]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
.info-container {
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
.info-container .info-section {
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
.info-container .info-section h3 {
|
||||||
|
color: #000000;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.info-container .info-table {
|
||||||
|
width: 70%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.info-container .info-table th {
|
||||||
|
background-color: #EEE;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
.info-container .info-table td {
|
||||||
|
border-bottom: 1px solid #e9ecef;
|
||||||
|
}
|
||||||
|
.info-container .info-table tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.info-container .info-table tr:hover td {
|
||||||
|
background-color: #f8f5f9;
|
||||||
|
}
|
||||||
|
.info-container .info-value {
|
||||||
|
color: #212529;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
.info-container .badge {
|
||||||
|
padding: 5px 12px;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 3px 6px 3px 0;
|
||||||
|
}
|
||||||
|
.info-container .badge-success { background:#d4edda; color:#155724; }
|
||||||
|
.info-container .badge-danger { background:#f8d7da; color:#721c24; }
|
||||||
|
.info-container .badge-info { background:#d1ecf1; color:#0c5460; }
|
||||||
|
.info-container .badge-secondary{ background:#e2e3e5; color:#383d41; }
|
||||||
|
.info-container .file-link {
|
||||||
|
color: #875A92;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.info-container .file-link:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.info-container .info-empty {
|
||||||
|
color: #adb5bd;
|
||||||
|
font-style: italic;
|
||||||
|
text-align: center;
|
||||||
|
background: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.o_form_sheet_not_found {
|
||||||
|
text-align:center;
|
||||||
|
padding:50px;
|
||||||
|
background:#f8f9fa;
|
||||||
|
border:2px dashed #dee2e6;
|
||||||
|
border-radius:12px;
|
||||||
|
color:#6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.o_form_sheet_not_found .o_form_sheet_not_found_icon {
|
||||||
|
font-size:48px;
|
||||||
|
opacity:0.3;
|
||||||
|
margin-bottom:16px;
|
||||||
|
}
|
||||||
|
|
@ -444,6 +444,11 @@
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
|
<page string="Related Information">
|
||||||
|
<group>
|
||||||
|
<field name="related_information_html" nolabel="1" readonly="1"/>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
</notebook>
|
</notebook>
|
||||||
</sheet>
|
</sheet>
|
||||||
<div class="oe_chatter">
|
<div class="oe_chatter">
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,17 @@
|
||||||
</group>
|
</group>
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
|
<page string="Related Information">
|
||||||
|
<group>
|
||||||
|
<group>
|
||||||
|
<field name="family_related_fields" widget="many2many_tags"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="member_related_fields" widget="many2many_tags"
|
||||||
|
attrs="{'invisible': [('benefit_type', '!=', 'member')]}"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
</notebook>
|
</notebook>
|
||||||
</sheet>
|
</sheet>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
<template id="custom_assets_backend" inherit_id="web.assets_backend">
|
<template id="custom_assets_backend" inherit_id="web.assets_backend">
|
||||||
<xpath expr="." position="inside">
|
<xpath expr="." position="inside">
|
||||||
<link rel="stylesheet" type="text/scss" href="/odex_benefit/static/src/scss/custom_style.scss"/>
|
<link rel="stylesheet" type="text/scss" href="/odex_benefit/static/src/scss/custom_style.scss"/>
|
||||||
|
<link rel="stylesheet" type="text/scss" href="/odex_benefit/static/src/css/backend_style.css"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
</template>
|
</template>
|
||||||
</odoo>
|
</odoo>
|
||||||
Loading…
Reference in New Issue