Initial commit
This commit is contained in:
196
fusion_claims/wizard/ready_for_submission_wizard.py
Normal file
196
fusion_claims/wizard/ready_for_submission_wizard.py
Normal file
@@ -0,0 +1,196 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2024-2025 Nexa Systems Inc.
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import UserError
|
||||
from markupsafe import Markup
|
||||
from datetime import date
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ReadyForSubmissionWizard(models.TransientModel):
|
||||
"""Wizard to collect required fields before marking as Ready for Submission."""
|
||||
_name = 'fusion_claims.ready.for.submission.wizard'
|
||||
_description = 'Ready for Submission Wizard'
|
||||
|
||||
sale_order_id = fields.Many2one(
|
||||
'sale.order',
|
||||
string='Sale Order',
|
||||
required=True,
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
# Authorization Details
|
||||
claim_authorization_date = fields.Date(
|
||||
string='Claim Authorization Date',
|
||||
required=True,
|
||||
default=fields.Date.context_today,
|
||||
help='Date when the claim was authorized by the OT/Authorizer',
|
||||
)
|
||||
|
||||
# Client References (may already be filled)
|
||||
client_ref_1 = fields.Char(
|
||||
string='Client Reference 1',
|
||||
help='First client reference number (e.g., PO number)',
|
||||
)
|
||||
client_ref_2 = fields.Char(
|
||||
string='Client Reference 2',
|
||||
help='Second client reference number',
|
||||
)
|
||||
|
||||
# Reason for Application
|
||||
reason_for_application = fields.Selection([
|
||||
('first_access', 'First Time Access - NO previous ADP'),
|
||||
('additions', 'Additions'),
|
||||
('mod_non_adp', 'Modification/Upgrade - Original NOT through ADP'),
|
||||
('mod_adp', 'Modification/Upgrade - Original through ADP'),
|
||||
('replace_status', 'Replacement - Change in Status'),
|
||||
('replace_size', 'Replacement - Change in Body Size'),
|
||||
('replace_worn', 'Replacement - Worn out (past useful life)'),
|
||||
('replace_lost', 'Replacement - Lost'),
|
||||
('replace_stolen', 'Replacement - Stolen'),
|
||||
('replace_damaged', 'Replacement - Damaged beyond repair'),
|
||||
('replace_no_longer_meets', 'Replacement - No longer meets needs'),
|
||||
('growth', 'Growth/Change in condition'),
|
||||
], string='Reason for Application')
|
||||
|
||||
# Previous Funding (required for some reasons)
|
||||
requires_previous_funding = fields.Boolean(
|
||||
string='Requires Previous Funding Date',
|
||||
compute='_compute_requires_previous_funding',
|
||||
)
|
||||
previous_funding_date = fields.Date(
|
||||
string='Previous Funding Date',
|
||||
help='Date of previous ADP funding (required for modifications/replacements)',
|
||||
)
|
||||
|
||||
# Show which fields are already filled
|
||||
has_authorization_date = fields.Boolean(compute='_compute_field_status')
|
||||
has_client_refs = fields.Boolean(compute='_compute_field_status')
|
||||
has_reason = fields.Boolean(compute='_compute_field_status')
|
||||
has_documents = fields.Boolean(compute='_compute_field_status')
|
||||
|
||||
notes = fields.Text(
|
||||
string='Notes',
|
||||
help='Any notes about the submission preparation',
|
||||
)
|
||||
|
||||
@api.depends('reason_for_application')
|
||||
def _compute_requires_previous_funding(self):
|
||||
no_prev_funding_reasons = ['first_access', 'mod_non_adp']
|
||||
for wizard in self:
|
||||
reason = wizard.reason_for_application
|
||||
wizard.requires_previous_funding = bool(reason) and reason not in no_prev_funding_reasons
|
||||
|
||||
@api.depends('sale_order_id')
|
||||
def _compute_field_status(self):
|
||||
for wizard in self:
|
||||
order = wizard.sale_order_id
|
||||
wizard.has_authorization_date = bool(order.x_fc_claim_authorization_date)
|
||||
wizard.has_client_refs = bool(order.x_fc_client_ref_1 and order.x_fc_client_ref_2)
|
||||
wizard.has_reason = bool(order.x_fc_reason_for_application)
|
||||
wizard.has_documents = bool(order.x_fc_original_application and order.x_fc_signed_pages_11_12)
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields_list):
|
||||
res = super().default_get(fields_list)
|
||||
active_id = self._context.get('active_id')
|
||||
if active_id:
|
||||
order = self.env['sale.order'].browse(active_id)
|
||||
res['sale_order_id'] = order.id
|
||||
# Pre-fill from existing values
|
||||
if order.x_fc_claim_authorization_date:
|
||||
res['claim_authorization_date'] = order.x_fc_claim_authorization_date
|
||||
if order.x_fc_client_ref_1:
|
||||
res['client_ref_1'] = order.x_fc_client_ref_1
|
||||
if order.x_fc_client_ref_2:
|
||||
res['client_ref_2'] = order.x_fc_client_ref_2
|
||||
if order.x_fc_reason_for_application:
|
||||
res['reason_for_application'] = order.x_fc_reason_for_application
|
||||
if order.x_fc_previous_funding_date:
|
||||
res['previous_funding_date'] = order.x_fc_previous_funding_date
|
||||
return res
|
||||
|
||||
def action_confirm(self):
|
||||
"""Validate and mark as ready for submission."""
|
||||
self.ensure_one()
|
||||
|
||||
order = self.sale_order_id
|
||||
|
||||
if order.x_fc_adp_application_status != 'application_received':
|
||||
raise UserError("Can only mark ready for submission from 'Application Received' status.")
|
||||
|
||||
# Validate required fields
|
||||
missing = []
|
||||
|
||||
if not self.claim_authorization_date:
|
||||
missing.append('Claim Authorization Date')
|
||||
if not self.client_ref_1 and not order.x_fc_client_ref_1:
|
||||
missing.append('Client Reference 1')
|
||||
if not self.client_ref_2 and not order.x_fc_client_ref_2:
|
||||
missing.append('Client Reference 2')
|
||||
if not self.reason_for_application and not order.x_fc_reason_for_application:
|
||||
missing.append('Reason for Application')
|
||||
|
||||
# Check previous funding if required
|
||||
reason = self.reason_for_application or order.x_fc_reason_for_application
|
||||
no_prev_funding_reasons = ['first_access', 'mod_non_adp']
|
||||
if reason and reason not in no_prev_funding_reasons:
|
||||
if not self.previous_funding_date and not order.x_fc_previous_funding_date:
|
||||
missing.append('Previous Funding Date')
|
||||
|
||||
# Check documents
|
||||
if not order.x_fc_original_application:
|
||||
missing.append('Original ADP Application (upload in Application Received step)')
|
||||
if not order.x_fc_signed_pages_11_12:
|
||||
missing.append('Page 11 & 12 Signed (upload in Application Received step)')
|
||||
|
||||
if missing:
|
||||
raise UserError(
|
||||
"Cannot mark as Ready for Submission.\n\n"
|
||||
"Required fields/documents missing:\n• " + "\n• ".join(missing)
|
||||
)
|
||||
|
||||
# Build update values
|
||||
update_vals = {
|
||||
'x_fc_adp_application_status': 'ready_submission',
|
||||
'x_fc_claim_authorization_date': self.claim_authorization_date,
|
||||
}
|
||||
|
||||
# Only update if new values provided
|
||||
if self.client_ref_1:
|
||||
update_vals['x_fc_client_ref_1'] = self.client_ref_1
|
||||
if self.client_ref_2:
|
||||
update_vals['x_fc_client_ref_2'] = self.client_ref_2
|
||||
if self.reason_for_application:
|
||||
update_vals['x_fc_reason_for_application'] = self.reason_for_application
|
||||
if self.previous_funding_date:
|
||||
update_vals['x_fc_previous_funding_date'] = self.previous_funding_date
|
||||
|
||||
# Update sale order
|
||||
order.with_context(skip_status_validation=True).write(update_vals)
|
||||
|
||||
# Post to chatter
|
||||
reason_label = ''
|
||||
if self.reason_for_application:
|
||||
reason_label = dict(self._fields['reason_for_application'].selection or []).get(
|
||||
self.reason_for_application, ''
|
||||
)
|
||||
|
||||
order.message_post(
|
||||
body=Markup(
|
||||
'<div style="background: #d4edda; border-left: 4px solid #28a745; padding: 12px; margin: 8px 0; border-radius: 4px;">'
|
||||
'<h4 style="color: #28a745; margin: 0 0 8px 0;"><i class="fa fa-check"/> Ready for Submission</h4>'
|
||||
f'<p style="margin: 0;"><strong>Authorization Date:</strong> {self.claim_authorization_date.strftime("%B %d, %Y")}</p>'
|
||||
f'{f"<p style=\'margin: 4px 0 0 0;\'><strong>Reason:</strong> {reason_label}</p>" if reason_label else ""}'
|
||||
'<p style="margin: 8px 0 0 0; color: #666;">Application is ready to be submitted to ADP. Use "Submit Application" to proceed.</p>'
|
||||
'</div>'
|
||||
),
|
||||
message_type='notification',
|
||||
subtype_xmlid='mail.mt_note',
|
||||
)
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
Reference in New Issue
Block a user