From 73b7bf3bc43d1370bfc7b948300393304f513f7e Mon Sep 17 00:00:00 2001 From: younes Date: Sun, 9 Nov 2025 16:01:23 +0100 Subject: [PATCH 1/2] [IMP] odex_benefit: IMP benefit --- .../odex_benefit/data/server_actions.xml | 15 +- odex25_ensan/odex_benefit/i18n/ar_001.po | 36 ++-- .../odex_benefit/models/family_expense.py | 79 +-------- .../models/family_expense_line.py | 1 + .../models/family_validation_setting.py | 1 + .../odex_benefit/models/payment_order.py | 131 ++++++++++++--- .../odex_benefit/models/seasonal_service.py | 7 + .../odex_benefit/models/service_request.py | 158 +++++++----------- .../odex_benefit/models/services_settings.py | 5 + .../views/family_expense_line_view.xml | 2 + .../views/family_expense_view.xml | 1 + .../views/family_validation_setting.xml | 1 + .../odex_benefit/views/payment_order.xml | 43 ++++- .../views/seasonal_service_view.xml | 31 ++-- .../odex_benefit/views/service_request.xml | 6 +- .../odex_benefit/views/services_settings.xml | 1 + 16 files changed, 281 insertions(+), 237 deletions(-) diff --git a/odex25_ensan/odex_benefit/data/server_actions.xml b/odex25_ensan/odex_benefit/data/server_actions.xml index 26feb0a10..e4e5c7bf0 100644 --- a/odex25_ensan/odex_benefit/data/server_actions.xml +++ b/odex25_ensan/odex_benefit/data/server_actions.xml @@ -2,13 +2,13 @@ - - Exchange orders + + Accounting Transfer code - action = records.action_create_payment_order() + action = records.action_accounting_transfer() @@ -22,15 +22,6 @@ - - - Create Vendor Bill - - - code - action = records.create_vendor_bill() - - Assign Visit Sequence diff --git a/odex25_ensan/odex_benefit/i18n/ar_001.po b/odex25_ensan/odex_benefit/i18n/ar_001.po index 32da4817f..c3f981abb 100644 --- a/odex25_ensan/odex_benefit/i18n/ar_001.po +++ b/odex25_ensan/odex_benefit/i18n/ar_001.po @@ -4523,8 +4523,6 @@ msgstr "" #: model:ir.model.fields.selection,name:odex_benefit.selection__receive_benefit_zkat__state__done #: model:ir.model.fields.selection,name:odex_benefit.selection__receive_food_basket__state__done #: model:ir.model.fields.selection,name:odex_benefit.selection__visit_location__state__done -#: model:ir.model.fields.selection,name:odex_benefit.selection__payment_orders__state__done -#: model:ir.model.fields.selection,name:odex_benefit.selection__seasonal_service__state__done #: model_terms:ir.ui.view,arch_db:odex_benefit.appliances_furniture_form #: model_terms:ir.ui.view,arch_db:odex_benefit.benefit_club_form #: model_terms:ir.ui.view,arch_db:odex_benefit.benefit_food_basket_form @@ -4537,6 +4535,12 @@ msgstr "" msgid "Done" msgstr "تمت الزيارة" +#. module: odex_benefit +#: model:ir.model.fields.selection,name:odex_benefit.selection__payment_orders__state__done +#: model:ir.model.fields.selection,name:odex_benefit.selection__seasonal_service__state__done +msgid "Done" +msgstr "تم" + #. module: odex_benefit #: model:ir.model.fields,field_description:odex_benefit.field_receive_appliances_furniture__donor_name msgid "Donor Name" @@ -11513,7 +11517,7 @@ msgid "Total" msgstr "الإجمالي" #. module: odex_benefit -#: code:addons/odex_benefit/models/family_expense.py:0 +#: code:addons/odex_benefit/models/payment_order.py:0 #, python-format msgid "Total Credit for Family Expenses" msgstr "ملفات تغذيه تحت الصرف" @@ -14307,6 +14311,7 @@ msgstr "إعتماد إدارة المالية" #. module: odex_benefit #: model:ir.model.fields.selection,name:odex_benefit.selection__service_request__state__accounting_approve +#: model:ir.model.fields.selection,name:odex_benefit.selection__seasonal_service__state__accounting_approve msgid "Accounting Approve" msgstr "بانتظار المالية" @@ -14363,7 +14368,7 @@ msgstr "فئة الأسرة" #: model:ir.model.fields,field_description:odex_benefit.field_seasonal_grant_benefit__aid_amount #: model:ir.model.fields,field_description:odex_benefit.field_seasonal_service__aid_amount msgid "Aid Amount" -msgstr "مبلغ المساعدة" +msgstr "قيمة الخدمة" #. module: odex_benefit #: model:ir.model.fields,field_description:odex_benefit.field_seasonal_service__family_count @@ -14378,7 +14383,7 @@ msgstr "عدد الأفراد المستفيدين" #. module: odex_benefit #: model:ir.model.fields,field_description:odex_benefit.field_seasonal_service__family_disbursement_total_amount msgid "Total Family Disbursement Amount" -msgstr "إجمالي مبلغ صرف الخدمة للأسر" +msgstr "الأجمالي" #. module: odex_benefit #: model:ir.model.fields,field_description:odex_benefit.field_seasonal_grant_benefit__family_id @@ -14411,7 +14416,6 @@ msgid "Expenses Account" msgstr "حساب المصروف" #. module: odex_benefit -#: model:ir.actions.server,name:odex_benefit.server_action_exchange_orders #: model:ir.actions.server,name:odex_benefit.server_action_seasonal_service_exchange_orders msgid "Exchange orders" msgstr "أمر الصرف" @@ -14438,6 +14442,11 @@ msgstr "أمر الصرف تم" msgid "Payment Order Done" msgstr "أمر الصرف تم" +#. module: odex_benefit +#: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_form +msgid "Payment Done" +msgstr "تم الدفع" + #. module: odex_benefit #: model:ir.model.fields,field_description:odex_benefit.field_payment_orders__is_seasonal #: model:ir.model.fields,field_description:odex_benefit.field_service_request__is_seasonal @@ -16913,7 +16922,6 @@ msgstr "يجب إضافة طلب خدمة واحد على الأقل." #. module: odex_benefit #: code:addons/odex_benefit/models/service_request.py:0 -#: code:addons/odex_benefit/models/service_request.py:0 #, python-format msgid "" "All selected service requests must belong to the same Service Cat.\n" @@ -16924,7 +16932,6 @@ msgstr "يجب أن تنتمي جميع طلبات الخدمة المحددة #. module: odex_benefit #: code:addons/odex_benefit/models/service_request.py:0 -#: code:addons/odex_benefit/models/service_request.py:0 #, python-format msgid "" "The following service requests do not meet the conditions:\n" @@ -16933,20 +16940,17 @@ msgid "" "• Be in 'Accounting Approve' state\n" "• Have payment order state = 'None'\n" "• Not be linked to any payment order" -msgstr "طلبات الخدمة التالية لا تستوفي الشروط:\n%s\nيجب أن يكون كل طلب:\n• في حالة 'موافقة المحاسبة'\n• حالة أمر الدفع = 'لا يوجد'\n• غير مرتبط بأي أمر دفع" - -#. module: odex_benefit -#: code:addons/odex_benefit/models/service_request.py:0 -#, python-format -msgid "Only 'Electrical Devices' service cat requests can create a invoice." -msgstr "يمكن فقط لطلبات فئة خدمة 'الأجهزة الكهربائية' إنشاء فاتورة." +msgstr "طلبات الخدمة التالية لا تستوفي الشروط:\n%s\nيجب أن يكون كل طلب:\n• في حالة 'بانتظار المالية'\n• حالة أمر الدفع = 'لا يوجد'\n• غير مرتبط بأي أمر دفع" #. module: odex_benefit #: model_terms:ir.ui.view,arch_db:odex_benefit.payment_orders_form msgid "Manager approval" msgstr "موافقة المسؤول" - +#. module: odex_benefit +#: model_terms:ir.ui.view,arch_db:odex_benefit.service_request_form +msgid "Payment Waiting" +msgstr "في انتظار الدفع" #. module: odex_benefit #: code:addons/odex_benefit/models/service_request.py:0 diff --git a/odex25_ensan/odex_benefit/models/family_expense.py b/odex25_ensan/odex_benefit/models/family_expense.py index b11d41233..17b37b6c1 100644 --- a/odex25_ensan/odex_benefit/models/family_expense.py +++ b/odex25_ensan/odex_benefit/models/family_expense.py @@ -82,7 +82,8 @@ class ConfirmBenefitExpense(models.Model): family_domain_ids = fields.Many2many(comodel_name='grant.benefit', compute='_compute_domain_ids') journal_domain_ids = fields.Many2many(comodel_name='account.journal', compute='_compute_domain_ids') company_id = fields.Many2one('res.company', default=lambda self: self.env.company) - currency_id = fields.Many2one(comodel_name='res.currency',string="Company Currency",related='company_id.currency_id') + currency_id = fields.Many2one(comodel_name='res.currency', string="Company Currency", + related='company_id.currency_id') @api.model def create(self, vals): @@ -111,7 +112,7 @@ class ConfirmBenefitExpense(models.Model): self.ensure_one() for line in self.benefit_expense_line_ids: family = line.family_id - income,meals,clotting = 0,0,0 + income, meals, clotting = 0, 0, 0 if not family: continue monthly_meals = family.family_monthly_meals @@ -439,16 +440,12 @@ class ConfirmBenefitExpense(models.Model): if not credit_account_id: raise UserError(_("Please select credit account.")) - 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, inv_lines) + self.env['payment.orders'].create({ + 'state': 'draft', + 'accountant_id': validation_setting.accountant_id.id, + 'benefit_expense_line_ids': [(6, 0, rec.benefit_expense_line_ids.ids)], + 'type': 'benefit_expense', + }) else: account_id = validation_setting.meal_expense_account_id invoice_lines = [] @@ -478,61 +475,3 @@ class ConfirmBenefitExpense(models.Model): rec.state = 'confirm' return True - - def _prepare_entry_lines(self, line,validation_setting): - """Prepare debit and credit lines for a benefit""" - entry_lines = [] - total_credit_amount = 0 - expense_types = [ - ('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 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") % ( - 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, line, account_id, amount, name): - """Create a debit line""" - return (0, 0, { - 'name': name, - 'family_confirm_id': self.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, - }) - - def _create_credit_line(self, account_id, amount, name): - """Create a credit line""" - return (0, 0, { - 'name': name, - 'family_confirm_id': self.id, - 'account_id': account_id, - 'debit': 0.0, - 'credit': amount, - }) - - def create_entry(self, journal_id, lines): - """Create an account move entry""" - move_vals = { - 'journal_id': journal_id, - 'date': self.date, - # 'ref': self.name, - 'ref': f'{self.name}/{self.family_expense_seq}', - 'family_confirm_id': self.id, - '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) - move_id.action_post() - return True diff --git a/odex25_ensan/odex_benefit/models/family_expense_line.py b/odex25_ensan/odex_benefit/models/family_expense_line.py index f02448e7d..b2b209139 100644 --- a/odex25_ensan/odex_benefit/models/family_expense_line.py +++ b/odex25_ensan/odex_benefit/models/family_expense_line.py @@ -23,6 +23,7 @@ class BenefitExpenseLine(models.Model): 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', ) + payment_order_id = fields.Many2one('payment.orders', string='Payment Order', ondelete="set null", copy=False) @api.depends('family_monthly_income', 'family_monthly_clotting', 'family_monthly_meals') def _compute_total_family_expenses(self): diff --git a/odex25_ensan/odex_benefit/models/family_validation_setting.py b/odex25_ensan/odex_benefit/models/family_validation_setting.py index a8d5a8f99..6ea0ec399 100644 --- a/odex25_ensan/odex_benefit/models/family_validation_setting.py +++ b/odex25_ensan/odex_benefit/models/family_validation_setting.py @@ -32,6 +32,7 @@ class FamilyValidationSetting(models.Model): meal_partner_id = fields.Many2one('res.partner', string='Meal Partner') journal_id = fields.Many2one('account.journal', string='Journal') account_id = fields.Many2one('account.account',string='Expenses Account') + accountant_id = fields.Many2one('res.users', string='Accountant') @api.constrains('meal_expense_account_id', 'clothing_expense_account_id', 'cash_expense_account_id') def _constraint_amount_should_be_positive_if_account_selected(self): diff --git a/odex25_ensan/odex_benefit/models/payment_order.py b/odex25_ensan/odex_benefit/models/payment_order.py index 6933c442a..c32b0e8e7 100644 --- a/odex25_ensan/odex_benefit/models/payment_order.py +++ b/odex25_ensan/odex_benefit/models/payment_order.py @@ -22,6 +22,8 @@ class PaymentOrders(models.Model): inverse='_inverse_service_type_id', store=True) service_requests_ids = fields.One2many('service.request', 'payment_order_id', string='Service Requests') + benefit_expense_line_ids = fields.One2many('benefit.expense.line', 'payment_order_id', + string='Benefit Expense Lines') 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') @@ -31,11 +33,20 @@ class PaymentOrders(models.Model): ('waiting_head', 'Waiting for Head of Expenses Department'), ('waiting_finance', 'Waiting for Financial Manager'), ('waiting_gm', 'Waiting for General Manager'), + ('waiting_deposit', 'Waiting for Deposit'), ('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) + domain="[('type','in',['cash','bank'])]", required=True, default=_default_journal) + type = fields.Selection( + selection=[ + ('services', 'Services'), + ('seasonal_services', 'Seasonal Services'), + ('benefit_expense', 'Monthly Expense'), + ], + string='Payment Order Type', required=True, default='services', ) + move_id = fields.Many2one('account.move', ondelete='cascade') def action_manager_approval(self): for rec in self: @@ -49,19 +60,42 @@ class PaymentOrders(models.Model): 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 create_entry(self): + for rec in self: + vals = {} + line_ids = rec.get_lines() + move_vals = { + 'journal_id': rec.journal_id.id, + # 'payment_order_id': rec.id, # bug + 'line_ids': line_ids, + 'ref': f'{rec.payment_order_description}/{rec.ref_num}', + } + if rec.type == "benefit_expense": + # ref1 = ", ".join(rec.benefit_expense_line_ids.mapped('name')) + # ref2 = ", ".join(rec.benefit_expense_line_ids.mapped('family_expense_seq')) + family_ids = rec.benefit_expense_line_ids.mapped('family_id').ids + + move_vals.update({ + # 'ref': ref1 + '/' + ref2, + 'benefit_family_ids': [(6, 0, family_ids)], + }) + move_id = self.env['account.move'].create(vals) + #move_id.action_post() + rec.move_id = move_id + + def action_deposit(self): + for rec in self: + if rec.type == "seasonal_services": + rec.seasonal_requests_ids.action_accounting_approve() + elif rec.type == "services": + rec.service_requests_ids.write({'state':'action_accounting_approve'}) + rec.state = 'waiting_deposit' + def action_gm_approval(self): for rec in self: - rec.state = 'done' + rec.state = 'waiting_deposit' def action_refuse(self): for rec in self: @@ -104,6 +138,12 @@ class PaymentOrders(models.Model): res.name = self.env['ir.sequence'].sudo().next_by_code('payment.orders.sequence') or _('New') return res + def unlink(self): + for payment in self: + if payment.state not in ['draft']: + raise ValidationError(_('You cannot delete this record')) + return super(PaymentOrders, self).unlink() + @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( @@ -129,26 +169,67 @@ class PaymentOrders(models.Model): 'domain': [('id', 'in', moves)], } + def _prepare_entry_lines(self, line, validation_setting): + entry_lines = [] + total_credit_amount = 0 + expense_types = [ + ('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 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") % ( + line.family_id.code, expense_type, line.confirm_expense_id.name, + line.confirm_expense_id.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, line, account_id, amount, name): + """Create a debit line""" + return (0, 0, { + 'name': name, + 'family_confirm_id': line.confirm_expense_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, + }) + def get_lines(self): lines = [] total_credit = 0 - if self.service_requests_ids: - for request in self.service_requests_ids: - lines.append( - { - 'name': f'{"Family code"}{request.family_id.code}-{request.description}-{request.payment_order_id.name}-{request.payment_order_id.ref_num}', - 'benefit_family_id': request.family_id.id, - 'account_id': request.account_id.id, - 'partner_id': request.family_id.partner_id.id, - 'analytic_account_id': request.branch_custom_id.branch.analytic_account_id.id, - 'debit': request.requested_service_amount, - 'credit': 0.0, - } - ) - total_credit += request.aid_amount + # credit_line_name = _("Total Credit for Family Expenses") + if self.type in ['seasonal_services', 'services']: + if self.service_requests_ids: + for request in self.service_requests_ids: + lines.append( + { + 'name': f'{"Family code"}{request.family_id.code}-{request.description}-{request.payment_order_id.name}-{request.payment_order_id.ref_num}', + 'benefit_family_id': request.family_id.id, + 'account_id': request.account_id.id, + 'partner_id': request.family_id.partner_id.id, + 'analytic_account_id': request.branch_custom_id.branch.analytic_account_id.id, + 'debit': request.requested_service_amount, + 'credit': 0.0, + } + ) + total_credit += request.aid_amount + elif self.type == 'benefit_expense': + validation_setting = self.env["family.validation.setting"].search([], limit=1) + for line in self.benefit_expense_line_ids: + sum_line, credit_total = self._prepare_entry_lines(line, validation_setting) + total_credit += credit_total + lines += sum_line lines.append({ - 'account_id': self.env["family.validation.setting"].search([], limit=1).account_id.id, + 'account_id': self.journal_id.default_account_id.id, 'name': f'{self.name}-{self.ref_num}', 'credit': total_credit, 'debit': 0.0, diff --git a/odex25_ensan/odex_benefit/models/seasonal_service.py b/odex25_ensan/odex_benefit/models/seasonal_service.py index 1225451a9..e4edcc62f 100644 --- a/odex25_ensan/odex_benefit/models/seasonal_service.py +++ b/odex25_ensan/odex_benefit/models/seasonal_service.py @@ -9,6 +9,7 @@ from dateutil.relativedelta import relativedelta class SeasonalService(models.Model): _name = 'seasonal.service' _inherit = ['mail.thread', 'mail.activity.mixin'] + _order = "name desc" name = fields.Char(string='Reference', required=True, copy=False, readonly=True, index=True, default=lambda self: _('New')) @@ -204,6 +205,7 @@ class SeasonalService(models.Model): 'seasonal_requests_ids': rec.ids, 'service_requests_ids': rec.service_requests_ids.ids, 'is_seasonal': True, + 'type': 'seasonal_services', }) # rec.payment_order_id = payment_order.id rec.is_payment_order_done = True @@ -272,6 +274,11 @@ class SeasonalService(models.Model): rec.service_requests_ids.unlink() rec.state = 'draft' + def action_reset_to_calculated(self): + for rec in self: + rec.service_requests_ids.write({'state': 'draft'}) + rec.state = 'calculated' + class SeasonalGrantBenefit(models.Model): _name = 'seasonal.grant.benefit' diff --git a/odex25_ensan/odex_benefit/models/service_request.py b/odex25_ensan/odex_benefit/models/service_request.py index e1d5c1284..b2fb549ce 100644 --- a/odex25_ensan/odex_benefit/models/service_request.py +++ b/odex25_ensan/odex_benefit/models/service_request.py @@ -120,7 +120,7 @@ class ServiceRequest(models.Model): # 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', ondelete="set null") + payment_order_id = fields.Many2one('payment.orders', string='Payment Order', ondelete="set null", copy=False) 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 @@ -129,7 +129,7 @@ class ServiceRequest(models.Model): # 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') + vendor_bill = fields.Many2one('account.move', copy=False) 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', @@ -146,10 +146,6 @@ class ServiceRequest(models.Model): # ('programs_transportation', 'Programs Transportation'), # ], string='Service Reason') service_reason_id = fields.Many2one('transportation.insurance') - # max_government_transportation_amount = fields.Float(string='Max Government Transportation Amount') - # max_universities_training_institutes_transportation_amount = fields.Float(string='Max Universities Training Institutes Transportation Amount') - # 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) # Marriage @@ -222,13 +218,19 @@ class ServiceRequest(models.Model): ('waiting', 'Waiting Payment'), ('done', 'Done Payment'), ], copy=False, compute="_compute_payment_order_state", store=True) - @api.depends('payment_order_id', 'payment_order_id.state') + @api.depends('payment_order_id', 'payment_order_id.state', 'vendor_bill', 'vendor_bill.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: if rec.payment_order_id.state == "done": payment_order_state = "done" + rec.is_payment_order_done = True + else: + payment_order_state = "waiting" + elif rec.vendor_bill: + if rec.vendor_bill.state == "posted": + payment_order_state = "done" else: payment_order_state = "waiting" rec.payment_order_state = payment_order_state @@ -974,59 +976,7 @@ class ServiceRequest(models.Model): for rec in self: rec.state = 'draft' - def action_open_exchange_order_wizard(self): - ids = [] - for rec in self: - ids.append(rec.id) - default_service_ids = ids - service_requests = self.env['service.request'].browse(ids) - if any(request.state not in 'send_request_to_supplier' for request in service_requests): - raise UserError(_("All selected requests should be in Accounting Approve state")) - if any(request.payment_order_id for request in service_requests): - 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} - } - - 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): + def action_accounting_transfer(self): line_ids = [] service_cats = self.mapped('service_cat') if len(service_cats) > 1: @@ -1036,39 +986,59 @@ class ServiceRequest(models.Model): "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.")) + if service_cats.payment_method == "payment_order": + invalid_records = self.filtered( + lambda r: r.state != 'accounting_approve' + or r.payment_order_state != 'none' + or r.payment_order_id + ) - 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) - 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: - invoice_line = (0, 0, { - '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, + self.env['payment.orders'].create({ + 'state': 'draft', + 'accountant_id': service_cats.accountant_id.id, + 'service_requests_ids': [(6, 0, self.ids)], + 'type': 'services', }) - line_ids.append(invoice_line) - vendor_bill = self.env['account.move'].create({ - '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 + elif service_cats.payment_method == "invoice": + invalid_records = self.filtered( + lambda r: r.state != 'accounting_approve' + or r.payment_order_state != 'none' + or r.vendor_bill + ) + + 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 invoice" + ) % names) + + for rec in self: + invoice_line = (0, 0, { + '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': self[0].service_producer_id.id, + # 'accountant_id': self.accountant_id.id, + 'invoice_line_ids': line_ids, + }) + self.vendor_bill = vendor_bill diff --git a/odex25_ensan/odex_benefit/models/services_settings.py b/odex25_ensan/odex_benefit/models/services_settings.py index c60b0d621..4b2ff759f 100644 --- a/odex25_ensan/odex_benefit/models/services_settings.py +++ b/odex25_ensan/odex_benefit/models/services_settings.py @@ -111,6 +111,11 @@ class ServicesSettings(models.Model): help='Specify the maximum allowed number of months when the period type is monthly.' ) in_kind = fields.Boolean(string="In Kind") + payment_method = fields.Selection([ + ('none', 'None'), + ('payment_order', 'Payment Order'), + ('invoice', 'Invoice'), + ], string='Payment Method',default="payment_order") diff --git a/odex25_ensan/odex_benefit/views/family_expense_line_view.xml b/odex25_ensan/odex_benefit/views/family_expense_line_view.xml index 2fbe2975d..72789dc73 100644 --- a/odex25_ensan/odex_benefit/views/family_expense_line_view.xml +++ b/odex25_ensan/odex_benefit/views/family_expense_line_view.xml @@ -17,6 +17,7 @@ + @@ -35,6 +36,7 @@ + diff --git a/odex25_ensan/odex_benefit/views/family_expense_view.xml b/odex25_ensan/odex_benefit/views/family_expense_view.xml index 1a3f76ba9..6250f9ce4 100644 --- a/odex25_ensan/odex_benefit/views/family_expense_view.xml +++ b/odex25_ensan/odex_benefit/views/family_expense_view.xml @@ -152,6 +152,7 @@ + diff --git a/odex25_ensan/odex_benefit/views/family_validation_setting.xml b/odex25_ensan/odex_benefit/views/family_validation_setting.xml index f2f8833d9..cc9a383df 100644 --- a/odex25_ensan/odex_benefit/views/family_validation_setting.xml +++ b/odex25_ensan/odex_benefit/views/family_validation_setting.xml @@ -40,6 +40,7 @@ + diff --git a/odex25_ensan/odex_benefit/views/payment_order.xml b/odex25_ensan/odex_benefit/views/payment_order.xml index e7016d26f..4452d1c1c 100644 --- a/odex25_ensan/odex_benefit/views/payment_order.xml +++ b/odex25_ensan/odex_benefit/views/payment_order.xml @@ -24,6 +24,15 @@ states="waiting_gm" string="Approve" class="oe_highlight"/> +