From 551652659e2fad4c603923edae6634d8e8fcfe22 Mon Sep 17 00:00:00 2001 From: younes Date: Thu, 11 Dec 2025 14:41:17 +0100 Subject: [PATCH] [IMP] odex_benefit: IMP benefit --- odex25_benefit/odex_benefit/MODULE_REVIEW.md | 2 +- .../odex_benefit/data/server_actions.xml | 2 +- .../odex_benefit/models/seasonal_service.py | 113 +++++++++++++++++- .../odex_benefit/models/service_request.py | 2 +- .../views/seasonal_service_view.xml | 29 ++++- 5 files changed, 135 insertions(+), 13 deletions(-) diff --git a/odex25_benefit/odex_benefit/MODULE_REVIEW.md b/odex25_benefit/odex_benefit/MODULE_REVIEW.md index f1386f66a..45686a709 100644 --- a/odex25_benefit/odex_benefit/MODULE_REVIEW.md +++ b/odex25_benefit/odex_benefit/MODULE_REVIEW.md @@ -212,7 +212,7 @@ - `_get_estimated_rent_amount()`: حساب المبلغ المقدر للإيجار - `_get_aid_amount()`: حساب مبلغ المساعدة - `_compute_attachment_lines()`: حساب المرفقات المطلوبة -- `action_create_payment_order()`: إنشاء أمر دفع +- `action_accounting_transfer()`: إنشاء أمر دفع - `create_vendor_bill()`: إنشاء فاتورة مورد #### 1.4 `visit.location` - الزيارات diff --git a/odex25_benefit/odex_benefit/data/server_actions.xml b/odex25_benefit/odex_benefit/data/server_actions.xml index e4e5c7bf0..033ea1973 100644 --- a/odex25_benefit/odex_benefit/data/server_actions.xml +++ b/odex25_benefit/odex_benefit/data/server_actions.xml @@ -18,7 +18,7 @@ code - action = records.action_create_payment_order() + action = records.action_accounting_transfer() diff --git a/odex25_benefit/odex_benefit/models/seasonal_service.py b/odex25_benefit/odex_benefit/models/seasonal_service.py index ccfc177c8..53b0ed0fd 100644 --- a/odex25_benefit/odex_benefit/models/seasonal_service.py +++ b/odex25_benefit/odex_benefit/models/seasonal_service.py @@ -37,6 +37,9 @@ class SeasonalService(models.Model): 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, ondelete="set null") + payment_order_count = fields.Integer(compute='_compute_payment_order', string='Number of Payment Orders') + vendor_bill = fields.Many2one('account.move', copy=False) + total_moves = fields.Integer(string="Total Move", compute='_get_total_move_lines') state = fields.Selection(selection=[ ('draft', 'Draft'), ('calculated', 'Calculated'), @@ -69,19 +72,42 @@ class SeasonalService(models.Model): 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') + @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.service_requests_ids.write({'state': 'send_request_to_supplier'}) + rec.state = 'waiting_receive' + else: + payment_order_state = "waiting" + elif rec.vendor_bill: + if rec.vendor_bill.state == "posted": + payment_order_state = "done" rec.state = 'waiting_receive' else: payment_order_state = "waiting" rec.payment_order_state = payment_order_state + @api.depends('payment_order_id') + def _compute_payment_order(self): + for rec in self: + if rec.payment_order_id: + rec.payment_order_count = 1 + else: + rec.payment_order_count = 0 + + @api.depends('vendor_bill', 'payment_order_id') + def _get_total_move_lines(self): + for rec in self: + if rec.service_type_id.payment_method == "payment_order": + moves = rec.payment_order_id.mapped('move_id') + elif rec.service_type_id.payment_method == "invoice": + moves = rec.vendor_bill + + rec.total_moves = len(moves) + @api.depends('benefit_ids', 'service_type_id') def _compute_allowed_member_ids(self): for rec in self: @@ -185,6 +211,55 @@ class SeasonalService(models.Model): # rec.payment_order_id = payment_order.id rec.is_payment_order_done = True + def action_accounting_transfer(self): + validation_setting = self.env["family.validation.setting"].search([], limit=1) + line_ids = [] + for rec in self: + if rec.state != 'accounting_approve': + raise UserError(_( + "All selected requests must be in 'Accounting Approve' state." + )) + if rec.service_type_id.payment_method == "payment_order": + if rec.payment_order_id: + raise UserError(_( + "A payment order is already linked to this request: %s" + ) % rec.name) + payment_order = 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, + 'type': 'seasonal_services', + }) + rec.payment_order_id = payment_order.id + elif rec.service_type_id.payment_method == "invoice": + if rec.vendor_bill: + raise UserError(_( + "A vendor bill is already linked to this request: %s" + ) % rec.name) + if not rec.service_requests_ids: + raise UserError(_( + "No service requests found to generate a vendor bill for: %s" + ) % rec.name) + for request in rec.service_requests_ids: + invoice_line = (0, 0, { + 'name': f'{request.family_id.name}/{request.description}-{request.name}', + 'benefit_family_id': request.family_id.id, + 'account_id': request.account_id.id, + 'analytic_account_id': request.family_id.branch_family_id.branch.analytic_account_id.id, + 'quantity': request.requested_quantity or 1, # todo check + 'price_unit': request.requested_service_amount, + }) + line_ids.append(invoice_line) + vendor_bill = self.env['account.move'].create({ + 'move_type': 'in_invoice', + 'partner_id': rec.service_type_id.service_producer_id.id, + 'journal_id': validation_setting.journal_id.id, + 'invoice_line_ids': line_ids, + }) + rec.vendor_bill = vendor_bill + @api.depends('service_requests_ids') def compute_family_benefit(self): for record in self: @@ -223,7 +298,7 @@ class SeasonalService(models.Model): rec.state = 'gm_assistant' rec.service_requests_ids.write({'state': 'gm_assistant'}) elif rec.service_delivery_method == "cash": - # rec.action_create_payment_order() + # rec.action_accounting_transfer() rec.state = "accounting_approve" rec.service_requests_ids.write({'state': 'accounting_approve'}) elif rec.service_delivery_method == "in_kind": @@ -233,7 +308,7 @@ class SeasonalService(models.Model): def action_approval_of_gm_assistant(self): for rec in self: if rec.service_delivery_method == "cash": - # rec.action_create_payment_order() + # rec.action_accounting_transfer() rec.state = "accounting_approve" rec.service_requests_ids.write({'state': 'accounting_approve'}) elif rec.service_delivery_method == "in_kind": @@ -317,3 +392,31 @@ class SeasonalService(models.Model): for rec in self: rec.service_requests_ids.write({'state': 'draft'}) rec.state = 'calculated' + + def action_open_related_move_records(self): + if self.service_type_id.payment_method == "payment_order": + moves = self.payment_order_id.mapped('move_id') + elif self.service_type_id.payment_method == "invoice": + moves = self.vendor_bill + + return { + 'name': _('Vendor Bills'), + 'type': 'ir.actions.act_window', + 'res_model': 'account.move', + 'view_mode': 'tree,form', + 'domain': [('id', 'in', moves.ids)], + } + + def action_open_payment_orders(self): + self.ensure_one() + if not self.payment_order_id: + raise UserError(_("No payment order are linked to this request.")) + + return { + 'name': _('Payment Orders'), + 'type': 'ir.actions.act_window', + 'res_model': 'payment.orders', + 'view_mode': 'tree,form', + 'domain': [('id', 'in', self.payment_order_id.ids)], + 'context': {'create': False}, + } diff --git a/odex25_benefit/odex_benefit/models/service_request.py b/odex25_benefit/odex_benefit/models/service_request.py index bdde37445..2eb81a2c3 100644 --- a/odex25_benefit/odex_benefit/models/service_request.py +++ b/odex25_benefit/odex_benefit/models/service_request.py @@ -956,7 +956,7 @@ class ServiceRequest(models.Model): if self.service_cat.payment_method == "payment_order": moves = self.payment_order_ids.mapped('move_id') elif self.service_cat.payment_method == "invoice": - moves = self.vendor_bill.ids + moves = self.vendor_bill return { 'name': _('Vendor Bills'), diff --git a/odex25_benefit/odex_benefit/views/seasonal_service_view.xml b/odex25_benefit/odex_benefit/views/seasonal_service_view.xml index 9390dd95a..9912aeb86 100644 --- a/odex25_benefit/odex_benefit/views/seasonal_service_view.xml +++ b/odex25_benefit/odex_benefit/views/seasonal_service_view.xml @@ -28,7 +28,7 @@ groups="odex_benefit.group_benefit_manager" attrs="{'invisible': [('state', '!=', 'gm_assistant')]}"/> - + + + 'invisible': [('payment_order_id', '=', False)], + 'readonly': [('state', '!=', 'draft')]}"/> +