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,194 @@
# Fusion Accounting - Account Transfer Wizard
# Copyright (C) 2026 Nexa Systems Inc. (https://nexasystems.ca)
# Original implementation for the Fusion Accounting module.
#
# Provides a transient model that creates a journal entry to move
# a balance from one account to another within the same company.
import logging
from datetime import date
from odoo import api, fields, models, Command, _
from odoo.exceptions import UserError, ValidationError
_logger = logging.getLogger(__name__)
class FusionAccountTransfer(models.TransientModel):
"""Wizard for transferring balances between two accounts.
Creates a balanced journal entry with one debit line and one credit
line, effectively moving a specified amount from the source account
to the destination account.
"""
_name = 'fusion.account.transfer'
_description = 'Account Balance Transfer'
# =====================================================================
# Fields
# =====================================================================
company_id = fields.Many2one(
comodel_name='res.company',
string="Company",
required=True,
default=lambda self: self.env.company,
readonly=True,
)
currency_id = fields.Many2one(
comodel_name='res.currency',
string="Currency",
related='company_id.currency_id',
readonly=True,
)
source_account_id = fields.Many2one(
comodel_name='account.account',
string="Source Account",
required=True,
domain="[('company_ids', 'in', company_id)]",
help="The account to transfer funds FROM (will be credited).",
)
destination_account_id = fields.Many2one(
comodel_name='account.account',
string="Destination Account",
required=True,
domain="[('company_ids', 'in', company_id)]",
help="The account to transfer funds TO (will be debited).",
)
amount = fields.Monetary(
string="Amount",
required=True,
currency_field='currency_id',
help="Amount to transfer between the accounts.",
)
journal_id = fields.Many2one(
comodel_name='account.journal',
string="Journal",
required=True,
domain="[('type', '=', 'general'), ('company_id', '=', company_id)]",
help="Miscellaneous journal to record the transfer entry.",
)
date = fields.Date(
string="Date",
required=True,
default=fields.Date.context_today,
help="Date of the transfer journal entry.",
)
memo = fields.Char(
string="Memo",
help="Optional description for the journal entry.",
)
partner_id = fields.Many2one(
comodel_name='res.partner',
string="Partner",
help="Optional partner for the journal entry lines.",
)
# =====================================================================
# Constraints
# =====================================================================
@api.constrains('source_account_id', 'destination_account_id')
def _check_different_accounts(self):
for record in self:
if record.source_account_id == record.destination_account_id:
raise ValidationError(
_("Source and destination accounts must be different.")
)
@api.constrains('amount')
def _check_positive_amount(self):
for record in self:
if record.amount <= 0:
raise ValidationError(
_("Transfer amount must be greater than zero.")
)
# =====================================================================
# Default Values
# =====================================================================
@api.model
def default_get(self, fields_list):
"""Set default journal to the company's miscellaneous journal."""
defaults = super().default_get(fields_list)
if 'journal_id' not in defaults:
misc_journal = self.env['account.journal'].search([
('type', '=', 'general'),
('company_id', '=', self.env.company.id),
], limit=1)
if misc_journal:
defaults['journal_id'] = misc_journal.id
return defaults
# =====================================================================
# Action
# =====================================================================
def action_transfer(self):
"""Create a journal entry moving balance between accounts.
Generates a balanced journal entry:
- Credit line on the source account
- Debit line on the destination account
:returns: action dict pointing to the created journal entry
:raises UserError: if required fields are missing or invalid
"""
self.ensure_one()
if not self.source_account_id or not self.destination_account_id:
raise UserError(_("Both source and destination accounts are required."))
if self.amount <= 0:
raise UserError(_("The transfer amount must be positive."))
ref = self.memo or _("Account Transfer: %s%s",
self.source_account_id.display_name,
self.destination_account_id.display_name)
move_vals = {
'journal_id': self.journal_id.id,
'date': self.date,
'ref': ref,
'company_id': self.company_id.id,
'move_type': 'entry',
'line_ids': [
# Credit the source account
Command.create({
'account_id': self.source_account_id.id,
'name': ref,
'debit': 0.0,
'credit': self.amount,
'partner_id': self.partner_id.id if self.partner_id else False,
}),
# Debit the destination account
Command.create({
'account_id': self.destination_account_id.id,
'name': ref,
'debit': self.amount,
'credit': 0.0,
'partner_id': self.partner_id.id if self.partner_id else False,
}),
],
}
move = self.env['account.move'].create(move_vals)
_logger.info(
"Fusion Account Transfer: created journal entry %s (id=%s) "
"for %.2f from %s to %s",
move.name, move.id, self.amount,
self.source_account_id.code,
self.destination_account_id.code,
)
return {
'type': 'ir.actions.act_window',
'res_model': 'account.move',
'res_id': move.id,
'view_mode': 'form',
'target': 'current',
'name': _("Transfer Entry"),
}