Merge pull request #6132 from expsa/rrro

Rrro
This commit is contained in:
kchyounes19 2026-01-11 15:37:52 +01:00 committed by GitHub
commit fc532c9e2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 113 additions and 73 deletions

View File

@ -1580,7 +1580,6 @@ msgstr "موافقة رئيس العمليات"
#: model_terms:ir.ui.view,arch_db:odex_benefit.payment_orders_form
#: model_terms:ir.ui.view,arch_db:odex_benefit.payment_orders_tree
#: model_terms:ir.ui.view,arch_db:odex_benefit.seasonal_service_form_view
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_benefit_category_form
msgid "Approve"
msgstr "موافقة"
@ -1596,7 +1595,6 @@ msgstr "الموافقة على العائلة"
#. module: odex_benefit
#: model:ir.model.fields.selection,name:odex_benefit.selection__appliances_furniture__state__approve
#: model:ir.model.fields.selection,name:odex_benefit.selection__benefit_category__state__approve
#: model:ir.model.fields.selection,name:odex_benefit.selection__benefit_club__state__approve
#: model:ir.model.fields.selection,name:odex_benefit.selection__benefit_food_basket__state__approve
#: model:ir.model.fields.selection,name:odex_benefit.selection__benefit_food_surplus__state__approve
@ -1633,7 +1631,6 @@ msgstr "ايقاف"
#. module: odex_benefit
#: model_terms:ir.ui.view,arch_db:odex_benefit.changes_requests_form
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_benefit_category_form
msgid "Are you sure you want to Approve?"
msgstr "هل أنت متأكد أنك تريد الموافقة؟"
@ -1647,11 +1644,6 @@ msgstr "هل أنت متأكد أنك تريد إنهاء البيانات ال
msgid "Are you sure you want to Refuse ?"
msgstr "هل أنت متأكد أنك تريد الرفض؟"
#. module: odex_benefit
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_benefit_category_form
msgid "Are you sure you want to Reject?"
msgstr "هل أنت متأكد أنك تريد الرفض؟"
#. module: odex_benefit
#: model_terms:ir.ui.view,arch_db:odex_benefit.appliances_furniture_form
#: model_terms:ir.ui.view,arch_db:odex_benefit.expenses_line_form
@ -3172,7 +3164,6 @@ msgstr "انشطة النادي"
#: model:ir.model.fields,field_description:odex_benefit.field_receive_food_basket__code
#: model:ir.model.fields,field_description:odex_benefit.field_res_bank__code
#: model:ir.model.fields,field_description:odex_benefit.field_res_country_city__code
#: model:ir.model.fields,field_description:odex_benefit.field_visit_location__benefit_code
msgid "Code"
msgstr "الكود"
@ -4254,7 +4245,6 @@ msgstr "تصنيفات الشكوى"
#. module: odex_benefit
#: model:ir.model.fields.selection,name:odex_benefit.selection__family_complaints__state__draft
#: model:ir.model.fields.selection,name:odex_benefit.selection__appliances_furniture__state__draft
#: model:ir.model.fields.selection,name:odex_benefit.selection__benefit_category__state__draft
#: model:ir.model.fields.selection,name:odex_benefit.selection__benefit_club__state__draft
#: model:ir.model.fields.selection,name:odex_benefit.selection__benefit_expenses__state__draft
#: model:ir.model.fields.selection,name:odex_benefit.selection__benefit_food_basket__state__draft
@ -5374,6 +5364,7 @@ msgstr "فئة الأسرة"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_account_move_line__family_code
#: model:ir.model.fields,field_description:odex_benefit.field_family_member__benefit_code
#: model:ir.model.fields,field_description:odex_benefit.field_visit_location__benefit_code
#: model:ir.model.fields,field_description:odex_benefit.field_service_request__family_code
#: model_terms:ir.ui.view,arch_db:odex_benefit.grant_benefit_search
#: model_terms:ir.ui.view,arch_db:odex_benefit.grant_benefit_tree
@ -7284,12 +7275,16 @@ msgid "Last Education Entity"
msgstr "نوع الجهة التعليمية السابقة"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_family_member__last_education_levels
#: model:ir.model.fields,field_description:odex_benefit.field_grant_benefit__last_education_levels
#: model:ir.model.fields,field_description:odex_benefit.field_grant_benefit__replacement_last_education_levels
msgid "Last Education Levels"
msgstr "المرحلة التعليمية السابقة"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_family_member__last_education_levels
msgid "Last Education Levels"
msgstr "المرحلة التعليمية"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_family_member__last_education_start_date
#: model:ir.model.fields,field_description:odex_benefit.field_grant_benefit__last_education_start_date
@ -9972,12 +9967,6 @@ msgstr "المنطقة"
msgid "Rehabilitation center for the disabled"
msgstr "مركز التأهيل الشامل للمعاقين"
#. module: odex_benefit
#: model:ir.model.fields.selection,name:odex_benefit.selection__benefit_category__state__rejected
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_benefit_category_form
msgid "Rejected"
msgstr "مرفوض"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefits_representative__parent_id
#: model:ir.model.fields,field_description:odex_benefit.field_external_benefits__parent_id
@ -10994,7 +10983,6 @@ msgid "Sport Type"
msgstr "نوع الرياضة"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_category__state
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_sms_configuration__state
#: model:ir.model.fields,field_description:odex_benefit.field_benefits_representative__state_id
#: model:ir.model.fields,field_description:odex_benefit.field_changes_requests__state
@ -18515,3 +18503,7 @@ msgid ""
" be non-benefit to proceed."
msgstr "الإجراء غير مسموح: الأسرة لديها %s فرد مستفيد. يجب أن يكون جميع الأفراد غير مستفيدين للمتابعة."
#. module: odex_benefit
#: model:ir.model.fields.selection,name:odex_benefit.selection__education_status__education_entity__governmental_paid
msgid "Governmental/Paid"
msgstr "حكومي /مقابل مادي"

View File

@ -212,7 +212,7 @@ class GrantBenefitProfile(models.Model):
mother_location_conf = fields.Many2one('location.settings',string='Mother Location',domain="[('location_type','=','mother_location')]")
is_mother_work = fields.Boolean('Is Mother Work?')
mother_has_disabilities = fields.Boolean('Has Disabilities?')
mother_income = fields.Float("Mother Income", digits=(16, 0),compute='calculate_income', store=True)
mother_income = fields.Float("Mother Income", digits=(16, 0),compute='calculate_income', store=True,tracking=True)
mother_net_income = fields.Float(string="Mother Net Income",compute='_compute_mother_net_income',
store=True,help="Mother gross income minus her deducted expenses and monthly debt installments")
mother_birth_date = fields.Date(string="Birth Date")
@ -387,8 +387,8 @@ class GrantBenefitProfile(models.Model):
is_sport = fields.Boolean()
support_separation = fields.Boolean(string="Support Separation", tracking=True)
is_life = fields.Boolean(string="Life", default=True)
total_expenses = fields.Float('Total Expenses', compute="get_total_expenses",store=True)
total_income = fields.Float('Total Income', compute="get_total_income", store=True)
total_expenses = fields.Float('Total Expenses', compute="get_total_expenses",store=True,tracking=True)
total_income = fields.Float('Total Income', compute="get_total_income", store=True,tracking=True)
benefit_member_count = fields.Integer(string="Members count", compute="get_members_count")
non_member_count = fields.Integer(string="Non Benefit Members count", compute="get_non_members_count")
member_income = fields.Float(string="Member Income Average", compute="get_member_income",store=True,tracking=True)
@ -1886,6 +1886,7 @@ class GrantBenefitProfile(models.Model):
def action_auto_suspend(self):
# Fetch grants in second approval state that are not excluded from suspension
#case_one :
grants = self.env["grant.benefit"].search(
[('state', '=', 'second_approve'), ('is_excluded_suspension', '=', False)]
)
@ -1893,15 +1894,32 @@ class GrantBenefitProfile(models.Model):
for grant in grants:
# Check if there are no benefit members
if grant.benefit_member_count == 0:
grant.state = 'suspended_second_approve'
grant.state = 'complete_info'
grant.suspend_method = 'auto'
grant.action_type = 'suspended'
#case two :
members = self.env["family.member"].search(
[('state', '=', 'second_approve'), ('is_excluded_suspension', '=', False), ('member_status', '=', 'non_benefit')]
)
for member in members:
member.state_a = 'complete_info'
member.suspend_method = 'auto'
member.action_type = 'suspended'
member.is_member_workflow = True
def check_actt(self):
# case_one :
grants = self.env["grant.benefit"].search(
[('state', '=', 'second_approve'), ('is_excluded_suspension', '=', False)]
)
for grant in grants:
# Check if any attachment of the grant is expired
for attachment in grant.attachment_ids:
if attachment.attach_status == 'expired':
# Change state to temporarily suspended if there are benefit members
if grant.benefit_member_count != 0:
grant.state = 'waiting_approve'
grant.state = 'complete_info'
grant.action_type = 'suspended'
grant.suspend_method = 'auto'
break # Exit attachment loop after processing
@ -1912,7 +1930,7 @@ class GrantBenefitProfile(models.Model):
if member_attachment.attach_status == 'expired':
# Change state to temporarily suspended if there are benefit members
if grant.benefit_member_count != 0:
grant.state = 'waiting_approve'
grant.state = 'complete_info'
grant.action_type = 'suspended'
grant.suspend_method = 'auto'
break # Exit member attachment loop after processing

View File

@ -26,9 +26,6 @@ class BenefitCategory(models.Model):
max_income_amount = fields.Float(string="Max Income Amount")
expenses_ids = fields.One2many('expenses.line', 'category_id')
is_benefit = fields.Boolean(string="Is Benefit",default=True)
state = fields.Selection([('draft', 'Draft'),
('approve', 'Approved'),
('rejected', 'Rejected'), ], default='draft')
color = fields.Integer(string="Color Index", default=0)
decoration_color = fields.Selection([
('danger', 'Red'),
@ -44,12 +41,6 @@ class BenefitCategory(models.Model):
for rec in self:
rec.benefits_total = len(rec.benefit_ids)
def action_approve(self):
self.state = 'approve'
def action_reject(self):
self.state = 'rejected'
def open_benefits(self):
return {
'name': _("Benefits"),

View File

@ -46,6 +46,7 @@ class EducationStatus(models.Model):
education_entity = fields.Selection(
string='Education Entity',
selection=[('governmental', 'Governmental'),
('governmental_paid', 'Governmental/Paid'),
('special', 'Special')]
)
education_start_date = fields.Date(string='Education Start Date')
@ -69,7 +70,7 @@ class EducationStatus(models.Model):
('from_5', 'From 5'),
('from_100', 'From 100'),
], string='Rate Type')
degree = fields.Many2one('education.result', string='Degree')
degree = fields.Many2one('education.result', string='Degree', compute='_compute_percentage_rate_type', store=True)
percentage = fields.Float(string="Percentage%")
specialization_ids = fields.Many2one('specialization.specialization', string='Specialization')
intermittent_reason_id = fields.Many2one('education.illiterate.reason', string='Intermittent Reason')
@ -80,8 +81,8 @@ class EducationStatus(models.Model):
delay_reason_id = fields.Many2one('education.delay.reason', string='Delay Reason')
weak_course_ids = fields.One2many('weak.course', 'education_status_id')
@api.onchange('percentage', 'rate_type')
def _onchange_percentage_rate_type(self):
@api.depends('percentage', 'rate_type')
def _compute_percentage_rate_type(self):
for rec in self:
rec.degree = False

View File

@ -42,8 +42,11 @@ class FamilyMemberProfile(models.Model):
benefit_code = fields.Char(string='Family Code', related='benefit_id.code', store=True)
branch_custom_id = fields.Many2one('branch.settings', string="Branch", related="benefit_id.branch_custom_id",
search="_search_branch_custom_id")
researcher_id = fields.Many2one("committees.line", string="Researcher", related="benefit_id.researcher_id", search="_search_researcher_id")
benefit_category_id = fields.Many2one('benefit.category', string='Benefit Category',related="benefit_id.benefit_category_id",search="_search_benefit_category_id")
researcher_id = fields.Many2one("committees.line", string="Researcher", related="benefit_id.researcher_id",
search="_search_researcher_id")
benefit_category_id = fields.Many2one('benefit.category', string='Benefit Category',
related="benefit_id.benefit_category_id",
search="_search_benefit_category_id")
gender = fields.Selection(selection=[('male', 'Male'), ('female', 'Female')], string="Gender")
member_phone = fields.Char(string="Member Phone")
member_location = fields.Selection(selection=[('with_family', 'With Family'), ('with_relative', 'with a relative'),
@ -118,7 +121,8 @@ class FamilyMemberProfile(models.Model):
)
case_study = fields.Selection(string='Case Study',
selection=[('continuous', 'continuous'), ('intermittent', 'intermittent'),
('graduate', 'Graduate')])
('graduate', 'Graduate')], compute='_compute_last_education_data',
store=True)
illiterate_reason = fields.Char(string='Illiterate Reason')
intermittent_reason = fields.Many2one('education.illiterate.reason', string='Intermittent Reason')
educational_certificate = fields.Binary(attachment=True, string='Educational Certificate')
@ -130,7 +134,8 @@ class FamilyMemberProfile(models.Model):
entities = fields.Many2one("res.partner", string='Entity')
last_entities = fields.Many2one("res.partner", string='Last Entity')
education_levels = fields.Many2one("education.level", string='Education Levels')
last_education_levels = fields.Many2one("education.level", string='Last Education Levels')
last_education_levels = fields.Many2one("education.level", string='Last Education Levels',
compute='_compute_last_education_data', store=True)
nearest_literacy_school = fields.Char(string='The Nearest Literacy School', required=False)
literacy_school_note = fields.Text(string="Literacy School Note", required=False)
classroom = fields.Many2one('education.classroom', string='Classroom')
@ -317,6 +322,27 @@ class FamilyMemberProfile(models.Model):
def _search_benefit_category_id(self, operator, value):
return [('benefit_id.benefit_category_id', operator, value)]
@api.depends('member_education_status_ids',
'member_education_status_ids.education_levels',
'member_education_status_ids.case_study',
'member_education_status_ids.education_start_date')
def _compute_last_education_data(self):
for rec in self:
if rec.member_education_status_ids:
latest_education = rec.member_education_status_ids.sorted(
key=lambda r: (
r.education_start_date or date.min,
r.create_date or datetime.min,
r.id
),
reverse=True
)[:1]
rec.last_education_levels = latest_education.education_levels
rec.case_study = latest_education.case_study
else:
rec.last_education_levels = False
rec.case_study = False
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
if self._context.get('members_domain_force_all'):
@ -672,7 +698,8 @@ class FamilyMemberProfile(models.Model):
)
else:
rec.member_status = 'non_benefit'
reasons.append(_("She has exceeded the maximum age limit of %s years.") % female_benefit_age)
reasons.append(
_("She has exceeded the maximum age limit of %s years.") % female_benefit_age)
if rec.is_work and rec.member_income > max_income_for_benefit and rec.education_status in [
'educated'] and current_education_status_id.case_study == 'continuous':
rec.member_status = 'non_benefit'

View File

@ -1,3 +1,5 @@
from Tools.scripts.pdeps import store
from odoo import fields, models, api, _
import math, random
from odoo.exceptions import UserError, ValidationError
@ -22,10 +24,11 @@ class Visit(models.Model):
], string='Type', default="benefit")
benefit_id = fields.Many2one(
'grant.benefit', string='Family file', domain="[('state', '=', 'second_approve')]")
benefit_name = fields.Char(related="benefit_id.name")
benefit_code = fields.Char(related="benefit_id.code")
sms_phone = fields.Char(string="Contact Phone", related="benefit_id.sms_phone")
researcher_team = fields.Many2one("committees.line", string="Researcher Team", related="benefit_id.researcher_id")
benefit_name = fields.Char(related="benefit_id.name", store=True)
benefit_code = fields.Char(string="Family Code", related="benefit_id.code", store=True)
sms_phone = fields.Char(string="Contact Phone", related="benefit_id.sms_phone", store=True)
researcher_team = fields.Many2one("committees.line", string="Researcher Team", related="benefit_id.researcher_id",
store=True)
researcher_ids = fields.Many2many("hr.employee", string="Researcher", compute="get_researcher_ids", readonly=False)
visit_date = fields.Datetime(string='Visit Date', tracking=True)
description = fields.Char(string='Description')
@ -63,7 +66,6 @@ class Visit(models.Model):
response_count = fields.Integer(compute="_compute_response_count", store=True, string="Responses Count", copy=False)
survey_url = fields.Char(string="Survey URL")
def action_postpone(self):
"""Open wizard to postpone"""
context = dict(self.env.context or {})
@ -208,7 +210,8 @@ class Visit(models.Model):
email_values = {"email_from": self.env.user.company_id.hr_email or self.env.user.company_id.email,
'res_id': None}
template.with_context({'lang': self.env.user.lang}).send_mail(self.id, force_send=True,
raise_exception=False, email_values=email_values)
raise_exception=False,
email_values=email_values)
elif self.benefit_id.contact_type == 'sms':
if not self.benefit_id.sms_phone:
raise UserError(
@ -218,7 +221,9 @@ class Visit(models.Model):
raise UserError(
_("The SMS template 'Visit Location OTP' is missing. Please contact your administrator."))
sms_body = sms_template_id._render_template(sms_template_id.body,self._name,[self.id],post_process=True)[self.id]
sms_body = \
sms_template_id._render_template(sms_template_id.body, self._name, [self.id], post_process=True)[
self.id]
sms_values = {
'number': self.benefit_id.sms_phone,
'body': sms_body,
@ -317,7 +322,8 @@ class Visit(models.Model):
template = self.env.ref('odex_benefit.visit_location_survey_email_template', False)
if not template:
raise UserError(_("The email template 'Visit Location Survey Email' is missing."))
email_values = {"email_from": self.env.user.company_id.hr_email or self.env.user.company_id.email,"res_id": None}
email_values = {"email_from": self.env.user.company_id.hr_email or self.env.user.company_id.email,
"res_id": None}
template.write({'email_to': self.benefit_id.email,
'email_cc': self.env.user.company_id.hr_email or self.env.user.company_id.email, })
template.with_context(
@ -331,7 +337,8 @@ class Visit(models.Model):
if not sms_template:
raise UserError(_("The SMS template 'Visit Location Survey' is missing."))
sms_body = sms_template._render_template(sms_template.body, self._name, [self.id], post_process=True)[self.id]
sms_body = sms_template._render_template(sms_template.body, self._name, [self.id], post_process=True)[
self.id]
sms_values = {
'number': self.benefit_id.sms_phone,
'body': sms_body,

View File

@ -6,13 +6,6 @@
<field name="model">benefit.category</field>
<field name="arch" type="xml">
<form string="Category">
<header>
<button name="action_approve" type="object" class="oe_highlight" string="Approve"
confirm="Are you sure you want to Approve?" states="draft"/>
<button name="action_reject" type="object" string="Rejected"
confirm="Are you sure you want to Reject?" states="draft"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="open_benefits"
@ -23,23 +16,13 @@
<div class="oe_title">
<h1>
<field placeholder="Name" name="name"
class="oe_inline" attrs="{'readonly':[('state','!=','draft')],'required':True}"/>
class="oe_inline" required="1"/>
</h1>
</div>
<group col="4" colspan="2">
<field name="mini_income_amount"/>
<field name="max_income_amount"/>
</group>
<!-- <group col="4" colspan="2">-->
<!-- <field name="gender" attrs="{'readonly':[('state','!=','draft')],'required':True}"/>-->
<!-- <field name="description" attrs="{'readonly':[('state','!=','draft')],'required':True}"/>-->
<!-- </group>-->
<!-- <group col="6" colspan="3">-->
<!-- <field name="age_from" attrs="{'readonly':[('state','!=','draft')],'required':True}"/>-->
<!-- <p>Year</p>-->
<!-- <field name="age_to" attrs="{'readonly':[('state','!=','draft')],'required':True}"/>-->
<!-- <p>Year</p>-->
<!-- </group>-->
<group>
<group>
<field name="is_benefit" string="Is Benefit" widget="boolean_toggle"/>

View File

@ -1280,7 +1280,6 @@
options="{'no_create': True, 'no_create_edit': True}"
groups="!odex_benefit.group_benefit_manager"/>
<field name="mother_location" invisible="1"/>
<field name="education_status"/>
</group>
<group>
<field name="is_work"/>
@ -1289,6 +1288,11 @@
<field name="salary_certificate"
widget="many2many_attachment_preview"
attrs="{'invisible':[('is_work','=',False)]}"/>
<field name="education_status"/>
<field name="last_education_levels"
attrs="{'invisible':[('education_status','!=','educated')]}"/>
<field name="case_study"
attrs="{'invisible':[('education_status','!=','educated')]}"/>
</group>
</group>
<group>
@ -1424,6 +1428,8 @@
<field name="age"/>
<field name="member_location_conf"/>
<field name="education_status"/>
<field name="last_education_levels" optional="hide"/>
<field name="case_study" optional="hide"/>
<field name="member_status" widget="badge"
decoration-success="member_status == 'benefit'"
decoration-danger="member_status == 'non_benefit'"/>

View File

@ -177,7 +177,6 @@
<field name="mother_location" invisible="1"/>
<field name="mother_marital_conf"
attrs="{'invisible':[('relationn_type','not in',('mother','replacement_mother'))]}"/>
<field name="education_status"/>
<field name="benefit_id" attrs="{'readonly': [('state','!=','draft')]}" force_save="1"
required="1"/>
<field name="benefit_code"/>
@ -192,6 +191,12 @@
attrs="{'invisible':[('is_work','=',False)],'required':[('is_work','=',True)],'readonly':[('state','not in',['draft','complete_info'])]}"/>
<field name="salary_certificate" widget="many2many_attachment_preview"
attrs="{'invisible':[('is_work','=',False)],'readonly':[('state','not in',['draft','complete_info'])]}"/>
<field name="education_status"
attrs="{'readonly':[('state','not in',['draft','complete_info'])]}"/>
<field name="last_education_levels"
attrs="{'invisible':[('education_status','!=','educated')]}"/>
<field name="case_study"
attrs="{'invisible':[('education_status','!=','educated')]}"/>
</group>
</group>
<group>
@ -311,7 +316,8 @@
<page string="Attachments">
<field name="attachment_ids" mode="tree" options="{'no_open': True}"
widget="one2many_list" attrs="{'readonly':[('state','not in',['draft','complete_info'])]}">
widget="one2many_list"
attrs="{'readonly':[('state','not in',['draft','complete_info'])]}">
<tree editable="bottom">
<field name="name" string="Attachment Name" force_save="1"
attrs="{'readonly':[('is_default','=',True)]}"/>
@ -349,9 +355,11 @@
<field name="member_status" widget="badge"
decoration-success="member_status == 'benefit'"
decoration-danger="member_status == 'non_benefit'" string="Is Benefit?"/>
<field name="last_education_levels" optional="hide"/>
<field name="case_study" optional="hide"/>
<field name="is_excluded_suspension"/>
<field name="age"/>
<field name="benefit_id"/>
<field name="benefit_id" optional="hide"/>
<field name="branch_custom_id"/>
<field name="state" widget="badge" decoration-success="state in ['first_approve', 'second_approve']"
decoration-muted="state in ['draft','new']"

View File

@ -97,6 +97,7 @@
attrs="{'invisible':[('type','not in',['seasonal_services','services'])]}">
<field name="service_requests_ids" readonly="1">
<tree>
<field name="family_code"/>
<field name="family_id"/>
<field name="benefit_type" optional="hidden"/>
<field name="member_id" optional="hidden"/>

View File

@ -9,6 +9,7 @@
<field name="color"/>
<field name="visit_date"/>
<field name="visit_types"/>
<field name="benefit_code"/>
<field name="benefit_id"/>
<field name="researcher_team"/>
<field name="state"/>
@ -47,6 +48,9 @@
<div>
<field name="visit_types"/>
</div>
<div>
<field name="benefit_code"/>
</div>
<div>
<field name="benefit_id"/>
</div>
@ -158,6 +162,7 @@
]
}"
required="1"/>
<field name="benefit_code"/>
<field name="sms_phone"/>
<field name="researcher_team" required="1"/>
<field name="researcher_ids" invisible="1" widget="many2many_tags"
@ -194,6 +199,7 @@
<field name="arch" type="xml">
<tree string="Visits">
<field name="name"/>
<field name="benefit_code"/>
<field name="benefit_id"/>
<field name="researcher_team"/>
<field name="visit_date"/>