Initial commit

This commit is contained in:
gsinghpal
2026-02-22 01:22:18 -05:00
commit 5200d5baf0
2394 changed files with 386834 additions and 0 deletions

View File

@@ -0,0 +1,304 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import UserError
from odoo.fields import Command
from markupsafe import Markup
import logging
_logger = logging.getLogger(__name__)
class ModPcaReceivedWizard(models.TransientModel):
_name = 'fusion_claims.mod.pca.received.wizard'
_description = 'MOD - Record PCA Receipt and Create Invoice(s)'
sale_order_id = fields.Many2one('sale.order', required=True, readonly=True)
currency_id = fields.Many2one('res.currency', related='sale_order_id.currency_id')
order_total = fields.Monetary(
related='sale_order_id.amount_untaxed', string='Order Subtotal', readonly=True)
# PCA Document
pca_document = fields.Binary(string='PCA Document', required=True)
pca_filename = fields.Char(string='PCA Filename')
# Case details (pre-filled from order, editable)
hvmp_reference = fields.Char(string='HVMP Reference #')
case_worker_id = fields.Many2one(
'res.partner', string='Case Worker',
help='March of Dimes case worker assigned to this case',
)
# Approval details
approval_type = fields.Selection([
('full', 'Full Approval'),
('partial', 'Partial Approval'),
], string='Approval Type', required=True, default='full')
approved_amount = fields.Monetary(
string='MOD Approved Amount',
currency_field='currency_id',
help='Total amount approved by March of Dimes (before taxes)',
)
# Preview lines (computed when partial)
preview_line_ids = fields.One2many(
'fusion_claims.mod.funding.approved.wizard.line', 'wizard_id',
string='Line Split Preview',
)
@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
if self.env.context.get('active_id'):
order = self.env['sale.order'].browse(self.env.context['active_id'])
res['sale_order_id'] = order.id
if order.x_fc_case_reference:
res['hvmp_reference'] = order.x_fc_case_reference
if order.x_fc_case_worker:
res['case_worker_id'] = order.x_fc_case_worker.id
if order.x_fc_mod_pca_document:
res['pca_document'] = order.x_fc_mod_pca_document
res['pca_filename'] = order.x_fc_mod_pca_filename
if order.x_fc_mod_approved_amount:
res['approved_amount'] = order.x_fc_mod_approved_amount
res['approval_type'] = order.x_fc_mod_approval_type or 'full'
else:
res['approved_amount'] = order.amount_untaxed
return res
@api.onchange('approval_type', 'approved_amount')
def _onchange_compute_preview(self):
"""Compute the proportional split preview when partial approval."""
order = self.sale_order_id
if not order:
return
lines = []
product_lines = order.order_line.filtered(
lambda l: not l.display_type and l.product_uom_qty > 0 and l.product_id)
if self.approval_type == 'partial' and self.approved_amount and self.approved_amount > 0:
subtotal = order.amount_untaxed
if subtotal <= 0:
return
for line in product_lines:
ratio = line.price_subtotal / subtotal if subtotal else 0
mod_amount = round(self.approved_amount * ratio, 2)
client_amount = round(line.price_subtotal - mod_amount, 2)
lines.append((0, 0, {
'product_name': line.product_id.display_name,
'quantity': line.product_uom_qty,
'line_total': line.price_subtotal,
'mod_amount': mod_amount,
'client_amount': client_amount,
}))
elif self.approval_type == 'full':
for line in product_lines:
lines.append((0, 0, {
'product_name': line.product_id.display_name,
'quantity': line.product_uom_qty,
'line_total': line.price_subtotal,
'mod_amount': line.price_subtotal,
'client_amount': 0,
}))
self.preview_line_ids = [(5, 0, 0)] + lines
def action_confirm(self):
"""Record PCA, set approval amounts, and create invoice(s)."""
self.ensure_one()
order = self.sale_order_id
if not self.pca_document:
raise UserError(_("Please attach the PCA document."))
if self.approval_type == 'partial':
if not self.approved_amount or self.approved_amount <= 0:
raise UserError(_("Please enter the approved amount for partial approval."))
if self.approved_amount >= order.amount_untaxed:
raise UserError(_(
"Approved amount is equal to or greater than the order subtotal. "
"Use 'Full Approval' instead."))
client_name = order.partner_id.name or 'Client'
# Update sale order
vals = {
'x_fc_mod_status': 'contract_received',
'x_fc_mod_pca_received_date': fields.Date.today(),
'x_fc_mod_pca_document': self.pca_document,
'x_fc_mod_pca_filename': self.pca_filename or f'PCA - {client_name}.pdf',
'x_fc_mod_approval_type': self.approval_type,
}
if self.approval_type == 'partial':
vals['x_fc_mod_approved_amount'] = self.approved_amount
vals['x_fc_mod_payment_commitment'] = self.approved_amount
else:
vals['x_fc_mod_approved_amount'] = order.amount_untaxed
vals['x_fc_mod_payment_commitment'] = order.amount_total
if self.case_worker_id:
vals['x_fc_case_worker'] = self.case_worker_id.id
if self.hvmp_reference:
vals['x_fc_case_reference'] = self.hvmp_reference
order.write(vals)
# Create invoices
mod_partner = order._get_mod_partner()
client = order.partner_id
if self.approval_type == 'full':
mod_invoice = self._create_full_invoice(order, mod_partner)
self._log_pca_and_invoices(order, mod_invoice)
return self._open_invoice(mod_invoice)
else:
mod_invoice = self._create_split_mod_invoice(order, mod_partner)
client_invoice = self._create_split_client_invoice(order, client)
self._log_pca_and_invoices(order, mod_invoice, client_invoice)
return self._open_invoice(mod_invoice)
# ------------------------------------------------------------------
# Invoice creation helpers
# ------------------------------------------------------------------
def _create_full_invoice(self, order, mod_partner):
"""Create a single MOD invoice for the full order amount."""
line_vals = []
for line in order.order_line:
if line.display_type in ('line_section', 'line_note'):
line_vals.append(Command.create({
'display_type': line.display_type,
'name': line.name,
'sequence': line.sequence,
}))
elif not line.display_type and line.product_uom_qty > 0:
inv_line = line._prepare_invoice_line()
inv_line['quantity'] = line.product_uom_qty
inv_line['sequence'] = line.sequence
line_vals.append(Command.create(inv_line))
return order._create_mod_invoice(
partner_id=mod_partner.id,
invoice_lines=line_vals,
portion_type='full',
label=' (March of Dimes - Full)',
)
def _create_split_mod_invoice(self, order, mod_partner):
"""Create MOD invoice with proportionally reduced amounts."""
subtotal = order.amount_untaxed
approved = self.approved_amount
line_vals = []
for line in order.order_line:
if line.display_type in ('line_section', 'line_note'):
line_vals.append(Command.create({
'display_type': line.display_type,
'name': line.name,
'sequence': line.sequence,
}))
elif not line.display_type and line.product_uom_qty > 0:
ratio = line.price_subtotal / subtotal if subtotal else 0
mod_line_amount = round(approved * ratio, 2)
mod_price_unit = round(
mod_line_amount / line.product_uom_qty, 2
) if line.product_uom_qty else 0
inv_line = line._prepare_invoice_line()
inv_line['quantity'] = line.product_uom_qty
inv_line['price_unit'] = mod_price_unit
inv_line['sequence'] = line.sequence
line_vals.append(Command.create(inv_line))
return order._create_mod_invoice(
partner_id=mod_partner.id,
invoice_lines=line_vals,
portion_type='adp',
label=' (March of Dimes Portion)',
)
def _create_split_client_invoice(self, order, client):
"""Create Client invoice with the difference amounts."""
subtotal = order.amount_untaxed
approved = self.approved_amount
line_vals = []
for line in order.order_line:
if line.display_type in ('line_section', 'line_note'):
line_vals.append(Command.create({
'display_type': line.display_type,
'name': line.name,
'sequence': line.sequence,
}))
elif not line.display_type and line.product_uom_qty > 0:
ratio = line.price_subtotal / subtotal if subtotal else 0
mod_line_amount = round(approved * ratio, 2)
client_line_amount = round(line.price_subtotal - mod_line_amount, 2)
client_price_unit = round(
client_line_amount / line.product_uom_qty, 2
) if line.product_uom_qty else 0
inv_line = line._prepare_invoice_line()
inv_line['quantity'] = line.product_uom_qty
inv_line['price_unit'] = client_price_unit
inv_line['sequence'] = line.sequence
if client_line_amount <= 0:
inv_line['price_unit'] = 0
inv_line['name'] = f'{line.name}\n[Covered by March of Dimes]'
line_vals.append(Command.create(inv_line))
return order._create_mod_invoice(
partner_id=client.id,
invoice_lines=line_vals,
portion_type='client',
label=' (Client Portion)',
)
# ------------------------------------------------------------------
# Logging and navigation
# ------------------------------------------------------------------
def _log_pca_and_invoices(self, order, mod_invoice, client_invoice=None):
"""Log PCA receipt and invoice creation to chatter."""
parts = [f'<strong>PCA Received and Invoice(s) Created</strong>']
parts.append(f'Date: {fields.Date.today().strftime("%B %d, %Y")}')
if self.hvmp_reference:
parts.append(f'HVMP Reference: {self.hvmp_reference}')
if self.case_worker_id:
parts.append(f'Case Worker: {self.case_worker_id.name}')
type_label = 'Full Approval' if self.approval_type == 'full' else 'Partial Approval'
parts.append(f'Approval Type: {type_label}')
if self.approval_type == 'partial':
parts.append(f'MOD Approved: ${self.approved_amount:,.2f}')
parts.append(
f'Client Portion: ${order.amount_untaxed - self.approved_amount:,.2f}')
inv_links = [
f'MOD Invoice: <a href="/web#id={mod_invoice.id}'
f'&amp;model=account.move&amp;view_type=form">'
f'{mod_invoice.name or "Draft"}</a>'
]
if client_invoice:
inv_links.append(
f'Client Invoice: <a href="/web#id={client_invoice.id}'
f'&amp;model=account.move&amp;view_type=form">'
f'{client_invoice.name or "Draft"}</a>'
)
parts.extend(inv_links)
order.message_post(
body=Markup('<div class="alert alert-success">' + '<br/>'.join(parts) + '</div>'),
message_type='notification', subtype_xmlid='mail.mt_note',
)
def _open_invoice(self, invoice):
return {
'type': 'ir.actions.act_window',
'name': 'Invoice',
'res_model': 'account.move',
'view_mode': 'form',
'res_id': invoice.id,
}