bzr revid: nch@tinyerp.com-20080926044734-u24wj2rgugaztjut
This commit is contained in:
Naresh Choksy
2008-09-26 10:17:34 +05:30
38 changed files with 797 additions and 679 deletions
+51 -14
View File
@@ -160,14 +160,29 @@ class account_account(osv.osv):
return super(account_account,self).search(cr, uid, args, offset, limit,
order, context=context, count=count)
def _get_children_and_consol(self, cr, uid, ids, context={}):
#this function search for all the children and all consolidated children (recursively) of the given account ids
res = self.search(cr, uid, [('parent_id', 'child_of', ids)])
for id in res:
this = self.browse(cr, uid, id, context)
for child in this.child_consol_ids:
if child.id not in res:
res.append(child.id)
if len(res) != len(ids):
return self._get_children_and_consol(cr, uid, res, context)
return res
def __compute(self, cr, uid, ids, field_names, arg, context={}, query=''):
#compute the balance/debit/credit accordingly to the value of field_name for the given account ids
mapping = {
'balance': "COALESCE(SUM(l.debit) - SUM(l.credit), 0) as balance ",
'debit': "COALESCE(SUM(l.debit), 0) as debit ",
'credit': "COALESCE(SUM(l.credit), 0) as credit "
}
ids2 = self.search(cr, uid, [('parent_id', 'child_of', ids)])
#get all the necessary accounts
ids2 = self._get_children_and_consol(cr, uid, ids, context)
acc_set = ",".join(map(str, ids2))
#compute for each account the balance/debit/credit from the move lines
accounts = {}
if ids2:
query = self.pool.get('account.move.line')._query_get(cr, uid,
@@ -184,13 +199,29 @@ class account_account(osv.osv):
for res in cr.dictfetchall():
accounts[res['id']] = res
#for the asked accounts, get from the dictionnary 'accounts' the value of it
res = {}
for id in ids:
res[id] = {}.fromkeys(field_names, 0.0)
ids2 = self.search(cr, uid, [('parent_id', 'child_of', [id])])
res[id] = self._get_account_values(cr, uid, id, accounts, field_names, context)
return res
def _get_account_values(self, cr, uid, id, accounts, field_names, context={}):
res = {}.fromkeys(field_names, 0.0)
browse_rec = self.browse(cr, uid, id)
if browse_rec.type == 'consolidation':
ids2 = self.read(cr, uid, [browse_rec.id], ['child_consol_ids'], context)[0]['child_consol_ids']
for t in self.search(cr, uid, [('parent_id', 'child_of', [browse_rec.id])]):
if t not in ids2 and t != browse_rec.id:
ids2.append(t)
for i in ids2:
tmp = self._get_account_values(cr, uid, i, accounts, field_names, context)
for a in field_names:
res[a] += tmp[a]
else:
ids2 = self.search(cr, uid, [('parent_id', 'child_of', [browse_rec.id])])
for i in ids2:
for a in field_names:
res[id][a] += accounts.get(i, {}).get(a, 0.0)
res[a] += accounts.get(i, {}).get(a, 0.0)
return res
def _get_company_currency(self, cr, uid, ids, field_name, arg, context={}):
@@ -216,7 +247,7 @@ class account_account(osv.osv):
_columns = {
'name': fields.char('Name', size=128, required=True, select=True),
'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Force all moves for this account to have this secondary currency."),
'code': fields.char('Code', size=64),
'code': fields.char('Code', size=64, required=True),
'type': fields.selection([
('receivable','Receivable'),
('payable','Payable'),
@@ -229,7 +260,7 @@ class account_account(osv.osv):
'user_type': fields.many2one('account.account.type', 'Account Type', required=True),
'parent_id': fields.many2one('account.account','Parent', ondelete='cascade'),
'child_parent_ids':fields.one2many('account.account','parent_id','Children'),
'child_consol_ids':fields.many2many('account.account', 'account_account_consol_rel', 'child_id', 'parent_id', 'Consolidated Children',domain=[('type', '=', 'consolidation')]),
'child_consol_ids':fields.many2many('account.account', 'account_account_consol_rel', 'child_id', 'parent_id', 'Consolidated Children'),
'child_id': fields.function(_get_child_ids, method=True, type='many2many',relation="account.account",string="Children Accounts"),
'balance': fields.function(__compute, digits=(16,2), method=True, string='Balance', multi='balance'),
'credit': fields.function(__compute, digits=(16,2), method=True, string='Credit', multi='balance'),
@@ -245,7 +276,7 @@ class account_account(osv.osv):
'parent_left': fields.integer('Parent Left', select=1),
'parent_right': fields.integer('Parent Right', select=1),
'check_history': fields.boolean('Display History', help="Check this box if you want to print all entries otherwise it will print balance of this account")
'check_history': fields.boolean('Display History', help="Check this box if you want to print all entries when printing the General Ledger, otherwise it will only print its balance.")
}
def _default_company(self, cr, uid, context={}):
@@ -924,15 +955,21 @@ class account_move_reconcile(osv.osv):
{'reconcile_id': rec.id }
)
return True
def name_get(self, cr, uid, ids, context=None):
result = {}
if not len(ids):
return []
result = []
for r in self.browse(cr, uid, ids, context):
total = reduce(lambda y,t: (t.debit or 0.0) - (t.credit or 0.0) + y, r.line_partial_ids, 0.0)
if total:
result[r.id] = '%s (%.2f)' % (r.name, total)
name = '%s (%.2f)' % (r.name, total)
result.append((r.id,name))
else:
result[r.id] = r.name
result.append((r.id,r.name))
return result
account_move_reconcile()
#----------------------------------------------------------
@@ -1510,7 +1547,7 @@ class account_config_wizard(osv.osv_memory):
}
def install_account_chart(self, cr, uid,ids, context=None):
for res in self.read(cr,uid,ids):
for res in self.read(cr,uid,ids):
id = res['charts']
def install(id):
mod_obj = self.pool.get('ir.module.module')
@@ -1558,7 +1595,7 @@ class account_config_wizard(osv.osv_memory):
'target':'new',
}
account_config_wizard()
@@ -2036,8 +2073,8 @@ class wizard_multi_charts_accounts(osv.osv_memory):
'res_model': 'ir.module.module.configuration.wizard',
'type': 'ir.actions.act_window',
'target':'new',
}
}
wizard_multi_charts_accounts()
+3 -3
View File
@@ -167,8 +167,8 @@ class account_bank_statement(osv.osv):
if not (abs(st.balance_end - st.balance_end_real) < 0.0001):
raise osv.except_osv(_('Error !'),
_('The statement balance is incorrect !\n'
'Check that the ending balance equals the computed one.'))
_('The statement balance is incorrect !\n') +
_('The expected balance (%.2f) is different than the computed one. (%.2f)') % (st.balance_end_real, st.balance_end))
if (not st.journal_id.default_credit_account_id) \
or (not st.journal_id.default_debit_account_id):
raise osv.except_osv(_('Configration Error !'),
@@ -177,7 +177,7 @@ class account_bank_statement(osv.osv):
for line in st.move_line_ids:
if line.state <> 'valid':
raise osv.except_osv(_('Error !'),
_('The account entries lines are not valid.'))
_('The account entries lines are not in valid state.'))
for move in st.line_ids:
move_id = account_move_obj.create(cr, uid, {
+17 -10
View File
@@ -175,15 +175,14 @@
</field>
</group>
<group col="4" colspan="2">
<label colspan="2"/>
<field name="amount_untaxed"/>
<button colspan="2" name="button_reset_taxes" states="draft" string="Reset taxes" type="object"/>
<field name="amount_tax"/>
<field name="amount_untaxed"/>
<button colspan="2" name="button_compute" states="draft" string="Compute" type="object"/>
<field name="amount_total"/>
<field name="amount_tax"/>
<field name="reconciled"/>
<field name="residual"/>
<field name="amount_total"/>
<field name="state" select="2"/>
<field name="residual"/>
<group col="3" colspan="4">
<button name="invoice_open" states="draft,proforma" string="Validate"/>
<button name="invoice_cancel" states="draft,proforma,sale,open" string="Cancel"/>
@@ -258,15 +257,14 @@
</field>
</group>
<group col="4" colspan="2">
<label colspan="2"/>
<field name="amount_untaxed"/>
<button colspan="2" name="button_reset_taxes" states="draft" string="Reset taxes" type="object"/>
<field name="amount_tax"/>
<field name="amount_untaxed"/>
<button colspan="2" name="button_compute" states="draft" string="Compute" type="object"/>
<field name="amount_total"/>
<field name="amount_tax"/>
<field name="reconciled"/>
<field name="residual"/>
<field name="amount_total"/>
<field name="state" select="2"/>
<field name="residual"/>
<group col="3" colspan="4">
<button name="invoice_proforma" states="draft" string="PRO-FORMA"/>
<button name="invoice_open" states="draft,proforma" string="Create"/>
@@ -420,6 +418,7 @@
<field name="name">Draft Customer Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="domain">[('state','=','draft'),('type','=','out_invoice')]</field>
<field name="context">{'type':'out_invoice'}</field>
</record>
@@ -441,6 +440,7 @@
<field name="name">PRO-FORMA Customer Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="domain">[('state','=','proforma'),('type','=','out_invoice')]</field>
<field name="context">{'type':'out_invoice'}</field>
</record>
@@ -462,6 +462,7 @@
<field name="name">Unpaid Customer Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="domain">[('state','!=','draft'),('reconciled','=',False),('type','=','out_invoice')]</field>
<field name="context">{'type':'out_invoice'}</field>
</record>
@@ -483,6 +484,7 @@
<field name="name">Draft Supplier Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="domain">[('state','=','draft'),('type','=','in_invoice')]</field>
<field name="context">{'type':'in_invoice'}</field>
</record>
@@ -504,6 +506,7 @@
<field name="name">Unpaid Supplier Invoices</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="domain">[('state','!=','draft'),('reconciled','=',False),('type','=','in_invoice')]</field>
<field name="context">{'type':'in_invoice'}</field>
</record>
@@ -525,6 +528,7 @@
<field name="name">Draft Customer Refunds</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="domain">[('state','=','draft'),('type','=','out_refund')]</field>
<field name="context">{'type':'out_refund'}</field>
</record>
@@ -546,6 +550,7 @@
<field name="name">Unpaid Customer Refunds</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="domain">[('state','!=','draft'),('reconciled','=',False),('type','=','out_refund')]</field>
<field name="context">{'type':'out_refund'}</field>
</record>
@@ -567,6 +572,7 @@
<field name="name">Draft Supplier Refunds</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="domain">[('state','=','draft'),('type','=','in_refund')]</field>
<field name="context">{'type':'in_refund'}</field>
</record>
@@ -588,6 +594,7 @@
<field name="name">Unpaid Supplier Refunds</field>
<field name="res_model">account.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
<field name="domain">[('state','!=','draft'),('reconciled','=',False),('type','=','in_refund')]</field>
<field name="context">{'type':'in_refund'}</field>
</record>
+13 -3
View File
@@ -305,6 +305,8 @@ class account_move_line(osv.osv):
'analytic_account_id' : fields.many2one('account.analytic.account', 'Analytic Account'),
#TODO: remove this
'amount_taxed':fields.float("Taxed Amount",digits=(16,2)),
'parent_move_lines':fields.many2many('account.move.line', 'account_move_line_rel', 'child_id', 'parent_id', 'Parent'),
'reconcile_implicit':fields.boolean('Implicit Reconciliaiton')
}
def _get_date(self, cr, uid, context):
@@ -435,7 +437,11 @@ class account_move_line(osv.osv):
currency = 0.0
account_id = False
partner_id = False
implicit_lines = []
for line in unrec_lines:
if line.parent_move_lines:
for i in line.parent_move_lines:
implicit_lines.append(i.id)
if line.state <> 'valid':
raise osv.except_osv(_('Error'),
_('Entry "%s" is not valid !') % line.name)
@@ -481,7 +487,7 @@ class account_move_line(osv.osv):
self_debit = -writeoff
# If comment exist in context, take it
if context['comment']:
if 'comment' in context and context['comment']:
libelle=context['comment']
else:
libelle='Write-Off'
@@ -531,9 +537,13 @@ class account_move_line(osv.osv):
'line_id': map(lambda x: (4,x,False), ids),
'line_partial_ids': map(lambda x: (3,x,False), ids)
})
wf_service = netsvc.LocalService("workflow")
if implicit_lines:
self.write(cr, uid, implicit_lines, {'reconcile_implicit':True,'reconcile_id':r_id})
for id in implicit_lines:
wf_service.trg_trigger(uid, 'account.move.line', id, cr)
# the id of the move.reconcile is written in the move.line (self) by the create method above
# because of the way the line_id are defined: (4, x, False)
wf_service = netsvc.LocalService("workflow")
for id in ids:
wf_service.trg_trigger(uid, 'account.move.line', id, cr)
return r_id
@@ -629,7 +639,7 @@ class account_move_line(osv.osv):
if raise_ex:
raise osv.except_osv(_('Wrong Accounting Entry!'), _('Both Credit and Debit cannot be zero!'))
account_obj = self.pool.get('account.account')
if ('account_id' in vals) and not account_obj.read(cr, uid, vals['account_id'], ['active'])['active']:
raise osv.except_osv(_('Bad account!'), _('You can not use an inactive account!'))
if update_check:
+15 -9
View File
@@ -116,19 +116,19 @@
<field name="type" select="1"/>
<field name="company_id" select="2"/>
<field name="parent_id"/>
<field name="active"/>
<field name="user_type" select="1"/>
</group>
<notebook colspan="4">
<page string="General Information">
<newline/>
<field name="user_type" select="1"/>
<field name="currency_id" select="2"/>
<field name="active" select="2"/>
<field name="reconcile"/>
<field name="check_history"/>
<newline/>
<newline/>
<field name="child_consol_ids" colspan="4"/>
<field colspan="4" name="tax_ids" domain="[('parent_id','=',False)]"/>
<field name="child_consol_ids" colspan="4" attrs="{'readonly':[('type','!=','consolidation')]}"/>/>
</page>
<page string="Notes">
<field colspan="4" name="note" nolabel="1"/>
@@ -654,6 +654,7 @@
<field name="state"/>
<field name="reconcile_id"/>
<field name="reconcile_partial_id"/>
<field colspan="4" name="reconcile_implicit"/>
</tree>
</field>
</record>
@@ -705,6 +706,10 @@
<page string="Analytic Lines">
<field colspan="4" name="analytic_lines" nolabel="1"/>
</page>
<page string="Move Lines">
<field colspan="4" name="reconcile_implicit"/>
<field colspan="4" name="parent_move_lines" nolabel="0"/>
</page>
</notebook>
</form>
</field>
@@ -744,7 +749,7 @@
<newline/>
<field name="account_tax_id" domain="[('parent_id','=',False)]"/>
<field name="analytic_account_id"/>
<field colspan="4" name="reconcile_implicit"/>
<separator colspan="4" string="State"/>
<newline/>
<field name="reconcile_id"/>
@@ -1285,6 +1290,7 @@
<field name="credit" sum="Total credit"/>
<field name="account_tax_id"/>
<field name="analytic_account_id"/>
<field colspan="4" name="reconcile_implicit"/>
<field name="state"/>
</tree>
</field>
@@ -1354,10 +1360,10 @@
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</record>
<!-- register configuration wizard -->
@@ -1367,8 +1373,8 @@
<field name="note">Define Fiscal Years and Select Charts of Account</field>
<field name="action_id" ref="action_account_config_wizard_form"/>
<field name="state">open</field>
</record>
</record>
<!-- Account Templates -->
+7 -2
View File
@@ -21,15 +21,20 @@
<field name="code">liability</field>
<field name="close_method">balance</field>
</record>
<record id="account_type_cash_equity" model="account.account.type">
<field name="name">Equity</field>
<field name="code">equity</field>
<field name="close_method">balance</field>
</record>
<record id="account_type_income" model="account.account.type">
<field name="name">Income</field>
<field name="code">income</field>
<field name="close_method">none</field>
<field name="close_method">unreconciled</field>
</record>
<record id="account_type_expense" model="account.account.type">
<field name="name">Expense</field>
<field name="code">expense</field>
<field name="close_method">none</field>
<field name="close_method">unreconciled</field>
</record>
<record id="account_type_cash_moves" model="account.account.type">
<field name="name">Cash</field>
+4 -2
View File
@@ -150,7 +150,9 @@
<field name="view_type">form</field>
<field name="view_id" ref="view_account_analytic_line_tree"/>
</record>
<menuitem id="next_id_41" name="Analytic Entries" parent="account.menu_finance_entries"/><menuitem action="action_account_analytic_line_form" id="account_entries_analytic_entries" parent="next_id_41"/>
<wizard id="action_account_analytic_line" menu="False" model="account.analytic.line" name="account.analytic.line" string="Entries Encoding by Line"/>
<menuitem id="next_id_41" name="Analytic Entries" parent="account.menu_finance_entries"/>
<menuitem type="wizard" icon="STOCK_JUSTIFY_FILL" action="action_account_analytic_line" id="account_entries_analytic_entries" parent="next_id_41"/>
<record id="action_account_tree1" model="ir.actions.act_window">
@@ -238,7 +240,7 @@
#
<record id="action_account_analytic_journal_open_form" model="ir.actions.act_window">
<field name="name">account.analytic.journal.open.form</field>
<field name="name">Entries of Open Analytic Journals</field>
<field name="res_model">account.analytic.line</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
@@ -34,6 +34,7 @@ import wizard_account_analytic_inverted_balance_report
import wizard_account_analytic_cost_ledger_report
import wizard_account_analytic_cost_ledger_for_journal_report
import wizard_account_analytic_analytic_check
import wizard_account_analytic_line
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,86 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
#
# $Id$
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import wizard
import pooler
import time
def _action_open_window(self, cr, uid, data, context):
domain=[]
from_date= data['form']['from_date']
to_date=data['form']['to_date']
if from_date and to_date:
domain=[('date','>=',from_date),('date','<=',to_date)]
elif from_date:
domain=[('date','>=',from_date)]
elif to_date:
domain=[('date','<=',to_date)]
return {
'name': 'Analytic Entries',
'view_type': 'form',
"view_mode": 'tree,form',
'res_model': 'account.analytic.line',
'type': 'ir.actions.act_window',
'domain': domain}
class account_analytic_line(wizard.interface):
form1 = '''<?xml version="1.0"?>
<form string="View Account Analytic Lines">
<separator string="Account Analytic Lines Analysis" colspan="4"/>
<field name="from_date"/>
<newline/>
<field name="to_date"/>
<newline/>
<label string=""/>
<label string="(Keep empty to open the current situation)" align="0.0" colspan="3"/>
</form>'''
form1_fields = {
'from_date': {
'string': 'From',
'type': 'date',
},
'to_date': {
'string': 'To',
'type': 'date',
},
}
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [('end', 'Cancel','gtk-cancel'),('open', 'Open Entries','gtk-ok')]}
},
'open': {
'actions': [],
'result': {'type': 'action', 'action': _action_open_window, 'state':'end'}
}
}
account_analytic_line('account.analytic.line')
@@ -110,7 +110,7 @@ def _data_save(self, cr, uid, data, context):
offset = 0
limit = 100
while True:
cr.execute('SELECT name, quantity, debit, credit, account_id, ref, ' \
cr.execute('SELECT id, name, quantity, debit, credit, account_id, ref, ' \
'amount_currency, currency_id, blocked, partner_id, ' \
'date_maturity, date_created ' \
'FROM account_move_line ' \
@@ -123,10 +123,13 @@ def _data_save(self, cr, uid, data, context):
if not result:
break
for move in result:
parent_id = move['id']
move.pop('id')
move.update({
'date': period.date_start,
'journal_id': new_journal.id,
'period_id': period.id,
'parent_move_lines':[(6,0,[parent_id])]
})
pool.get('account.move.line').create(cr, uid, move, {
'journal_id': new_journal.id,
@@ -137,7 +140,7 @@ def _data_save(self, cr, uid, data, context):
offset = 0
limit = 100
while True:
cr.execute('SELECT name, quantity, debit, credit, account_id, ref, ' \
cr.execute('SELECT id, name, quantity, debit, credit, account_id, ref, ' \
'amount_currency, currency_id, blocked, partner_id, ' \
'date_maturity, date_created ' \
'FROM account_move_line ' \
@@ -149,10 +152,13 @@ def _data_save(self, cr, uid, data, context):
if not result:
break
for move in result:
parent_id = move['id']
move.pop('id')
move.update({
'date': period.date_start,
'journal_id': new_journal.id,
'period_id': period.id,
'parent_move_lines':[(6,0,[parent_id])]
})
pool.get('account.move.line').create(cr, uid, move)
offset += limit
+1 -1
View File
@@ -124,7 +124,7 @@ def _get_period(self, cr, uid, data, context={}):
raise wizard.except_wizard(_('Error !'), _('Can not pay draft invoice.'))
return {
'period_id': period_id,
'amount': invoice.amount_total,
'amount': invoice.residual,
'date': time.strftime('%Y-%m-%d')
}
+20 -51
View File
@@ -138,7 +138,7 @@ crossovered_budget()
class crossovered_budget_lines(osv.osv):
def _pra_amt(self, cr, uid, ids,name,args,context):
def _prac_amt(self, cr, uid, ids,context={}):
res = {}
for line in self.browse(cr, uid, ids):
acc_ids = ','.join([str(x.id) for x in line.general_budget_id.account_ids])
@@ -157,7 +157,14 @@ class crossovered_budget_lines(osv.osv):
res[line.id]=result
return res
def _theo_amt(self, cr, uid, ids,name,args,context):
def _prac(self, cr, uid, ids,name,args,context):
res={}
for line in self.browse(cr, uid, ids):
res[line.id]=self._prac_amt(cr,uid,[line.id],context=context)[line.id]
return res
def _theo_amt(self, cr, uid, ids,context={}):
res = {}
for line in self.browse(cr, uid, ids):
today=datetime.datetime.today()
@@ -184,6 +191,13 @@ class crossovered_budget_lines(osv.osv):
res[line.id]=theo_amt
return res
def _theo(self, cr, uid, ids,name,args,context):
res={}
for line in self.browse(cr, uid, ids):
res[line.id]=self._theo_amt(cr,uid,[line.id],context=context)[line.id]
return res
def _perc(self, cr, uid, ids,name,args,context):
res = {}
for line in self.browse(cr, uid, ids):
@@ -201,58 +215,13 @@ class crossovered_budget_lines(osv.osv):
'date_from': fields.date('Start Date',required=True),
'date_to': fields.date('End Date',required=True),
'paid_date': fields.date('Paid Date'),
'planned_amount':fields.float('Planned Amount',required=True),
'practical_amount':fields.function(_pra_amt,method=True, string='Practical Amount',type='float'),
'theoritical_amount':fields.function(_theo_amt,method=True, string='Theoritical Amount',type='float'),
'planned_amount':fields.float('Planned Amount',required=True,digits=(16,2)),
'practical_amount':fields.function(_prac,method=True, string='Practical Amount',type='float',digits=(16,2)),
'theoritical_amount':fields.function(_theo,method=True, string='Theoritical Amount',type='float',digits=(16,2)),
'percentage':fields.function(_perc,method=True, string='Percentage',type='float'),
}
crossovered_budget_lines()
#class account_budget_post(osv.osv): #old code
# _name = 'account.budget.post'
# _inherit = 'account.budget.post'
# _columns = {
# 'crossovered_budget_line': fields.one2many('crossovered.budget.lines', 'general_budget_id', 'Budget Lines'),
# }
#account_budget_post()
#
#class account_budget_post_dotation(osv.osv):
# _name = 'account.budget.post.dotation'
# _inherit = 'account.budget.post.dotation'
#
# def _tot_planned(self, cr, uid, ids,name,args,context):
# res={}
# for line in self.browse(cr, uid, ids):
# if line.period_id:
# obj_period=self.pool.get('account.period').browse(cr, uid,line.period_id.id)
#
# total_days=strToDate(obj_period.date_stop) - strToDate(obj_period.date_start)
# budget_id=line.post_id and line.post_id.id or False
# query="select id from crossovered_budget_lines where general_budget_id= '"+ str(budget_id) + "' AND (date_from >='" +obj_period.date_start +"' and date_from <= '"+obj_period.date_stop + "') OR (date_to >='" +obj_period.date_start +"' and date_to <= '"+obj_period.date_stop + "') OR (date_from <'" +obj_period.date_start +"' and date_to > '"+obj_period.date_stop + "')"
# cr.execute(query)
# res1=cr.fetchall()
#
# tot_planned=0.00
# for record in res1:
# obj_lines = self.pool.get('crossovered.budget.lines').browse(cr, uid,record[0])
# count_days = min(strToDate(obj_period.date_stop),strToDate(obj_lines.date_to)) - max(strToDate(obj_period.date_start), strToDate(obj_lines.date_from))
# days_in_period = count_days.days +1
# count_days = strToDate(obj_lines.date_to) - strToDate(obj_lines.date_from)
# total_days_of_rec = count_days.days +1
# tot_planned += obj_lines.planned_amount/total_days_of_rec* days_in_period
# res[line.id]=tot_planned
# else:
# res[line.id]=0.00
# return res
#
# _columns = {
# 'tot_planned':fields.function(_tot_planned,method=True, string='Total Planned Amount',type='float',store=True),
# }
#
#account_budget_post_dotation()
class account_analytic_account(osv.osv):
_name = 'account.analytic.account'
_inherit = 'account.analytic.account'
@@ -266,7 +235,7 @@ account_analytic_account()
#--------------------------------------------------------------
# moved from account/project/project.py
# ---------------------------------------------------------
# Budgets
# Budgets.
# ---------------------------------------------------------
#class account_analytic_budget_post(osv.osv):
@@ -1,310 +0,0 @@
# Translation of OpenERP Server.
# This file containt the translation of the following modules:
# * account_budget_crossover
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 4.3.0"
"Report-Msgid-Bugs-To: support@openerp.com"
"POT-Creation-Date: 2008-09-10 12:47:16+0000"
"PO-Revision-Date: 2008-09-10 12:47:16+0000"
"Last-Translator: <>"
"Language-Team: "
"MIME-Version: 1.0"
"Content-Type: text/plain; charset=UTF-8"
"Content-Transfer-Encoding: "
"Plural-Forms: "
#. module: account_budget_crossover
#: field:crossovered.budget,creating_user_id:0
msgid "Responsible User"
msgstr ""
#. module: account_budget_crossover
#: selection:crossovered.budget,state:0
msgid "Confirmed"
msgstr ""
#. module: account_budget_crossover
#: constraint:ir.model:0
msgid "The Object name must start with x_ and not contain any special character !"
msgstr ""
#. module: account_budget_crossover
#: rml:account.analytic.account.budget:0
#: rml:crossovered.budget.report:0
msgid "Printed at:"
msgstr ""
#. module: account_budget_crossover
#: view:crossovered.budget:0
msgid "Confirm"
msgstr ""
#. module: account_budget_crossover
#: field:crossovered.budget,validating_user_id:0
msgid "Validate User"
msgstr ""
#. module: account_budget_crossover
#: field:crossovered.budget.lines,analytic_account_id:0
msgid "Analytic Account Ref"
msgstr ""
#. module: account_budget_crossover
#: rml:account.analytic.account.budget:0
#: rml:crossovered.budget.report:0
msgid "Currency:"
msgstr ""
#. module: account_budget_crossover
#: selection:crossovered.budget,state:0
msgid "Draft"
msgstr ""
#. module: account_budget_crossover
#: rml:account.analytic.account.budget:0
#: rml:crossovered.budget.report:0
msgid "at"
msgstr ""
#. module: account_budget_crossover
#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
msgid "Print Budgets"
msgstr ""
#. module: account_budget_crossover
#: wizard_button:wizard.analytic.account.budget.report,init,report:0
#: wizard_button:wizard.crossovered.budget,init,report:0
#: wizard_button:wizard.crossovered.budget.summary,init,report:0
msgid "Print"
msgstr ""
#. module: account_budget_crossover
#: field:crossovered.budget.lines,percentage:0
msgid "Percentage"
msgstr ""
#. module: account_budget_crossover
#: selection:crossovered.budget,state:0
msgid "Validated"
msgstr ""
#. module: account_budget_crossover
#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
msgid "Crossovered Budget Lines"
msgstr ""
#. module: account_budget_crossover
#: field:crossovered.budget,name:0
msgid "Name"
msgstr ""
#. module: account_budget_crossover
#: field:crossovered.budget,state:0
msgid "Status"
msgstr ""
#. module: account_budget_crossover
#: rml:account.analytic.account.budget:0
#: rml:crossovered.budget.report:0
msgid "%"
msgstr ""
#. module: account_budget_crossover
#: rml:account.analytic.account.budget:0
#: rml:crossovered.budget.report:0
msgid "Description"
msgstr ""
#. module: account_budget_crossover
#: rml:account.analytic.account.budget:0
msgid "Analytic Account :"
msgstr ""
#. module: account_budget_crossover
#: field:crossovered.budget.lines,crossovered_budget_id:0
msgid "Budget Ref"
msgstr ""
#. module: account_budget_crossover
#: rml:account.analytic.account.budget:0
#: rml:crossovered.budget.report:0
msgid "to"
msgstr ""
#. module: account_budget_crossover
#: rml:account.analytic.account.budget:0
#: rml:crossovered.budget.report:0
#: field:crossovered.budget.lines,planned_amount:0
msgid "Planned Amount"
msgstr ""
#. module: account_budget_crossover
#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
msgid "Entries"
msgstr ""
#. module: account_budget_crossover
#: view:crossovered.budget:0
msgid "Validate"
msgstr ""
#. module: account_budget_crossover
#: wizard_view:wizard.crossovered.budget,init:0
#: wizard_view:wizard.crossovered.budget.summary,init:0
msgid "Select Options"
msgstr ""
#. module: account_budget_crossover
#: rml:account.analytic.account.budget:0
#: rml:crossovered.budget.report:0
#: field:crossovered.budget.lines,practical_amount:0
msgid "Practical Amount"
msgstr ""
#. module: account_budget_crossover
#: field:crossovered.budget,date_to:0
#: field:crossovered.budget.lines,date_to:0
msgid "End Date"
msgstr ""
#. module: account_budget_crossover
#: constraint:ir.ui.view:0
msgid "Invalid XML for View Architecture!"
msgstr ""
#. module: account_budget_crossover
#: field:crossovered.budget.lines,theoritical_amount:0
msgid "Theoritical Amount"
msgstr ""
#. module: account_budget_crossover
#: rml:account.analytic.account.budget:0
#: rml:crossovered.budget.report:0
msgid "Total:"
msgstr ""
#. module: account_budget_crossover
#: selection:crossovered.budget,state:0
msgid "Cancelled"
msgstr ""
#. module: account_budget_crossover
#: field:crossovered.budget.lines,general_budget_id:0
msgid "Master Budget Ref"
msgstr ""
#. module: account_budget_crossover
#: view:account.analytic.account:0
msgid "Lines"
msgstr ""
#. module: account_budget_crossover
#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
#: view:crossovered.budget:0
msgid "Budget"
msgstr ""
#. module: account_budget_crossover
#: wizard_view:wizard.analytic.account.budget.report,init:0
msgid "Select Dates Period"
msgstr ""
#. module: account_budget_crossover
#: field:crossovered.budget.lines,paid_date:0
msgid "Paid Date"
msgstr ""
#. module: account_budget_crossover
#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
msgid "Budgets"
msgstr ""
#. module: account_budget_crossover
#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
#: wizard_field:wizard.crossovered.budget,init,date_to:0
#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
msgid "End of period"
msgstr ""
#. module: account_budget_crossover
#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
msgid "Crossovered Budget"
msgstr ""
#. module: account_budget_crossover
#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
#: wizard_field:wizard.crossovered.budget,init,date_from:0
#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
msgid "Start of period"
msgstr ""
#. module: account_budget_crossover
#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
msgid "Print Summary of Budgets"
msgstr ""
#. module: account_budget_crossover
#: field:crossovered.budget,code:0
msgid "Code"
msgstr ""
#. module: account_budget_crossover
#: rml:account.analytic.account.budget:0
#: rml:crossovered.budget.report:0
msgid "Theoretical Amount"
msgstr ""
#. module: account_budget_crossover
#: rml:crossovered.budget.report:0
msgid "Budget :"
msgstr ""
#. module: account_budget_crossover
#: selection:crossovered.budget,state:0
#: view:crossovered.budget:0
msgid "Done"
msgstr ""
#. module: account_budget_crossover
#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
#: field:account.analytic.account,crossovered_budget_line:0
#: field:account.budget.post,crossovered_budget_line:0
#: field:crossovered.budget,crossovered_budget_line:0
#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
#: view:crossovered.budget:0
#: view:account.analytic.account:0
#: view:crossovered.budget.lines:0
msgid "Budget Lines"
msgstr ""
#. module: account_budget_crossover
#: wizard_button:wizard.analytic.account.budget.report,init,end:0
#: wizard_button:wizard.crossovered.budget,init,end:0
#: wizard_button:wizard.crossovered.budget.summary,init,end:0
#: view:crossovered.budget:0
msgid "Cancel"
msgstr ""
#. module: account_budget_crossover
#: field:account.budget.post.dotation,tot_planned:0
msgid "Total Planned Amount"
msgstr ""
#. module: account_budget_crossover
#: field:crossovered.budget,date_from:0
#: field:crossovered.budget.lines,date_from:0
msgid "Start Date"
msgstr ""
#. module: account_budget_crossover
#: rml:account.analytic.account.budget:0
#: rml:crossovered.budget.report:0
msgid "Analysis from"
msgstr ""
@@ -63,6 +63,7 @@ class budget_report(report_sxw.rml_parse):
budgets = self.pool.get('crossovered.budget').browse(self.cr, self.uid, [object.id], self.context.copy())
c_b_lines_obj=self.pool.get('crossovered.budget.lines')
for budget_id in budgets:
res={}
@@ -90,6 +91,7 @@ class budget_report(report_sxw.rml_parse):
self.cr.execute('select distinct(analytic_account_id) from crossovered_budget_lines where id in (%s)'%(b_line_ids))
an_ids=self.cr.fetchall()
context={'wizard_date_from':d_from,'wizard_date_to':d_to}
for i in range(0,len(an_ids)):
analytic_name=self.pool.get('account.analytic.account').browse(self.cr, self.uid,[an_ids[i][0]])
@@ -106,9 +108,9 @@ class budget_report(report_sxw.rml_parse):
}
result.append(res)
line_ids = self.pool.get('crossovered.budget.lines').search(self.cr, self.uid, [('id', 'in', budget_ids),('analytic_account_id','=',an_ids[i][0])])
line_ids = c_b_lines_obj.search(self.cr, self.uid, [('id', 'in', budget_ids),('analytic_account_id','=',an_ids[i][0])])
line_id = self.pool.get('crossovered.budget.lines').browse(self.cr,self.uid,line_ids)
line_id = c_b_lines_obj.browse(self.cr,self.uid,line_ids)
tot_theo=tot_pln=tot_prac=tot_perc=0.00
done_budget=[]
@@ -116,8 +118,8 @@ class budget_report(report_sxw.rml_parse):
if line.id in budget_lines:
theo=pract=0.00
theo=line._theo_amt(self.cr, self.uid, [line.id],"theoritical_amount",None,context={'wizard_date_from':d_from,'wizard_date_to':d_to})[line.id]
pract=line._pra_amt(self.cr, self.uid, [line.id],"practical_amount",None,context={'wizard_date_from':d_from,'wizard_date_to':d_to})[line.id]
theo=c_b_lines_obj._theo_amt(self.cr, self.uid, [line.id],context)[line.id]
pract=c_b_lines_obj._prac_amt(self.cr, self.uid, [line.id],context)[line.id]
if line.general_budget_id.id in done_budget:
@@ -212,7 +212,7 @@ class followup_all_print(wizard.interface):
def _get_partners(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
cr.execute(
"SELECT l.partner_id, l.followup_line_id, l.date, l.id "\
"SELECT l.partner_id, l.followup_line_id,l.date_maturity, l.date, l.id "\
"FROM account_move_line AS l "\
"LEFT JOIN account_account AS a "\
"ON (l.account_id=a.id) "\
@@ -251,14 +251,17 @@ class followup_all_print(wizard.interface):
partner_list = []
to_update = {}
for partner_id, followup_line_id, date, id in move_lines:
for partner_id, followup_line_id, date_maturity,date, id in move_lines:
if not partner_id:
continue
if partner_id in partner_list:
to_update[str(id)] = fups[followup_line_id][1]
if followup_line_id not in fups:
continue
if date <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
if date_maturity and date_maturity <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
partner_list.append(partner_id)
to_update[str(id)] = fups[followup_line_id][1]
elif date and date <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
partner_list.append(partner_id)
to_update[str(id)] = fups[followup_line_id][1]
return {'partner_ids': partner_list, 'to_update': to_update}
@@ -142,10 +142,12 @@ class account_invoice_line(osv.osv):
'sequence': fields.integer('Sequence Number'),
'functional_field': fields.function(_fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type='char', fnct_search=None, obj=None, method=True, store=False, string="Source Account"),
}
def _default_account(self, cr, uid, context=None):
cr.execute("select id from account_account where code = 0 LIMIT 1")
cr.execute("select id from account_account where parent_id IS NULL LIMIT 1")
res=cr.fetchone()
return res[0]
_defaults = {
'state': lambda *a: 'article',
# 'account_id': _default_account
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<openerp>
<data>
<wizard string="Formatted Inv. + Message"
<wizard string="Invoice + Message"
model="account.invoice"
name="wizard.notify_message"
id="wizard_notify_message"
@@ -9,7 +9,7 @@
/>
<report id="account_invoices_1"
string="Formatted Inv."
string="Invoice"
model="account.invoice"
name="account.invoice.layout"
rml="account_invoice_layout/report/report_account_invoice_layout.rml"
+4 -5
View File
@@ -58,13 +58,12 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Delivery grids">
<field name="name" select="1"/>
<field name="active" select="1"/>
<field name="carrier_id" select="1"/>
<field name="sequence" select="1"/>
<notebook>
<page string="Grid definition">
<field name="name" select="1"/>
<field name="active" select="1"/>
<field name="carrier_id" select="1"/>
<field name="sequence" select="1"/>
<separator colspan="4" string="Grid Lines"/>
<field colspan="4" name="line_ids" nolabel="1" select="1"/>
</page>
<page string="Destination">
+1 -1
View File
@@ -144,7 +144,7 @@
</field>
</record>
<record id="action2" model="ir.actions.act_window">
<field name="name">Hierarchical view of this employee</field>
<field name="name">Employee Hierarchy</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">hr.employee</field>
<field name="domain">[('id','in',active_ids)]</field>
+24 -25
View File
@@ -383,17 +383,17 @@
</field>
</record>
<record model="ir.ui.view" id="view_production_graph">
<field name="name">mrp.production.graph</field>
<field name="model">mrp.production</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Production orders" type="bar">
<field name="product_id"/>
<field name="product_qty" operator="+"/>
</graph>
</field>
</record>
<record model="ir.ui.view" id="view_production_graph">
<field name="name">mrp.production.graph</field>
<field name="model">mrp.production</field>
<field name="type">graph</field>
<field name="arch" type="xml">
<graph string="Production orders" type="bar">
<field name="product_id"/>
<field name="product_qty" operator="+"/>
</graph>
</field>
</record>
<record id="mrp_production_form_view" model="ir.ui.view">
@@ -439,7 +439,7 @@
<page string="Finnished Products">
<field colspan="4" name="move_created_ids" nolabel="1"/>
</page>
<page string="Operations">
<page string="Work Orders">
<field colspan="4" name="workcenter_lines" nolabel="1" widget="one2many_list"/>
</page>
<page string="Extra Information">
@@ -448,7 +448,7 @@
<field name="picking_id"/>
<field name="move_prod_id"/>
<field name="sale_name"/>
<field name="sale_ref"/>
<field name="sale_ref"/>
</page>
</notebook>
</form>
@@ -623,20 +623,19 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Procurement">
<group col="2" colspan="2">
<separator colspan="2" string="References"/>
<field name="name" select="1" string="Procurement Reason"/>
<field name="origin" select="2"/>
</group>
<group col="2" colspan="2">
<separator colspan="2" string="Planification"/>
<field name="date_planned" select="1"/>
<field name="procure_method" select="2"/>
<field name="priority"/>
</group>
<notebook>
<page string="Procurement Details">
<group col="2" colspan="2">
<separator colspan="2" string="References"/>
<field name="name" select="1" string="Procurement Reason"/>
<field name="origin" select="2"/>
</group>
<group col="2" colspan="2">
<separator colspan="2" string="Planification"/>
<field name="date_planned" select="1"/>
<field name="procure_method" select="2"/>
<field name="priority"/>
</group>
<separator colspan="4" string="Product &amp; Location"/>
<field name="product_id" select="1"/>
<field name="location_id" select="2"/>
+140 -44
View File
@@ -63,6 +63,29 @@ class process_process(osv.osv):
'active' : lambda *a: True,
}
def search_by_model(self, cr, uid, res_model, context):
pool = pooler.get_pool(cr.dbname)
model_ids = pool.get('ir.model').search(cr, uid, [('model', '=', res_model)])
if not model_ids:
return []
nodes = pool.get('process.node').search(cr, uid, [('model_id', 'in', model_ids)])
if not nodes:
return []
nodes = pool.get('process.node').browse(cr, uid, nodes, context)
unique = []
result = []
for node in nodes:
if node.process_id.id not in unique:
result.append((node.process_id.id, node.process_id.name))
unique.append(node.process_id.id)
return result
def graph_get(self, cr, uid, id, res_model, res_id, scale, context):
pool = pooler.get_pool(cr.dbname)
@@ -72,38 +95,7 @@ class process_process(osv.osv):
current_user = pool.get('res.users').browse(cr, uid, [uid], context)[0]
expr_context = Env(current_object, current_user)
def get_resource_info(node):
ret = False
src_model = res_model
src_id = res_id
if node.transition_in:
tr = node.transition_in[0]
src = nodes.get(tr.source_node_id.id)
if src['res']:
src_model = src['res']['model']
src_id = src['res']['id']
else:
return False
fields = pool.get(src_model).fields_get(cr, uid, context=context)
for name, field in fields.items():
if node.model_id and field.get('relation', False) == node.model_id.model:
src_obj = pool.get(src_model).browse(cr, uid, [src_id], context)[0]
rel = src_obj[name]
if rel:
if isinstance(rel, (list, tuple)):
rel = rel[0]
ret = {}
ret['name'] = rel.name_get(context)[0][1]
ret['model'] = field['relation']
ret['id'] = rel.id
return ret
notes = process.note
nodes = {}
start = []
@@ -112,6 +104,8 @@ class process_process(osv.osv):
states = dict(pool.get(res_model).fields_get(cr, uid, context=context).get('state', {}).get('selection', {}))
title = "%s - Resource: %s, State: %s" % (process.name, current_object.name, states.get(getattr(current_object, 'state'), 'N/A'))
perm = pool.get(res_model).perm_read(cr, uid, [res_id], context)[0]
for node in process.node_ids:
data = {}
data['name'] = node.name
@@ -121,18 +115,12 @@ class process_process(osv.osv):
data['notes'] = node.note
data['active'] = False
data['gray'] = False
data['res'] = get_resource_info(node)
data['url'] = node.help_url
if node.menu_id:
data['menu'] = {'name': node.menu_id.complete_name, 'id': node.menu_id.id}
if node.model_id and node.model_id.model == res_model:
data['res'] = resource = {}
resource['name'] = current_object.name_get(context)[0][1]
resource['model'] = res_model
resource['id'] = res_id
try:
data['active'] = eval(node.model_states, expr_context)
except Exception, e:
@@ -178,12 +166,60 @@ class process_process(osv.osv):
roles.append(role)
transitions[tr.id] = data
# now populate resource information
def update_relatives(nid, ref_id, ref_model):
relatives = []
for tid, tr in transitions.items():
if tr['source'] == nid:
relatives.append(tr['target'])
if tr['target'] == nid:
relatives.append(tr['source'])
if not ref_id:
nodes[nid]['res'] = False
return
nodes[nid]['res'] = resource = {'id': ref_id, 'model': ref_model}
refobj = pool.get(ref_model).browse(cr, uid, [ref_id], context)[0]
fields = pool.get(ref_model).fields_get(cr, uid, context=context)
resource['name'] = refobj.name_get(context)[0][1]
resource['perm'] = pool.get(ref_model).perm_read(cr, uid, [ref_id], context)[0]
for r in relatives:
node = nodes[r]
if 'res' not in node:
for n, f in fields.items():
if node['model'] == ref_model:
update_relatives(r, ref_id, ref_model)
elif f.get('relation') == node['model']:
rel = refobj[n]
if rel and isinstance(rel, list) :
rel = rel[0]
if isinstance(rel, basestring):
print "XXX: ", rel
try: # XXXXXXXXXXXXXXXXXXX
_id = (rel or False) and rel.id
_model = node['model']
update_relatives(r, _id, _model)
except:
pass
for nid, node in nodes.items():
if not node['gray'] and (node['active'] or node['model'] == res_model):
update_relatives(nid, res_id, res_model)
break
# calculate graph layout
g = tools.graph(nodes.keys(), map(lambda x: (x['source'], x['target']), transitions.values()))
g.process(start)
#g.scale(100, 100, 180, 120)
g.scale(*scale)
g.process(start)
g.scale(*scale) #g.scale(100, 100, 180, 120)
graph = g.result_get()
# fix the height problem
miny = -1
for k,v in nodes.items():
x = graph[k]['y']
@@ -198,7 +234,45 @@ class process_process(osv.osv):
y = v['y']
v['y'] = min(y - miny + 10, y)
return dict(title=title, notes=notes, nodes=nodes, transitions=transitions)
return dict(title=title, perm=perm, notes=notes, nodes=nodes, transitions=transitions)
def copy(self, cr, uid, id, default=None, context={}):
""" Deep copy the entire process.
"""
if not default:
default = {}
pool = pooler.get_pool(cr.dbname)
process = pool.get('process.process').browse(cr, uid, [id], context)[0]
nodes = {}
transitions = {}
# first copy all nodes and and map the new nodes with original for later use in transitions
for node in process.node_ids:
for t in node.transition_in:
tr = transitions.setdefault(t.id, {})
tr['target'] = node.id
for t in node.transition_out:
tr = transitions.setdefault(t.id, {})
tr['source'] = node.id
nodes[node.id] = pool.get('process.node').copy(cr, uid, node.id, context=context)
# then copy transitions with new nodes
for tid, tr in transitions.items():
vals = {
'source_node_id': nodes[tr['source']],
'target_node_id': nodes[tr['target']]
}
tr = pool.get('process.transition').copy(cr, uid, tid, default=vals, context=context)
# and finally copy the process itself with new nodes
default.update({
'active': True,
'node_ids': [(6, 0, nodes.values())]
})
return super(process_process, self).copy(cr, uid, id, default, context)
process_process()
@@ -217,13 +291,24 @@ class process_node(osv.osv):
'flow_start': fields.boolean('Starting Flow'),
'transition_in': fields.one2many('process.transition', 'target_node_id', 'Starting Transitions'),
'transition_out': fields.one2many('process.transition', 'source_node_id', 'Ending Transitions'),
'condition_ids': fields.one2many('process.condition', 'node_id', 'Conditions')
'condition_ids': fields.one2many('process.condition', 'node_id', 'Conditions'),
'help_url': fields.char('Help URL', size=255)
}
_defaults = {
'kind': lambda *args: 'state',
'model_states': lambda *args: False,
'flow_start': lambda *args: False,
}
def copy(self, cr, uid, id, default=None, context={}):
if not default:
default = {}
default.update({
'transition_in': [],
'transition_out': []
})
return super(process_node, self).copy(cr, uid, id, default, context)
process_node()
class process_node_condition(osv.osv):
@@ -271,5 +356,16 @@ class process_transition_action(osv.osv):
_defaults = {
'state': lambda *args: 'dummy',
}
def copy(self, cr, uid, id, default=None, context={}):
if not default:
default = {}
state = self.pool.get('process.transition.action').browse(cr, uid, [id], context)[0].state
if state:
default['state'] = state
return super(process_transition_action, self).copy(cr, uid, id, default, context)
process_transition_action()
+13 -4
View File
@@ -21,17 +21,25 @@
<notebook colspan="4">
<page string="Nodes">
<field name="node_ids" colspan="4" nolabel="1">
<tree string="Process Nodes">
<field name="name"/>
<field name="model_id" select="1"/>
<field name="kind" select="1"/>
<field name="flow_start"/>
</tree>
<form string="Process Node">
<group colspan="4" string="Details">
<field name="name" select="1"/>
<field name="flow_start"/>
<newline/>
<field name="process_id" invisible="1" readonly="1" required="0"/> <!-- used by transition_out -->
<newline/>
<field name="model_id" select="1"/>
<field name="menu_id" select="2"/>
<newline/>
<field name="kind" select="1"/>
<field name="help_url" widget="url"/>
<field name="model_states"/>
<field name="subflow_id"/>
<field name="subflow_id" domain="[('name', '!=', parent.name)]"/>
</group>
<notebook colspan="4">
<page string="Outgoing Transitions">
@@ -44,7 +52,7 @@
<group colspan="4" string="Details">
<field name="name"/>
<newline/>
<field name="target_node_id"/>
<field name="target_node_id" domain="[('process_id', '=', parent.process_id)]"/>
</group>
<notebook colspan="4">
<page string="Buttons">
@@ -159,6 +167,7 @@
<field name="menu_id" select="2"/>
<newline/>
<field name="kind" select="1"/>
<field name="help_url" widget="url"/>
<field name="model_states"/>
<field name="subflow_id"/>
</group>
@@ -173,7 +182,7 @@
<group colspan="4" string="Details">
<field name="name"/>
<newline/>
<field name="target_node_id"/>
<field name="target_node_id" domain="[('process_id', '=', parent.process_id)]"/>
</group>
<notebook colspan="4">
<page string="Buttons">
+4 -4
View File
@@ -329,10 +329,9 @@ product_template()
class product_product(osv.osv):
def view_header_get(self, cr, uid, view_id, view_type, context):
res = super(product_product, self).view_header_get(cr, uid, view_id, view_type, context)
if res: return res
if (not context.get('categ_id', False)):
return False
return _('Products: ')+self.pool.get('product.category').browse(cr, uid, context['categ_id'], context).name
if (context.get('categ_id', False)):
return _('Products: ')+self.pool.get('product.category').browse(cr, uid, context['categ_id'], context).name
return res
def _product_price(self, cr, uid, ids, name, arg, context={}):
res = {}
@@ -589,6 +588,7 @@ class product_supplierinfo(osv.osv):
}
_defaults = {
'qty': lambda *a: 0.0,
'sequence': lambda *a: 1,
'delay': lambda *a: 1,
}
_order = 'sequence'
+2 -2
View File
@@ -260,7 +260,7 @@ class task(osv.osv):
'sequence': fields.integer('Sequence'),
'type': fields.many2one('project.task.type', 'Type'),
'state': fields.selection([('draft', 'Draft'),('open', 'Open'),('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'Status', readonly=True, required=True),
'date_start': fields.datetime('Date'),
'date_start': fields.datetime('Date Opened'),
'date_deadline': fields.datetime('Deadline'),
'date_close': fields.datetime('Date Closed', readonly=True),
'project_id': fields.many2one('project.project', 'Project', ondelete='cascade'),
@@ -289,7 +289,7 @@ class task(osv.osv):
'active': lambda *a: True,
'date_start': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
}
_order = "state, sequence, priority, date_deadline, id"
_order = "sequence, priority, date_deadline, id"
#
# Override view according to the company definition
+25 -11
View File
@@ -14,10 +14,9 @@ class project_work(osv.osv):
vals_line={}
obj_task = self.pool.get('project.task').browse(cr, uid, vals['task_id'])
vals_line['name']=vals['name']
vals_line['name']=obj_task.name + ': ' + vals['name']
vals_line['user_id']=vals['user_id']
c_date=datetime.date(int(vals['date'][:4]),int(vals['date'][5:7]),int(vals['date'][8:10]))
vals_line['date']=c_date
vals_line['date']=vals['date'][:10]
vals_line['unit_amount']=vals['hours']
vals_line['account_id']=obj_task.project_id.category_id.id
vals_line['amount']=00.0
@@ -32,17 +31,21 @@ class project_work(osv.osv):
def write(self, cr, uid, ids,vals,context={}):
vals_line={}
line_id=self.pool.get('project.task.work').browse(cr,uid,ids)[0].hr_analytic_timesheet_id
task=self.pool.get('project.task.work').browse(cr,uid,ids)[0]
line_id=task.hr_analytic_timesheet_id
# in case,if a record is deleted from timesheet,but we change it from tasks!
list_avail_ids=self.pool.get('hr.analytic.timesheet').search(cr,uid,[])
if line_id in list_avail_ids:
obj = self.pool.get('hr.analytic.timesheet')
vals_line['name']=vals['name']
vals_line['user_id']=vals['user_id']
c_date=datetime.date(int(vals['date'][:4]),int(vals['date'][5:7]),int(vals['date'][8:10]))
vals_line['date']=c_date
vals_line['unit_amount']=vals['hours']
vals_line['amount']=(-1) * vals['hours'] * obj.browse(cr,uid,line_id).product_id.standard_price
if 'name' in vals:
vals_line['name']=task.name+': '+vals['name']
if 'user_id' in vals:
vals_line['user_id']=vals['user_id']
if 'date' in vals:
vals_line['date']=vals['date'][:10]
if 'hours' in vals:
vals_line['unit_amount']=vals['hours']
vals_line['amount']=(-1) * vals['hours'] * obj.browse(cr,uid,line_id).product_id.standard_price
obj.write(cr, uid,[line_id],vals_line,{})
return super(project_work,self).write(cr, uid, ids,vals,context)
@@ -62,5 +65,16 @@ class project_work(osv.osv):
project_work()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
class project_project(osv.osv):
_inherit = "project.project"
def name_get(self, cr, user, ids, context=None):
result = []
for project in self.browse(cr, user, ids, context):
if project.category_id:
result.append((project.id, '['+(project.category_id.code or '')+'] '+project.name))
else:
result.append((project.id, '[?] '+project.name))
return result
project_project()
+1 -1
View File
@@ -169,9 +169,9 @@
<form string="Purchase Order Line">
<notebook>
<page string="Order Line">
<field colspan="4" context="partner_id=parent.partner_id,quantity=product_qty,pricelist=parent.pricelist_id,uom=product_uom,warehouse=parent.warehouse_id" name="product_id" on_change="product_id_change(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order)"/>
<field name="product_qty"/>
<field name="product_uom" on_change="product_uom_change(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order)"/>
<field colspan="4" context="partner_id=parent.partner_id,quantity=product_qty,pricelist=parent.pricelist_id,uom=product_uom,warehouse=parent.warehouse_id" name="product_id" on_change="product_id_change(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order)"/>
<field colspan="4" name="name"/>
<field name="date_planned"/>
<field name="price_unit"/>
+1
View File
@@ -35,6 +35,7 @@
import sale
import stock
import partner
import product
import wizard
import report
+1
View File
@@ -62,6 +62,7 @@
"sale_report.xml",
"sale_wizard.xml",
"stock_view.xml",
"product_view.xml",
],
"active": False,
"installable": True
+84
View File
@@ -0,0 +1,84 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
#
# $Id$
#
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from osv import fields, osv
from tools import config
class product_pricelist(osv.osv):
_inherit = "product.pricelist"
def _compute_price(self, cr, uid, ids, field_name, arg, context):
res = {}
for id in ids:
res[id]=0.0
return res
_columns = {
'price': fields.function(_compute_price, type='float', method=True, string='Price', digits=(16, int(config['price_accuracy']))),
}
product_pricelist()
class product_product(osv.osv):
_name = 'product.product'
_inherit = 'product.product'
def _pricelist_sale_ids(self, cr, uid, ids, name, arg, context=None):
result = {}
if not context:
context={}
pricelist_obj=self.pool.get('product.pricelist')
for product in self.browse(cr, uid, ids, context):
pricelist_ids=pricelist_obj.search(cr,uid,[('type','=','sale')], context=context)
result[product.id]=pricelist_ids
return result
def _pricelist_purchase_ids(self, cr, uid, ids, name, arg, context=None):
result = {}
pricelist_obj=self.pool.get('product.pricelist')
for product in self.browse(cr, uid, ids, context):
pricelist_ids=pricelist_obj.search(cr,uid,[('type','=','purchase')])
result[product.id]=pricelist_ids
return result
_columns = {
'pricelist_sale':fields.function(
_pricelist_sale_ids,
method=True,
relation='product.pricelist',
string='Sale Pricelists',
type="many2many"),
'pricelist_purchase':fields.function(
_pricelist_purchase_ids,
method=True,
relation='product.pricelist',
string='Purchase Pricelists',
type="many2many"),
}
product_product()
+33
View File
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_product_pricelists_function_form" model="ir.ui.view">
<field name="name">view.product.pricelists.function.form.inherit</field>
<field name="model">product.product</field>
<field name="type">form</field>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<field colspan="4" name="seller_ids" nolabel="1" position="after">
<group colspan="4" groups="base.group_extended">
<separator string="Sale Pricelists" colspan="2"/>
<separator string="Purchase Pricelists" colspan="2"/>
<field nolabel="1" name="pricelist_sale" colspan="2">
<tree string="Sale Price List">
<field name="name"/>
<field name="price" context="{'product_id':parent.id}"/>
</tree>
</field>
<field nolabel="1" name="pricelist_purchase" colspan="2" context="product_id=parent.id">
<tree string="Purchase Price List" context="product_id=parent.id">
<field name="name"/>
<field name="price" context="product_id=parent.id"/>
</tree>
</field>
</group>
</field>
</field>
</record>
</data>
</openerp>
+17 -4
View File
@@ -214,7 +214,8 @@ class sale_order(osv.osv):
'partner_shipping_id':fields.many2one('res.partner.address', 'Shipping Address', readonly=True, required=True, states={'draft':[('readonly',False)]}),
'incoterm': fields.selection(_incoterm_get, 'Incoterm',size=3),
'picking_policy': fields.selection([('direct','Partial Delivery'),('one','Complete Delivery')], 'Packing Policy', required=True),
'picking_policy': fields.selection([('direct','Partial Delivery'),('one','Complete Delivery')],
'Packing Policy', required=True, help="""If you don't have enough stock available to deliver all at once, do you accept partial shippings or not."""),
'order_policy': fields.selection([
('prepaid','Payment before delivery'),
('manual','Shipping & Manual Invoice'),
@@ -928,15 +929,27 @@ class sale_config_picking_policy(osv.osv_memory):
_name='sale.config.picking_policy'
_columns = {
'name':fields.char('Name', size=64),
'picking_policy': fields.selection([('direct','Direct Delivery'),('one','All at once')], 'Packing Policy', required=True ),
'picking_policy': fields.selection([
('direct','Direct Delivery'),
('one','All at once')
], 'Packing Policy', required=True ),
'order_policy': fields.selection([
('manual','Invoice based on Sales Orders'),
('picking','Invoice based on Deliveries'),
], 'Shipping Policy', required=True, readonly=True, states={'draft':[('readonly',False)]}),
}
_defaults={
'picking_policy': lambda *a: 'direct',
'order_policy': lambda *a: 'picking'
}
def set_default(self, cr, uid, ids, context=None):
if 'name' in context:
print context
for o in self.browse(cr, uid, ids, context=context):
print o.picking_policy, o.order_policy
ir_values_obj = self.pool.get('ir.values')
ir_values_obj.set(cr,uid,'default',False,'picking_policy',['sale.order'],context['picking_policy'])
ir_values_obj.set(cr,uid,'default',False,'picking_policy',['sale.order'],o.picking_policy)
ir_values_obj = self.pool.get('ir.values')
ir_values_obj.set(cr,uid,'default',False,'order_policy',['sale.order'],o.order_policy)
return {
'view_type': 'form',
"view_mode": 'form',
+7 -3
View File
@@ -39,6 +39,7 @@
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.shop</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_shop_tree"/>
</record>
<menuitem id="menu_shop_configuration" name="Configuration" parent="sale.menu_sale_root" sequence="1"/>
@@ -93,7 +94,7 @@
<form string="Sales order">
<group col="6" colspan="4">
<field name="name" select="1"/>
<field name="client_order_ref"/>
<field name="client_order_ref" select="2"/>
<field name="shipped" select="2"/>
<field name="shop_id" on_change="onchange_shop_id(shop_id)" select="2"/>
<field name="date_order" select="1"/>
@@ -221,6 +222,7 @@
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,graph</field>
</record>
<menuitem action="action_order_form" id="menu_sale_order" parent="sale.menu_sale_root"/>
@@ -453,10 +455,12 @@
<field name="model">sale.config.picking_policy</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Configure Picking Policy for Sale Order">
<separator col="4" colspan="4" string="Configure Picking Policy for Sale Order"/>
<form string="Sales Configuration">
<separator colspan="4" string="Configure Sale Order Logistic"/>
<newline/>
<field name="picking_policy"/>
<newline/>
<field name="order_policy"/>
<group col="4" colspan="4">
<button icon="gtk-cancel" name="action_cancel" type="object" special="cancel" string="Cancel"/>
<button icon="gtk-ok" name="set_default" string="Set Default" type="object"/>
+154 -37
View File
@@ -32,63 +32,180 @@ from osv import fields, osv
class product_product(osv.osv):
_inherit = "product.product"
# def view_header_get(self, cr, user, view_id, view_type, context):
# print self, cr, user
# res = super(product_product, self).view_header_get(cr, user, view_id, view_type, context)
# if res: return res
# if (not context.get('location', False)):
# return False
# cr.execute('select name from stock_location where id=%d', (context['location'],))
# j = cr.fetchone()[0]
# if j:
# return 'Products: '+j
# return False
#
def _get_product_available_func(states, what):
def _product_available(self, cr, uid, ids, name, arg, context={}):
if context.get('shop', False):
cr.execute('select warehouse_id from sale_shop where id=%d', (int(context['shop']),))
res2 = cr.fetchone()
if res2:
context['warehouse'] = res2[0]
def view_header_get(self, cr, user, view_id, view_type, context):
res = super(product_product, self).view_header_get(cr, user, view_id, view_type, context)
if res: return res
if (context.get('location', False)):
return _('Products: ')+self.pool.get('stock.location').browse(cr, user, context['location'], context).name
return res
if context.get('warehouse', False):
cr.execute('select lot_stock_id from stock_warehouse where id=%d', (int(context['warehouse']),))
res2 = cr.fetchone()
if res2:
context['location'] = res2[0]
def get_product_available(self,cr,uid,ids,context=None):
if not context:
context = {}
print 'CONTEXT', context
states=context.get('states',[])
what=context.get('what',())
if not ids:
ids = self.search(cr, uid, [])
res = {}.fromkeys(ids, 0.0)
if not ids:
return res
if context.get('location', False):
if context.get('shop', False):
cr.execute('select warehouse_id from sale_shop where id=%d', (int(context['shop']),))
res2 = cr.fetchone()
if res2:
context['warehouse'] = res2[0]
if context.get('warehouse', False):
cr.execute('select lot_stock_id from stock_warehouse where id=%d', (int(context['warehouse']),))
res2 = cr.fetchone()
if res2:
context['location'] = res2[0]
if context.get('location', False):
if type(context['location']) == type(1):
location_ids = [context['location']]
else:
cr.execute("select lot_stock_id from stock_warehouse")
location_ids = [id for (id,) in cr.fetchall()]
location_ids = context['location']
else:
cr.execute("select lot_stock_id from stock_warehouse")
location_ids = [id for (id,) in cr.fetchall()]
# build the list of ids of children of the location given by id
location_ids = self.pool.get('stock.location').search(cr, uid, [('location_id', 'child_of', location_ids)])
res = self.pool.get('stock.location')._product_get_multi_location(cr, uid, location_ids, ids, context, states, what)
# build the list of ids of children of the location given by id
location_ids = self.pool.get('stock.location').search(cr, uid, [('location_id', 'child_of', location_ids)])
states_str = ','.join(map(lambda s: "'%s'" % s, states))
product2uom = {}
for product in self.browse(cr, uid, ids, context=context):
product2uom[product.id] = product.uom_id.id
prod_ids_str = ','.join(map(str, ids))
location_ids_str = ','.join(map(str, location_ids))
results = []
results2 = []
from_date=context.get('from_date',False)
to_date=context.get('to_date',False)
date_str=False
if from_date and to_date:
date_str="date>='%s' and date<=%s"%(from_date,to_date)
elif from_date:
date_str="date>='%s'"%(from_date)
elif to_date:
date_str="date<='%s'"%(to_date)
if 'in' in what:
# all moves from a location out of the set to a location in the set
cr.execute(
'select sum(product_qty), product_id, product_uom '\
'from stock_move '\
'where location_id not in ('+location_ids_str+') '\
'and location_dest_id in ('+location_ids_str+') '\
'and product_id in ('+prod_ids_str+') '\
'and state in ('+states_str+') '+ (date_str and 'and '+date_str+' ' or '') +''\
'group by product_id,product_uom'
)
results = cr.fetchall()
if 'out' in what:
# all moves from a location in the set to a location out of the set
cr.execute(
'select sum(product_qty), product_id, product_uom '\
'from stock_move '\
'where location_id in ('+location_ids_str+') '\
'and location_dest_id not in ('+location_ids_str+') '\
'and product_id in ('+prod_ids_str+') '\
'and state in ('+states_str+') '+ (date_str and 'and '+date_str+' ' or '') + ''\
'group by product_id,product_uom'
)
results2 = cr.fetchall()
uom_obj = self.pool.get('product.uom')
for amount, prod_id, prod_uom in results:
amount = uom_obj._compute_qty(cr, uid, prod_uom, amount,
context.get('uom', False) or product2uom[prod_id])
res[prod_id] += amount
for amount, prod_id, prod_uom in results2:
amount = uom_obj._compute_qty(cr, uid, prod_uom, amount,
context.get('uom', False) or product2uom[prod_id])
res[prod_id] -= amount
return res
def _get_product_available_func(states, what):
def _product_available(self, cr, uid, ids, field_names=False, arg=False, context={}):
context.update({
'states':states,
'what':what
})
stock=self.get_product_available(cr,uid,ids,context=context)
res = {}
for id in ids:
res.setdefault(id, 0.0)
res[id] = {}.fromkeys(field_names, 0.0)
for a in field_names:
res[id][a] = stock.get(id, 0.0)
return res
return _product_available
_product_qty_available = _get_product_available_func(('done',), ('in', 'out'))
_product_virtual_available = _get_product_available_func(('confirmed','waiting','assigned','done'), ('in', 'out'))
_product_outgoing_qty = _get_product_available_func(('confirmed','waiting','assigned'), ('out',))
_product_incoming_qty = _get_product_available_func(('confirmed','waiting','assigned'), ('in',))
_columns = {
'qty_available': fields.function(_product_qty_available, method=True, type='float', string='Real Stock', help="Current quantities of products in selected locations or all internal if none have been selected."),
'virtual_available': fields.function(_product_virtual_available, method=True, type='float', string='Virtual Stock', help="Futur stock for this product according to the selected location or all internal if none have been selected. Computed as: Real Stock - Outgoing + Incoming."),
'incoming_qty': fields.function(_product_incoming_qty, method=True, type='float', string='Incoming', help="Quantities of products that are planned to arrive in selected locations or all internal if none have been selected."),
'outgoing_qty': fields.function(_product_outgoing_qty, method=True, type='float', string='Outgoing', help="Quantities of products that are planned to leave in selected locations or all internal if none have been selected."),
'qty_available': fields.function(_product_qty_available, method=True, type='float', string='Real Stock',multi='qty_available', help="Current quantities of products in selected locations or all internal if none have been selected."),
'virtual_available': fields.function(_product_virtual_available, method=True, type='float', string='Virtual Stock',multi='qty_available', help="Futur stock for this product according to the selected location or all internal if none have been selected. Computed as: Real Stock - Outgoing + Incoming."),
'incoming_qty': fields.function(_product_incoming_qty, method=True, type='float', string='Incoming',multi='qty_available', help="Quantities of products that are planned to arrive in selected locations or all internal if none have been selected."),
'outgoing_qty': fields.function(_product_outgoing_qty, method=True, type='float', string='Outgoing',multi='qty_available', help="Quantities of products that are planned to leave in selected locations or all internal if none have been selected."),
'track_production' : fields.boolean('Track Production Lots' , help="Force to use a Production Lot during production order"),
'track_incoming' : fields.boolean('Track Incomming Lots', help="Force to use a Production Lot during receptions"),
'track_outgoing' : fields.boolean('Track Outging Lots', help="Force to use a Production Lot during deliveries"),
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False):
res = super(product_product,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar)
if ('location' in context) and context['location']:
location_info = self.pool.get('stock.location').browse(cr, uid, context['location'])
fields=res.get('fields',{})
if fields:
if location_info.usage == 'supplier':
if fields.get('virtual_available'):
res['fields']['virtual_available']['string'] = 'Futur Receptions'
if fields.get('qty_available'):
res['fields']['qty_available']['string'] = 'Received Qty'
if location_info.usage == 'internal':
if fields.get('virtual_available'):
res['fields']['virtual_available']['string'] = 'Futur Stock'
if location_info.usage == 'customer':
if fields.get('virtual_available'):
res['fields']['virtual_available']['string'] = 'Futur Deliveries'
if fields.get('qty_available'):
res['fields']['qty_available']['string'] = 'Delivered Qty'
if location_info.usage == 'inventory':
if fields.get('virtual_available'):
res['fields']['virtual_available']['string'] = 'Futur P&L'
res['fields']['qty_available']['string'] = 'P&L Qty'
if location_info.usage == 'procurement':
if fields.get('virtual_available'):
res['fields']['virtual_available']['string'] = 'Futur Qty'
if fields.get('qty_available'):
res['fields']['qty_available']['string'] = 'Unplanned Qty'
if location_info.usage == 'production':
if fields.get('virtual_available'):
res['fields']['virtual_available']['string'] = 'Futur Productions'
if fields.get('qty_available'):
res['fields']['qty_available']['string'] = 'Produced Qty'
return res
product_product()
class product_product(osv.osv):
class product_template(osv.osv):
_name = 'product.template'
_inherit = 'product.template'
_columns = {
@@ -126,7 +243,7 @@ class product_product(osv.osv):
help='This account will be used, instead of the default one, to value output stock'),
}
product_product()
product_template()
class product_category(osv.osv):
+1 -1
View File
@@ -62,7 +62,7 @@
<field name="arch" type="xml">
<group name="status" position="after">
<group colspan="2" col="2">
<separator string="Stocks" colspan="4"/>
<separator string="Stocks" colspan="4"/>
<field name="qty_available"/>
<field name="virtual_available"/>
<field name="incoming_qty"/>
+4
View File
@@ -79,6 +79,8 @@ class report_stock(report_int):
for (qty, dt, prod_id) in cr.fetchall():
if dt<=dt_from:
dt= (DateTime.now() + DateTime.RelativeDateTime(days=1)).strftime('%Y-%m-%d')
else:
dt = dt[:10]
products.setdefault(prod_id, [])
products[prod_id].append((dt,-qty))
@@ -86,6 +88,8 @@ class report_stock(report_int):
for (qty, dt, prod_id) in cr.fetchall():
if dt<=dt_from:
dt= (DateTime.now() + DateTime.RelativeDateTime(days=1)).strftime('%Y-%m-%d')
else:
dt = dt[:10]
products.setdefault(prod_id, [])
products[prod_id].append((dt,qty))
+11 -100
View File
@@ -201,69 +201,14 @@ class stock_location(osv.osv):
})
return result
def _product_get_multi_location(self, cr, uid, ids, product_ids=False, context={}, states=['done'], what=('in', 'out')):
product_obj = self.pool.get('product.product')
states_str = ','.join(map(lambda s: "'%s'" % s, states))
if not product_ids:
product_ids = product_obj.search(cr, uid, [])
res = {}.fromkeys(product_ids, 0.0)
if not ids:
return res
product2uom = {}
for product in product_obj.browse(cr, uid, product_ids, context=context):
product2uom[product.id] = product.uom_id.id
prod_ids_str = ','.join(map(str, product_ids))
location_ids_str = ','.join(map(str, ids))
results = []
results2 = []
from_date=context.get('from_date',False)
to_date=context.get('to_date',False)
date_str=False
if from_date and to_date:
date_str="date>='%s' and date<=%s"%(from_date,to_date)
elif from_date:
date_str="date>='%s'"%(from_date)
elif to_date:
date_str="date<='%s'"%(to_date)
if 'in' in what:
# all moves from a location out of the set to a location in the set
cr.execute(
'select sum(product_qty), product_id, product_uom '\
'from stock_move '\
'where location_id not in ('+location_ids_str+') '\
'and location_dest_id in ('+location_ids_str+') '\
'and product_id in ('+prod_ids_str+') '\
'and state in ('+states_str+') '+ (date_str and 'and '+date_str+' ' or '') +''\
'group by product_id,product_uom'
)
results = cr.fetchall()
if 'out' in what:
# all moves from a location in the set to a location out of the set
cr.execute(
'select sum(product_qty), product_id, product_uom '\
'from stock_move '\
'where location_id in ('+location_ids_str+') '\
'and location_dest_id not in ('+location_ids_str+') '\
'and product_id in ('+prod_ids_str+') '\
'and state in ('+states_str+') '+ (date_str and 'and '+date_str+' ' or '') + ''\
'group by product_id,product_uom'
)
results2 = cr.fetchall()
uom_obj = self.pool.get('product.uom')
for amount, prod_id, prod_uom in results:
amount = uom_obj._compute_qty(cr, uid, prod_uom, amount,
context.get('uom', False) or product2uom[prod_id])
res[prod_id] += amount
for amount, prod_id, prod_uom in results2:
amount = uom_obj._compute_qty(cr, uid, prod_uom, amount,
context.get('uom', False) or product2uom[prod_id])
res[prod_id] -= amount
return res
def _product_get_multi_location(self, cr, uid, ids, product_ids=False, context={}, states=['done'], what=('in', 'out')):
product_obj = self.pool.get('product.product')
context.update({
'states':states,
'what':what,
'location':ids
})
return product_obj.get_product_available(cr,uid,product_ids,context=context)
def _product_get(self, cr, uid, id, product_ids=False, context={}, states=['done']):
ids = id and [id] or []
@@ -434,7 +379,8 @@ class stock_picking(osv.osv):
], 'Status', readonly=True, select=True),
'min_date': fields.function(get_min_max_date, fnct_inv=_set_minimum_date, multi="min_max_date",
method=True,store=True, type='datetime', string='Planned Date', select=1),
'date':fields.datetime('Date create'),
'date':fields.datetime('Date Order'),
'date_done':fields.datetime('Date Done'),
'max_date': fields.function(get_min_max_date, fnct_inv=_set_maximum_date, multi="min_max_date",
method=True,store=True, type='datetime', string='Max. Planned Date', select=2),
'move_lines': fields.one2many('stock.move', 'picking_id', 'Move lines'),
@@ -569,7 +515,7 @@ class stock_picking(osv.osv):
# TODO: change and create a move if not parents
#
def action_done(self, cr, uid, ids, context=None):
self.write(cr,uid, ids, {'state':'done'})
self.write(cr,uid, ids, {'state':'done', 'date_done': time.strftime('%Y-%m-%d %H:%M:%S')})
return True
def action_move(self, cr, uid, ids, context={}):
@@ -1383,39 +1329,4 @@ class stock_picking_move_wizard(osv.osv_memory):
return {'type':'ir.actions.act_window_close' }
stock_picking_move_wizard()
class product_product(osv.osv):
_inherit = 'product.product'
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False):
res = super(product_product,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar)
if ('location' in context) and context['location']:
location_info = self.pool.get('stock.location').browse(cr, uid, context['location'])
if location_info.usage == 'supplier':
res['fields']['virtual_available']['string'] = 'Futur Receptions'
res['fields']['qty_available']['string'] = 'Received Qty'
if location_info.usage == 'internal':
res['fields']['virtual_available']['string'] = 'Futur Stock'
if location_info.usage == 'customer':
res['fields']['virtual_available']['string'] = 'Futur Deliveries'
res['fields']['qty_available']['string'] = 'Delivered Qty'
if location_info.usage == 'inventory':
res['fields']['virtual_available']['string'] = 'Futur P&L'
res['fields']['qty_available']['string'] = 'P&L Qty'
if location_info.usage == 'procurement':
res['fields']['virtual_available']['string'] = 'Futur Qty'
res['fields']['qty_available']['string'] = 'Unplanned Qty'
if location_info.usage == 'production':
res['fields']['virtual_available']['string'] = 'Futur Productions'
res['fields']['qty_available']['string'] = 'Produced Qty'
return res
product_product()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+14 -8
View File
@@ -492,12 +492,12 @@
<field name="arch" type="xml">
<tree color="red:state=='cancel'" string="Packing list">
<field name="name"/>
<field name="address_id" select="1"/>
<field name="invoice_state"/>
<field name="origin"/>
<field name="address_id" select="1"/>
<field name="backorder_id"/>
<field name="date"/>
<field name="min_date"/>
<field name="invoice_state"/>
<field name="state"/>
</tree>
</field>
@@ -568,6 +568,7 @@
<field name="active" select="2"/>
<field name="auto_picking"/>
<field name="invoice_state" select="2"/>
<field name="date_done" select="2"/>
<newline/>
<field name="move_type"/>
</page>
@@ -587,8 +588,9 @@
<field name="arch" type="xml">
<tree color="red:state=='cancel'" string="Packing list">
<field name="name"/>
<field name="address_id" select="1"/>
<field name="origin"/>
<field name="address_id" select="1"/>
<field name="backorder_id"/>
<field name="date" select="1"/>
<field name="min_date" select="1"/>
<field name="state" select="1"/>
@@ -655,8 +657,9 @@
<field name="auto_picking"/>
<field name="active" select="2"/>
<newline/>
<field name="move_type"/>
<field name="date" select="1"/>
<field name="date_done" select="2"/>
<field name="move_type"/>
</page>
</notebook>
</form>
@@ -771,10 +774,12 @@
<field name="arch" type="xml">
<tree color="red:state=='cancel'" string="Packing list">
<field name="name"/>
<field name="origin"/>
<field name="address_id"/>
<field name="backorder_id"/>
<field name="date"/>
<field name="min_date"/>
<field name="invoice_state"/>
<field name="state"/>
</tree>
</field>
@@ -839,8 +844,9 @@
<field name="active" select="2"/>
<field name="auto_picking"/>
<newline/>
<field name="move_type"/>
<field name="date" select="2"/>
<field name="date_done" select="2"/>
<field name="move_type"/>
</page>
</notebook>
</form>
@@ -940,13 +946,13 @@
<field name="type">tree</field>
<field name="arch" type="xml">
<tree color="red:state=='cancel'" string="Packing list">
<field colspan="4" name="name"/>
<field name="address_id" select="1"/>
<field name="invoice_state"/>
<field name="name"/>
<field name="origin"/>
<field name="address_id"/>
<field name="backorder_id"/>
<field name="date"/>
<field name="min_date"/>
<field name="invoice_state"/>
<field name="state"/>
</tree>
</field>
+13 -12
View File
@@ -34,24 +34,27 @@ import time
def _action_open_window(self, cr, uid, data, context):
return {
'view_type': 'form',
"view_mode": 'tree,form',
'res_model': 'product.product',
'type': 'ir.actions.act_window',
'context':{'location': data['ids'][0],'from_date':data['form']['from_date'],'to_date':data['form']['to_date']},
'domain':[('type','<>','service')]
}
'name': False,
'view_type': 'form',
"view_mode": 'tree,form',
'res_model': 'product.product',
'type': 'ir.actions.act_window',
'context':{'location': data['ids'][0],'from_date':data['form']['from_date'],'to_date':data['form']['to_date']},
'domain':[('type','<>','service')]
}
class product_by_location(wizard.interface):
form1 = '''<?xml version="1.0"?>
<form string="View Stock of Products">
<separator string="Stock Location Analysis" colspan="4"/>
<field name="from_date"/>
<newline/>
<field name="to_date"/>
<newline/>
<label string=""/>
<label string="(Keep empty to open the current situation)" align="0.0" colspan="3"/>
</form>'''
form1_fields = {
'from_date': {
'string': 'From',
@@ -66,13 +69,11 @@ class product_by_location(wizard.interface):
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [ ('open', 'Open Products'),('end', 'Cancel')]}
'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [('end', 'Cancel','gtk-cancel'),('open', 'Open Products','gtk-ok')]}
},
'open': {
'actions': [],
'result': {'type': 'action', 'action': _action_open_window, 'state':'end'}
}
}
product_by_location('stock.location.products')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: