[IMP] odex_benefit: imp benefit

This commit is contained in:
younes 2025-11-06 15:57:56 +01:00
parent 317311c4c1
commit c001a77f85
9 changed files with 564 additions and 419 deletions

View File

@ -8,8 +8,7 @@
<field name="binding_model_id" ref="odex_benefit.model_service_request"/>
<field name="state">code</field>
<field name="code">
if record.project_create == False:
action = records.action_open_exchange_order_wizard()
action = records.action_create_payment_order()
</field>
</record>
@ -19,7 +18,7 @@
<field name="binding_model_id" ref="odex_benefit.model_seasonal_service"/>
<field name="state">code</field>
<field name="code">
action = records.action_open_exchange_order_wizard()
action = records.action_create_payment_order()
</field>
</record>

View File

@ -14283,9 +14283,7 @@ msgstr "المدينة"
#. module: odex_benefit
#: model:ir.model.fields.selection,name:odex_benefit.selection__payment_orders__state__accounting_approve
#: model:ir.model.fields.selection,name:odex_benefit.selection__seasonal_service__state__accounting_approve
#: model_terms:ir.ui.view,arch_db:odex_benefit.payment_orders_form
#: model_terms:ir.ui.view,arch_db:odex_benefit.seasonal_service_form_view
#: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_form
#: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_search
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_payment_ordres_search
@ -14312,16 +14310,6 @@ msgstr "بانتظار استلام"
msgid "Family Received Device"
msgstr "تم"
#. module: odex_benefit
#: model_terms:ir.ui.view,arch_db:odex_benefit.seasonal_service_form_view
msgid "Approve Beneficiary Services"
msgstr "إعتماد خدمات المستفيدين"
#. module: odex_benefit
#: model:ir.model.fields.selection,name:odex_benefit.selection__seasonal_service__state__approval_of_beneficiary_services
msgid "Approval Of Beneficiary Services"
msgstr "إعتماد خدمات المستفيدين"
#. module: odex_benefit
#: model:ir.actions.act_window,name:odex_benefit.action_exchange_order_wizard
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_exchange_order_wizard_form
@ -14472,7 +14460,7 @@ msgstr "مسودة"
#: code:addons/odex_benefit/models/seasonal_service.py:0
#, python-format
msgid "All selected requests should be in Accounting Approve state"
msgstr "جميع الطلبات يجب ان تكون في حالة إعتماد الإدارة المالية"
msgstr "جميع الطلبات يجب ان تكون في حالة بانتظار الإدارة المالية"
#. module: odex_benefit
#: code:addons/odex_benefit/models/seasonal_service.py:0

View File

@ -1,5 +1,6 @@
from odoo import fields, models, api, _
from stdnum.au.acn import to_abn
from odoo.exceptions import ValidationError
class PaymentOrders(models.Model):
@ -7,47 +8,94 @@ class PaymentOrders(models.Model):
_description = "Payment Orders"
_inherit = ['mail.thread', 'mail.activity.mixin']
def _default_journal(self):
setting = self.env['family.validation.setting'].search([], limit=1)
return setting.journal_id.id if setting and setting.journal_id else False
name = fields.Char(string="Code", copy=False, readonly=True, default=lambda x: _('New'))
ref_num = fields.Many2one('seasonal.service',string='Ref. Number',compute='_compute_ref_num')
payment_order_date = fields.Datetime(string="Payment Order Date",default=fields.Datetime.now)
accountant_id = fields.Many2one('res.users',string='Accountant')
payment_order_description = fields.Many2one('services.settings',
string='Payment Order Description',
compute='_compute_service_type_id',
inverse='_inverse_service_type_id',
store=True)
service_requests_ids = fields.One2many('service.request', 'payment_order_id', string ='Service Requests')
seasonal_requests_ids = fields.One2many('seasonal.service', 'payment_order_id', string ='Seasonal Requests')
family_seasonal_requests_ids = fields.One2many('seasonal.grant.benefit', 'payment_order_id', string ='Seasonal Requests')
ref_num = fields.Many2one('seasonal.service', string='Ref. Number', compute='_compute_ref_num')
payment_order_date = fields.Datetime(string="Payment Order Date", default=fields.Datetime.now)
accountant_id = fields.Many2one('res.users', string='Accountant')
payment_order_description = fields.Many2one('services.settings',
string='Payment Order Description',
compute='_compute_service_type_id',
inverse='_inverse_service_type_id',
store=True)
service_requests_ids = fields.One2many('service.request', 'payment_order_id', string='Service Requests')
seasonal_requests_ids = fields.One2many('seasonal.service', 'payment_order_id', string='Seasonal Requests')
family_seasonal_requests_ids = fields.One2many('seasonal.grant.benefit', 'payment_order_id',
string='Seasonal Requests')
total_moves = fields.Integer(string="Total Move Lines", compute='_get_total_moves')
state = fields.Selection(string='Status', selection=[('draft', 'Draft'),('accountant_approve', 'accountant Approve'),('department_manager_approve', 'Department Manager Approve')
,('accounting_approve', 'Accounting Approve'),('general_manager_approve', 'General Manager Approve'),('refused', 'Refused')],default = 'draft',tracking=True)
state = fields.Selection(string='Status',
selection=[('draft', 'Draft'),
('waiting_head', 'Waiting for Head of Expenses Department'),
('waiting_finance', 'Waiting for Financial Manager'),
('waiting_gm', 'Waiting for General Manager'),
('done', 'Done'),
('refused', 'Refused')], default='draft', tracking=True)
is_seasonal = fields.Boolean(string='Is Seasonal Service?')
journal_id = fields.Many2one(comodel_name='account.journal', string="Journal", copy=False,
domain="[('type','in',['cash','bank'])]", default=_default_journal)
def action_manager_approval(self):
for rec in self:
if self.env.user != rec.accountant_id:
raise ValidationError(_("Only the assigned accountant can approve this payment order."))
rec.state = 'waiting_head'
def action_head_approval(self):
for rec in self:
rec.state = 'waiting_finance'
def action_finance_approval(self):
for rec in self:
account_move = self.env['account.move'].create(
{
'ref': f'{rec.payment_order_description}/{rec.ref_num}',
'journal_id': rec.journal_id.id,
'payment_order_id': rec.id,
'line_ids': rec.get_lines()
}
)
rec.state = 'waiting_gm'
def action_gm_approval(self):
for rec in self:
rec.state = 'done'
def action_refuse(self):
for rec in self:
rec.state = 'refused'
def action_reset_to_draft(self):
for rec in self:
rec.state = 'draft'
# Compute method
@api.depends('seasonal_requests_ids')
def _compute_ref_num(self):
for record in self:
record.ref_num = record.seasonal_requests_ids[0] if record.seasonal_requests_ids else False
for record in self:
record.ref_num = record.seasonal_requests_ids[0] if record.seasonal_requests_ids else False
@api.depends('seasonal_requests_ids.service_type_id')
def _compute_service_type_id(self):
for record in self:
# Take value from first seasonal_requests record (if exists)
record.payment_order_description = record.seasonal_requests_ids[:1].service_type_id
for record in self:
# Take value from first seasonal_requests record (if exists)
record.payment_order_description = record.seasonal_requests_ids[:1].service_type_id
# Inverse method
# Inverse method
def _inverse_service_type_id(self):
for record in self:
if record.seasonal_requests_ids:
# Update first related record
record.seasonal_requests_ids[0].service_type_id = record.payment_order_description
else:
# Create new seasonal_requests record if none exists
self.env['seasonal.service'].create({
'payment_order_id': record.id,
'service_type_id': record.payment_order_description.id,
# Add other required fields here if necessary
})
for record in self:
if record.seasonal_requests_ids:
# Update first related record
record.seasonal_requests_ids[0].service_type_id = record.payment_order_description
else:
# Create new seasonal_requests record if none exists
self.env['seasonal.service'].create({
'payment_order_id': record.id,
'service_type_id': record.payment_order_description.id,
# Add other required fields here if necessary
})
@api.model
def create(self, vals):
@ -58,7 +106,8 @@ class PaymentOrders(models.Model):
@api.model
def search(self, args, offset=0, limit=None, order=None, count=False):
if self.env.user and self.env.user.id and self.env.user.has_group("odex_benefit.group_benefit_payment_accountant_accept"):
if self.env.user and self.env.user.id and self.env.user.has_group(
"odex_benefit.group_benefit_payment_accountant_accept"):
args += [('accountant_id', '=', self.env.user.id)]
return super(PaymentOrders, self).search(args, offset, limit, order, count)
@ -67,33 +116,6 @@ class PaymentOrders(models.Model):
rec.total_moves = self.env['account.move'].search_count([
('payment_order_id', '=', rec.id), ('move_type', '!=', 'in_invoice')])
def action_accountant_approve(self):
for rec in self:
rec.state = 'accountant_approve'
def action_department_manager_approve(self):
for rec in self:
rec.state = 'department_manager_approve'
def action_accounting_approve(self):
for rec in self:
rec.state = 'accounting_approve'
def action_general_manager_approve(self):
for rec in self:
rec.state = 'general_manager_approve'
x = self.env['account.move'].create(
{
'ref': f'{rec.payment_order_description}/{rec.ref_num}',
'journal_id': self.env["family.validation.setting"].search([], limit=1).journal_id.id,
'payment_order_id': rec.id,
'line_ids' : rec.get_lines()
}
)
def action_refuse(self):
for rec in self:
rec.state = 'refused'
def action_open_related_move_records(self):
""" Opens a tree view with related records filtered by a dynamic domain """
moves = self.env['account.move'].search([
@ -106,6 +128,7 @@ class PaymentOrders(models.Model):
'view_mode': 'tree,form',
'domain': [('id', 'in', moves)],
}
def get_lines(self):
lines = []
total_credit = 0
@ -113,25 +136,13 @@ class PaymentOrders(models.Model):
for request in self.service_requests_ids:
lines.append(
{
'account_id': request.account_id.id,
'partner_id': request.family_id.partner_id.id,
# 'branch_id' : request.branch_custom_id.id,
'analytic_account_id': request.branch_custom_id.branch.analytic_account_id.id,
'debit': request.aid_amount,
'name': f'{"Family code"}{request.family_id.code}-{request.description}-{request.payment_order_id.name}-{request.payment_order_id.ref_num}',
}
)
total_credit += request.aid_amount
if self.family_seasonal_requests_ids:
for request in self.family_seasonal_requests_ids:
lines.append(
{
'benefit_family_id': request.family_id.id,
'account_id': request.account_id.id,
'partner_id': request.family_id.partner_id.id,
# 'branch_id' : request.branch_custom_id.id,
'analytic_account_id': request.branch_custom_id.branch.analytic_account_id.id,
'debit': request.aid_amount,
'name': f'{"Family code"}{request.family_id.code}-{request.payment_order_id.name}-{request.payment_order_id.ref_num}',
'debit': request.requested_service_amount,
'credit': 0.0,
}
)
total_credit += request.aid_amount
@ -139,19 +150,7 @@ class PaymentOrders(models.Model):
lines.append({
'account_id': self.env["family.validation.setting"].search([], limit=1).account_id.id,
'name': f'{self.name}-{self.ref_num}',
'credit' : total_credit,
'credit': total_credit,
'debit': 0.0,
})
return [(0, 0, line) for line in lines]
# def create_entry(self, journal_id, lines):
# """Create an account move entry"""
# move_vals = {
# 'journal_id': journal_id,
# 'date': self.date,
# 'ref': self.name,
# 'family_confirm_id': self.id,
# 'benefit_family_ids': [(6, 0, self.family_ids.ids)],
# 'line_ids': lines,
# }
# move_id = self.env['account.move'].create(move_vals)
# move_id.action_post()
# return True

View File

@ -1,3 +1,5 @@
from asyncore import write
from odoo import fields, models, api, _
from odoo.exceptions import UserError, ValidationError
from datetime import timedelta
@ -24,20 +26,25 @@ class SeasonalService(models.Model):
string='Family Category',
compute='_compute_family_category_ids', )
family_ids = fields.One2many('seasonal.grant.benefit', 'seasonal_service_id', string='Family')
aid_amount = fields.Float(string="Aid Amount", compute="_compute_aid_amount", store=True)
aid_amount = fields.Float(string="Aid Amount", compute="_compute_amounts", store=True, readonly=False)
benefit_member_count = fields.Integer(string="Benefit Member count", compute="compute_family_benefit", store=True)
family_count = fields.Integer(string="Family count", compute="compute_family_benefit", store=True)
family_disbursement_total_amount = fields.Float(string="Total Family Disbursement Amount",
compute="_compute_family_disbursement", store=True)
payment_order_id = fields.Many2one('payment.orders', string='Payment Order', copy=False)
payment_order_id = fields.Many2one('payment.orders', string='Payment Order', copy=False, ondelete="set null")
state = fields.Selection(selection=[
('draft', 'Draft'),
('calculated', 'Calculated'),
('approval_of_beneficiary_services', 'Approval of beneficiary services'),
('gm_assistant', 'Waiting Assistant General Manager'),
('accounting_approve', 'Accounting Approve'),
('waiting_receive', 'Waiting for Receive'),
('done', 'Done'),
], string='state', default='draft', tracking=True, copy=False)
is_payment_order_done = fields.Boolean(string='Is Payment Order Done?', copy=False)
payment_order_state = fields.Selection(string='Payment Order State', selection=[
('none', 'None'),
('waiting', 'Waiting Payment'),
('done', 'Done Payment'), ], copy=False, compute="_compute_payment_order_state", store=True)
account_id = fields.Many2one('account.account', string='Expenses Account', related="service_type_id.account_id")
service_requests_ids = fields.One2many('service.request', 'seasonal_service_id', string='Service Requests')
benefit_ids = fields.Many2many(comodel_name='grant.benefit', relation='benefit_grant_seasonal_service_rel',
@ -50,7 +57,21 @@ class SeasonalService(models.Model):
string="Eligible Families")
service_delivery_method = fields.Selection(selection=[
('cash', 'Cash'),
('in_kind', 'In kind'),], string='Service Delivery Method', default='cash')
('in_kind', 'In kind'), ], string='Service Delivery Method', default='cash')
is_in_kind = fields.Boolean(string="In Kind", related="service_type_id.in_kind")
company_id = fields.Many2one('res.company', string="Company", default=lambda self: self.env.user.company_id)
currency_id = fields.Many2one('res.currency', string="Currency", related='company_id.currency_id')
@api.depends('payment_order_id', 'payment_order_id.state')
def _compute_payment_order_state(self):
for rec in self:
payment_order_state = 'none'
if rec.payment_order_state:
if rec.payment_order_id.state == "done":
payment_order_state = "done"
else:
payment_order_state = "waiting"
rec.payment_order_state = payment_order_state
@api.depends('branch_ids', 'family_category_ids')
def _compute_domain_ids(self):
@ -94,6 +115,7 @@ class SeasonalService(models.Model):
self.member_ids = [(5, 0, 0)]
def action_open_exchange_order_wizard(self):
ids = []
for rec in self:
ids.append(rec.id)
@ -114,92 +136,135 @@ class SeasonalService(models.Model):
}
}
@api.depends('family_ids', 'family_ids.family_id')
@api.depends('service_requests_ids')
def compute_family_benefit(self):
for record in self:
record.family_count = len(record.family_ids)
if record.service_type_id and record.service_type_id.service_type == 'eid_gift':
record.benefit_member_count = len(record.family_ids.family_id.member_ids.filtered(
lambda x: x.member_status == 'benefit' and x.age <= self.service_type_id.max_age))
else:
record.benefit_member_count = sum(record.family_ids.family_id.mapped('benefit_member_count'))
families = record.service_requests_ids.mapped('family_id')
family_count = len(families)
member_count = sum(record.service_requests_ids.mapped('service_benefit_count'))
record.family_count = family_count
record.benefit_member_count = member_count
@api.depends('service_type_id')
def _compute_aid_amount(self):
""" Compute Aid Amount based on service_type_id """
def _compute_amounts(self):
for record in self:
aid_amount = 0.0
if record.service_type_id:
if record.service_type_id.service_type == 'ramadan_basket':
aid_amount = record.service_type_id.max_amount
elif record.service_type_id.service_type == 'eid_gift':
aid_amount = record.service_type_id.max_amount
elif record.service_type_id.service_type == 'winter_clothing':
aid_amount = record.service_type_id.max_amount
record.write({'aid_amount': aid_amount})
if record.service_type_id and record.service_delivery_method == 'cash':
record.aid_amount = record.service_type_id.max_amount
else:
record.aid_amount = 0
@api.depends('service_type_id', 'aid_amount', 'benefit_member_count', 'family_count')
@api.depends('service_requests_ids')
def _compute_family_disbursement(self):
""" Compute total disbursement amount based on service type """
for record in self:
if record.service_type_id:
if record.service_type_id.service_type == 'ramadan_basket':
record.family_disbursement_total_amount = record.aid_amount * record.family_count
elif record.service_type_id.service_type == 'eid_gift':
record.family_disbursement_total_amount = record.aid_amount * record.benefit_member_count
elif record.service_type_id.service_type == 'winter_clothing':
record.family_disbursement_total_amount = record.aid_amount * record.benefit_member_count
if record.service_requests_ids:
if record.service_delivery_method == "cash":
record.family_disbursement_total_amount = sum(
record.service_requests_ids.mapped('requested_service_amount'))
else:
record.family_disbursement_total_amount = 0.0
record.family_disbursement_total_amount = sum(
record.service_requests_ids.mapped('service_qty'))
else:
record.family_disbursement_total_amount = 0.0
def action_approval_of_beneficiary_services(self):
def action_first_approval(self):
for rec in self:
if not rec.service_requests_ids:
raise UserError(_("You must add at least one service request."))
if rec.service_type_id.needs_beneficiary_manager_approval:
rec.state = 'gm_assistant'
rec.service_requests_ids.write({'state': 'gm_assistant'})
elif rec.service_delivery_method == "cash":
# rec.action_create_payment_order()
rec.state = "accounting_approve"
rec.service_requests_ids.write({'state': 'accounting_approve'})
elif rec.service_delivery_method == "in_kind":
rec.state = 'waiting_receive'
rec.service_requests_ids.write({'state': 'send_request_to_supplier'})
rec.service_requests_ids.write({'state': 'accounting_approve'})
rec.state = 'approval_of_beneficiary_services'
def action_approval_of_gm_assistant(self):
for rec in self:
if rec.service_delivery_method == "cash":
# rec.action_create_payment_order()
rec.state = "accounting_approve"
rec.service_requests_ids.write({'state': 'accounting_approve'})
elif rec.service_delivery_method == "in_kind":
rec.state = 'waiting_receive'
rec.service_requests_ids.write({'state': 'send_request_to_supplier'})
def action_accounting_approve(self):
for rec in self:
rec.service_requests_ids.write({'state': 'send_request_to_supplier'})
rec.state = 'accounting_approve'
rec.state = 'waiting_receive'
def action_create_payment_order(self):
for rec in self:
self.env['payment.orders'].create({
'state': 'draft',
'accountant_id': rec.service_type_id.accountant_id.id,
'seasonal_requests_ids': rec.ids,
'service_requests_ids': rec.service_requests_ids.ids,
'is_seasonal': True,
})
# rec.payment_order_id = payment_order.id
rec.is_payment_order_done = True
def action_calculate(self):
# if self.service_type_id and self.service_type_id.service_type == 'eid_gift':
# family_ids = self.env['family.member'].search(
# [('age', '<=', self.service_type_id.eid_gift_max_age),('member_status','=','benefit')]).benefit_id
# domain.append(('id', 'in', family_ids.ids)) # Append the filtered family IDs to domain
Service = self.env['service.request']
vals = []
for rec in self:
if not rec.benefit_ids:
raise UserError(_("You must add at least one family."))
rec.service_requests_ids.unlink()
if rec.benefit_type == "family":
for benefit in rec.benefit_ids:
service_request = Service.create(
{'family_id': benefit.id, 'service_cat': rec.service_type_id.id, 'seasonal_service_id': rec.id,
'benefit_type': rec.benefit_type})
service_request.onchange_requested_service_amount()
if rec.service_delivery_method == "cash":
service_request.requested_service_amount = service_request.service_max_amount
else:
service_request.requested_service_amount = 0
service_request.is_in_kind = True
else:
pass
rec._generate_service_requests()
rec.state = 'calculated'
def action_recalculate(self):
for rec in self:
rec.service_requests_ids.unlink()
rec._generate_service_requests()
def _generate_service_requests(self):
Service = self.env['service.request']
for rec in self:
if not rec.benefit_ids:
raise UserError(_("You must add at least one family."))
if rec.benefit_type == "family":
for benefit in rec.benefit_ids:
service_request = Service.create({
'family_id': benefit.id,
'service_cat': rec.service_type_id.id,
'seasonal_service_id': rec.id,
'benefit_type': rec.benefit_type,
})
service_request.onchange_requested_service_amount()
if rec.service_delivery_method == "cash":
service_request.requested_service_amount = service_request.service_max_amount
else:
service_request.requested_service_amount = 0
service_request.is_in_kind = True
service_request.service_qty = rec.aid_amount
else:
if not rec.member_ids:
raise UserError(_("You must add at least one member."))
for member in rec.member_ids:
if not member.benefit_id:
raise UserError(_("Member %s has no related family (benefit).") % member.name)
service_request = Service.create({
'family_id': member.benefit_id.id,
'member_id': member.id,
'service_cat': rec.service_type_id.id,
'seasonal_service_id': rec.id,
'benefit_type': rec.benefit_type,
})
service_request.onchange_requested_service_amount()
if rec.service_delivery_method == "cash":
service_request.requested_service_amount = service_request.service_max_amount
else:
service_request.requested_service_amount = 0
service_request.is_in_kind = True
service_request.service_qty = rec.aid_amount
def action_reset_to_draft(self):
for rec in self:

View File

@ -3,41 +3,53 @@ from odoo.exceptions import UserError, ValidationError
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
class ServiceRequest(models.Model):
_name = 'service.request'
_inherit = ['mail.thread', 'mail.activity.mixin']
name = fields.Char(string='Reference', required=True, copy=False, readonly=True, index=True,default=lambda self: _('New'))
benefit_type = fields.Selection(string='Benefit Type',selection=[('family', 'Family'),('member', 'Member')])
date = fields.Datetime(string='Request Date',default=fields.Datetime.now)
name = fields.Char(string='Reference', required=True, copy=False, readonly=True, index=True,
default=lambda self: _('New'))
benefit_type = fields.Selection(string='Benefit Type', selection=[('family', 'Family'), ('member', 'Member')])
date = fields.Datetime(string='Request Date', default=fields.Datetime.now)
marriage_contract_date = fields.Date(string="Marriage Contract Date")
family_id = fields.Many2one('grant.benefit',string='Family',domain="['|',('state','=','second_approve'),'&',('state','in',['waiting_approve','first_approve']),('action_type','=','suspended')]")
researcher_id = fields.Many2one("committees.line", string="Researcher", related="family_id.researcher_id",store=True)
family_category = fields.Many2one('benefit.category',string='Family Category',related='family_id.benefit_category_id')
family_id = fields.Many2one('grant.benefit', string='Family',
domain="['|',('state','=','second_approve'),'&',('state','in',['waiting_approve','first_approve']),('action_type','=','suspended')]")
researcher_id = fields.Many2one("committees.line", string="Researcher", related="family_id.researcher_id",
store=True)
family_category = fields.Many2one('benefit.category', string='Family Category',
related='family_id.benefit_category_id')
benefit_member_count = fields.Integer(string="Benefit Member count", related='family_id.benefit_member_count')
branch_custom_id = fields.Many2one('branch.settings', string="Branch",related='family_id.branch_custom_id',store=True)
member_id = fields.Many2one('family.member',domain="[('benefit_id','=',family_id)]",string='Member')
branch_custom_id = fields.Many2one('branch.settings', string="Branch", related='family_id.branch_custom_id',
store=True)
member_id = fields.Many2one('family.member', domain="[('benefit_id','=',family_id)]", string='Member')
description = fields.Char(string='Description')
need_status = fields.Selection(string='Need Status',selection=[('urgent', 'urgent'),('not_urgent', 'Not urgent')])
main_service_category = fields.Many2one('services.settings',domain="[('service_type','=','main_service')]",string="Main Service Category")
sub_service_category = fields.Many2one('services.settings',domain="[('service_type','=','main_service'),('service_type','=',False),('parent_service','=',main_service_category)]",string='Sub Service Category')
service_cat = fields.Many2one('services.settings',string='Service Cat.')
available_service_cats = fields.Many2many('services.settings', compute='_compute_available_service_cats', store=True)
service_attach = fields.Many2many('ir.attachment', 'rel_service_attachment_service_request', 'service_request_id','attachment_id', string='Service Attachment')
need_status = fields.Selection(string='Need Status', selection=[('urgent', 'urgent'), ('not_urgent', 'Not urgent')])
main_service_category = fields.Many2one('services.settings', domain="[('service_type','=','main_service')]",
string="Main Service Category")
sub_service_category = fields.Many2one('services.settings',
domain="[('service_type','=','main_service'),('service_type','=',False),('parent_service','=',main_service_category)]",
string='Sub Service Category')
service_cat = fields.Many2one('services.settings', string='Service Cat.')
available_service_cats = fields.Many2many('services.settings', compute='_compute_available_service_cats',
store=True)
service_attach = fields.Many2many('ir.attachment', 'rel_service_attachment_service_request', 'service_request_id',
'attachment_id', string='Service Attachment')
requested_service_amount = fields.Float(string="Requested Service Amount")
#yearly Estimated Rent Amount
estimated_rent_amount = fields.Float(string="Estimated Rent Amount",compute="_get_estimated_rent_amount")
#The value of payment by payment method(yearly-half-quartarly)
estimated_rent_amount_payment = fields.Float(string="Estimated Rent Amount Payment",compute="_get_estimated_rent_amount_payment")
paid_rent_amount = fields.Float(string="Paid Rent Amount",compute="_get_paid_rent_amount")
service_type = fields.Selection([('rent', 'Rent')],string='Service Type',related='service_cat.service_type')
max_limit_period = fields.Selection(string='Maximum Limit Period',related='service_cat.max_limit_period')
# yearly Estimated Rent Amount
estimated_rent_amount = fields.Float(string="Estimated Rent Amount", compute="_get_estimated_rent_amount")
# The value of payment by payment method(yearly-half-quartarly)
estimated_rent_amount_payment = fields.Float(string="Estimated Rent Amount Payment",
compute="_get_estimated_rent_amount_payment")
paid_rent_amount = fields.Float(string="Paid Rent Amount", compute="_get_paid_rent_amount")
service_type = fields.Selection([('rent', 'Rent')], string='Service Type', related='service_cat.service_type')
max_limit_period = fields.Selection(string='Maximum Limit Period', related='service_cat.max_limit_period')
# is_alternative_housing = fields.Boolean(string='Is Alternative Housing?')
rent_contract_number = fields.Char(string="Rent Contract Number",compute='_compute_rent_details',store=True)
rent_start_date = fields.Date(string='Rent Start Date',compute='_compute_rent_details',store=True)
rent_end_date = fields.Date(string='Rent End Date' ,compute='_compute_rent_details',store=True)
rent_amount = fields.Float(string='Rent Amount',compute='_compute_rent_details',store=True)
rent_amount_payment = fields.Float(string='Rent Amount Payment',compute ='_get_rent_amount_payment')
rent_contract_number = fields.Char(string="Rent Contract Number", compute='_compute_rent_details', store=True)
rent_start_date = fields.Date(string='Rent Start Date', compute='_compute_rent_details', store=True)
rent_end_date = fields.Date(string='Rent End Date', compute='_compute_rent_details', store=True)
rent_amount = fields.Float(string='Rent Amount', compute='_compute_rent_details', store=True)
rent_amount_payment = fields.Float(string='Rent Amount Payment', compute='_get_rent_amount_payment')
payment_type = fields.Selection(
[
('1', 'Yearly'),
@ -49,12 +61,14 @@ class ServiceRequest(models.Model):
compute='_compute_rent_details',
store=True
)
rent_attachment = fields.Many2many('ir.attachment', 'rel_rent_attachment_service_request', 'service_request_id', 'attachment_id',string='Rent Attachment',compute='_compute_rent_details',store=True)
rent_attachment = fields.Many2many('ir.attachment', 'rel_rent_attachment_service_request', 'service_request_id',
'attachment_id', string='Rent Attachment', compute='_compute_rent_details',
store=True)
rent_payment_date = fields.Date(string='Rent Payment Date')
rent_payment_date_exception = fields.Boolean(string='Rent Payment Date Exception?')
start = fields.Date(string="Start Date")
end = fields.Date(string='End Date')
#New Rent Contract
# New Rent Contract
new_rent_contract = fields.Boolean(string='New Rent Contract?')
new_start = fields.Date(string="Start Date")
new_end = fields.Date(string='End Date')
@ -62,26 +76,28 @@ class ServiceRequest(models.Model):
new_rent_start_date = fields.Date(string='Rent Start Date')
new_rent_end_date = fields.Date(string='Rent End Date')
new_rent_amount = fields.Float(string='Rent Amount')
new_rent_amount_payment = fields.Float(string='New Rent Amount Payment',compute='_get_new_rent_amount_payment')
new_rent_amount_payment = fields.Float(string='New Rent Amount Payment', compute='_get_new_rent_amount_payment')
new_payment_type = fields.Selection([
('1', 'Yearly'),
('2', 'Half-yearly'),
('4', 'Quarterly'),
('5', 'Monthly')
],
('1', 'Yearly'),
('2', 'Half-yearly'),
('4', 'Quarterly'),
('5', 'Monthly')
],
string='Payment Type'
)
new_rent_attachment = fields.Many2many('ir.attachment', 'rel_rent_attachment_service_request', 'service_request_id',
'attachment_id', string='Rent Attachment')
'attachment_id', string='Rent Attachment')
new_rent_payment_date = fields.Date(string='Rent Payment Date')
new_rent_payment_date_exception = fields.Boolean(string='Rent Payment Date Exception?')
# Rent details for member
member_rent_contract_number = fields.Char(string="Rent Contract Number")
member_rent_start_date = fields.Date(string='Rent Start Date')
member_rent_end_date = fields.Date(string='Rent End Date')
member_rent_attachment = fields.Many2many('ir.attachment', 'rel_member_rent_attachment_service_request', 'service_request_id',
'attachment_id', string='Rent Attachment')
added_amount_if_mother_dead = fields.Float(string="Added Amount (If mother dead)",compute="_get_added_amount_if_mother_dead")
member_rent_attachment = fields.Many2many('ir.attachment', 'rel_member_rent_attachment_service_request',
'service_request_id',
'attachment_id', string='Rent Attachment')
added_amount_if_mother_dead = fields.Float(string="Added Amount (If mother dead)",
compute="_get_added_amount_if_mother_dead")
attachment_lines = fields.One2many(
'service.attachments.settings',
'service_request_id',
@ -95,28 +111,34 @@ class ServiceRequest(models.Model):
string='Expenses Account',
compute="_compute_account_id"
)
device_account_id = fields.Many2one('account.account',string='Expenses Account',related='device_id.account_id')
accountant_id = fields.Many2one('res.users',string='Accountant',related='service_cat.accountant_id',readonly=False)
service_producer_id = fields.Many2one('res.partner',string='Service Producer',related='service_cat.service_producer_id')
is_service_producer = fields.Boolean(string='Is Service Producer?',related='service_cat.is_service_producer')
device_account_id = fields.Many2one('account.account', string='Expenses Account', related='device_id.account_id')
accountant_id = fields.Many2one('res.users', string='Accountant', related='service_cat.accountant_id',
readonly=False)
service_producer_id = fields.Many2one('res.partner', string='Service Producer',
related='service_cat.service_producer_id')
is_service_producer = fields.Boolean(string='Is Service Producer?', related='service_cat.is_service_producer')
# maintenance_items_id = fields.Many2one('home.maintenance.lines', string="Maintenance Items")
maintenance_items_ids = fields.One2many('home.maintenance.items','service_request_id', string="Maintenance Items",)
payment_order_id = fields.Many2one('payment.orders',string='Payment Order')
maintenance_items_ids = fields.One2many('home.maintenance.items', 'service_request_id',
string="Maintenance Items", )
payment_order_id = fields.Many2one('payment.orders', string='Payment Order', ondelete="set null")
is_payment_order_done = fields.Boolean(string='Is Payment Order Done?')
aid_amount = fields.Float(string='Aid Amount',compute='_get_aid_amount')
#Fields for alternative house
aid_amount = fields.Float(string='Aid Amount', compute='_get_aid_amount')
# Fields for alternative house
providing_alternative_housing_based_rent = fields.Boolean(string='Providing alternative housing based on rent')
rent_for_alternative_housing = fields.Many2one('services.settings',compute='_get_rent_for_alternative_housing')
#Fields for electrical_devices service
device_id = fields.Many2one('electrical.devices',string='Device',domain="[('min_count_member','<=',benefit_member_count),('max_count_member','>=',benefit_member_count)]")
rent_for_alternative_housing = fields.Many2one('services.settings', compute='_get_rent_for_alternative_housing')
# Fields for electrical_devices service
device_id = fields.Many2one('electrical.devices', string='Device',
domain="[('min_count_member','<=',benefit_member_count),('max_count_member','>=',benefit_member_count)]")
vendor_bill = fields.Many2one('account.move')
requested_quantity = fields.Integer(string='Requested Quantity')
exception_or_steal = fields.Boolean(string='Exception Or Steal?')
exception_or_steal_attach = fields.Many2many('ir.attachment', 'rel_exception_or_steal_attachment_service_request', 'exception_or_steal_id','attachment_id', string='Exception or steal Attachment')
#Home furnishing Exception
exception_or_steal_attach = fields.Many2many('ir.attachment', 'rel_exception_or_steal_attachment_service_request',
'exception_or_steal_id', 'attachment_id',
string='Exception or steal Attachment')
# Home furnishing Exception
home_furnishing_exception = fields.Boolean(string='Exception(Fire Or Steal or Natural disaster)')
furnishing_items_ids = fields.One2many('home.furnishing.items','service_request_id', string="Furnishing Items")
#Transportation insurance
furnishing_items_ids = fields.One2many('home.furnishing.items', 'service_request_id', string="Furnishing Items")
# Transportation insurance
# service_reason = fields.Selection(selection=[
# ('government_transportation', 'Government Transportation'),
# ('universities_training_institutes_transportation', 'Universities Training Institutes Transportation'),
@ -129,7 +151,7 @@ class ServiceRequest(models.Model):
# max_hospitals_transportation_amount = fields.Float(string='Max Hospitals Transportation Amount')
# max_programs_transportation_amount = fields.Float(string='Max Programs Transportation Amount')
max_amount = fields.Float(string='Max Transportation Amount')
requests_counts = fields.Integer(string='Requests Counts',default = 1)
requests_counts = fields.Integer(string='Requests Counts', default=1)
# Marriage
member_age = fields.Integer(string="Member Age", related="member_id.age")
member_payroll = fields.Float(string="Member Payroll", related="member_id.member_income")
@ -137,51 +159,53 @@ class ServiceRequest(models.Model):
('yes', 'Yes'),
('no', 'No'),
], string='Has Marriage Course')
service_benefit_count = fields.Integer(string='Service Benefit Count',compute="_compute_service_benefit_count")
#Buy home
service_benefit_count = fields.Integer(string='Service Benefit Count', compute="_compute_service_benefit_count")
# Buy home
amount_for_buy_home_for_member_count = fields.Float(string="Amount For Buy Home for member count")
home_age = fields.Integer(string='Home Age')
required_attach = fields.Boolean(string='Required Attach',related='service_cat.required_attach')
state = fields.Selection( selection = [
('draft', 'Draft'),
('researcher', 'Researcher'),
('waiting_approve', 'Waiting for Operation Manager'),
('first_approve', 'Waiting for Branch Manager'),
('family_services_manager', 'Waiting Family Services Manager'),
('legal_department', 'Waiting Legal Department'),
('projects_department', 'Waiting Projects Department'),
('gm_assistant', 'Waiting Assistant General Manager'),
('accounting_approve', 'Accounting Approve'),
('approval_of_beneficiary_services', 'Approval of beneficiary services'),
('send_request_to_supplier', 'Send Request To Supplier'),
('family_received_device', 'Family Received Device'),
('refused', 'Refused')
], string='state',default='draft', tracking=True, group_expand='_expand_states')
#dynamic_state = fields.Selection(selection=[],string="State",default='draft',tracking=True,)
required_attach = fields.Boolean(string='Required Attach', related='service_cat.required_attach')
state = fields.Selection(selection=[
('draft', 'Draft'),
('researcher', 'Researcher'),
('waiting_approve', 'Waiting for Operation Manager'),
('first_approve', 'Waiting for Branch Manager'),
('family_services_manager', 'Waiting Family Services Manager'),
('legal_department', 'Waiting Legal Department'),
('projects_department', 'Waiting Projects Department'),
('gm_assistant', 'Waiting Assistant General Manager'),
('accounting_approve', 'Accounting Approve'),
('approval_of_beneficiary_services', 'Approval of beneficiary services'),
('send_request_to_supplier', 'Send Request To Supplier'),
('family_received_device', 'Family Received Device'),
('refused', 'Refused')
], string='state', default='draft', tracking=True, group_expand='_expand_states')
# dynamic_state = fields.Selection(selection=[],string="State",default='draft',tracking=True,)
state_a = fields.Selection(related='state', tracking=False)
state_b = fields.Selection(related='state', tracking=False)
refuse_reason_id = fields.Many2one('service.refuse.reason', string="Refuse Reason")
return_reason = fields.Text(string="Reason for Returning the Request")
refuse_reason = fields.Text(string="Reason for Refusal")
specialist_note = fields.Text(string="Specialist's Note After Return")
exception = fields.Boolean(string='Exception',default=False)
exception_attach = fields.Many2many('ir.attachment', 'rel_exception_attachment_service_request', 'service_request_id',
'attachment_id', string='Exception Attachment')
exception = fields.Boolean(string='Exception', default=False)
exception_attach = fields.Many2many('ir.attachment', 'rel_exception_attachment_service_request',
'service_request_id',
'attachment_id', string='Exception Attachment')
service_conditions = fields.Html(related='service_cat.service_conditions', string="Service Conditions")
service_approval_date = fields.Datetime(string="Service Approval Date",readonly=True,)
service_approval_date = fields.Datetime(string="Service Approval Date", readonly=True, )
company_id = fields.Many2one('res.company', string="Company", default=lambda self: self.env.user.company_id)
currency_id = fields.Many2one('res.currency', string="Currency", related='company_id.currency_id')
service_max_amount = fields.Float(string="Maximum Amount", copy=False)
rent_period = fields.Integer('Rent Period')
is_orphan = fields.Boolean(string='Orphaned (Both Parents Deceased)',compute='_compute_is_orphan',store=True)
has_money_for_payment_is_appearance = fields.Boolean(string='Has money Field is appearance?',compute='_get_money_for_payment_is_appearance')
is_orphan = fields.Boolean(string='Orphaned (Both Parents Deceased)', compute='_compute_is_orphan', store=True)
has_money_for_payment_is_appearance = fields.Boolean(string='Has money Field is appearance?',
compute='_get_money_for_payment_is_appearance')
has_money_for_payment = fields.Selection([('yes', 'Yes'), ('no', 'No')], string='Has money for payment?')
has_money_to_pay_first_payment = fields.Selection([('yes', 'Yes'), ('no', 'No')],
string='Has money to pay first payment?')
has_money_field_is_appearance = fields.Boolean(string='Has money Field is appearance?',
compute='_get_money_field_is_appearance')
car_name = fields.Char(string='Car Name')
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')
application_form = fields.Many2many('ir.attachment', 'request_application_form_rel', 'request_id', 'attachment_id',
string="Application Form")
@ -190,8 +214,24 @@ class ServiceRequest(models.Model):
owner_identity = fields.Many2many('ir.attachment', 'request_owner_identity_rel', 'request_id', 'attachment_id',
string="Owner Identity")
seasonal_service_id = fields.Many2one('seasonal.service', string='Seasonal Service', ondelete='cascade')
is_seasonal = fields.Boolean(string='Is Seasonal Service?',related='service_cat.is_seasonal_service')
is_in_kind = fields.Boolean(string="In Kind",default=False)
is_seasonal = fields.Boolean(string='Is Seasonal Service?', related='service_cat.is_seasonal_service')
is_in_kind = fields.Boolean(string="In Kind", default=False)
service_qty = fields.Float(string='Quantity', default=1)
payment_order_state = fields.Selection(string='Payment Order State', selection=[
('none', 'None'),
('waiting', 'Waiting Payment'),
('done', 'Done Payment'), ], copy=False, compute="_compute_payment_order_state", store=True)
@api.depends('payment_order_id', 'payment_order_id.state')
def _compute_payment_order_state(self):
for rec in self:
payment_order_state = 'none'
if rec.payment_order_state:
if rec.payment_order_id.state == "done":
payment_order_state = "done"
else:
payment_order_state = "waiting"
rec.payment_order_state = payment_order_state
@api.depends('requested_service_amount', 'service_max_amount')
def _get_money_for_payment_is_appearance(self):
@ -209,7 +249,7 @@ class ServiceRequest(models.Model):
else:
rec.has_money_field_is_appearance = False
@api.depends('family_id.mother_marital_conf','family_id.replacement_mother_marital_conf')
@api.depends('family_id.mother_marital_conf', 'family_id.replacement_mother_marital_conf')
def _compute_is_orphan(self):
for rec in self:
if not rec.family_id.add_replacement_mother:
@ -240,7 +280,7 @@ class ServiceRequest(models.Model):
'service_id': False,
'service_request_id': rec.id,
'name': attachment_line.name,
'notes':attachment_line.notes,
'notes': attachment_line.notes,
'previous_service_attachment_settings_id': attachment_line.id,
}))
@ -294,13 +334,13 @@ class ServiceRequest(models.Model):
if record.family_id:
# Prepare values for family_id write
update_values = {}
# Add fields to update_values only if they exist in vals
# Add fields to update_values only if they exist in vals
if 'new_rent_contract_number' in vals:
update_values['contract_num'] = vals['new_rent_contract_number']
if 'new_rent_start_date' in vals:
update_values['rent_start_date'] = vals['new_rent_start_date']
if 'new_rent_end_date' in vals:
update_values['rent_end_date'] = vals['new_rent_end_date']
update_values['rent_end_date'] = vals['new_rent_end_date']
if 'new_rent_amount' in vals:
update_values['rent_amount'] = vals['new_rent_amount']
if 'new_payment_type' in vals:
@ -390,6 +430,7 @@ class ServiceRequest(models.Model):
rec.rent_amount_payment = rec.rent_amount / int(rec.payment_type)
else:
rec.rent_amount_payment = 0.0
def _get_new_rent_amount_payment(self):
for rec in self:
if rec.new_rent_amount and rec.new_payment_type:
@ -417,11 +458,12 @@ class ServiceRequest(models.Model):
def _get_rent_for_alternative_housing(self):
for rec in self:
if rec.service_cat.service_type == 'alternative_housing':
rec.rent_for_alternative_housing = self.env['services.settings'].search([('service_type','=','rent')],limit=1).id
rec.rent_for_alternative_housing = self.env['services.settings'].search([('service_type', '=', 'rent')],
limit=1).id
else:
rec.rent_for_alternative_housing = False
@api.depends('family_id','service_cat')
@api.depends('family_id', 'service_cat')
def _compute_service_benefit_count(self):
for rec in self:
count = 1
@ -432,7 +474,6 @@ class ServiceRequest(models.Model):
rec.family_id.member_ids.filtered(lambda x: x.age <= rec.service_cat.max_age))
rec.service_benefit_count = count
@api.onchange('requests_counts', 'service_type', 'service_reason_id')
def _get_max_transportation_amounts(self):
for rec in self:
@ -550,8 +591,7 @@ class ServiceRequest(models.Model):
'target': 'new',
}
@api.onchange('rent_payment_date','new_rent_payment_date')
@api.onchange('rent_payment_date', 'new_rent_payment_date')
def onchange_rent_payment_date(self):
today_date = fields.Date.today()
for rec in self:
@ -571,7 +611,7 @@ class ServiceRequest(models.Model):
furnishing_cost_sum += rec.furnishing_cost
self.requested_service_amount = furnishing_cost_sum
@api.onchange('family_id','service_cat')
@api.onchange('family_id', 'service_cat')
def _onchange_member(self):
for rec in self:
rec.benefit_type = rec.service_cat.benefit_type
@ -580,8 +620,7 @@ class ServiceRequest(models.Model):
rec.service_cat = False
rec.available_service_cats = False
@api.onchange('service_cat','family_id')
@api.onchange('service_cat', 'family_id')
def _onchange_service_cat(self):
if self.service_cat.service_type == 'rent' and self.family_id.property_type != 'rent' and self.family_id.property_type != 'rent_shared' and self.benefit_type == 'family':
raise UserError(_("You cannot benefit from this service (property type not rent)"))
@ -602,7 +641,7 @@ class ServiceRequest(models.Model):
'requested_quantity',
'amount_for_buy_home_for_member_count',
'marriage_contract_date',
'start','end'
'start', 'end'
)
def onchange_requested_service_amount(self):
res = {}
@ -618,8 +657,9 @@ class ServiceRequest(models.Model):
interval = rec.service_cat.recurrence_interval or 1
period = rec.service_cat.recurrence_period or 'months'
max_limit_type = rec.service_cat.max_limit_type
special_services = ['home_furnishing', 'electrical_devices','rent','alternative_housing']
base_domain = [('family_id', '=', family_id),('service_cat', '=', rec.service_cat.id),('id', '!=', rec._origin.id),('state', '!=', 'refused')]
special_services = ['home_furnishing', 'electrical_devices', 'rent', 'alternative_housing']
base_domain = [('family_id', '=', family_id), ('service_cat', '=', rec.service_cat.id),
('id', '!=', rec._origin.id), ('state', '!=', 'refused')]
if rec.benefit_type == "member":
base_domain.append(('member_id', '=', rec.member_id.id))
if rec.service_cat.service_type == 'buy_car':
@ -653,7 +693,7 @@ class ServiceRequest(models.Model):
if not rec.family_id.add_replacement_mother and not disable_mother and not work_mother:
raise ValidationError(
_("You cannot request this service because mother should be worked or has disability"))
if service_type in ['home_maintenance','complete_building_house','buy_home']:
if service_type in ['home_maintenance', 'complete_building_house', 'buy_home']:
existing_request_restoration = Service.search([
('family_id', '=', family_id),
('service_cat.service_type', '=', 'home_restoration'),
@ -681,7 +721,7 @@ class ServiceRequest(models.Model):
if service_type == 'transportation_insurance':
if rec.family_id.has_car:
raise ValidationError(_("You cannot request this service because you have a car."))
if service_type == 'buy_home':
if service_type == 'buy_home':
if rec.service_cat.buy_home_max_total_amount < rec.amount_for_buy_home_for_member_count:
raise ValidationError(_(
"You can request this service because the total housing amount (%.2f) "
@ -704,7 +744,7 @@ class ServiceRequest(models.Model):
if overlap_requests:
raise ValidationError(
_("This service request overlaps with an existing requests [%s] for the same service "
"between %s and %s.") % (", ".join(overlap_requests.mapped('name')),rec.start, rec.end)
"between %s and %s.") % (", ".join(overlap_requests.mapped('name')), rec.start, rec.end)
)
if allowed:
@ -725,11 +765,13 @@ class ServiceRequest(models.Model):
if not rec.home_furnishing_exception:
rec.service_max_amount = rec.service_cat.max_amount
if total_amount > rec.service_cat.max_amount:
raise ValidationError(_("You cannot request more than %s") % rec.service_max_amount)
raise ValidationError(
_("You cannot request more than %s") % rec.service_max_amount)
if rec.home_furnishing_exception:
rec.service_max_amount = rec.service_cat.max_furnishing_amount_if_exception
if total_amount > rec.service_cat.max_furnishing_amount_if_exception:
raise ValidationError(_("You cannot request more than %s") % rec.service_max_amount)
raise ValidationError(
_("You cannot request more than %s") % rec.service_max_amount)
if service_type == 'electrical_devices':
rec.service_max_amount = rec.device_id.price_unit if rec.device_id else 0.0
if rec.device_id:
@ -776,9 +818,10 @@ class ServiceRequest(models.Model):
if max_limit_type == 'fixed':
rec.service_max_amount = rec.service_cat.max_amount
elif max_limit_type == 'category':
rec.service_max_amount = rec.service_cat.category_amount_lines and max(rec.service_cat.category_amount_lines.filtered(
lambda r: r.benefit_category_id.id == rec.family_category.id).mapped('max_amount'),
default=0.0) or 0
rec.service_max_amount = rec.service_cat.category_amount_lines and max(
rec.service_cat.category_amount_lines.filtered(
lambda r: r.benefit_category_id.id == rec.family_category.id).mapped('max_amount'),
default=0.0) or 0
elif max_limit_type == 'category_person':
rec.service_max_amount = rec.service_cat.bill_lines and max(rec.service_cat.bill_lines.filtered(
lambda x: x.benefit_category_id.id == rec.family_category.id and
@ -789,15 +832,18 @@ class ServiceRequest(models.Model):
elif max_limit_type == 'none':
pass
elif max_limit_type == 'amount_person':
rec.service_max_amount = rec.service_cat.limit_person_line_ids and max(rec.service_cat.limit_person_line_ids.filtered(
lambda x: x.min_count_member <= rec.benefit_member_count <= x.max_count_member)).amount or 0
rec.service_max_amount = rec.service_cat.limit_person_line_ids and max(
rec.service_cat.limit_person_line_ids.filtered(
lambda
x: x.min_count_member <= rec.benefit_member_count <= x.max_count_member)).amount or 0
if rec.max_limit_period:
if rec.max_limit_period == "month":
if rec.start and rec.end:
start_date = rec.start.date() if isinstance(rec.start, datetime) else rec.start
end_date = rec.end.date() if isinstance(rec.end, datetime) else rec.end
num_months = (end_date.year - start_date.year) * 12 + (end_date.month - start_date.month) + 1
num_months = (end_date.year - start_date.year) * 12 + (
end_date.month - start_date.month) + 1
if num_months > rec.service_cat.max_months_limit:
raise ValidationError(
_("You cannot request this service for more than %s months.") % rec.service_cat.max_months_limit
@ -833,11 +879,12 @@ class ServiceRequest(models.Model):
if rec.is_orphan:
rec.service_max_amount = rec.service_cat.orphan_member_amount
if rec.member_age > rec.service_cat.max_age:
raise ValidationError(_( "Member Age should be less than %s ") % rec.service_cat.max_age)
raise ValidationError(_("Member Age should be less than %s ") % rec.service_cat.max_age)
if rec.member_payroll > rec.service_cat.member_max_payroll:
raise ValidationError(_("Member Payroll should be less than %s ") % rec.service_cat.member_max_payroll)
raise ValidationError(
_("Member Payroll should be less than %s ") % rec.service_cat.member_max_payroll)
if not rec.is_orphan and rec.requested_service_amount > rec.service_max_amount:
raise ValidationError(_("You cannot request more than %s ") % rec.service_max_amount)
raise ValidationError(_("You cannot request more than %s ") % rec.service_max_amount)
if rec.is_orphan and rec.requested_service_amount > rec.service_max_amount:
raise ValidationError(_("You cannot request more than %s ") % rec.service_max_amount)
if rec.has_marriage_course == 'no':
@ -877,12 +924,12 @@ class ServiceRequest(models.Model):
raise UserError(
_("You Cannot request this service for period more than %s") % rec.service_cat.rent_period)
# Validation for 'family' benefit type with 'eid_gift' service type
#if rec.benefit_type == 'family' and rec.service_cat.service_type == 'eid_gift':
# if rec.benefit_type == 'family' and rec.service_cat.service_type == 'eid_gift':
# if rec.eid_gift_benefit_count == 0:
# raise UserError(
# _("You cannot request this service because family should have members his age less than %s") % rec.service_cat.max_age)
# Validation for 'member' benefit type with 'eid_gift' service type
#if rec.benefit_type == 'member' and rec.service_cat.service_type == 'eid_gift':
# if rec.benefit_type == 'member' and rec.service_cat.service_type == 'eid_gift':
# if rec.member_id.age > rec.service_cat.max_age:
# raise UserError(
# _("You cannot request this service because your age should be less than %s") % rec.service_cat.max_age)
@ -893,7 +940,8 @@ class ServiceRequest(models.Model):
if rec.member_id and rec.service_type == 'rent' and not rec.member_id.member_location_conf.is_far_from_family:
raise UserError(_("You Cannot request Service if you not study inside Saudi Arabia"))
@api.onchange('start', 'end', 'rent_start_date', 'rent_end_date','new_start', 'new_end', 'new_rent_start_date', 'new_rent_end_date', 'new_rent_contract')
@api.onchange('start', 'end', 'rent_start_date', 'rent_end_date', 'new_start', 'new_end', 'new_rent_start_date',
'new_rent_end_date', 'new_rent_contract')
def _check_date_range(self):
for rec in self:
# Ensure both start and end dates are set
@ -903,7 +951,7 @@ class ServiceRequest(models.Model):
rec.rent_start_date <= rec.end <= rec.rent_end_date):
raise UserError(
"The Start Date and End Date must be within the Rent Start Date and Rent End Date range.")
if rec.new_start and rec.new_end and rec.new_rent_start_date and rec.new_rent_end_date and rec.new_rent_contract :
if rec.new_start and rec.new_end and rec.new_rent_start_date and rec.new_rent_end_date and rec.new_rent_contract:
# Check if `start` and `end` are within `rent_start_date` and `rent_end_date`
if not (rec.new_rent_start_date <= rec.new_start <= rec.new_rent_end_date and
rec.new_rent_start_date <= rec.new_end <= rec.new_rent_end_date):
@ -913,7 +961,7 @@ class ServiceRequest(models.Model):
@api.depends('family_category')
def _compute_available_service_cats(self):
for rec in self:
domain = [('service_type', '!=', 'main_service'),('benefit_category_ids', 'in', [rec.family_category.id])]
domain = [('service_type', '!=', 'main_service'), ('benefit_category_ids', 'in', [rec.family_category.id])]
if rec.family_id.property_type not in ['ownership', 'ownership_shared', 'charitable']:
domain.append(('service_type', '!=', 'home_restoration'))
else:
@ -923,8 +971,8 @@ class ServiceRequest(models.Model):
# domain.append(('allow_non_beneficiary','=',True))
def action_set_to_draft(self):
for rec in self:
rec.state= 'draft'
for rec in self:
rec.state = 'draft'
def action_open_exchange_order_wizard(self):
ids = []
@ -938,37 +986,89 @@ class ServiceRequest(models.Model):
raise UserError(_("All selected requests should be not has payment order"))
else:
return {
'type': 'ir.actions.act_window',
'name': 'Exchange Order',
'res_model': 'exchange.order.wizard',
'view_mode': 'form',
'target': 'new',
'context': {'default_service_ids': ids}
}
'type': 'ir.actions.act_window',
'name': 'Exchange Order',
'res_model': 'exchange.order.wizard',
'view_mode': 'form',
'target': 'new',
'context': {'default_service_ids': ids}
}
def action_create_payment_order(self):
service_cats = self.mapped('service_cat')
if len(service_cats) > 1:
cat_names = ", ".join(service_cats.mapped('service_name'))
raise UserError(_(
"All selected service requests must belong to the same Service Cat.\n\n"
"Selected Services Cat:\n%s"
) % cat_names)
invalid_records = self.filtered(
lambda r: r.state != 'accounting_approve'
or r.payment_order_state != 'none'
or r.payment_order_id
)
if invalid_records:
names = ", ".join(invalid_records.mapped('name'))
raise UserError(_(
"The following service requests do not meet the conditions:\n%s\n"
"Each request must:\n"
"• Be in 'Accounting Approve' state\n"
"• Have payment order state = 'None'\n"
"• Not be linked to any payment order"
) % names)
self.env['payment.orders'].create({
'state': 'draft',
'accountant_id': self[0].service_cat.accountant_id.id,
'service_requests_ids': [(6, 0, self.ids)],
})
self.write({'is_payment_order_done': True})
def create_vendor_bill(self):
ids = []
line_ids = []
service_cats = self.mapped('service_cat')
if len(service_cats) > 1:
cat_names = ", ".join(service_cats.mapped('service_name'))
raise UserError(_(
"All selected service requests must belong to the same Service Cat.\n\n"
"Selected Services Cat:\n%s"
) % cat_names)
service_cat = service_cats[0] if service_cats else False
if service_cat and service_cat.service_type != 'electrical_devices':
raise UserError(_("Only 'Electrical Devices' service cat requests can create a invoice."))
invalid_records = self.filtered(
lambda r: r.state != 'accounting_approve'
or r.payment_order_state != 'none'
or r.payment_order_id
)
if invalid_records:
names = ", ".join(invalid_records.mapped('name'))
raise UserError(_(
"The following service requests do not meet the conditions:\n%s\n"
"Each request must:\n"
"• Be in 'Accounting Approve' state\n"
"• Have payment order state = 'None'\n"
"• Not be linked to any payment order"
) % names)
for rec in self:
ids.append(rec.id)
service_requests = self.env['service.request'].browse(ids)
service_producer_id = self.env['service.request'].search([('id','=',ids[0])],limit=1)
if any(request.state not in 'approval_of_beneficiary_services' for request in service_requests):
raise UserError(_("All selected requests should be in Family Received Device state"))
if any(request.vendor_bill for request in service_requests):
raise UserError(_("All selected requests should be not has Vendor Bill"))
for request in service_requests:
invoice_line = (0, 0, {
'name': f'{request.family_id.name}/{request.device_id.device_name}/{request.description}/{request.name}',
'account_id': request.device_account_id.id,
'analytic_account_id': request.branch_custom_id.branch.analytic_account_id.id,
'quantity' : request.requested_quantity,
'price_unit' : request.requested_service_amount,
'name': f'{rec.family_id.name}/{rec.device_id.device_name}/{rec.description}/{rec.name}',
'account_id': rec.device_account_id.id,
'analytic_account_id': rec.branch_custom_id.branch.analytic_account_id.id,
'quantity': rec.requested_quantity,
'price_unit': rec.requested_service_amount,
})
line_ids.append(invoice_line)
vendor_bill = self.env['account.move'].create({
'move_type':'in_invoice',
'partner_id':service_producer_id.service_producer_id.id,
'move_type': 'in_invoice',
'partner_id': self[0].service_producer_id.id,
# 'accountant_id': self.accountant_id.id,
'invoice_line_ids': line_ids,
})
self.vendor_bill = vendor_bill
self.vendor_bill = vendor_bill

View File

@ -6,80 +6,83 @@
<field name="arch" type="xml">
<form string="Payment Orders">
<header>
<button name="action_accountant_approve" type="object" states="draft"
string="Accountant Approve" class="oe_highlight"
groups="odex_benefit.group_benefit_accountant_accept" />
<button name="action_department_manager_approve" type="object"
states="accountant_approve"
string="Department Manager Approve" class="oe_highlight"
groups="odex25_account_payment_fix.group_depart_manager" />
<button name="action_accounting_approve" type="object"
states="department_manager_approve"
string="Accounting Approve" class="oe_highlight"
groups="odex25_account_payment_fix.group_accounting_manager" />
<button name="action_general_manager_approve" type="object"
states="accounting_approve"
string="General Manager Approve" class="oe_highlight"
groups="odex25_account_payment_fix.group_general_manager" />
<button name="action_refuse" type="object"
states="draft,accountant_approve,department_manager_approve,accounting_approve"
string="Refuse" class="oe_highlight" />
<button name="action_manager_approval" type="object" states="draft"
string="Manager approval" class="oe_highlight"/>
<field name="state" widget="statusbar" />
<button name="action_head_approval" type="object"
states="waiting_head"
string="Approve" class="oe_highlight"/>
<button name="action_reset_to_draft" type="object"
states="waiting_head"
string="Reset" class="oe_highlight"/>
<button name="action_finance_approval" type="object"
states="waiting_finance"
string="Approve" class="oe_highlight"/>
<button name="action_gm_approval" type="object"
states="waiting_gm"
string="Approve" class="oe_highlight"/>
<button name="action_refuse" type="object"
states="draft"
string="Refuse" class="oe_highlight"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box"
attrs="{'invisible': [('state','!=','general_manager_approve')]}">
attrs="{'invisible': [('state','!=','waiting_gm')]}">
<button icon="fa-usd" name="action_open_related_move_records"
type="object">
<field name="total_moves" string="Moves" widget="statinfo" />
type="object">
<field name="total_moves" string="Moves" widget="statinfo"/>
</button>
</div>
<group>
<div class="oe_title">
<h1>
<field name="name" readonly="1" />
<field name="name" readonly="1"/>
</h1>
</div>
<group>
<field name="payment_order_date" />
<field name="accountant_id" />
<field name="payment_order_date"/>
<field name="accountant_id"/>
<field name="journal_id"/>
</group>
<group>
<field name="payment_order_description" />
<field name="ref_num" />
<field name="is_seasonal" invisible="1" />
<field name="payment_order_description"/>
<field name="ref_num"/>
<field name="is_seasonal" invisible="1"/>
</group>
</group>
<notebook>
<page string="Services Requests"
attrs="{'invisible': [('is_seasonal', '=', True)]}">
<page string="Services Requests">
<field name="service_requests_ids" widget="one2many_list"
readonly="1">
readonly="1">
<tree editable="bottom">
<field name="family_id" />
<field name="member_id" />
<field name="branch_custom_id" />
<field name="account_id" />
<field name="name" string="Service Number" />
<field name="description" string="Service Description" />
<field name="aid_amount" string="Service Amount" />
<field name="family_id"/>
<field name="member_id"/>
<field name="branch_custom_id"/>
<field name="account_id"/>
<field name="name" string="Service Number"/>
<field name="description" string="Service Description"/>
<field name="aid_amount" string="Service Amount"/>
</tree>
</field>
</page>
<page string="Seasonal Services"
attrs="{'invisible': [('is_seasonal', '=', False)]}">
<page string="Seasonal Services">
<field name="family_seasonal_requests_ids" widget="one2many_list"
readonly="1">
readonly="1">
<tree editable="bottom">
<field name="family_id" />
<field name="branch_custom_id" />
<field name="account_id" />
<field name="name" string="Service Number" />
<field name="aid_amount" string="Service Amount" />
<field name="family_id"/>
<field name="branch_custom_id"/>
<field name="account_id"/>
<field name="name" string="Service Number"/>
<field name="aid_amount" string="Service Amount"/>
</tree>
</field>
@ -88,9 +91,9 @@
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"
groups="base.group_user" />
<field name="activity_ids" />
<field name="message_ids" widget="mail_thread" />
groups="base.group_user"/>
<field name="activity_ids"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
@ -100,11 +103,11 @@
<field name="model">payment.orders</field>
<field name="arch" type="xml">
<tree string="Payment Orders">
<field name="name" readonly="1" />
<field name="payment_order_date" />
<field name="accountant_id" />
<field name="payment_order_description" />
<field name="state" />
<field name="name" readonly="1"/>
<field name="payment_order_date"/>
<field name="accountant_id"/>
<field name="payment_order_description"/>
<field name="state"/>
</tree>
</field>
</record>
@ -113,28 +116,12 @@
<field name="model">payment.orders</field>
<field name="arch" type="xml">
<search>
<separator />
<filter string="Draft" name="draft" domain="[('state','=','draft')]" />
<separator />
<separator />
<filter string="Accountant Approve" name="accountant_approve"
domain="[('state', '=', 'accountant_approve')]" />
<separator />
<separator />
<filter string="Depart Manager Approve" name="depart_manager_approve"
domain="[('state', '=', 'department_manager_approve')]" />
<separator />
<separator />
<filter string="Accounting Approve" name="accounting_approve"
domain="[('state', '=', 'accounting_approve')]" />
<separator />
<separator />
<filter string="General Manager Approve" name="general_manager_approve"
domain="[('state', '=', 'general_manager_approve')]" />
<separator />
<separator />
<filter string="Refused" name="refused" domain="[('state', '=', 'refused')]" />
<separator />
<separator/>
<filter string="Draft" name="draft" domain="[('state','=','draft')]"/>
<separator/>
<separator/>
<filter string="Refused" name="refused" domain="[('state', '=', 'refused')]"/>
<separator/>
</search>
</field>
</record>
@ -143,7 +130,7 @@
<field name="name">Payment Orders</field>
<field name="res_model">payment.orders</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="payment_orders_tree" />
<field name="view_id" ref="payment_orders_tree"/>
</record>
</data>
</odoo>

View File

@ -12,23 +12,25 @@
string="Calculate" class="btn btn-info"
attrs="{'invisible': [('state', '!=', 'draft')]}"/>
<button name="action_approval_of_beneficiary_services" type="object"
string="Approve Beneficiary Services" class="oe_highlight"
attrs="{'invisible': [('state', '!=', 'calculated')]}"
groups="odex_benefit.group_approval_of_beneficiary_services"/>
<button name="action_first_approval" type="object"
string="Approve" class="oe_highlight"
attrs="{'invisible': [('state', '!=', 'calculated')]}"/>
<button string="Withdraw" type="object" name="action_reset_to_draft" class="btn btn-danger"
states="calculated"/>
<button name="action_recalculate" string="Recalculate" class="btn btn-info"
type="object" states="calculated"/>
<button name="action_approval_of_gm_assistant" type="object"
string="Approve" class="oe_highlight"
attrs="{'invisible': [('state', '!=', 'gm_assistant')]}"/>
<button name="action_accounting_approve" type="object"
string="Accounting Approve"
class="oe_highlight"
attrs="{'invisible': [('state', '!=', 'approval_of_beneficiary_services')]}"
attrs="{'invisible': [('state', '!=', 'accounting_approve')]}"
groups="odex_benefit.group_benefit_accounting_accept"/>
<button name="action_open_exchange_order_wizard"
<button name="action_create_payment_order"
type="object"
string="امر الصرف"
class="oe_highlight"
@ -36,20 +38,25 @@
groups="odex_benefit.group_benefit_accounting_accept"/>
<field name="state" widget="statusbar"
statusbar_visible="draft,calculated,approval_of_beneficiary_services,accounting_approve"/>
statusbar_visible="draft,calculated,accounting_approve,waiting_receive,done"/>
</header>
<sheet>
<field name="is_payment_order_done" invisible="1"/>
<field name="payment_order_state" invisible="1"/>
<widget name="web_ribbon" title="Payment Order Done" bg_color="bg-success"
attrs="{'invisible': [('is_payment_order_done', '=', False)]}"/>
attrs="{'invisible': [('payment_order_state', '!=', 'done')]}"/>
<widget name="web_ribbon" title="Payment Order Waiting" bg_color="bg-warning"
attrs="{'invisible': [('payment_order_state', '!=', 'waiting')]}"/>
<group>
<group>
<field name="name" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
<field name="date" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
<field name="service_type_id"
attrs="{'readonly': [('state', '!=', 'draft')]}"/>
<field name="service_delivery_method" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
<field name="service_delivery_method"
attrs="{'required':[('is_in_kind','!=',False)],'invisible':[('is_in_kind','=',False)],'readonly': [('state', '!=', 'draft')]}"/>
<field name="is_in_kind" invisible="1"/>
<field name="branch_ids" widget="many2many_tags"
attrs="{'readonly': [('state', '!=', 'draft')]}"/>
<field name="family_category_ids" widget="many2many_tags" readonly="1"/>
@ -63,7 +70,7 @@
</group>
<group>
<field name="aid_amount" readonly="1"/>
<field name="aid_amount"/>
<field name="family_count" readonly="1"/>
<field name="benefit_member_count" readonly="1"/>
<field name="family_disbursement_total_amount" readonly="1"/>
@ -71,33 +78,19 @@
</group>
</group>
<notebook>
<page string="Families">
<field name="family_ids" widget="one2many_list"
attrs="{'readonly': [('state', '!=', 'draft')]}">
<tree editable="bottom">
<field name="family_id"/>
<field name="branch_custom_id"/>
<field name="account_id"/>
<field name="name" string="Service Number"/>
<field name="aid_amount" string="Service Amount"/>
</tree>
</field>
</page>
<page string="Families">
<field name="benefit_ids" domain="[('id', 'in', family_domain_ids)]"/>
</page>
<page string="Members" attrs="{'invisible': [('benefit_type', '!=', 'member')]}">
<field name="member_ids" domain="[('benefit_id', 'in', family_domain_ids)]"/>
</page>
<page string="Services Requests">
<field name="service_requests_ids">
<page string="Services Requests" attrs="{'invisible': [('state', '=', 'draft')]}">
<field name="service_requests_ids" readonly="1">
<tree>
<field name="family_id"/>
<field name="member_id"
attrs="{'column_invisible':[('parent.benefit_type','=','family')]}"/>
<field name="branch_custom_id" optional="hidden"/>
<field name="researcher_id" optional="hidden"/>
<field name="family_category"/>
<field name="benefit_member_count"/>
<field name="service_benefit_count"/>
<field name="service_qty"
attrs="{'column_invisible':[('parent.service_delivery_method','=','cash')]}"/>
<field name="requested_service_amount"
attrs="{'column_invisible':[('parent.service_delivery_method','!=','cash')]}"/>
<field name="state" widget="badge" decoration-success="state in ['gm_assistant']"
@ -108,6 +101,12 @@
</tree>
</field>
</page>
<page string="Families">
<field name="benefit_ids" domain="[('id', 'in', family_domain_ids)]"/>
</page>
<page string="Members" attrs="{'invisible': [('benefit_type', '!=', 'member')]}">
<field name="member_ids" domain="[('benefit_id', 'in', benefit_ids)]"/>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
@ -129,11 +128,13 @@
<field name="name"/>
<field name="date"/>
<field name="service_type_id"/>
<field name="service_delivery_method"/>
<field name="aid_amount"/>
<field name="family_count"/>
<field name="benefit_member_count"/>
<field name="family_disbursement_total_amount"/>
<field name="state"/>
<field name="payment_order_state"/>
</tree>
</field>
</record>

View File

@ -158,8 +158,11 @@
</header>
<sheet>
<field name="is_payment_order_done" invisible="1"/>
<field name="payment_order_state" invisible="1"/>
<widget name="web_ribbon" title="Payment Order Done" bg_color="bg-success"
attrs="{'invisible': [('is_payment_order_done', '=', False)]}"/>
attrs="{'invisible': [('payment_order_state', '!=', 'done')]}"/>
<widget name="web_ribbon" title="Payment Order Waiting" bg_color="bg-warning"
attrs="{'invisible': [('payment_order_state', '!=', 'waiting')]}"/>
<group>
<div class="oe_title">
<h1>
@ -205,8 +208,10 @@
<field name="service_cat"
attrs="{'readonly':[('state','not in',['draft','researcher','waiting_approve'])]}"
domain="[('id','in',available_service_cats)]" required="1"/>
<field name="is_in_kind"
<field name="is_in_kind" widget="boolean_toggle"
attrs="{'readonly':[('state','not in',['draft','researcher','waiting_approve'])]}"/>
<field name="service_qty"
attrs="{'invisible':[('is_in_kind','=',False)]}"/>
<label for="start" string="Period"
attrs="{'invisible': ['&amp;', ('service_type', '!=', 'rent'), ('max_limit_period', '!=', 'month')]}"/>
<div name="dates" class="o_row"
@ -486,6 +491,7 @@
decoration-danger="state in ['refused']"
decoration-info="state in ['first_approve','waiting_approve']"
decoration-warning="state in ['researcher']"/>
<field name="payment_order_state"/>
</tree>
</field>
</record>

View File

@ -20,7 +20,7 @@ class FamilyBankReportWizard(models.TransientModel):
)
move_ids = fields.Many2many(comodel_name='account.move',
string="Monthly Expenses", required=True,
domain="[('state', '=', 'posted'),('date','>=', start_date),('date','<=', end_date),('family_confirm_id', '!=', False)]"
domain="[('state', '=', 'posted'),('date','>=', start_date),('date','<=', end_date),('line_ids.benefit_family_id', '!=', False)]"
)
def action_print_bank_report(self):