[MERGE]: Merged with lp:openobject-addons
bzr revid: atp@tinyerp.com-20120925050759-xueuicxhp36ahpe9
This commit is contained in:
@@ -63,6 +63,8 @@ for a particular financial year and for preparation of vouchers there is a modul
|
||||
'wizard/account_use_model_view.xml',
|
||||
'account_installer.xml',
|
||||
'wizard/account_period_close_view.xml',
|
||||
'wizard/account_reconcile_view.xml',
|
||||
'wizard/account_unreconcile_view.xml',
|
||||
'account_view.xml',
|
||||
'account_report.xml',
|
||||
'account_financial_report_data.xml',
|
||||
@@ -85,14 +87,12 @@ for a particular financial year and for preparation of vouchers there is a modul
|
||||
'wizard/account_journal_select_view.xml',
|
||||
'wizard/account_change_currency_view.xml',
|
||||
'wizard/account_validate_move_view.xml',
|
||||
'wizard/account_unreconcile_view.xml',
|
||||
'wizard/account_report_general_ledger_view.xml',
|
||||
'wizard/account_invoice_state_view.xml',
|
||||
'wizard/account_report_partner_balance_view.xml',
|
||||
'wizard/account_report_account_balance_view.xml',
|
||||
'wizard/account_report_aged_partner_balance_view.xml',
|
||||
'wizard/account_report_partner_ledger_view.xml',
|
||||
'wizard/account_reconcile_view.xml',
|
||||
'wizard/account_reconcile_partner_process_view.xml',
|
||||
'wizard/account_automatic_reconcile_view.xml',
|
||||
'wizard/account_financial_report_view.xml',
|
||||
@@ -126,6 +126,14 @@ for a particular financial year and for preparation of vouchers there is a modul
|
||||
'res_config_view.xml',
|
||||
'account_pre_install.yml'
|
||||
],
|
||||
'js': [
|
||||
'static/src/js/account_move_reconciliation.js',
|
||||
],
|
||||
'qweb' : [
|
||||
"static/src/xml/account_move_reconciliation.xml",
|
||||
],
|
||||
'css':['static/src/css/account_move_reconciliation.css'
|
||||
],
|
||||
'demo': [
|
||||
'demo/account_demo.xml',
|
||||
'project/project_demo.xml',
|
||||
|
||||
@@ -601,7 +601,7 @@ class account_account(osv.osv):
|
||||
if not default:
|
||||
default = {}
|
||||
default = default.copy()
|
||||
default['code'] = (account['code'] or '') + '(copy)'
|
||||
default.update(code=_("%s (copy)") % (account['code'] or ''))
|
||||
if not local:
|
||||
done_list = []
|
||||
if account.id in done_list:
|
||||
@@ -782,9 +782,10 @@ class account_journal(osv.osv):
|
||||
if not default:
|
||||
default = {}
|
||||
default = default.copy()
|
||||
default['code'] = (journal['code'] or '') + '(copy)'
|
||||
default['name'] = (journal['name'] or '') + '(copy)'
|
||||
default['sequence_id'] = False
|
||||
default.update(
|
||||
code=_("%s (copy)") % (journal['code'] or ''),
|
||||
name=_("%s (copy)") % (journal['name'] or ''),
|
||||
sequence_id=False)
|
||||
return super(account_journal, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
|
||||
@@ -708,7 +708,9 @@ class account_move_line(osv.osv):
|
||||
context = {}
|
||||
if context and context.get('next_partner_only', False):
|
||||
if not context.get('partner_id', False):
|
||||
partner = self.get_next_partner_only(cr, uid, offset, context)
|
||||
partner = self.list_partners_to_reconcile(cr, uid, context=context)
|
||||
if partner:
|
||||
partner = partner[0]
|
||||
else:
|
||||
partner = context.get('partner_id', False)
|
||||
if not partner:
|
||||
@@ -716,26 +718,26 @@ class account_move_line(osv.osv):
|
||||
args.append(('partner_id', '=', partner[0]))
|
||||
return super(account_move_line, self).search(cr, uid, args, offset, limit, order, context, count)
|
||||
|
||||
def get_next_partner_only(self, cr, uid, offset=0, context=None):
|
||||
def list_partners_to_reconcile(self, cr, uid, context=None):
|
||||
cr.execute(
|
||||
"""
|
||||
SELECT p.id
|
||||
FROM res_partner p
|
||||
RIGHT JOIN (
|
||||
SELECT l.partner_id AS partner_id, SUM(l.debit) AS debit, SUM(l.credit) AS credit
|
||||
SELECT partner_id
|
||||
FROM (
|
||||
SELECT l.partner_id, p.last_reconciliation_date, SUM(l.debit) AS debit, SUM(l.credit) AS credit
|
||||
FROM account_move_line l
|
||||
LEFT JOIN account_account a ON (a.id = l.account_id)
|
||||
LEFT JOIN res_partner p ON (l.partner_id = p.id)
|
||||
RIGHT JOIN account_account a ON (a.id = l.account_id)
|
||||
RIGHT JOIN res_partner p ON (l.partner_id = p.id)
|
||||
WHERE a.reconcile IS TRUE
|
||||
AND l.reconcile_id IS NULL
|
||||
AND (p.last_reconciliation_date IS NULL OR l.date > p.last_reconciliation_date)
|
||||
AND l.state <> 'draft'
|
||||
GROUP BY l.partner_id
|
||||
) AS s ON (p.id = s.partner_id)
|
||||
GROUP BY l.partner_id, p.last_reconciliation_date
|
||||
) AS s
|
||||
WHERE debit > 0 AND credit > 0
|
||||
ORDER BY p.last_reconciliation_date LIMIT 1 OFFSET %s""", (offset, )
|
||||
)
|
||||
return cr.fetchone()
|
||||
ORDER BY last_reconciliation_date""")
|
||||
ids = cr.fetchall()
|
||||
ids = len(ids) and [x[0] for x in ids] or []
|
||||
return self.pool.get('res.partner').name_get(cr, uid, ids, context=context)
|
||||
|
||||
def reconcile_partial(self, cr, uid, ids, type='auto', context=None, writeoff_acc_id=False, writeoff_period_id=False, writeoff_journal_id=False):
|
||||
move_rec_obj = self.pool.get('account.move.reconcile')
|
||||
@@ -915,8 +917,8 @@ class account_move_line(osv.osv):
|
||||
|
||||
if lines and lines[0]:
|
||||
partner_id = lines[0].partner_id and lines[0].partner_id.id or False
|
||||
if partner_id and context and context.get('stop_reconcile', False):
|
||||
partner_obj.write(cr, uid, [partner_id], {'last_reconciliation_date': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
if not partner_obj.has_something_to_reconcile(cr, uid, partner_id, context=context):
|
||||
partner_obj.mark_as_reconciled(cr, uid, [partner_id], context=context)
|
||||
return r_id
|
||||
|
||||
def view_header_get(self, cr, user, view_id, view_type, context=None):
|
||||
|
||||
@@ -1551,12 +1551,12 @@
|
||||
</record>
|
||||
|
||||
<record id="action_account_manual_reconcile" model="ir.actions.act_window">
|
||||
<field name="context">{'search_default_next_partner':1,'view_mode':True}</field>
|
||||
<field name="context">{'search_default_unreconciled': 1,'view_mode':True}</field>
|
||||
<field name="name">Journal Items to Reconcile</field>
|
||||
<field name="res_model">account.move.line</field>
|
||||
<field name="view_id" ref="view_move_line_tree_reconcile"/>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_mode">account_reconciliation_list</field>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
Good job!
|
||||
|
||||
@@ -122,6 +122,14 @@
|
||||
<field name="type">other</field>
|
||||
<field name="user_type" ref="data_account_type_income"/>
|
||||
</record>
|
||||
<record id="usd_bnk" model="account.account">
|
||||
<field name="code">X11007</field>
|
||||
<field name="name">USD Bank Account - (test)</field>
|
||||
<field ref="cas" name="parent_id"/>
|
||||
<field name="type">liquidity</field>
|
||||
<field name="user_type" ref="data_account_type_asset"/>
|
||||
<field name="currency_id" ref="base.USD"/>
|
||||
</record>
|
||||
|
||||
<record model="account.account" id="liabilities_view">
|
||||
<field name="name">Liabilities - (test)</field>
|
||||
@@ -360,8 +368,8 @@
|
||||
<field name="type">bank</field>
|
||||
<field name="view_id" ref="account_journal_bank_view"/>
|
||||
<field name="sequence_id" ref="sequence_bank_journal"/>
|
||||
<field model="account.account" name="default_debit_account_id" ref="cash"/>
|
||||
<field model="account.account" name="default_credit_account_id" ref="cash"/>
|
||||
<field model="account.account" name="default_debit_account_id" ref="bnk"/>
|
||||
<field model="account.account" name="default_credit_account_id" ref="bnk"/>
|
||||
<field name="analytic_journal_id" ref="sit"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
</record>
|
||||
@@ -412,6 +420,16 @@
|
||||
<field eval="True" name="centralisation"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
</record>
|
||||
|
||||
<record id="bank_journal_usd" model="account.journal">
|
||||
<field name="name">USD Bank Journal - (test)</field>
|
||||
<field name="code">TUBK</field>
|
||||
<field name="type">bank</field>
|
||||
<field name="view_id" ref="account_journal_bank_view"/>
|
||||
<field model="account.account" name="usd_debit_account_id" ref="usd_bnk"/>
|
||||
<field model="account.account" name="usd_credit_account_id" ref="usd_bnk"/>
|
||||
<field name="currency_id" ref="base.USD"/>
|
||||
</record>
|
||||
<!--
|
||||
Product income and expense accounts, default parameters
|
||||
-->
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
##############################################################################
|
||||
|
||||
from operator import itemgetter
|
||||
|
||||
from osv import fields, osv
|
||||
import time
|
||||
|
||||
class account_fiscal_position(osv.osv):
|
||||
_name = 'account.fiscal.position'
|
||||
@@ -145,6 +145,29 @@ class res_partner(osv.osv):
|
||||
def _debit_search(self, cr, uid, obj, name, args, context=None):
|
||||
return self._asset_difference_search(cr, uid, obj, name, 'payable', args, context=context)
|
||||
|
||||
def has_something_to_reconcile(self, cr, uid, partner_id, context=None):
|
||||
'''
|
||||
at least a debit, a credit and a line older than the last reconciliation date of the partner
|
||||
'''
|
||||
cr.execute('''
|
||||
SELECT l.partner_id, SUM(l.debit) AS debit, SUM(l.credit) AS credit
|
||||
FROM account_move_line l
|
||||
RIGHT JOIN account_account a ON (a.id = l.account_id)
|
||||
RIGHT JOIN res_partner p ON (l.partner_id = p.id)
|
||||
WHERE a.reconcile IS TRUE
|
||||
AND p.id = %s
|
||||
AND l.reconcile_id IS NULL
|
||||
AND (p.last_reconciliation_date IS NULL OR l.date > p.last_reconciliation_date)
|
||||
AND l.state <> 'draft'
|
||||
GROUP BY l.partner_id''', (partner_id,))
|
||||
res = cr.dictfetchone()
|
||||
if res:
|
||||
return bool(res['debit'] and res['credit'])
|
||||
return False
|
||||
|
||||
def mark_as_reconciled(self, cr, uid, ids, context=None):
|
||||
return self.write(cr, uid, ids, {'last_reconciliation_date': time.strftime('%Y-%m-%d %H:%M:%S')}, context=context)
|
||||
|
||||
_columns = {
|
||||
'credit': fields.function(_credit_debit_get,
|
||||
fnct_search=_credit_search, string='Total Receivable', multi='dc', help="Total amount this customer owes you."),
|
||||
@@ -185,7 +208,7 @@ class res_partner(osv.osv):
|
||||
help="This payment term will be used instead of the default one for the current partner"),
|
||||
'ref_companies': fields.one2many('res.company', 'partner_id',
|
||||
'Companies that refers to partner'),
|
||||
'last_reconciliation_date': fields.datetime('Latest Reconciliation Date', help='Date on which the partner accounting entries were reconciled last time')
|
||||
'last_reconciliation_date': fields.datetime('Latest Reconciliation Date', help='Date on which the partner accounting entries were fully reconciled last time. It differs from the date of the last reconciliation made for this partner, as here we depict the fact that nothing more was to be reconciled at this date. This can be achieved in 2 ways: either the last debit/credit entry was reconciled, either the user pressed the button "Fully Reconciled" in the manual reconciliation process')
|
||||
}
|
||||
|
||||
res_partner()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp><data>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="group_account_invoice" model="res.groups">
|
||||
<field name="name">Invoicing & Payments</field>
|
||||
@@ -7,11 +8,13 @@
|
||||
<field name="users" eval="[(4, ref('base.user_root'))]"/>
|
||||
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="group_account_user" model="res.groups">
|
||||
<field name="name">Accountant</field>
|
||||
<field name="category_id" ref="base.module_category_accounting_and_finance"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_account_invoice'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="group_account_manager" model="res.groups">
|
||||
<field name="name">Manager</field>
|
||||
<field name="category_id" ref="base.module_category_accounting_and_finance"/>
|
||||
@@ -25,100 +28,107 @@
|
||||
|
||||
<record id="account_move_comp_rule" model="ir.rule">
|
||||
<field name="name">Account Entry</field>
|
||||
<field ref="model_account_move" name="model_id"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_move"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="account_move_line_comp_rule" model="ir.rule">
|
||||
<field name="name">Entry lines</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_move_line"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="name">Entry lines</field>
|
||||
<field name="model_id" ref="model_account_move_line"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="journal_period_comp_rule" model="ir.rule">
|
||||
<field name="name">Journal Period</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_journal_period"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_journal_period"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
<record id="journal_comp_rule" model="ir.rule">
|
||||
<field name="name">Journal multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_journal"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_journal"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="analytic_journal_comp_rule" model="ir.rule">
|
||||
<field name="name">Analytic journal multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_analytic_journal"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_analytic_journal"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="period_comp_rule" model="ir.rule">
|
||||
<field name="name">Period multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_period"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_period"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="fiscal_year_comp_rule" model="ir.rule">
|
||||
<field name="name">Fiscal year multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_fiscalyear"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_fiscalyear"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="account_comp_rule" model="ir.rule">
|
||||
<field name="name">Account multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_account"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_account"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_comp_rule" model="ir.rule">
|
||||
<field name="name">Tax multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_tax"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="name">Tax multi-company</field>
|
||||
<field name="model_id" ref="model_account_tax"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="tax_code_comp_rule" model="ir.rule">
|
||||
<field name="name">Tax code multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_tax_code"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_tax_code"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="invoice_comp_rule" model="ir.rule">
|
||||
<field name="name">Invoice multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_invoice"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_invoice"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="invoice_analysis_comp_rule" model="ir.rule">
|
||||
<field name="name">Invoice Analysis multi-company</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_invoice_report"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_invoice_report"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="entry_analysis_comp_rule" model="ir.rule">
|
||||
<field name="name">Entries Analysis multi-company</field>
|
||||
<field name="model_id" ref="model_account_entries_report"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="account_fiscal_position_comp_rule" model="ir.rule">
|
||||
<field name="name">Account fiscal Mapping company rule</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_fiscal_position"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_fiscal_position"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="account_model_comp_rule" model="ir.rule">
|
||||
<field name="name">Account model company rule</field>
|
||||
<field model="ir.model" name="model_id" ref="model_account_model"/>
|
||||
<field eval="True" name="global"/>
|
||||
<field name="model_id" ref="model_account_model"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
@@ -143,4 +153,5 @@
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
</data></openerp>
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
.openerp .oe_account_reconciliation {
|
||||
border-bottom: 1px solid #CACACA;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.openerp .oe_account_reconciliation button {
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
.openerp .oe_account_reconciliation>div {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.openerp .oe_account_reconciliation>div>div {
|
||||
display: table-cell;
|
||||
width: 50%:
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
openerp.account = function (instance) {
|
||||
var _t = instance.web._t,
|
||||
_lt = instance.web._lt;
|
||||
var QWeb = instance.web.qweb;
|
||||
|
||||
instance.web.account = {};
|
||||
|
||||
instance.web.views.add('account_reconciliation_list', 'instance.web.account.ReconciliationListView');
|
||||
instance.web.account.ReconciliationListView = instance.web.ListView.extend({
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
var self = this;
|
||||
this.current_partner = null;
|
||||
this.do_select.add(function() {
|
||||
if (self.get_selected_ids().length === 0) {
|
||||
self.$(".oe_account_recon_reconcile").attr("disabled", "");
|
||||
} else {
|
||||
self.$(".oe_account_recon_reconcile").removeAttr("disabled");
|
||||
}
|
||||
});
|
||||
},
|
||||
on_loaded: function() {
|
||||
var self = this;
|
||||
var tmp = this._super.apply(this, arguments);
|
||||
if (this.partners) {
|
||||
this.$el.prepend(QWeb.render("AccountReconciliation", {widget: this}));
|
||||
this.$(".oe_account_recon_previous").click(function() {
|
||||
self.current_partner = (self.current_partner - 1) % self.partners.length;
|
||||
self.search_by_partner();
|
||||
});
|
||||
this.$(".oe_account_recon_next").click(function() {
|
||||
self.current_partner = (self.current_partner + 1) % self.partners.length;
|
||||
self.search_by_partner();
|
||||
});
|
||||
this.$(".oe_account_recon_reconcile").click(function() {
|
||||
self.reconcile();
|
||||
});
|
||||
this.$(".oe_account_recom_mark_as_reconciled").click(function() {
|
||||
self.mark_as_reconciled();
|
||||
});
|
||||
}
|
||||
return tmp;
|
||||
},
|
||||
do_search: function(domain, context, group_by) {
|
||||
var self = this;
|
||||
this.last_domain = domain;
|
||||
this.last_context = context;
|
||||
this.last_group_by = group_by;
|
||||
this.old_search = _.bind(this._super, this);
|
||||
var mod = new instance.web.Model("account.move.line", context, domain);
|
||||
return mod.call("list_partners_to_reconcile", []).pipe(function(result) {
|
||||
var current = self.current_partner !== null ? self.partners[self.current_partner][0] : null;
|
||||
self.partners = result;
|
||||
var index = _.find(_.range(self.partners.length), function(el) {
|
||||
if (current === self.partners[el][0])
|
||||
return true;
|
||||
});
|
||||
if (index !== undefined)
|
||||
self.current_partner = index;
|
||||
else
|
||||
self.current_partner = self.partners.length == 0 ? null : 0;
|
||||
self.search_by_partner();
|
||||
});
|
||||
},
|
||||
search_by_partner: function() {
|
||||
var self = this;
|
||||
var fct = function() {
|
||||
return self.old_search(new instance.web.CompoundDomain(self.last_domain,
|
||||
[["partner_id", "in", self.current_partner === null ? [] :
|
||||
[self.partners[self.current_partner][0]] ]]), self.last_context, self.last_group_by);
|
||||
};
|
||||
if (self.current_partner === null) {
|
||||
self.last_reconciliation_date = _t("Never");
|
||||
return fct();
|
||||
} else {
|
||||
return new instance.web.Model("res.partner").call("read",
|
||||
[self.partners[self.current_partner][0], ["last_reconciliation_date"]]).pipe(function(res) {
|
||||
self.last_reconciliation_date =
|
||||
instance.web.format_value(res.last_reconciliation_date, {"type": "datetime"}, _t("Never"));
|
||||
return fct();
|
||||
});
|
||||
}
|
||||
},
|
||||
reconcile: function() {
|
||||
var self = this;
|
||||
var ids = this.get_selected_ids();
|
||||
if (ids.length === 0) {
|
||||
instance.web.dialog($("<div />").text(_t("You must choose at least one record.")), {
|
||||
title: _t("Warning"),
|
||||
modal: true
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
new instance.web.Model("ir.model.data").call("get_object_reference", ["account", "action_view_account_move_line_reconcile"]).pipe(function(result) {
|
||||
var additional_context = _.extend({
|
||||
active_id: ids[0],
|
||||
active_ids: ids,
|
||||
active_model: self.model
|
||||
});
|
||||
return self.rpc("/web/action/load", {
|
||||
action_id: result[1],
|
||||
context: additional_context
|
||||
}, function (result) {
|
||||
result = result.result;
|
||||
result.context = _.extend(result.context || {}, additional_context);
|
||||
result.flags = result.flags || {};
|
||||
result.flags.new_window = true;
|
||||
return self.do_action(result, function () {
|
||||
self.do_search(self.last_domain, self.last_context, self.last_group_by);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
mark_as_reconciled: function() {
|
||||
var self = this;
|
||||
var id = self.partners[self.current_partner][0];
|
||||
new instance.web.Model("res.partner").call("mark_as_reconciled", [[id]]).pipe(function() {
|
||||
self.do_search(self.last_domain, self.last_context, self.last_group_by);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<templates id="template" xml:space="preserve">
|
||||
|
||||
<t t-name="AccountReconciliation">
|
||||
<div class="oe_account_reconciliation">
|
||||
<t t-if="widget.current_partner === null">
|
||||
There is no pending reconciliation.
|
||||
</t>
|
||||
<t t-if="widget.current_partner !== null">
|
||||
<div>
|
||||
<div>
|
||||
<button class="oe_account_recon_previous oe_button" href="javascript:void(0)"><</button>
|
||||
<t t-esc="'' + widget.partners[widget.current_partner][1] + ' (' + (widget.current_partner + 1) + '/' + widget.partners.length + ')'"/>
|
||||
<button class="oe_account_recon_next oe_button" href="javascript:void(0)">></button>
|
||||
</div>
|
||||
<div>
|
||||
Last Reconciliation: <t t-esc="widget.last_reconciliation_date" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button class="oe_account_recon_reconcile oe_button oe_highlight" href="javascript:void(0)"
|
||||
disabled="">Reconcile</button>
|
||||
<button class="oe_account_recom_mark_as_reconciled oe_button" href="javascript:void(0)">Nothing to reconcile</button>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -86,19 +86,6 @@ class account_move_line_reconcile(osv.osv_memory):
|
||||
ids = period_obj.find(cr, uid, dt=date, context=context)
|
||||
if ids:
|
||||
period_id = ids[0]
|
||||
#stop the reconciliation process by partner (manual reconciliation) only if there is nothing more to reconcile for this partner
|
||||
if 'active_ids' in context and context['active_ids']:
|
||||
tmp_ml_id = account_move_line_obj.browse(cr, uid, context['active_ids'], context)[0]
|
||||
partner_id = tmp_ml_id.partner_id and tmp_ml_id.partner_id.id or False
|
||||
debit_ml_ids = account_move_line_obj.search(cr, uid, [('partner_id', '=', partner_id), ('account_id.reconcile', '=', True), ('reconcile_id', '=', False), ('debit', '>', 0)], context=context)
|
||||
credit_ml_ids = account_move_line_obj.search(cr, uid, [('partner_id', '=', partner_id), ('account_id.reconcile', '=', True), ('reconcile_id', '=', False), ('credit', '>', 0)], context=context)
|
||||
for ml_id in context['active_ids']:
|
||||
if ml_id in debit_ml_ids:
|
||||
debit_ml_ids.remove(ml_id)
|
||||
if ml_id in credit_ml_ids:
|
||||
credit_ml_ids.remove(ml_id)
|
||||
if not debit_ml_ids and credit_ml_ids:
|
||||
context.update({'stop_reconcile': True})
|
||||
account_move_line_obj.reconcile(cr, uid, context['active_ids'], 'manual', account_id,
|
||||
period_id, journal_id, context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
@@ -166,7 +153,6 @@ class account_move_line_reconcile_writeoff(osv.osv_memory):
|
||||
if ids:
|
||||
period_id = ids[0]
|
||||
|
||||
context.update({'stop_reconcile': True})
|
||||
account_move_line_obj.reconcile(cr, uid, context['active_ids'], 'manual', account_id,
|
||||
period_id, journal_id, context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
@@ -57,10 +57,10 @@ class account_partner_reconcile_process(osv.osv_memory):
|
||||
def _get_partner(self, cr, uid, context=None):
|
||||
move_line_obj = self.pool.get('account.move.line')
|
||||
|
||||
partner = move_line_obj.get_next_partner_only(cr, uid, offset=1, context=context)
|
||||
partner = move_line_obj.list_partners_to_reconcile(cr, uid, context=context)
|
||||
if not partner:
|
||||
return False
|
||||
return partner[0]
|
||||
return partner[0][0]
|
||||
|
||||
def data_get(self, cr, uid, to_reconcile, today_reconciled, context=None):
|
||||
return {'progress': (100 / (float(to_reconcile + today_reconciled) or 1.0)) * today_reconciled}
|
||||
@@ -100,4 +100,4 @@ class account_partner_reconcile_process(osv.osv_memory):
|
||||
|
||||
account_partner_reconcile_process()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -107,11 +107,12 @@ class coda_bank_account(osv.osv):
|
||||
if not default:
|
||||
default = {}
|
||||
default = default.copy()
|
||||
default.update({'journal_id': None})
|
||||
default['description1'] = cba['description1'] or ''
|
||||
default['description2'] = cba['description2'] or ''
|
||||
default['name'] = (cba['name'] or '') + ' (copy)'
|
||||
default['state'] = cba['state']
|
||||
default.update(
|
||||
journal_id=None,
|
||||
description1=cba['description1'] or '',
|
||||
description2=cba['description2'] or '',
|
||||
name=_("%s (copy)") % (cba['name'] or ''),
|
||||
state=cba['state'])
|
||||
return super(coda_bank_account, self).copy(cr, uid, id, default, context)
|
||||
|
||||
def onchange_state(self, cr, uid, ids, state):
|
||||
|
||||
@@ -140,7 +140,7 @@ class account_analytic_account(osv.osv):
|
||||
'name': fields.char('Account/Contract Name', size=128, required=True),
|
||||
'complete_name': fields.function(_complete_name_calc, type='char', string='Full Account Name'),
|
||||
'code': fields.char('Reference', size=24, select=True),
|
||||
'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Project')], 'Type of Account', required=True,
|
||||
'type': fields.selection([('view','Analytic View'), ('normal','Analytic Account'),('contract','Contract or Project'),('template','Template of Project')], 'Type of Account', required=True,
|
||||
help="If you select the View Type, it means you won\'t allow to create journal entries using that account.\n"\
|
||||
"The type 'Analytic account' stands for usual accounts that you only want to use in accounting.\n"\
|
||||
"If you select Contract or Project, it offers you the possibility to manage the validity and the invoicing options for this account.\n"\
|
||||
@@ -168,7 +168,7 @@ class account_analytic_account(osv.osv):
|
||||
'res.company': (_get_analytic_account, ['currency_id'], 10),
|
||||
}, string='Currency', type='many2one', relation='res.currency'),
|
||||
}
|
||||
|
||||
|
||||
def on_change_template(self, cr, uid, ids, template_id, context=None):
|
||||
if not template_id:
|
||||
return {}
|
||||
@@ -179,7 +179,7 @@ class account_analytic_account(osv.osv):
|
||||
res['value']['quantity_max'] = template.quantity_max
|
||||
res['value']['description'] = template.description
|
||||
return res
|
||||
|
||||
|
||||
def on_change_partner_id(self, cr, uid, ids,partner_id, name, context={}):
|
||||
res={}
|
||||
if partner_id:
|
||||
@@ -222,8 +222,11 @@ class account_analytic_account(osv.osv):
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
if not default:
|
||||
default = {}
|
||||
default['code'] = False
|
||||
default['line_ids'] = []
|
||||
analytic = self.browse(cr, uid, id, context=context)
|
||||
default.update(
|
||||
code=False,
|
||||
line_ids=[],
|
||||
name=_("%s (copy)") % (analytic['name']))
|
||||
return super(account_analytic_account, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
def on_change_company(self, cr, uid, id, company_id):
|
||||
|
||||
@@ -209,7 +209,7 @@ class document_file(osv.osv):
|
||||
default = {}
|
||||
if 'name' not in default:
|
||||
name = self.read(cr, uid, [id], ['name'])[0]['name']
|
||||
default.update({'name': name + " " + _("(copy)")})
|
||||
default.update(name=_("%s (copy)") % (name))
|
||||
return super(document_file, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
|
||||
@@ -231,7 +231,7 @@ class document_directory(osv.osv):
|
||||
if not default:
|
||||
default ={}
|
||||
name = self.read(cr, uid, [id])[0]['name']
|
||||
default.update({'name': name+ " (copy)"})
|
||||
default.update(name=_("%s (copy)") % (name))
|
||||
return super(document_directory,self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
def _check_duplication(self, cr, uid, vals, ids=[], op='create'):
|
||||
|
||||
@@ -215,7 +215,10 @@ class email_template(osv.osv):
|
||||
if default is None:
|
||||
default = {}
|
||||
default = default.copy()
|
||||
default['name'] = template.name + _('(copy)')
|
||||
default.update(
|
||||
name=_("%s (copy)") % (template.name),
|
||||
ref_ir_act_window=False,
|
||||
ref_ir_value=False)
|
||||
return super(email_template, self).copy(cr, uid, id, default, context)
|
||||
|
||||
def build_expression(self, field_name, sub_field_name, null_value):
|
||||
@@ -335,7 +338,7 @@ class email_template(osv.osv):
|
||||
:param bool force_send: if True, the generated mail.message is
|
||||
immediately sent after being created, as if the scheduler
|
||||
was executed for this message only.
|
||||
:returns: id of the mail.message that was created
|
||||
:returns: id of the mail.message that was created
|
||||
"""
|
||||
if context is None: context = {}
|
||||
mail_mail = self.pool.get('mail.mail')
|
||||
|
||||
@@ -81,10 +81,9 @@ class hr_payroll_structure(osv.osv):
|
||||
"""
|
||||
if not default:
|
||||
default = {}
|
||||
default.update({
|
||||
'code': self.browse(cr, uid, id, context=context).code + "(copy)",
|
||||
'company_id': self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id
|
||||
})
|
||||
default.update(
|
||||
code=_("%s (copy)") % (self.browse(cr, uid, id, context=context).code),
|
||||
company_id=self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id)
|
||||
return super(hr_payroll_structure, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
def get_all_rules(self, cr, uid, structure_ids, context=None):
|
||||
@@ -305,7 +304,7 @@ class hr_payslip(osv.osv):
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [(_check_dates, "Payslip 'Date From' must be before 'Date To'.", ['date_from', 'date_to'])]
|
||||
_constraints = [(_check_dates, "Payslip 'Date From' must be before 'Date To'.", ['date_from', 'date_to'])]
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
if not default:
|
||||
@@ -851,7 +850,7 @@ result = rules.NET > categories.NET * 0.10''',
|
||||
"""
|
||||
:param rule_id: id of rule to compute
|
||||
:param localdict: dictionary containing the environement in which to compute the rule
|
||||
:return: returns a tuple build as the base/amount computed, the quantity and the rate
|
||||
:return: returns a tuple build as the base/amount computed, the quantity and the rate
|
||||
:rtype: (float, float, float)
|
||||
"""
|
||||
rule = self.browse(cr, uid, rule_id, context=context)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="update_posted" eval="True" />
|
||||
<field name="entry_posted" eval="True" />
|
||||
<field name="currency" model="res.currency" ref="base.CHF" />
|
||||
</record>
|
||||
|
||||
<record id="bank_euro_journal" model="account.journal">
|
||||
|
||||
+1
-1
@@ -356,7 +356,7 @@ class mrp_bom(osv.osv):
|
||||
if default is None:
|
||||
default = {}
|
||||
bom_data = self.read(cr, uid, id, [], context=context)
|
||||
default.update({'name': bom_data['name'] + ' ' + _('Copy'), 'bom_id':False})
|
||||
default.update(name=_("%s (copy)") % (bom_data['name']), bom_id=False)
|
||||
return super(mrp_bom, self).copy_data(cr, uid, id, default, context=context)
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
<record id="portal_stock_picking_user_rule" model="ir.rule">
|
||||
<field name="name">Portal Personal Delivery Orders</field>
|
||||
<field ref="stock.model_stock_picking" name="model_id"/>
|
||||
<field name="model_id" ref="stock.model_stock_picking"/>
|
||||
<field name="domain_force">[('partner_id','child_of',[user.partner_id.id])]</field>
|
||||
<field name="groups" eval="[(4, ref('portal.group_portal'))]"/>
|
||||
</record>
|
||||
|
||||
@@ -511,7 +511,7 @@ class product_product(osv.osv):
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
result[obj.id] = tools.image_get_resized_images(obj.image, avoid_resize_medium=True)
|
||||
return result
|
||||
|
||||
|
||||
def _set_image(self, cr, uid, id, name, value, args, context=None):
|
||||
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
|
||||
|
||||
@@ -727,7 +727,7 @@ class product_product(osv.osv):
|
||||
context_wo_lang.pop('lang', None)
|
||||
product = self.read(cr, uid, id, ['name'], context=context_wo_lang)
|
||||
default = default.copy()
|
||||
default['name'] = product['name'] + ' (copy)'
|
||||
default.update(name=_("%s (copy)") % (product['name']))
|
||||
|
||||
if context.get('variant',False):
|
||||
fields = ['product_tmpl_id', 'active', 'variants', 'default_code',
|
||||
@@ -897,4 +897,43 @@ class pricelist_partnerinfo(osv.osv):
|
||||
}
|
||||
_order = 'min_quantity asc'
|
||||
pricelist_partnerinfo()
|
||||
|
||||
class res_currency(osv.osv):
|
||||
_inherit = 'res.currency'
|
||||
|
||||
def _check_main_currency_rounding(self, cr, uid, ids, context=None):
|
||||
cr.execute('SELECT digits FROM decimal_precision WHERE name like %s',('Account',))
|
||||
digits = cr.fetchone()
|
||||
if digits and len(digits):
|
||||
digits = digits[0]
|
||||
main_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id
|
||||
for currency_id in ids:
|
||||
if currency_id == main_currency.id:
|
||||
if main_currency.rounding < 10 ** -digits:
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_main_currency_rounding, 'Error! You cannot define a rounding factor for the company\'s main currency that is smaller than the decimal precision of \'Account\'.', ['rounding']),
|
||||
]
|
||||
|
||||
class decimal_precision(osv.osv):
|
||||
_inherit = 'decimal.precision'
|
||||
|
||||
def _check_main_currency_rounding(self, cr, uid, ids, context=None):
|
||||
cr.execute('SELECT id, digits FROM decimal_precision WHERE name like %s',('Account',))
|
||||
res = cr.fetchone()
|
||||
if res and len(res):
|
||||
account_precision_id, digits = res
|
||||
main_currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id
|
||||
for decimal_precision in ids:
|
||||
if decimal_precision == account_precision_id:
|
||||
if main_currency.rounding < 10 ** -digits:
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_main_currency_rounding, 'Error! You cannot define the decimal precision of \'Account\' as greater than the rounding factor of the company\'s main currency', ['digits']),
|
||||
]
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -323,7 +323,7 @@ class project(osv.osv):
|
||||
default.pop('alias_id', None)
|
||||
proj = self.browse(cr, uid, id, context=context)
|
||||
if not default.get('name', False):
|
||||
default['name'] = proj.name + _(' (copy)')
|
||||
default.update(name=_("%s (copy)") % (proj.name))
|
||||
res = super(project, self).copy(cr, uid, id, default, context)
|
||||
self.map_tasks(cr,uid,id,res,context)
|
||||
return res
|
||||
@@ -344,7 +344,7 @@ class project(osv.osv):
|
||||
new_date_end = (datetime(*time.strptime(new_date_start,'%Y-%m-%d')[:3])+(end_date-start_date)).strftime('%Y-%m-%d')
|
||||
context.update({'copy':True})
|
||||
new_id = self.copy(cr, uid, proj.id, default = {
|
||||
'name': proj.name +_(' (copy)'),
|
||||
'name':_("%s (copy)") % (proj.name),
|
||||
'state':'open',
|
||||
'date_start':new_date_start,
|
||||
'date':new_date_end,
|
||||
@@ -694,7 +694,7 @@ class task(base_stage, osv.osv):
|
||||
if not default.get('name', False):
|
||||
default['name'] = self.browse(cr, uid, id, context=context).name or ''
|
||||
if not context.get('copy',False):
|
||||
new_name = _("%s (copy)")%default.get('name','')
|
||||
new_name = _("%s (copy)") % (default.get('name', ''))
|
||||
default.update({'name':new_name})
|
||||
return super(task, self).copy_data(cr, uid, id, default, context)
|
||||
|
||||
|
||||
@@ -355,7 +355,7 @@ class project_issue(base_stage, osv.osv):
|
||||
if not default:
|
||||
default = {}
|
||||
default = default.copy()
|
||||
default['name'] = issue['name'] + _(' (copy)')
|
||||
default.update(name=_('%s (copy)') % (issue['name']))
|
||||
return super(project_issue, self).copy(cr, uid, id, default=default,
|
||||
context=context)
|
||||
|
||||
@@ -534,7 +534,7 @@ class project(osv.osv):
|
||||
|
||||
def _get_alias_models(self, cr, uid, context=None):
|
||||
return [('project.task', "Tasks"), ("project.issue", "Issues")]
|
||||
|
||||
|
||||
def _issue_count(self, cr, uid, ids, field_name, arg, context=None):
|
||||
res = dict.fromkeys(ids, 0)
|
||||
issue_ids = self.pool.get('project.issue').search(cr, uid, [('project_id', 'in', ids)])
|
||||
@@ -557,7 +557,7 @@ class project(osv.osv):
|
||||
_constraints = [
|
||||
(_check_escalation, 'Error! You cannot assign escalation to the same project!', ['project_escalation_id'])
|
||||
]
|
||||
|
||||
|
||||
project()
|
||||
|
||||
class account_analytic_account(osv.osv):
|
||||
|
||||
@@ -138,7 +138,7 @@ class project_phase(osv.osv):
|
||||
if default is None:
|
||||
default = {}
|
||||
if not default.get('name', False):
|
||||
default['name'] = self.browse(cr, uid, id, context=context).name + _(' (copy)')
|
||||
default.update(name=_('%s (copy)') % (self.browse(cr, uid, id, context=context).name))
|
||||
return super(project_phase, self).copy(cr, uid, id, default, context)
|
||||
|
||||
def set_draft(self, cr, uid, ids, *args):
|
||||
@@ -227,7 +227,7 @@ class project(osv.osv):
|
||||
'phase_ids': fields.one2many('project.phase', 'project_id', "Project Phases"),
|
||||
'phase_count': fields.function(_phase_count, type='integer', string="Open Phases"),
|
||||
}
|
||||
|
||||
|
||||
def schedule_phases(self, cr, uid, ids, context=None):
|
||||
context = context or {}
|
||||
if type(ids) in (long, int,):
|
||||
@@ -250,7 +250,7 @@ class project(osv.osv):
|
||||
# Maybe it's better to update than unlink/create if it already exists ?
|
||||
p = getattr(project_gantt, 'Phase_%d' % (phase.id,))
|
||||
|
||||
self.pool.get('project.user.allocation').unlink(cr, uid,
|
||||
self.pool.get('project.user.allocation').unlink(cr, uid,
|
||||
[x.id for x in phase.user_ids],
|
||||
context=context
|
||||
)
|
||||
|
||||
+24
-24
@@ -45,24 +45,24 @@ class resource_calendar(osv.osv):
|
||||
def working_hours_on_day(self, cr, uid, resource_calendar_id, day, context=None):
|
||||
"""Calculates the Working Total Hours based on Resource Calendar and
|
||||
given working day (datetime object).
|
||||
|
||||
|
||||
@param resource_calendar_id: resource.calendar browse record
|
||||
@param day: datetime object
|
||||
|
||||
|
||||
@return: returns the working hours (as float) men should work on the given day if is in the attendance_ids of the resource_calendar_id (i.e if that day is a working day), returns 0.0 otherwise
|
||||
"""
|
||||
res = 0.0
|
||||
for working_day in resource_calendar_id.attendance_ids:
|
||||
if (int(working_day.dayofweek) + 1) == day.isoweekday():
|
||||
res += working_day.hour_to - working_day.hour_from
|
||||
return res
|
||||
return res
|
||||
|
||||
def _get_leaves(self, cr, uid, id, resource):
|
||||
"""Private Method to Calculate resource Leaves days
|
||||
|
||||
"""Private Method to Calculate resource Leaves days
|
||||
|
||||
@param id: resource calendar id
|
||||
@param resource: resource id for which leaves will ew calculated
|
||||
|
||||
@param resource: resource id for which leaves will ew calculated
|
||||
|
||||
@return : returns the list of dates, where resource on leave in
|
||||
resource.calendar.leaves object (e.g.['%Y-%m-%d', '%Y-%m-%d'])
|
||||
"""
|
||||
@@ -85,9 +85,9 @@ class resource_calendar(osv.osv):
|
||||
"""
|
||||
Calculates the working Schedule from supplied from date to till hours
|
||||
will be satisfied based or resource calendar id. If resource is also
|
||||
given then it will consider the resource leave also and than will
|
||||
given then it will consider the resource leave also and than will
|
||||
calculates resource working schedule
|
||||
|
||||
|
||||
@param dt_from: datetime object, start of working scheduled
|
||||
@param hours: float, total number working hours needed scheduled from
|
||||
start date
|
||||
@@ -187,29 +187,29 @@ class resource_calendar(osv.osv):
|
||||
|
||||
def interval_get(self, cr, uid, id, dt_from, hours, resource=False, byday=True):
|
||||
"""Calculates Resource Working Internal Timing Based on Resource Calendar.
|
||||
|
||||
|
||||
@param dt_from: start resource schedule calculation.
|
||||
@param hours : total number of working hours to be scheduled.
|
||||
@param resource: optional resource id, If supplied it will take care of
|
||||
@param resource: optional resource id, If supplied it will take care of
|
||||
resource leave while scheduling.
|
||||
@param byday: boolean flag bit enforce day wise scheduling
|
||||
|
||||
|
||||
@return : list of scheduled working timing based on resource calendar.
|
||||
"""
|
||||
res = self.interval_get_multi(cr, uid, [(dt_from.strftime('%Y-%m-%d %H:%M:%S'), hours, id)], resource, byday)[(dt_from.strftime('%Y-%m-%d %H:%M:%S'), hours, id)]
|
||||
return res
|
||||
|
||||
def interval_hours_get(self, cr, uid, id, dt_from, dt_to, resource=False):
|
||||
""" Calculates the Total Working hours based on given start_date to
|
||||
end_date, If resource id is supplied that it will consider the source
|
||||
""" Calculates the Total Working hours based on given start_date to
|
||||
end_date, If resource id is supplied that it will consider the source
|
||||
leaves also in calculating the hours.
|
||||
|
||||
|
||||
@param dt_from : date start to calculate hours
|
||||
@param dt_end : date end to calculate hours
|
||||
@param resource: optional resource id, If given resource leave will be
|
||||
considered.
|
||||
|
||||
@return : Total number of working hours based dt_from and dt_end and
|
||||
considered.
|
||||
|
||||
@return : Total number of working hours based dt_from and dt_end and
|
||||
resource if supplied.
|
||||
"""
|
||||
if not id:
|
||||
@@ -257,7 +257,7 @@ resource_calendar()
|
||||
class resource_calendar_attendance(osv.osv):
|
||||
_name = "resource.calendar.attendance"
|
||||
_description = "Work Detail"
|
||||
|
||||
|
||||
_columns = {
|
||||
'name' : fields.char("Name", size=64, required=True),
|
||||
'dayofweek': fields.selection([('0','Monday'),('1','Tuesday'),('2','Wednesday'),('3','Thursday'),('4','Friday'),('5','Saturday'),('6','Sunday')], 'Day of Week', required=True, select=True),
|
||||
@@ -266,9 +266,9 @@ class resource_calendar_attendance(osv.osv):
|
||||
'hour_to' : fields.float("Work to", required=True),
|
||||
'calendar_id' : fields.many2one("resource.calendar", "Resource's Calendar", required=True),
|
||||
}
|
||||
|
||||
|
||||
_order = 'dayofweek, hour_from'
|
||||
|
||||
|
||||
_defaults = {
|
||||
'dayofweek' : '0'
|
||||
}
|
||||
@@ -302,12 +302,12 @@ class resource_resource(osv.osv):
|
||||
'company_id': lambda self, cr, uid, context: self.pool.get('res.company')._company_default_get(cr, uid, 'resource.resource', context=context)
|
||||
}
|
||||
|
||||
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
if not default.get('name', False):
|
||||
default['name'] = self.browse(cr, uid, id, context=context).name + _(' (copy)')
|
||||
default.update(name=_('%s (copy)') % (self.browse(cr, uid, id, context=context).name))
|
||||
return super(resource_resource, self).copy(cr, uid, id, default, context)
|
||||
|
||||
def generate_resources(self, cr, uid, user_ids, calendar_id, context=None):
|
||||
@@ -368,7 +368,7 @@ class resource_resource(osv.osv):
|
||||
"""
|
||||
if not calendar_id:
|
||||
# Calendar is not specified: working days: 24/7
|
||||
return [('fri', '8:0-12:0','13:0-17:0'), ('thu', '8:0-12:0','13:0-17:0'), ('wed', '8:0-12:0','13:0-17:0'),
|
||||
return [('fri', '8:0-12:0','13:0-17:0'), ('thu', '8:0-12:0','13:0-17:0'), ('wed', '8:0-12:0','13:0-17:0'),
|
||||
('mon', '8:0-12:0','13:0-17:0'), ('tue', '8:0-12:0','13:0-17:0')]
|
||||
resource_attendance_pool = self.pool.get('resource.calendar.attendance')
|
||||
time_range = "8:00-8:00"
|
||||
|
||||
+2397
-1950
File diff suppressed because it is too large
Load Diff
+2031
-1813
File diff suppressed because it is too large
Load Diff
+1848
-1763
File diff suppressed because it is too large
Load Diff
+2413
-1991
File diff suppressed because it is too large
Load Diff
+2160
-1828
File diff suppressed because it is too large
Load Diff
+1820
-1736
File diff suppressed because it is too large
Load Diff
+2788
-2058
File diff suppressed because it is too large
Load Diff
+2007
-1765
File diff suppressed because it is too large
Load Diff
+2530
-2008
File diff suppressed because it is too large
Load Diff
+1860
-1760
File diff suppressed because it is too large
Load Diff
+2448
-1999
File diff suppressed because it is too large
Load Diff
+2779
-2120
File diff suppressed because it is too large
Load Diff
+2181
-1897
File diff suppressed because it is too large
Load Diff
+1869
-1762
File diff suppressed because it is too large
Load Diff
+2369
-1858
File diff suppressed because it is too large
Load Diff
+2734
-2110
File diff suppressed because it is too large
Load Diff
+1770
-1789
File diff suppressed because it is too large
Load Diff
+2462
-1975
File diff suppressed because it is too large
Load Diff
+2414
-1992
File diff suppressed because it is too large
Load Diff
+2409
-1978
File diff suppressed because it is too large
Load Diff
+1929
-1876
File diff suppressed because it is too large
Load Diff
+2420
-1995
File diff suppressed because it is too large
Load Diff
+2565
-1903
File diff suppressed because it is too large
Load Diff
+1849
-1760
File diff suppressed because it is too large
Load Diff
+1699
-1721
File diff suppressed because it is too large
Load Diff
+2053
-1896
File diff suppressed because it is too large
Load Diff
+1839
-1759
File diff suppressed because it is too large
Load Diff
+2755
-2096
File diff suppressed because it is too large
Load Diff
+2599
-2014
File diff suppressed because it is too large
Load Diff
+2775
-2116
File diff suppressed because it is too large
Load Diff
+2763
-2095
File diff suppressed because it is too large
Load Diff
+1704
-1723
File diff suppressed because it is too large
Load Diff
+2737
-2091
File diff suppressed because it is too large
Load Diff
+2762
-2103
File diff suppressed because it is too large
Load Diff
+2666
-2006
File diff suppressed because it is too large
Load Diff
+2780
-2123
File diff suppressed because it is too large
Load Diff
+2537
-2003
File diff suppressed because it is too large
Load Diff
+2028
-1795
File diff suppressed because it is too large
Load Diff
+2157
-1840
File diff suppressed because it is too large
Load Diff
+1699
-1721
File diff suppressed because it is too large
Load Diff
+2097
-1850
File diff suppressed because it is too large
Load Diff
+2096
-1849
File diff suppressed because it is too large
Load Diff
+2750
-2091
File diff suppressed because it is too large
Load Diff
+1826
-1723
File diff suppressed because it is too large
Load Diff
+1699
-1721
File diff suppressed because it is too large
Load Diff
+2783
-2121
File diff suppressed because it is too large
Load Diff
+1798
-1751
File diff suppressed because it is too large
Load Diff
+1969
-1768
File diff suppressed because it is too large
Load Diff
+2502
-1923
File diff suppressed because it is too large
Load Diff
+1834
-1759
File diff suppressed because it is too large
Load Diff
+574
-2400
File diff suppressed because it is too large
Load Diff
+550
-2479
File diff suppressed because it is too large
Load Diff
+540
-2370
File diff suppressed because it is too large
Load Diff
+581
-2843
File diff suppressed because it is too large
Load Diff
+562
-2209
File diff suppressed because it is too large
Load Diff
+543
-2032
File diff suppressed because it is too large
Load Diff
+594
-2902
File diff suppressed because it is too large
Load Diff
+559
-2543
File diff suppressed because it is too large
Load Diff
+588
-2857
File diff suppressed because it is too large
Load Diff
+544
-2412
File diff suppressed because it is too large
Load Diff
+568
-2689
File diff suppressed because it is too large
Load Diff
+577
-2944
File diff suppressed because it is too large
Load Diff
+526
-2009
File diff suppressed because it is too large
Load Diff
+577
-2725
File diff suppressed because it is too large
Load Diff
+563
-2776
File diff suppressed because it is too large
Load Diff
+583
-2515
File diff suppressed because it is too large
Load Diff
+530
-2002
File diff suppressed because it is too large
Load Diff
+585
-2784
File diff suppressed because it is too large
Load Diff
+571
-2144
File diff suppressed because it is too large
Load Diff
+538
-2365
File diff suppressed because it is too large
Load Diff
+526
-1982
File diff suppressed because it is too large
Load Diff
+541
-2475
File diff suppressed because it is too large
Load Diff
+537
-2241
File diff suppressed because it is too large
Load Diff
+588
-2635
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user