cash statement form with cashbox
This commit is contained in:
parent
9f06e88b88
commit
12572120e3
23
gn_cash/README.md
Normal file
23
gn_cash/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# GN-CASH
|
||||
|
||||
This modules revivals cash statements from Odoo 15.
|
||||
|
||||
It adds a wizard for cashbox counting after balance_start an balance_end_real fields of bank.statement form view.
|
||||
|
||||
It is based on modules:
|
||||
- (account_statement_base from OCA)[https://github.com/OCA/account-reconcile]
|
||||
|
||||
## How do we work with it:
|
||||
|
||||
1. Each day, users create operations they assume (like receive donation, etc.)
|
||||
2. If time is short, they can also declare it on a simple solo statement line
|
||||
3. At the end of the week, Odoo generates a statement with missing lines (i.e. lines with payment suspense accounts)
|
||||
4. the accountant verifies cashbox balance and validate loss/profit
|
||||
|
||||
|
||||
## Whats Needs to Be Done:
|
||||
|
||||
- add validate cashbox and entry lines creation
|
||||
- allow user to add statement lines 'on-the-fly'
|
||||
- allow user to create Donation / Expense / Cash-In / Cash-Out operations
|
||||
- create an action triggered by a button leading to a wizard that auto-generates cash statement from lines with payment suspense account.
|
||||
@ -6,13 +6,10 @@
|
||||
'description': """
|
||||
This module revivals cash statements from odoo 15.
|
||||
""",
|
||||
'depends': ['account_reconcile_oca', 'account_statement_import_sheet_file'],
|
||||
'depends': ['account_statement_base'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'views/delete_views.xml',
|
||||
'views/account_journal_views.xml',
|
||||
'views/account_cash_statement_views.xml',
|
||||
'views/account_journal_dashboard_view.xml',
|
||||
'views/cash_statement_views.xml',
|
||||
],
|
||||
'translate': True,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import cash_statement
|
||||
#, account_journal_dashboard
|
||||
#account_journal_dashboard
|
||||
@ -1,90 +0,0 @@
|
||||
from odoo import models, api, _, fields
|
||||
from odoo.exceptions import UserError
|
||||
import ast
|
||||
|
||||
class account_journal(models.Model):
|
||||
_inherit = "account.journal"
|
||||
def _select_action_to_open(self):
|
||||
self.ensure_one()
|
||||
if self._context.get('action_name'):
|
||||
return self._context.get('action_name')
|
||||
elif self.type == 'bank':
|
||||
return 'account.action_bank_statement_tree'
|
||||
elif self.type == 'cash':
|
||||
#return 'gn_cash.action_cash_statement_tree'
|
||||
return 'account.action_view_bank_statement_tree'
|
||||
elif self.type == 'sale':
|
||||
return 'account.action_move_out_invoice_type'
|
||||
elif self.type == 'purchase':
|
||||
return 'account.action_move_in_invoice_type'
|
||||
else:
|
||||
return 'account.action_move_journal_line'
|
||||
|
||||
def create_cash_statement(self):
|
||||
"""return action to create a cash statements."""
|
||||
action = self.env["ir.actions.actions"]._for_xml_id("gn_cash.action_cash_statement_tree")
|
||||
action.update({
|
||||
'views': [(self.env.ref('gn_cash.view_cash_statement_form').id, 'form')],
|
||||
'context': {
|
||||
'default_journal_id': str(self.id),
|
||||
'journal_type': str(self.type),
|
||||
}
|
||||
})
|
||||
return action
|
||||
|
||||
|
||||
def open_action(self):
|
||||
"""return action based on type for related journals"""
|
||||
self.ensure_one()
|
||||
action_name = self._select_action_to_open()
|
||||
|
||||
# Set 'account.' prefix if missing.
|
||||
#if not action_name.startswith("account."):
|
||||
# action_name = 'account.%s' % action_name
|
||||
|
||||
action = self.env["ir.actions.act_window"]._for_xml_id(action_name)
|
||||
|
||||
context = self._context.copy()
|
||||
if 'context' in action and isinstance(action['context'], str):
|
||||
context.update(ast.literal_eval(action['context']))
|
||||
else:
|
||||
context.update(action.get('context', {}))
|
||||
action['context'] = context
|
||||
action['context'].update({
|
||||
'default_journal_id': self.id,
|
||||
})
|
||||
domain_type_field = action['res_model'] == 'account.move.line' and 'move_id.move_type' or 'move_type' # The model can be either account.move or account.move.line
|
||||
|
||||
# Override the domain only if the action was not explicitly specified in order to keep the
|
||||
# original action domain.
|
||||
if action.get('domain') and isinstance(action['domain'], str):
|
||||
action['domain'] = ast.literal_eval(action['domain'] or '[]')
|
||||
if not self._context.get('action_name'):
|
||||
if self.type == 'sale':
|
||||
action['domain'] = [(domain_type_field, 'in', ('out_invoice', 'out_refund', 'out_receipt'))]
|
||||
elif self.type == 'purchase':
|
||||
action['domain'] = [(domain_type_field, 'in', ('in_invoice', 'in_refund', 'in_receipt', 'entry'))]
|
||||
|
||||
action['domain'] = (action['domain'] or []) + [('journal_id', '=', self.id)]
|
||||
return action
|
||||
|
||||
|
||||
def open_action_with_context(self):
|
||||
action_name = self.env.context.get('action_name', False)
|
||||
if not action_name:
|
||||
return False
|
||||
ctx = dict(self.env.context, default_journal_id=self.id)
|
||||
if ctx.get('search_default_journal', False):
|
||||
ctx.update(search_default_journal_id=self.id)
|
||||
ctx['search_default_journal'] = False # otherwise it will do a useless groupby in bank statements
|
||||
ctx.pop('group_by', None)
|
||||
action = self.env['ir.actions.act_window']._for_xml_id(action_name)
|
||||
action['context'] = ctx
|
||||
if ctx.get('use_domain', False):
|
||||
action['domain'] = isinstance(ctx['use_domain'], list) and ctx['use_domain'] or ['|', ('journal_id', '=', self.id), ('journal_id', '=', False)]
|
||||
action['name'] = _(
|
||||
"%(action)s for journal %(journal)s",
|
||||
action=action["name"],
|
||||
journal=self.name,
|
||||
)
|
||||
return action
|
||||
@ -95,9 +95,14 @@ class AccountBankStmtCloseCheck(models.TransientModel):
|
||||
"""
|
||||
Account Bank Statement wizard that check that closing balance is correct.
|
||||
"""
|
||||
_name = 'account.bank.statement.closebalance'
|
||||
_name = 'gn_cash.account.bank.statement.closebalance'
|
||||
_description = 'Bank Statement Closing Balance'
|
||||
|
||||
"""
|
||||
Warning!! This method is not linked to effective operations.
|
||||
We need to figure out what to do with difference found beetween calculated total and wizard total
|
||||
i.e. which moves need to be created
|
||||
"""
|
||||
def validate(self):
|
||||
bnk_stmt_id = self.env.context.get('active_id', False)
|
||||
if bnk_stmt_id:
|
||||
@ -110,6 +115,9 @@ class BankStatement(models.Model):
|
||||
cashbox_start_id = fields.Many2one('gn_cash.account.bank.statement.cashbox', string="Starting Cashbox")
|
||||
cashbox_end_id = fields.Many2one('gn_cash.account.bank.statement.cashbox', string="Ending Cashbox")
|
||||
|
||||
|
||||
#This is the function we need to verify in order to have a functionnal validate on wizard
|
||||
|
||||
def _check_cash_balance_end_real_same_as_computed(self):
|
||||
""" Check the balance_end_real (encoded manually by the user) is equals to the balance_end (computed by odoo).
|
||||
For a cash statement, if there is a difference, the different is set automatically to a profit/loss account.
|
||||
|
||||
@ -1,85 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="view_cash_statement_form" model="ir.ui.view">
|
||||
<field name="name">gn_cash.account.cash.statement.form</field>
|
||||
<field name="model">account.bank.statement</field>
|
||||
<field name="priority">1</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Cash registry">
|
||||
<div
|
||||
class="alert alert-warning"
|
||||
role="alert"
|
||||
attrs="{'invisible': [('problem_description', '=', False)]}"
|
||||
>
|
||||
<field name="problem_description" />
|
||||
</div>
|
||||
<sheet>
|
||||
<div name="button_box" position="inside">
|
||||
<button
|
||||
class="oe_stat_button"
|
||||
type="action"
|
||||
name="%(account_statement_base.account_bank_statement_line_action)d"
|
||||
icon="fa-bars"
|
||||
context="{'search_default_statement_id': id}"
|
||||
string="Transactions for cashbox"
|
||||
/>
|
||||
</div>
|
||||
<div class="oe_title oe_inline">
|
||||
<label for="name" />
|
||||
<h1><field
|
||||
name="name"
|
||||
placeholder="e.g. BNK/2021/0001"
|
||||
/></h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="date" />
|
||||
<field
|
||||
name='company_id'
|
||||
options="{'no_create': True}"
|
||||
groups="base.group_multi_company"
|
||||
/>
|
||||
<field name="currency_id" invisible="1" />
|
||||
<field name="journal_id" invisible="1" />
|
||||
<field name="cashbox_start_id" invisible="1"/>
|
||||
<field name="cashbox_end_id" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<label for="balance_start" />
|
||||
<div>
|
||||
<field name="balance_start" class="oe_inline" />
|
||||
<button name="open_cashbox_id" string="→ Count" type="object" class="oe_edit_only oe_link oe_inline" context="{'balance':'start'}"/>
|
||||
</div>
|
||||
<label for="balance_end_real" />
|
||||
<div>
|
||||
<field name="balance_end_real" class="oe_inline" />
|
||||
<button name="open_cashbox_id" string="→ Count" type="object" class="oe_edit_only oe_link oe_inline" context="{'balance':'close'}"/>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<field
|
||||
name="line_ids"
|
||||
context="{'default_journal_id': journal_id}"
|
||||
/>
|
||||
<group
|
||||
class="oe_subtotal_footer oe_right"
|
||||
name="sale_total"
|
||||
col="1"
|
||||
>
|
||||
<field
|
||||
name="balance_end"
|
||||
class="oe_subtotal_footer_separator"
|
||||
/>
|
||||
</group>
|
||||
<field name="attachment_ids" widget="many2many_binary" />
|
||||
<div class="oe_clear" />
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_cash_statement_tree" model="ir.actions.act_window">
|
||||
<record id="gn_cash.action_cash_statement_tree" model="ir.actions.act_window">
|
||||
<field name="name">Cash Logs</field>
|
||||
<field name="res_model">account.bank.statement</field>
|
||||
<field name="view_mode">tree,form,pivot,graph</field>
|
||||
@ -96,29 +18,19 @@
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window.view" id="action_cash_statement_tree_cash">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="account.view_bank_statement_tree"/>
|
||||
<field name="act_window_id" ref="action_cash_statement_tree"/>
|
||||
</record>
|
||||
<record model="ir.actions.act_window.view" id="action_cash_statement_form_cash">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_cash_statement_form"/>
|
||||
<field name="act_window_id" ref="action_cash_statement_tree"/>
|
||||
</record>
|
||||
<record model="ir.actions.act_window.view" id="action_cash_statement_tree_cash">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="account.view_bank_statement_tree"/>
|
||||
<field name="act_window_id" ref="account.action_view_bank_statement_tree"/>
|
||||
</record>
|
||||
<record model="ir.actions.act_window.view" id="action_cash_statement_form_cash">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_cash_statement_form"/>
|
||||
<field name="act_window_id" ref="account.action_view_bank_statement_tree"/>
|
||||
</record>
|
||||
<record id="gn_cash.view_cash_statement_form" model="ir.ui.view">
|
||||
<field name="name">gn_cash.account.cash.statement.form</field>
|
||||
<field name="model">account.bank.statement</field>
|
||||
<field name="inherit_id" ref="account_statement_base.view_bank_statement_form"/>
|
||||
<field name="priority">100</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='balance_start']" position="after" >
|
||||
<button name="open_cashbox_id" invisible ="context.get('journal_type', False) != 'cash'" string="→ Count" type="object" class="oe_edit_only oe_link oe_inline" context="{'balance':'start'}"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='balance_end_real']" position="after">
|
||||
<button name="open_cashbox_id" invisible ="context.get('journal_type', False) != 'cash'" string="→ Count" type="object" class="oe_edit_only oe_link oe_inline" context="{'balance':'close'}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="account_journal_dashboard_kanban_view" model="ir.ui.view">
|
||||
<field name="name">gn_cash.journal.dashboard.kanban</field>
|
||||
<field name="model">account.journal</field>
|
||||
<field name="inherit_id" ref="account.account_journal_dashboard_kanban_view"/>
|
||||
<field name="arch" type="xml">
|
||||
|
||||
<xpath
|
||||
expr='//a[@name="create_cash_statement"]/..'
|
||||
position='replace'
|
||||
>
|
||||
<t t-if="dashboard.bank_statements_source == 'file_import_oca'">
|
||||
<t t-if="journal_type == 'cash'">
|
||||
<button
|
||||
name="import_account_statement"
|
||||
type="object"
|
||||
class="btn btn-primary"
|
||||
groups="account.group_account_user"
|
||||
>
|
||||
<span>Import Cash Log</span>
|
||||
</button>
|
||||
</t>
|
||||
</t>
|
||||
</xpath>
|
||||
<xpath expr='//div[@name="bank_customer_payment"]' position="before">
|
||||
<div t-if="journal_type == 'cash'" groups="account.group_account_user">
|
||||
<a
|
||||
type="object"
|
||||
name="import_account_statement"
|
||||
>Import Cash Statement (OCA)</a>
|
||||
<a
|
||||
type="object"
|
||||
name="action_view_bank_statement_tree"
|
||||
groups="account.group_account_invoice"
|
||||
>New manual Cash Statement</a>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="gn_cash.view_account_journal_form" model="ir.ui.view">
|
||||
<field name="name">gn_cash.account.journal.form</field>
|
||||
<field name="model">account.journal</field>
|
||||
<field name="inherit_id" ref="account_statement_import_sheet_file.view_account_journal_form_n43"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//page[@name='advanced_settings']/group/group/field[@name='default_sheet_mapping_id']/.." position="after">
|
||||
<group string="Statement Import Map for Cash and Bank" attrs="{'invisible': [('type','!=', 'cash')]}">
|
||||
<field name="bank_statements_source" attrs="{'required': [('type', '=', 'cash')]}" widget="radio" groups="account.group_account_readonly"/>
|
||||
<field name="default_sheet_mapping_id" />
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="view_account_bnk_stmt_cashbox" model="ir.ui.view">
|
||||
<record id="gn_cash.view_account_bnk_stmt_cashbox" model="ir.ui.view">
|
||||
<field name="name">gn_cash.account.bnk_stmt_cashbox.form</field>
|
||||
<field name="model">gn_cash.account.bank.statement.cashbox</field>
|
||||
<field name="arch" type="xml">
|
||||
@ -31,12 +31,12 @@
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_account_bnk_stmt_cashbox_footer" model="ir.ui.view">
|
||||
<record id="gn_cash.view_account_bnk_stmt_cashbox_footer" model="ir.ui.view">
|
||||
<field name="name">gn_cash.account.bnk_stmt_cashbox.form</field>
|
||||
<field name="model">gn_cash.account.bank.statement.cashbox</field>
|
||||
<field name="priority">1000</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="inherit_id" ref="view_account_bnk_stmt_cashbox"/>
|
||||
<field name="inherit_id" ref="gn_cash.view_account_bnk_stmt_cashbox"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//sheet" position="after">
|
||||
<footer>
|
||||
@ -46,9 +46,9 @@
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_account_bnk_stmt_check" model="ir.ui.view">
|
||||
<record id="gn_cash.view_account_bnk_stmt_check" model="ir.ui.view">
|
||||
<field name="name">gn_cash.account.bnk_stmt_check.form</field>
|
||||
<field name="model">account.bank.statement.closebalance</field>
|
||||
<field name="model">gn_cash.account.bank.statement.closebalance</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<div>
|
||||
@ -62,9 +62,9 @@
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_view_account_bnk_stmt_check" model="ir.actions.act_window">
|
||||
<record id="gn_cash.action_view_account_bnk_stmt_check" model="ir.actions.act_window">
|
||||
<field name="name">Check Closing Balance</field>
|
||||
<field name="res_model">account.bank.statement.closebalance</field>
|
||||
<field name="res_model">gn_cash.account.bank.statement.closebalance</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_account_bnk_stmt_check"/>
|
||||
<field name="target">new</field>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user