cash statement form with cashbox
parent
9f06e88b88
commit
12572120e3
@ -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.
|
@ -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
|
@ -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>
|
Loading…
Reference in New Issue