-
-
Notifications
You must be signed in to change notification settings - Fork 674
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[IMP] hr_expense_advance_clearing: black, isort, prettier
- Loading branch information
1 parent
f62b159
commit ded2950
Showing
10 changed files
with
333 additions
and
228 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,81 +1,83 @@ | ||
# Copyright 2019 Kitti Upariphutthiphong <[email protected]> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from odoo import api, fields, models, _ | ||
from odoo import _, api, fields, models | ||
from odoo.exceptions import ValidationError | ||
|
||
|
||
class HrExpense(models.Model): | ||
_inherit = 'hr.expense' | ||
_inherit = "hr.expense" | ||
|
||
advance = fields.Boolean( | ||
string='Employee Advance', | ||
string="Employee Advance", | ||
default=False, | ||
) | ||
|
||
@api.multi | ||
@api.constrains('advance') | ||
@api.constrains("advance") | ||
def _check_advance(self): | ||
for expense in self.filtered('advance'): | ||
emp_advance = self.env.ref('hr_expense_advance_clearing.' | ||
'product_emp_advance') | ||
for expense in self.filtered("advance"): | ||
emp_advance = self.env.ref( | ||
"hr_expense_advance_clearing." "product_emp_advance" | ||
) | ||
if not emp_advance.property_account_expense_id: | ||
raise ValidationError( | ||
_('Employee advance product has no payable account')) | ||
_("Employee advance product has no payable account") | ||
) | ||
if expense.product_id != emp_advance: | ||
raise ValidationError( | ||
_('Employee advance, selected product is not valid')) | ||
_("Employee advance, selected product is not valid") | ||
) | ||
if expense.tax_ids: | ||
raise ValidationError( | ||
_('Employee advance, all taxes must be removed')) | ||
if expense.payment_mode != 'own_account': | ||
raise ValidationError( | ||
_('Employee advance, paid by must be employee')) | ||
raise ValidationError(_("Employee advance, all taxes must be removed")) | ||
if expense.payment_mode != "own_account": | ||
raise ValidationError(_("Employee advance, paid by must be employee")) | ||
return True | ||
|
||
@api.onchange('advance') | ||
@api.onchange("advance") | ||
def onchange_advance(self): | ||
self.tax_ids = False | ||
self.payment_mode = 'own_account' | ||
self.payment_mode = "own_account" | ||
if self.advance: | ||
self.product_id = self.env.ref( | ||
'hr_expense_advance_clearing.product_emp_advance') | ||
"hr_expense_advance_clearing.product_emp_advance" | ||
) | ||
else: | ||
self.product_id = False | ||
|
||
@api.multi | ||
def _get_account_move_line_values(self): | ||
move_line_values_by_expense = super()._get_account_move_line_values() | ||
# Only when do the clearing, change cr payable to cr advance | ||
emp_advance = self.env.ref('hr_expense_advance_clearing.' | ||
'product_emp_advance') | ||
sheets = self.mapped('sheet_id').filtered('advance_sheet_id') | ||
emp_advance = self.env.ref("hr_expense_advance_clearing." "product_emp_advance") | ||
sheets = self.mapped("sheet_id").filtered("advance_sheet_id") | ||
sheets_x = sheets.filtered(lambda x: x.advance_sheet_residual <= 0.0) | ||
if sheets_x: # Advance Sheets with no clearing residual left | ||
raise ValidationError(_('Advance: %s has no amount to clear') % | ||
', '.join(sheets_x.mapped('name'))) | ||
raise ValidationError( | ||
_("Advance: %s has no amount to clear") | ||
% ", ".join(sheets_x.mapped("name")) | ||
) | ||
for sheet in sheets: | ||
advance_to_clear = sheet.advance_sheet_residual | ||
for expense_id, move_lines in move_line_values_by_expense.items(): | ||
payable_move_line = False | ||
for move_line in move_lines: | ||
credit = move_line['credit'] | ||
credit = move_line["credit"] | ||
if not credit: | ||
continue | ||
# cr payable -> cr advance | ||
remain_payable = 0.0 | ||
if credit > advance_to_clear: | ||
remain_payable = credit - advance_to_clear | ||
move_line['credit'] = advance_to_clear | ||
move_line["credit"] = advance_to_clear | ||
advance_to_clear = 0.0 | ||
# extra payable line | ||
payable_move_line = move_line.copy() | ||
payable_move_line['credit'] = remain_payable | ||
payable_move_line["credit"] = remain_payable | ||
else: | ||
advance_to_clear -= credit | ||
# advance line | ||
move_line['account_id'] = \ | ||
emp_advance.property_account_expense_id.id | ||
move_line["account_id"] = emp_advance.property_account_expense_id.id | ||
if payable_move_line: | ||
move_lines.append(payable_move_line) | ||
return move_line_values_by_expense |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,81 @@ | ||
# Copyright 2019 Kitti Upariphutthiphong <[email protected]> | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
|
||
from odoo import api, models, fields, _ | ||
from odoo.tools.safe_eval import safe_eval | ||
from odoo.tools import pycompat | ||
from odoo import _, api, fields, models | ||
from odoo.exceptions import ValidationError | ||
from odoo.tools import pycompat | ||
from odoo.tools.safe_eval import safe_eval | ||
|
||
|
||
class HrExpenseSheet(models.Model): | ||
_inherit = 'hr.expense.sheet' | ||
_inherit = "hr.expense.sheet" | ||
|
||
advance = fields.Boolean( | ||
string='Employee Advance', | ||
compute='_compute_advance', | ||
string="Employee Advance", | ||
compute="_compute_advance", | ||
store=True, | ||
) | ||
advance_sheet_id = fields.Many2one( | ||
comodel_name='hr.expense.sheet', | ||
string='Clear Advance', | ||
comodel_name="hr.expense.sheet", | ||
string="Clear Advance", | ||
domain="[('advance', '=', True), ('employee_id', '=', employee_id)," | ||
" ('clearing_residual', '>', 0.0)]", | ||
" ('clearing_residual', '>', 0.0)]", | ||
readonly=True, | ||
states={'draft': [('readonly', False)], | ||
'submit': [('readonly', False)], | ||
'approve': [('readonly', False)]}, | ||
states={ | ||
"draft": [("readonly", False)], | ||
"submit": [("readonly", False)], | ||
"approve": [("readonly", False)], | ||
}, | ||
help="Show remaining advance of this employee", | ||
) | ||
clearing_residual = fields.Monetary( | ||
string='Amount to clear', | ||
compute='_compute_clearing_residual', | ||
string="Amount to clear", | ||
compute="_compute_clearing_residual", | ||
store=True, | ||
help="Amount to clear of this expense sheet in company currency", | ||
) | ||
advance_sheet_residual = fields.Monetary( | ||
string='Advance Remaining', | ||
related='advance_sheet_id.clearing_residual', | ||
string="Advance Remaining", | ||
related="advance_sheet_id.clearing_residual", | ||
store=True, | ||
help="Remaining amount to clear the selected advance sheet", | ||
) | ||
amount_payable = fields.Monetary( | ||
string='Payable Amount', | ||
compute='_compute_amount_payable', | ||
string="Payable Amount", | ||
compute="_compute_amount_payable", | ||
help="Final regiter payment amount even after advance clearing", | ||
) | ||
|
||
@api.multi | ||
@api.depends('expense_line_ids') | ||
@api.depends("expense_line_ids") | ||
def _compute_advance(self): | ||
for sheet in self: | ||
sheet.advance = bool(sheet.expense_line_ids.filtered('advance') and | ||
len(sheet.expense_line_ids) == 1) | ||
sheet.advance = bool( | ||
sheet.expense_line_ids.filtered("advance") | ||
and len(sheet.expense_line_ids) == 1 | ||
) | ||
return | ||
|
||
@api.one | ||
@api.constrains('advance_sheet_id', 'expense_line_ids') | ||
@api.constrains("advance_sheet_id", "expense_line_ids") | ||
def _check_advance_expense(self): | ||
advance_lines = self.expense_line_ids.filtered('advance') | ||
advance_lines = self.expense_line_ids.filtered("advance") | ||
if self.advance_sheet_id and advance_lines: | ||
raise ValidationError(_('Advance clearing must not contain any ' | ||
'advance expense line')) | ||
raise ValidationError( | ||
_("Advance clearing must not contain any " "advance expense line") | ||
) | ||
if advance_lines and len(self.expense_line_ids) != 1: | ||
raise ValidationError(_('Advance must contain only 1 ' | ||
'advance expense line')) | ||
raise ValidationError( | ||
_("Advance must contain only 1 " "advance expense line") | ||
) | ||
|
||
@api.one | ||
@api.depends('account_move_id.line_ids.amount_residual') | ||
@api.depends("account_move_id.line_ids.amount_residual") | ||
def _compute_clearing_residual(self): | ||
residual_company = 0.0 | ||
emp_advance = self.env.ref('hr_expense_advance_clearing.' | ||
'product_emp_advance', False) | ||
emp_advance = self.env.ref( | ||
"hr_expense_advance_clearing." "product_emp_advance", False | ||
) | ||
if emp_advance: | ||
for line in self.sudo().account_move_id.line_ids: | ||
if line.account_id == emp_advance.property_account_expense_id: | ||
|
@@ -79,34 +86,39 @@ def _compute_clearing_residual(self): | |
def _compute_amount_payable(self): | ||
for sheet in self: | ||
rec_lines = sheet.account_move_id.line_ids.filtered( | ||
lambda x: | ||
x.credit and x.account_id.reconcile and not x.reconciled) | ||
sheet.amount_payable = -sum(rec_lines.mapped('amount_residual')) | ||
lambda x: x.credit and x.account_id.reconcile and not x.reconciled | ||
) | ||
sheet.amount_payable = -sum(rec_lines.mapped("amount_residual")) | ||
|
||
@api.multi | ||
def action_sheet_move_create(self): | ||
res = super(HrExpenseSheet, self).action_sheet_move_create() | ||
# Reconcile advance of this sheet with the advance_sheet | ||
emp_advance = self.env.ref('hr_expense_advance_clearing.' | ||
'product_emp_advance') | ||
emp_advance = self.env.ref("hr_expense_advance_clearing." "product_emp_advance") | ||
for sheet in self: | ||
move_lines = sheet.account_move_id.line_ids | \ | ||
sheet.advance_sheet_id.account_move_id.line_ids | ||
move_lines = ( | ||
sheet.account_move_id.line_ids | ||
| sheet.advance_sheet_id.account_move_id.line_ids | ||
) | ||
account_id = emp_advance.property_account_expense_id.id | ||
adv_move_lines = self.env['account.move.line'].sudo().search([ | ||
('id', 'in', move_lines.ids), ('account_id', '=', account_id)]) | ||
adv_move_lines = ( | ||
self.env["account.move.line"] | ||
.sudo() | ||
.search([("id", "in", move_lines.ids), ("account_id", "=", account_id)]) | ||
) | ||
adv_move_lines.reconcile() | ||
return res | ||
|
||
@api.multi | ||
def open_clear_advance(self): | ||
self.ensure_one() | ||
action = self.env.ref('hr_expense_advance_clearing.' | ||
'action_hr_expense_sheet_advance_clearing') | ||
action = self.env.ref( | ||
"hr_expense_advance_clearing." "action_hr_expense_sheet_advance_clearing" | ||
) | ||
vals = action.read()[0] | ||
context1 = vals.get('context', {}) | ||
context1 = vals.get("context", {}) | ||
if isinstance(context1, pycompat.string_types): | ||
context1 = safe_eval(context1) | ||
context1['default_advance_sheet_id'] = self.id | ||
vals['context'] = context1 | ||
context1["default_advance_sheet_id"] = self.id | ||
vals["context"] = context1 | ||
return vals |
Oops, something went wrong.