[IMP] account, usability: little big details
* Fiscal positions: add stat button for 'Active' (instead of checkbox ) * Customer Invoice line form view no need for purchase order remove(or hide in customer invoice) and put Anallytic tag field in form view * Currencies sorted based on active field (so we can see all active currency first) * Improve graph for bank and cash journals on dashboard: based on ending balance and statement lines. Was PR #14833. Was task 29541
This commit is contained in:
@@ -38,65 +38,57 @@ class account_journal(models.Model):
|
||||
elif self.type == 'bank':
|
||||
return ['', _('Bank: Balance')]
|
||||
|
||||
# Below method is used to get data of bank and cash statemens
|
||||
@api.multi
|
||||
def get_line_graph_datas(self):
|
||||
"""Computes the data used to display the graph for bank and cash journals in the accounting dashboard"""
|
||||
|
||||
def build_graph_data(date, amount):
|
||||
#display date in locale format
|
||||
name = format_date(date, 'd LLLL Y', locale=locale)
|
||||
short_name = format_date(date, 'd MMM', locale=locale)
|
||||
return {'x':short_name,'y': amount, 'name':name}
|
||||
|
||||
self.ensure_one()
|
||||
BankStatement = self.env['account.bank.statement']
|
||||
data = []
|
||||
today = datetime.today()
|
||||
last_month = today + timedelta(days=-30)
|
||||
bank_stmt = []
|
||||
# Query to optimize loading of data for bank statement graphs
|
||||
# Return a list containing the latest bank statement balance per day for the
|
||||
# last 30 days for current journal
|
||||
query = """SELECT a.date, a.balance_end
|
||||
FROM account_bank_statement AS a,
|
||||
(SELECT c.date, max(c.id) AS stmt_id
|
||||
FROM account_bank_statement AS c
|
||||
WHERE c.journal_id = %s
|
||||
AND c.date > %s
|
||||
AND c.date <= %s
|
||||
GROUP BY date, id
|
||||
ORDER BY date, id) AS b
|
||||
WHERE a.id = b.stmt_id;"""
|
||||
|
||||
self.env.cr.execute(query, (self.id, last_month, today))
|
||||
bank_stmt = self.env.cr.dictfetchall()
|
||||
|
||||
last_bank_stmt = self.env['account.bank.statement'].search([('journal_id', 'in', self.ids),('date', '<=', last_month.strftime(DF))], order="date desc, id desc", limit=1)
|
||||
start_balance = last_bank_stmt and last_bank_stmt[0].balance_end or 0
|
||||
|
||||
locale = self._context.get('lang') or 'en_US'
|
||||
show_date = last_month
|
||||
#get date in locale format
|
||||
name = format_date(show_date, 'd LLLL Y', locale=locale)
|
||||
short_name = format_date(show_date, 'd MMM', locale=locale)
|
||||
data.append({'x':short_name,'y':start_balance, 'name':name})
|
||||
|
||||
for stmt in bank_stmt:
|
||||
#fill the gap between last data and the new one
|
||||
number_day_to_add = (datetime.strptime(stmt.get('date'), DF) - show_date).days
|
||||
last_balance = data[len(data) - 1]['y']
|
||||
for day in range(0,number_day_to_add + 1):
|
||||
show_date = show_date + timedelta(days=1)
|
||||
#get date in locale format
|
||||
name = format_date(show_date, 'd LLLL Y', locale=locale)
|
||||
short_name = format_date(show_date, 'd MMM', locale=locale)
|
||||
data.append({'x': short_name, 'y':last_balance, 'name': name})
|
||||
#add new stmt value
|
||||
data[len(data) - 1]['y'] = stmt.get('balance_end')
|
||||
#starting point of the graph is the last statement
|
||||
last_stmt = BankStatement.search([('journal_id', '=', self.id), ('date', '<=', today.strftime(DF))], order='date desc, id desc', limit=1)
|
||||
if not last_stmt:
|
||||
last_stmt = BankStatement.search([('journal_id', '=', self.id), ('date', '<=', last_month.strftime(DF))], order='date desc, id desc', limit=1)
|
||||
last_balance = last_stmt and last_stmt.balance_end_real or 0
|
||||
data.append(build_graph_data(today, last_balance))
|
||||
|
||||
#continue the graph if the last statement isn't today
|
||||
if show_date != today:
|
||||
number_day_to_add = (today - show_date).days
|
||||
last_balance = data[len(data) - 1]['y']
|
||||
for day in range(0,number_day_to_add):
|
||||
show_date = show_date + timedelta(days=1)
|
||||
#get date in locale format
|
||||
name = format_date(show_date, 'd LLLL Y', locale=locale)
|
||||
short_name = format_date(show_date, 'd MMM', locale=locale)
|
||||
data.append({'x': short_name, 'y':last_balance, 'name': name})
|
||||
#then we subtract the total amount of bank statement lines per day to get the previous points
|
||||
#(graph is drawn backward)
|
||||
date = today
|
||||
amount = last_balance
|
||||
query = """SELECT l.date, sum(l.amount) as amount
|
||||
FROM account_bank_statement_line l
|
||||
RIGHT JOIN account_bank_statement st ON l.statement_id = st.id
|
||||
WHERE st.journal_id = %s
|
||||
AND l.date > %s
|
||||
AND l.date <= %s
|
||||
GROUP BY l.date
|
||||
ORDER BY l.date desc
|
||||
"""
|
||||
self.env.cr.execute(query, (self.id, last_month, today))
|
||||
for val in self.env.cr.dictfetchall():
|
||||
date = datetime.strptime(val['date'], DF)
|
||||
if val['date'] != today.strftime(DF): # make sure the last point in the graph is today
|
||||
data[:0] = [build_graph_data(date, amount)]
|
||||
amount -= val['amount']
|
||||
|
||||
# make sure the graph starts 1 month ago
|
||||
if date.strftime(DF) != last_month.strftime(DF):
|
||||
data[:0] = [build_graph_data(last_month, amount)]
|
||||
|
||||
[graph_title, graph_key] = self._graph_title_and_key()
|
||||
color = '#875A7B' if '+e' in version else '#7c7bad'
|
||||
color = '#875A7B' if 'e' in version else '#7c7bad'
|
||||
return [{'values': data, 'title': graph_title, 'key': graph_key, 'area': True, 'color': color}]
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
fill: white;
|
||||
stroke-width: 2;
|
||||
}
|
||||
.nv-point:nth-child(5n+1) {
|
||||
.nv-point:nth-child(n+1) {
|
||||
visibility: visible;
|
||||
fill-opacity: .95 !important;
|
||||
stroke-opacity: .95 !important;
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
<field domain="[('company_id', '=', parent.company_id)]" name="account_id" groups="account.group_account_user"/>
|
||||
<field name="invoice_line_tax_ids" context="{'type':parent.get('type')}" domain="[('type_tax_use','!=','none'),('company_id', '=', parent.company_id)]" widget="many2many_tags" options="{'no_create': True}"/>
|
||||
<field domain="[('company_id', '=', parent.company_id)]" name="account_analytic_id" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="analytic_tag_ids" widget="many2many_tags" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
@@ -1643,18 +1643,27 @@
|
||||
<field name="model">account.payment.term</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payment Terms">
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="active"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
</group>
|
||||
<label for="note"/>
|
||||
<field name="note" placeholder="Payment terms explanation for the customer..."/>
|
||||
<separator string="Terms"/>
|
||||
<p class="text-muted">
|
||||
The last line's computation type should be "Balance" to ensure that the whole amount will be allocated.
|
||||
</p>
|
||||
<field name="line_ids"/>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" type="object" name="toggle_active" icon="fa-archive">
|
||||
<field name="active" widget="boolean_button"
|
||||
options='{"terminology": "archive"}'/>
|
||||
</button>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<label for="note"/>
|
||||
<field name="note" placeholder="Payment term explanation for the customer..."/>
|
||||
<separator string="Terms"/>
|
||||
<p class="text-muted">
|
||||
The last line's computation type should be "Balance" to ensure that the whole amount will be allocated.
|
||||
</p>
|
||||
<field name="line_ids"/>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<record id="view_account_position_form" model="ir.ui.view">
|
||||
<field name="name">account.fiscal.position.form</field>
|
||||
<field name="model">account.fiscal.position</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Fiscal Position">
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" type="object" name="toggle_active" icon="fa-archive">
|
||||
<field name="active" widget="boolean_button"
|
||||
options='{"terminology": "archive"}'/>
|
||||
</button>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="active"/>
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -70,6 +74,15 @@
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_account_position_filter" model="ir.ui.view">
|
||||
<field name="name">account.fiscal.position.filter</field>
|
||||
<field name="model">account.fiscal.position</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Fiscal Positions">
|
||||
<filter name="active" string="Archived" domain="[('active', '=', False)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_account_position_tree" model="ir.ui.view">
|
||||
<field name="name">account.fiscal.position.tree</field>
|
||||
<field name="model">account.fiscal.position</field>
|
||||
@@ -165,6 +178,7 @@
|
||||
<field name="res_model">account.fiscal.position</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="search_view_id" ref="view_account_position_filter"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
|
||||
@@ -212,6 +212,11 @@
|
||||
<field name="context">{'search_default_active':1}</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to add an analytic account.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
<field name="inherit_id" ref="account.view_invoice_line_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="account_id" position="before">
|
||||
<field name="purchase_id"/>
|
||||
<field name="purchase_id" invisible="context.get('type') in ('out_invoice', 'out_refund')"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -21,7 +21,7 @@ CURRENCY_DISPLAY_PATTERN = re.compile(r'(\w+)\s*(?:\((.*)\))?')
|
||||
class Currency(models.Model):
|
||||
_name = "res.currency"
|
||||
_description = "Currency"
|
||||
_order = "name"
|
||||
_order = 'active desc, name'
|
||||
|
||||
# Note: 'code' column was removed as of v6.0, the 'name' should now hold the ISO code.
|
||||
name = fields.Char(string='Currency', size=3, required=True, help="Currency Code (ISO 4217)")
|
||||
|
||||
Reference in New Issue
Block a user