[IMP] odex_benefit: IMP Monthly Expense for Families

This commit is contained in:
younes 2025-10-23 11:40:37 +01:00
parent 482bbda54a
commit 5a20c303a7
9 changed files with 375 additions and 137 deletions

View File

@ -46,6 +46,7 @@
'reports/benefit_template.xml',
'views/benefit_services_view.xml',
'views/family_expense_view.xml',
'views/family_expense_line_view.xml',
'views/services_settings.xml',
'views/service_request.xml',
'views/benefit_config_view.xml',

View File

@ -1364,17 +1364,6 @@ msgstr ""
msgid "All expenses"
msgstr "جميع المصاريف"
#. module: odex_benefit
#: code:addons/odex_benefit/models/family_expense.py:0
#: code:addons/odex_benefit/wizards/family_expense_move_wiz.py:0
#, python-format
msgid ""
"All selected benefits should be either state of "
"'second_approve','temporarily_suspend','suspend' state."
msgstr ""
"كل الاسر المحددة يجب أن تكون في حالة 'الموافقة الثانية' أو 'التعليق المؤقت' "
"أو 'التعليق'."
#. module: odex_benefit
#: model:ir.model.fields,help:odex_benefit.field_benefits_representative__lang
#: model:ir.model.fields,help:odex_benefit.field_external_benefits__lang
@ -2181,6 +2170,7 @@ msgstr "عدد أفراد الأسرة/المستفيدين"
#. module: odex_benefit
#: model:ir.ui.menu,name:odex_benefit.menu_confirm_benefit_expense
#: model:ir.ui.menu,name:odex_benefit.menu_confirm_benefit_expense_duplicate
msgid "Benefit Expense Flow"
msgstr "اجراءت مصاريف الاسر"
@ -2692,6 +2682,7 @@ msgid "Bounce"
msgstr "المرتد"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__branch_id
#: model:ir.model.fields,field_description:odex_benefit.field_branch_settings__branch
#: model:ir.model.fields,field_description:odex_benefit.field_changes_requests__branch_custom_id
#: model:ir.model.fields,field_description:odex_benefit.field_changes_requests__researcher_branch_id
@ -3199,6 +3190,7 @@ msgstr "تاكيد"
#. module: odex_benefit
#: model:ir.model,name:odex_benefit.model_confirm_benefit_expense
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__confirm_expense_id
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_form
msgid "Confirm Benefit Expense"
msgstr "اجراءت مصاريف الاسر"
@ -5132,6 +5124,7 @@ msgid "Families"
msgstr "الاسر المستفيدة"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__family_id
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_loans__family_id
#: model:ir.model.fields,field_description:odex_benefit.field_changes_requests__benefit_id
#: model:ir.model.fields,field_description:odex_benefit.field_generate_reports__family_id
@ -5233,16 +5226,19 @@ msgid "Family Members"
msgstr "أفراد الأسر"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__family_monthly_clotting
#: model:ir.model.fields,field_description:odex_benefit.field_grant_benefit__family_monthly_clotting
msgid "Family Monthly Clotting"
msgstr "مصروف الكساء للأسرة"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__family_monthly_income
#: model:ir.model.fields,field_description:odex_benefit.field_grant_benefit__family_monthly_income
msgid "Family Monthly Income"
msgstr "المصروف النقدي للأسرة"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__family_monthly_meals
#: model:ir.model.fields,field_description:odex_benefit.field_grant_benefit__family_monthly_meals
msgid "Family Monthly Meals"
msgstr "مصروف الغذاء للأسرة"
@ -7855,6 +7851,7 @@ msgid "Maximum Percentage"
msgstr ""
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__meal_card
#: model:ir.model.fields,field_description:odex_benefit.field_grant_benefit__meal_card
#: model:ir.model.fields,field_description:odex_benefit.field_res_districts__meal_card
msgid "Meal Card"
@ -8002,6 +7999,7 @@ msgid "Members"
msgstr "أفراد/مستفيدين الأسرة"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__benefit_member_count
#: model:ir.model.fields,field_description:odex_benefit.field_grant_benefit__benefit_member_count
msgid "Members count"
msgstr "عدد المستفيدين"
@ -9280,12 +9278,6 @@ msgstr ""
msgid "Please configure the expense accounts in the validation settings."
msgstr "برجاء تكوين حسابات المصروفات فى اعدادات الاسر"
#. module: odex_benefit
#: code:addons/odex_benefit/models/family_expense.py:0
#, python-format
msgid "Please select at least one family to create an invoice."
msgstr "برجاء اختيار علي الاقل اسرة واحدة"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefits_representative__pos_order_ids
#: model:ir.model.fields,field_description:odex_benefit.field_external_benefits__pos_order_ids
@ -10423,7 +10415,7 @@ msgstr "الاسم الثاني"
#: code:addons/odex_benefit/models/family_expense.py:0
#, python-format
msgid "Select Family"
msgstr ""
msgstr "اختر الأسرة"
#. module: odex_benefit
#: model:ir.model.fields,help:odex_benefit.field_benefits_representative__free_member
@ -11479,7 +11471,7 @@ msgstr "سوف تستخدم قائمة الأسعار هذه بدلاً من ا
#: code:addons/odex_benefit/models/family_expense.py:0
#, python-format
msgid "This record can only be deleted in draft state."
msgstr ""
msgstr "يمكن حذف هذا السجل فقط في حالة المسودة."
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefits_representative__tz
@ -11544,6 +11536,7 @@ msgid "Total Expenses of Family"
msgstr ""
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__total_family_expenses
#: model:ir.model.fields,field_description:odex_benefit.field_grant_benefit__total_family_expenses
msgid "Total Family Expenses"
msgstr "إجمالي المصروف الشهري للأسرة"
@ -14374,6 +14367,7 @@ msgid "Branches"
msgstr " الفروع"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__family_category_id
#: model:ir.model.fields,field_description:odex_benefit.field_seasonal_grant_benefit__family_category
#: model:ir.model.fields,field_description:odex_benefit.field_seasonal_service__family_category_ids
msgid "Family Category"
@ -15948,6 +15942,7 @@ msgid "Waiting For The Assistant General Manager"
msgstr "بإنتظار مساعد المدير العام"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__start_date
#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__start_date
#: model:ir.model.fields,field_description:odex_benefit.field_service_request__new_start
#: model:ir.model.fields,field_description:odex_benefit.field_service_request__start
@ -15955,6 +15950,7 @@ msgid "Start Date"
msgstr "تاريخ البداية"
#. module: odex_benefit
#: model:ir.model.fields,field_description:odex_benefit.field_benefit_expense_line__end_date
#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__end_date
#: model:ir.model.fields,field_description:odex_benefit.field_service_request__end
#: model:ir.model.fields,field_description:odex_benefit.field_service_request__new_end
@ -16488,3 +16484,75 @@ msgstr "اعتماد مساعد المدير العام"
msgid "Researcher Supervisor"
msgstr "مشرف الأخصائي"
#. module: odex_benefit
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_form
msgid "Calculate"
msgstr "حساب"
#. module: odex_benefit
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_form
msgid "Withdraw"
msgstr "تراجع"
#. module: odex_benefit
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_form
msgid "Recalculate"
msgstr "إعادة حساب"
#. module: odex_benefit
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_confirm_benefit_expense_form
msgid "Family Monthly Expense"
msgstr "المصروف الشهري للأسر"
#. module: odex_benefit
#: model:ir.actions.act_window,name:odex_benefit.action_benefit_expense_line
#: model:ir.model.fields,field_description:odex_benefit.field_confirm_benefit_expense__benefit_expense_line_ids
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_benefit_expense_line_tree
msgid "Benefit Expense Lines"
msgstr "سجلات المصروف الشهري"
#. module: odex_benefit
#: model:ir.model,name:odex_benefit.model_benefit_expense_line
#: model_terms:ir.ui.view,arch_db:odex_benefit.view_benefit_expense_line_form
msgid "Benefit Expense Line"
msgstr "سجل المصروف الشهري"
#. module: odex_benefit
#: code:addons/odex_benefit/models/family_expense.py:0
#, python-format
msgid "You can only calculate in draft state."
msgstr "يمكنك الحساب فقط في حالة المسودة."
#. module: odex_benefit
#: code:addons/odex_benefit/models/family_expense.py:0
#, python-format
msgid "Please select at least one family to calculate."
msgstr "يرجى اختيار أسرة واحدة على الأقل لإجراء الحساب."
#. module: odex_benefit
#: code:addons/odex_benefit/models/family_expense.py:0
#, python-format
msgid "You can only recalculate when status is 'Calculated'."
msgstr "يمكنك إعادة الحساب فقط عندما تكون الحالة 'تم الحساب'."
#. module: odex_benefit
#: model:ir.model.fields.selection,name:odex_benefit.selection__confirm_benefit_expense__state__calculated
msgid "Calculated"
msgstr "تم الحساب"
#. module: odex_benefit
#: code:addons/odex_benefit/models/family_expense.py:0
#, python-format
msgid "Please make sure you have benefit expense lines."
msgstr "يرجى التأكد من وجود سجلات المصروفات الشهرية."
#. module: odex_benefit
#: code:addons/odex_benefit/models/family_expense.py:0
#, python-format
msgid ""
"Some selected benefits are not in valid state or are suspended:\n"
"%s"
msgstr ""
"بعض الأسر المحددة ليست في حالة معتمدة أو تم إيقافها:\n"
"%s"

View File

@ -26,6 +26,7 @@ from . import family_member_exam
from . import hr_department
from . import account_move_line
from . import family_expense
from . import family_expense_line
from . import services_settings
from . import res_country_inherit
from . import service_request

View File

@ -24,20 +24,22 @@ class ConfirmBenefitExpense(models.Model):
# endregion [Default Methods]
family_expense_seq = fields.Char(string="Family Expense Sequence", copy=False, readonly=True, default=lambda x: _('New'))
family_expense_seq = fields.Char(string="Family Expense Sequence", copy=False, readonly=True,
default=lambda x: _('New'))
state = fields.Selection(selection=[
('draft', 'Draft'),
('assistant_general_manager', 'Waiting For The Assistant General Manager'), # Translate
('calculated', 'Calculated'),
('assistant_general_manager', 'Waiting For The Assistant General Manager'), # Translate
('depart_manager', 'Department Manager'),
('account_manager', 'Account Manager'),
('cancel', 'Cancelled'),
('confirm', 'Confirmed'),
], string='Status', default='draft', required=True, copy=False,tracking=True)
], string='Status', default='draft', required=True, copy=False, tracking=True)
expense_type = fields.Selection(selection=[
('family_expense', 'Family Expense'),
('family_invoice', 'Meal Card Invoice'),
], string='Expense Type', default='family_expense', required=True, states={'confirm': [('readonly', True)]})
journal_id = fields.Many2one(comodel_name='account.journal', string="Journal", required=True,copy=False)
journal_id = fields.Many2one(comodel_name='account.journal', string="Journal", copy=False)
name = fields.Char(string="Name", states={'confirm': [('readonly', True)]}, copy=False)
date = fields.Date(string="Date", default=fields.Date.context_today, required=False,
@ -49,6 +51,8 @@ class ConfirmBenefitExpense(models.Model):
column1='expense_id',
column2='family_id', string='Families', states={'confirm': [('readonly', True)]},
copy=False)
benefit_expense_line_ids = fields.One2many(comodel_name='benefit.expense.line', inverse_name='confirm_expense_id',
string='Benefit Expense Lines')
cash_expense = fields.Boolean(string='Include Cash Expense', states={'confirm': [('readonly', True)]})
meal_expense = fields.Boolean(string='Include Meal Expense', states={'confirm': [('readonly', True)]})
cloth_expense = fields.Boolean(string='Include Clothing Expense', states={'confirm': [('readonly', True)]})
@ -99,6 +103,67 @@ class ConfirmBenefitExpense(models.Model):
# else:
# record.family_ids = [(5,)] # Clear the records if source_field is empty
def _update_benefit_expense_lines(self):
self.ensure_one()
for line in self.benefit_expense_line_ids:
family = line.family_id
if not family:
continue
monthly_meals = family.family_monthly_meals
if self.expense_type == 'family_expense' and family.meal_card:
monthly_meals = 0.0
vals = {
'branch_id': family.branch_custom_id.id,
'family_category_id': family.benefit_category_id.id,
'meal_card': family.meal_card,
'benefit_member_count': family.benefit_member_count,
'start_date': self.start_date,
'end_date': self.end_date,
}
if self.expense_type == 'family_expense':
vals.update({
'family_monthly_income': family.family_monthly_income,
'family_monthly_meals': monthly_meals,
'family_monthly_clotting': family.family_monthly_clotting,
})
else:
vals.update({
'family_monthly_income': 0.0,
'family_monthly_meals': monthly_meals,
'family_monthly_clotting': 0.0,
})
line.write(vals)
def action_calculate(self):
for rec in self:
if rec.state != 'draft':
raise UserError(_("You can only calculate in draft state."))
families = rec.family_ids
if not families:
raise UserError(_("Please select at least one family to calculate."))
rec.benefit_expense_line_ids.unlink()
lines = []
for fam in families:
vals = {
'confirm_expense_id': rec.id,
'family_id': fam.id,
'start_date': rec.start_date,
'end_date': rec.end_date,
}
lines.append((0, 0, vals))
rec.write({'benefit_expense_line_ids': lines})
rec._update_benefit_expense_lines()
rec.state = 'calculated'
def action_recalculate(self):
for rec in self:
if rec.state != 'calculated':
raise UserError(_("You can only recalculate when status is 'Calculated'."))
rec._update_benefit_expense_lines()
@api.depends('expense_type', 'date', 'branch_custom_id', 'start_date', 'end_date')
def _compute_domain_ids(self):
for rec in self:
@ -110,9 +175,8 @@ class ConfirmBenefitExpense(models.Model):
# Define base domain for family selection
validation_setting = self.env["family.validation.setting"].search([], limit=1)
# base_domain = ['|',('state','=','second_approve'),'&',('state','=',('waiting_approve','first_approve')),('action_type','=','suspended')]
base_domain = ['|',('state','=','second_approve'),'&',('state','in',('waiting_approve','first_approve')),('action_type','=','suspended')]
base_domain = ['|', ('state', '=', 'second_approve'), '&',
('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended')]
if rec.branch_custom_id:
base_domain.append(('branch_custom_id', '=', rec.branch_custom_id.id))
min_income = validation_setting.benefit_category_ids.mapped('mini_income_amount')
@ -148,20 +212,18 @@ class ConfirmBenefitExpense(models.Model):
# rec.family_ids = self.env['grant.benefit'].search(base_domain).ids
rec.journal_domain_ids = self.env['account.journal'].search(journal_domain)
# def unlink(self):
# for rec in self:
# if rec.state not in ['draft']:
# raise UserError(_('This record can only be deleted in draft state.'))
# return super(ConfirmBenefitExpense, self).unlink()
def unlink(self):
for rec in self:
if rec.state not in ['draft']:
raise UserError(_('This record can only be deleted in draft state.'))
return super(ConfirmBenefitExpense, self).unlink()
@api.depends('family_ids', 'expense_type')
@api.depends('benefit_expense_line_ids')
def _get_family_monthly_values(self):
for rec in self:
rec.family_monthly_income = sum(rec.family_ids.mapped('family_monthly_income'))
rec.family_monthly_meals = sum(rec.family_ids.filtered(lambda record: not record.meal_card).mapped(
'family_monthly_meals')) if rec.expense_type == 'family_expense' else sum(
rec.family_ids.mapped('family_monthly_meals'))
rec.family_monthly_clotting = sum(rec.family_ids.mapped('family_monthly_clotting'))
rec.family_monthly_income = sum(rec.benefit_expense_line_ids.mapped('family_monthly_income'))
rec.family_monthly_meals = sum(rec.benefit_expense_line_ids.mapped('family_monthly_meals'))
rec.family_monthly_clotting = sum(rec.benefit_expense_line_ids.mapped('family_monthly_clotting'))
@api.onchange('expense_type')
def _onchange_journal_id(self):
@ -202,6 +264,7 @@ class ConfirmBenefitExpense(models.Model):
self.state = 'cancel'
def action_reset_to_draft(self):
self.benefit_expense_line_ids.unlink()
self.state = 'draft'
@api.constrains('expense_type', 'cash_expense', 'meal_expense', 'cloth_expense')
@ -300,7 +363,8 @@ class ConfirmBenefitExpense(models.Model):
# Define base domain for family selection
validation_setting = self.env["family.validation.setting"].search([], limit=1)
base_domain = ['|',('state','=','second_approve'),'&',('state','in',('waiting_approve','first_approve')),('action_type','=','suspended')]
base_domain = ['|', ('state', '=', 'second_approve'), '&',
('state', 'in', ('waiting_approve', 'first_approve')), ('action_type', '=', 'suspended')]
if self.branch_custom_id:
base_domain.append(('branch_custom_id', '=', self.branch_custom_id.id))
min_income = validation_setting.benefit_category_ids.mapped('mini_income_amount')
@ -333,7 +397,6 @@ class ConfirmBenefitExpense(models.Model):
self.family_ids = [(5,)] # Clear the records if source_field is empty
# self.family_ids = self.env['grant.benefit'].search(base_domain).ids
# Return domain restrictions
return {
'domain': {
@ -344,115 +407,97 @@ class ConfirmBenefitExpense(models.Model):
def action_confirm_selected(self):
for rec in self:
validation_setting = self.env["family.validation.setting"].search([], limit=1)
lines = rec.benefit_expense_line_ids
if not lines:
raise UserError(_("Please make sure you have benefit expense lines."))
if rec.expense_type == 'family_expense':
benefits = rec.family_ids
if any(benefit.state != 'second_approve' or (benefit.state in ('waiting_approve', 'first_approve') and benefit.action_type == 'suspended') for benefit in
benefits):
raise UserError(_("All selected benefits should be either state of "
"'second_approve','waiting_approve','first_approve' state."))
validation_setting = self.env["family.validation.setting"].search([], limit=1)
# payment_method_line = rec.payment_method_id
families = lines.mapped('family_id')
invalid_families = families.filtered(
lambda f: f.state != 'second_approve'
or (f.state in ('waiting_approve', 'first_approve') and f.action_type == 'suspended')
)
if invalid_families:
raise UserError(_(
"Some selected benefits are not in valid state or are suspended:\n%s"
) % ", ".join(invalid_families.mapped('name')))
if not validation_setting.cash_expense_account_id or not validation_setting.meal_expense_account_id or not validation_setting.clothing_expense_account_id:
raise UserError(_("Please configure the expense accounts in the validation settings."))
# if not payment_method_line:
# raise UserError(_("Payment method is not configured for the selected journal."))
# credit_account_id = payment_method_line.payment_account_id.id
credit_account_id = self.env["family.validation.setting"].search([], limit=1).account_id.id
credit_account_id = validation_setting.account_id.id
if not credit_account_id:
raise UserError(_("Please select credit account."))
if benefits:
lines = []
total_credit = 0
credit_line_name = _("Total Credit for Family Expenses")
for benefit in benefits:
sum_line, credit_total = rec._prepare_entry_lines(benefit, validation_setting,
credit_account_id)
total_credit += credit_total
lines += sum_line
lines.append(self._create_credit_line(credit_account_id, total_credit, credit_line_name))
inv_lines = []
total_credit = 0
credit_line_name = _("Total Credit for Family Expenses")
for line in lines:
sum_line, credit_total = rec._prepare_entry_lines(line,validation_setting)
total_credit += credit_total
inv_lines += sum_line
inv_lines.append(self._create_credit_line(credit_account_id, total_credit, credit_line_name))
rec.create_entry(rec.journal_id.id, lines)
rec.create_entry(rec.journal_id.id, inv_lines)
else:
if not rec.family_ids:
raise UserError(_("Please select at least one family to create an invoice."))
validation_setting = self.env["family.validation.setting"].search([], limit=1)
account_id = validation_setting.meal_expense_account_id
invoice_lines = []
for family in rec.family_ids:
for line in lines:
family = line.family_id
invoice_lines.append((0, 0, {
'name': f'{family.name}/{family.code}', # Family name as the description
'account_id': account_id.id, # The same account for all lines
'quantity': 1, # Qty is 1
# The same analytic account
'name': f'{family.name}/{family.code}',
'account_id': account_id.id,
'quantity': 1,
'benefit_family_id': family.id,
'price_unit': family.benefit_member_count * validation_setting.meal_expense,
'price_unit': line.family_monthly_meals,
'analytic_account_id': family.branch_custom_id.branch.analytic_account_id.id
}))
# Create the invoice
invoice_vals = {
'move_type': 'in_invoice', # Set this to 'in_invoice' if it's a vendor bill
'partner_id': validation_setting.meal_partner_id.id, # The partner for the invoice
'invoice_date': rec.date, # The date of the invoice
'family_confirm_id': rec.id, # Link to the family expense record
'benefit_family_ids': [(6, 0, rec.family_ids.ids)], # Link to the families
'journal_id': rec.journal_id.id, # The journal for the invoice
'invoice_line_ids': invoice_lines, # The invoice lines
'ref': rec.name, # The reference for the invoice
'move_type': 'in_invoice',
'partner_id': validation_setting.meal_partner_id.id,
'invoice_date': rec.date,
'family_confirm_id': rec.id,
'benefit_family_ids': [(6, 0, rec.benefit_expense_line_ids.mapped('family_id').ids)],
'journal_id': rec.journal_id.id,
'invoice_line_ids': invoice_lines,
'ref': rec.name,
}
invoice = self.env['account.move'].create(invoice_vals)
invoice.action_confirm()
invoice.action_post()
rec.state = 'confirm'
return True
def _prepare_entry_lines(self, benefit, validation_setting, credit_account_id):
def _prepare_entry_lines(self, line,validation_setting):
"""Prepare debit and credit lines for a benefit"""
entry_lines = []
total_credit_amount = 0 # To accumulate the total credit amount
total_credit_amount = 0
expense_types = [
('meal', 'meal_expense', validation_setting.meal_expense_account_id.id),
('cash', 'cash_expense', validation_setting.cash_expense_account_id.id),
('clothing', 'clothing_expense', validation_setting.clothing_expense_account_id.id),
('family_monthly_income', 'cash_expense', validation_setting.cash_expense_account_id.id),
('family_monthly_meals', 'meal_expense',validation_setting.meal_expense_account_id.id ),
('family_monthly_clotting', 'clothing_expense', validation_setting.clothing_expense_account_id.id),
]
for expense_type, field, debit_account_id in expense_types:
amount = benefit.benefit_member_count * getattr(validation_setting, field, 0.0)
# Skip conditions based on expense type
if (benefit.district_id.meal_card and expense_type == 'meal') or (
not self.meal_expense and expense_type == 'meal'):
continue
if not self.cash_expense and expense_type == 'cash':
continue
if not self.cloth_expense and expense_type == 'clothing':
continue
# If there's an amount, create a debit line and accumulate the credit amount
for field, expense_type, debit_account_id in expense_types:
amount = getattr(line, field, 0.0)
if amount:
name = _("Family Code - %s Family Expense - %s - %s/%s") % (benefit.code ,expense_type, self.name,self.family_expense_seq)
entry_lines.append(self._create_debit_line(benefit, debit_account_id, amount, name))
name = _("Family Code - %s Family Expense - %s - %s/%s") % (
line.family_id.code, expense_type, self.name, self.family_expense_seq)
entry_lines.append(self._create_debit_line(line, debit_account_id, amount, name))
total_credit_amount += amount
return entry_lines, total_credit_amount
def _create_debit_line(self, benefit, account_id, amount, name):
def _create_debit_line(self, line, account_id, amount, name):
"""Create a debit line"""
return (0, 0, {
'name': name,
'family_confirm_id': self.id,
'benefit_family_id': benefit.id,
'partner_id': benefit.partner_id.id,
'analytic_account_id': benefit.branch_custom_id.branch.analytic_account_id.id,
'benefit_family_id': line.family_id.id,
'partner_id': line.family_id.partner_id.id,
'analytic_account_id': line.family_id.branch_custom_id.branch.analytic_account_id.id,
'account_id': account_id,
'debit': amount,
'credit': 0.0,
@ -476,7 +521,7 @@ class ConfirmBenefitExpense(models.Model):
# 'ref': self.name,
'ref': f'{self.name}/{self.family_expense_seq}',
'family_confirm_id': self.id,
'benefit_family_ids': [(6, 0, self.family_ids.ids)],
'benefit_family_ids': [(6, 0, self.benefit_expense_line_ids.mapped('family_id').ids)],
'line_ids': lines,
}
move_id = self.env['account.move'].create(move_vals)

View File

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
from dateutil.relativedelta import relativedelta
from odoo import models, fields, api, _
from odoo.exceptions import UserError
from odoo.tools import date_utils
class BenefitExpenseLine(models.Model):
_name = 'benefit.expense.line'
_description = 'Benefit Expense Line'
_inherit = ['mail.thread', 'mail.activity.mixin']
confirm_expense_id = fields.Many2one(comodel_name='confirm.benefit.expense', string='Confirm Benefit Expense',
ondelete='cascade')
family_id = fields.Many2one(comodel_name='grant.benefit', string='Family', required=True)
branch_id = fields.Many2one(comodel_name='branch.settings', string='Branch')
family_category_id = fields.Many2one(comodel_name='benefit.category', string='Family Category')
meal_card = fields.Boolean(string="Meal Card")
benefit_member_count = fields.Integer(string="Members count")
family_monthly_income = fields.Float(string="Family Monthly Income")
family_monthly_meals = fields.Float(string="Family Monthly Meals")
family_monthly_clotting = fields.Float(string="Family Monthly Clotting")
total_family_expenses = fields.Float(string="Total Family Expenses", compute='_compute_total_family_expenses')
start_date = fields.Date(string='Start Date', )
end_date = fields.Date(string='End Date', )
@api.depends('family_monthly_income', 'family_monthly_clotting', 'family_monthly_meals')
def _compute_total_family_expenses(self):
for rec in self:
total_family_expenses = 0.0
if rec.confirm_expense_id.cash_expense:
total_family_expenses += rec.family_monthly_income
if rec.confirm_expense_id.meal_expense:
total_family_expenses += rec.family_monthly_meals
if rec.confirm_expense_id.cloth_expense:
total_family_expenses += rec.family_monthly_clotting
rec.total_family_expenses = total_family_expenses

View File

@ -165,4 +165,5 @@ access_visit_location_refusal_reason_wizard,access_visit_location_refusal_reason
access_survey_user_input_group_benefit_info,survey.user_input.group_benefit_info,survey.model_survey_user_input,odex_benefit.group_benefit_info,1,0,0,0
access_survey_user_input_line_group_benefit_info,survey.user_input.line.group_benefit_info,survey.model_survey_user_input_line,odex_benefit.group_benefit_info,1,0,0,0
access_grant_benefit_account_move_line,access_grant_benefit_account_move_line,model_account_move_line,odex_benefit.group_benefit_info,1,0,0,0
access_grant_benefit_account_move,access_grant_benefit_account_move,model_account_move,odex_benefit.group_benefit_info,1,0,0,0
access_grant_benefit_account_move,access_grant_benefit_account_move,model_account_move,odex_benefit.group_benefit_info,1,0,0,0
access_benefit_expense_line,access_benefit_expense_line,model_benefit_expense_line,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
165 access_survey_user_input_group_benefit_info survey.user_input.group_benefit_info survey.model_survey_user_input odex_benefit.group_benefit_info 1 0 0 0
166 access_survey_user_input_line_group_benefit_info survey.user_input.line.group_benefit_info survey.model_survey_user_input_line odex_benefit.group_benefit_info 1 0 0 0
167 access_grant_benefit_account_move_line access_grant_benefit_account_move_line model_account_move_line odex_benefit.group_benefit_info 1 0 0 0
168 access_grant_benefit_account_move access_grant_benefit_account_move model_account_move odex_benefit.group_benefit_info 1 0 0 0
169 access_benefit_expense_line access_benefit_expense_line model_benefit_expense_line base.group_user 1 1 1 1

View File

@ -1003,6 +1003,8 @@
parent="odex_benefit.benefit_tools_services_settings_menu" action="services_settings_action" groups="odex_benefit.group_benefit_manager"/>
<menuitem id="services_requests_menu" name="Services Requests" sequence="2"
parent="odex_benefit.benefit_services" action="service_request_action"/>
<menuitem id="menu_confirm_benefit_expense_duplicate" name="Benefit Expense Flow" parent="odex_benefit.benefit_services"
action="action_confirm_benefit_expense" sequence="100"/>
<menuitem id="menu_service_request_accounting_accept" name="Services Requests" parent="account.menu_finance_payables"
action="service_request_accounting_action" sequence="9"/>

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Tree View -->
<record id="view_benefit_expense_line_tree" model="ir.ui.view">
<field name="name">benefit.expense.line.tree</field>
<field name="model">benefit.expense.line</field>
<field name="arch" type="xml">
<tree string="Benefit Expense Lines">
<field name="family_id"/>
<field name="branch_id"/>
<field name="family_category_id"/>
<field name="start_date" invisible="1"/>
<field name="end_date" invisible="1"/>
<field name="meal_card"/>
<field name="benefit_member_count"/>
<field name="family_monthly_income"/>
<field name="family_monthly_meals"/>
<field name="family_monthly_clotting"/>
<field name="total_family_expenses"/>
</tree>
</field>
</record>
<!-- Form View -->
<record id="view_benefit_expense_line_form" model="ir.ui.view">
<field name="name">benefit.expense.line.form</field>
<field name="model">benefit.expense.line</field>
<field name="arch" type="xml">
<form string="Benefit Expense Line">
<sheet>
<group>
<group>
<field name="family_id"/>
<field name="branch_id"/>
<field name="family_category_id"/>
<field name="meal_card"/>
<field name="benefit_member_count"/>
</group>
<group>
<field name="family_monthly_income"/>
<field name="family_monthly_meals"/>
<field name="family_monthly_clotting"/>
<field name="total_family_expenses" readonly="1"/>
</group>
</group>
<group invisible="1">
<field name="start_date"/>
<field name="end_date"/>
</group>
</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"/>
</div>
</form>
</field>
</record>
<!-- Action -->
<record id="action_benefit_expense_line" model="ir.actions.act_window">
<field name="name">Benefit Expense Lines</field>
<field name="res_model">benefit.expense.line</field>
<field name="view_mode">tree,form</field>
</record>
</odoo>

View File

@ -23,20 +23,32 @@
<form string="Confirm Benefit Expense">
<header>
<field name="state" widget="statusbar"
statusbar_visible="draft,assistant_general_manager,depart_manager,account_manager,confirm"/>
<!-- <button string="Cancel" type="object" name="action_cancel" class="btn btn-danger"-->
<!-- states="assistant_general_manager,depart_manager,account_manager"-->
<!-- groups="odex_benefit.group_benefit_manager"/>-->
statusbar_visible="draft,calculated,assistant_general_manager,depart_manager,account_manager,confirm"/>
<!-- <button string="Cancel" type="object" name="action_cancel" class="btn btn-danger"-->
<!-- states="assistant_general_manager,depart_manager,account_manager"-->
<!-- groups="odex_benefit.group_benefit_manager"/>-->
<button name="action_calculate" string="Calculate"
type="object" states="draft" class="btn btn-info"/>
<button string="Confirm" type="object" name="action_assistant_manager" class="oe_highlight"
states="draft"/>
states="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 string="Confirm" type="object" name="action_depart_manager" class="oe_highlight"
states="assistant_general_manager" groups="odex25_account_payment_fix.group_depart_manager"/>
states="assistant_general_manager"
groups="odex25_account_payment_fix.group_depart_manager"/>
<button string="Reset" type="object" name="action_reset_to_draft" class="btn btn-danger"
states="assistant_general_manager" groups="odex25_account_payment_fix.group_depart_manager"/>
states="assistant_general_manager"
groups="odex25_account_payment_fix.group_depart_manager"/>
<button string="Confirm" type="object" name="action_accounting_manager" class="oe_highlight"
states="depart_manager" groups="odex25_account_payment_fix.group_accounting_manager"/>
<button string="Reset" type="object" name="action_reset_to_draft" class="btn btn-danger"
states="depart_manager" groups="odex25_account_payment_fix.group_accounting_manager"/>
<button string="Confirm" type="object" name="action_confirm_selected" class="oe_highlight"
states="account_manager" groups="odex25_account_payment_fix.group_general_manager"/>
<button string="Reset" type="object" name="action_reset_to_draft" class="btn btn-danger"
@ -58,7 +70,9 @@
<div>
<field name="start_date"
attrs="{'readonly':[('state', '!=', 'draft')]}"/>
<strong><label for="end_date"/></strong>
<strong>
<label for="end_date"/>
</strong>
<field name="end_date"
attrs="{'readonly':[('state', '!=', 'draft')]}"/>
</div>
@ -68,8 +82,9 @@
</group>
<group>
<field name="expense_type" required="1"/>
<field name="journal_id" required="1" domain="[('id', 'in', journal_domain_ids)]"
attrs="{'invisible': [('expense_type', '!=', 'family_invoice')]}" forec_save="1"/>
<field name="journal_id" domain="[('id', 'in', journal_domain_ids)]"
attrs="{'required': [('expense_type', '=', 'family_invoice')],'invisible': [('expense_type', '!=', 'family_invoice')]}"
forec_save="1"/>
<field name="date" required="1" attrs="{'readonly':[('state', '!=', 'draft')]}"/>
</group>
</group>
@ -96,27 +111,26 @@
</group>
<!-- Notebook with Families page -->
<notebook>
<page string="Families">
<field name="family_ids" domain="[('id', 'in', family_domain_ids)]">
<tree string="Family">
<field name="code"/>
<field name="name"/>
<field name="sms_phone" optional="hide"/>
<field name="researcher_id" optional="hide"/>
<field name="sa_iban" />
<!-- <field name="father_id_number" />-->
<page string="Family Monthly Expense" attrs="{'invisible': [('state', '=', 'draft')]}">
<field name="benefit_expense_line_ids" readonly="1">
<tree editable="bottom">
<field name="family_id"/>
<field name="branch_id"/>
<field name="family_category_id"/>
<field name="start_date" invisible="1"/>
<field name="end_date" invisible="1"/>
<field name="meal_card"/>
<field name="benefit_member_count"/>
<field name="non_member_count" optional="hide"/>
<field name="family_monthly_income" attrs="{'column_invisible': [('parent.expense_type', '!=', 'family_expense')]}"/>
<field name="family_monthly_meals"/>
<field name="family_monthly_clotting" attrs="{'column_invisible': [('parent.expense_type', '!=', 'family_expense')]}"/>
<field name="total_family_expenses" attrs="{'column_invisible': [('parent.expense_type', '!=', 'family_expense')]}"/>
<field name="last_disbursement_date" optional="hide"/>
<!-- <field name="last_visit_date" optional="hide"/>-->
<field name="family_monthly_income" attrs="{'column_invisible': [('parent.cash_expense', '!=', True)]}"/>
<field name="family_monthly_meals" attrs="{'column_invisible': [('parent.meal_expense', '!=', True)]}"/>
<field name="family_monthly_clotting" attrs="{'column_invisible': [('parent.cloth_expense', '!=', True)]}"/>
<field name="total_family_expenses"/>
</tree>
</field>
</page>
<page string="Families">
<field name="family_ids" domain="[('id', 'in', family_domain_ids)]"/>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
@ -127,6 +141,8 @@
</form>
</field>
</record>
<!-- Search view-->
<record model="ir.ui.view" id="view_confirm_benefit_expense_search">
<field name="name">confirm.benefit.expense</field>
<field name="model">confirm.benefit.expense</field>