bzr revid: fp@tinyerp.com-20100519160002-fpaq0qr1pdomukd8
This commit is contained in:
Fabien Pinckaers 2010-05-19 18:00:02 +02:00
commit 6dc4c2e6db
87 changed files with 890 additions and 605 deletions

View File

@ -231,9 +231,9 @@ class account_account(osv.osv):
aml_query = self.pool.get('account.move.line')._query_get(cr, uid, context=context)
wheres = [""]
if query:
if query.strip():
wheres.append(query.strip())
if aml_query:
if aml_query.strip():
wheres.append(aml_query.strip())
query = " AND ".join(wheres)
@ -251,6 +251,7 @@ class account_account(osv.osv):
# consolidate accounts with direct children
ids2.reverse()
brs = list(self.browse(cr, uid, ids2, context=context))
sums = {}
while brs:
@ -270,8 +271,9 @@ class account_account(osv.osv):
if current.child_id:
sums[current.id][fn] += sum(sums[child.id][fn] for child in current.child_id)
res = {}
null_result = dict((fn, 0.0) for fn in field_names)
for id in ids:
res[id] = sums[id]
res[id] = sums.get(id, null_result)
return res
def _get_company_currency(self, cr, uid, ids, field_name, arg, context={}):
@ -313,7 +315,7 @@ class account_account(osv.osv):
'user_type': fields.many2one('account.account.type', 'Account Type', required=True,
help="These types are defined according to your country. The type contains more information "\
"about the account and its specificities."),
'parent_id': fields.many2one('account.account', 'Parent', ondelete='cascade'),
'parent_id': fields.many2one('account.account', 'Parent', ondelete='cascade', domain=[('type','=','view')]),
'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'),
'child_id': fields.function(_get_child_ids, method=True, type='many2many', relation="account.account", string="Child Accounts"),
@ -450,18 +452,42 @@ class account_account(osv.osv):
def _check_moves(self, cr, uid, ids, method, context):
line_obj = self.pool.get('account.move.line')
account_ids = self.search(cr, uid, [('id', 'child_of', ids)])
if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
if method == 'write':
raise osv.except_osv(_('Error !'), _('You cannot deactivate an account that contains account moves.'))
elif method == 'unlink':
raise osv.except_osv(_('Error !'), _('You cannot remove an account which has account entries!. '))
#Checking whether the account is set as a property to any Partner or not
value = 'account.account,' + str(ids[0])
partner_prop_acc = self.pool.get('ir.property').search(cr, uid, [('value_reference','=',value)], context=context)
if partner_prop_acc:
raise osv.except_osv(_('Warning !'), _('You cannot remove/deactivate an account which is set as a property to any Partner.'))
return True
def _check_allow_type_change(self, cr, uid, ids, new_type, context):
group1 = ['payable', 'receivable', 'other']
group2 = ['consolidation','view']
line_obj = self.pool.get('account.move.line')
for account in self.browse(cr, uid, ids, context=context):
old_type = account.type
account_ids = self.search(cr, uid, [('id', 'child_of', [account.id])])
if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]):
#Check for 'Closed' type
if old_type == 'closed' and new_type !='closed':
raise osv.except_osv(_('Warning !'), _("You cannot change the type of account from 'Closed' to any other type which contains account entries!"))
#Check for change From group1 to group2 and vice versa
if (old_type in group1 and new_type in group2) or (old_type in group2 and new_type in group1):
raise osv.except_osv(_('Warning !'), _("You cannot change the type of account from '%s' to '%s' type as it contains account entries!") % (old_type,new_type,))
return True
def write(self, cr, uid, ids, vals, context=None):
if not context:
if context is None:
context = {}
if 'active' in vals and not vals['active']:
self._check_moves(cr, uid, ids, "write", context)
if 'type' in vals.keys():
self._check_allow_type_change(cr, uid, ids, vals['type'], context=context)
return super(account_account, self).write(cr, uid, ids, vals, context=context)
def unlink(self, cr, uid, ids, context={}):
@ -557,15 +583,16 @@ class account_journal(osv.osv):
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
if not args:
args=[]
if not context:
context={}
args = []
if context is None:
context = {}
ids = []
if name:
ids = self.search(cr, user, [('code','ilike',name)]+ args, limit=limit)
ids = self.search(cr, user, [('code','ilike',name)]+ args, limit=limit, context=context)
if not ids:
ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit)
ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit, context=context)
return self.name_get(cr, user, ids, context=context)
account_journal()
class account_fiscalyear(osv.osv):
@ -631,6 +658,19 @@ class account_fiscalyear(osv.osv):
else:
return False
return ids[0]
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
if args is None:
args = []
if context is None:
context = {}
ids = []
if name:
ids = self.search(cr, user, [('code','ilike',name)]+ args, limit=limit)
if not ids:
ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit)
return self.name_get(cr, user, ids, context=context)
account_fiscalyear()
class account_period(osv.osv):
@ -706,6 +746,18 @@ class account_period(osv.osv):
cr.execute('update account_journal_period set state=%s where period_id=%s', (mode, id))
cr.execute('update account_period set state=%s where id=%s', (mode, id))
return True
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
if args is None:
args = []
if context is None:
context = {}
ids = []
if name:
ids = self.search(cr, user, [('code','ilike',name)]+ args, limit=limit)
if not ids:
ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit)
return self.name_get(cr, user, ids, context=context)
account_period()
@ -950,7 +1002,6 @@ class account_move(osv.osv):
l[2]['period_id'] = default_period
context['period_id'] = default_period
accnt_journal = self.pool.get('account.journal').browse(cr, uid, vals['journal_id'])
if 'line_id' in vals:
c = context.copy()
c['novalidate'] = True
@ -1248,7 +1299,7 @@ class account_tax_code(osv.osv):
_description = 'Tax Code'
_rec_name = 'code'
_columns = {
'name': fields.char('Tax Case Name', size=64, required=True),
'name': fields.char('Tax Case Name', size=64, required=True, translate=True),
'code': fields.char('Case Code', size=64),
'info': fields.text('Description'),
'sum': fields.function(_sum_year, method=True, string="Year Sum"),
@ -1262,6 +1313,15 @@ class account_tax_code(osv.osv):
}
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
if not args:
args = []
if context is None:
context = {}
ids = self.search(cr, user, ['|',('name',operator,name),('code',operator,name)] + args, limit=limit, context=context)
return self.name_get(cr, user, ids, context)
def name_get(self, cr, uid, ids, context=None):
if not len(ids):
return []
@ -1290,7 +1350,15 @@ class account_tax_code(osv.osv):
return False
level -= 1
return True
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
default = default.copy()
default.update({'line_ids': []})
return super(account_tax_code, self).copy(cr, uid, id, default, context)
_constraints = [
(_check_recursion, 'Error ! You can not create recursive accounts.', ['parent_id'])
]

View File

@ -558,35 +558,40 @@ class account_bank_statement_line(osv.osv):
def onchange_partner_id(self, cursor, user, line_id, partner_id, type, currency_id,
context={}):
res = {'value': {}}
if not partner_id:
return {}
res_currency_obj = self.pool.get('res.currency')
res_users_obj = self.pool.get('res.users')
company_currency_id = res_users_obj.browse(cursor, user, user,
context=context).company_id.currency_id.id
if not currency_id:
currency_id = company_currency_id
part = self.pool.get('res.partner').browse(cursor, user, partner_id,
return res
line = self.browse(cursor, user, line_id)
if not line or (line and not line[0].account_id):
part = self.pool.get('res.partner').browse(cursor, user, partner_id,
context=context)
if type == 'supplier':
account_id = part.property_account_payable.id
else:
account_id = part.property_account_receivable.id
if type == 'supplier':
account_id = part.property_account_payable.id
else:
account_id = part.property_account_receivable.id
res['value']['account_id'] = account_id
cursor.execute('SELECT sum(debit-credit) \
if not line or (line and not line[0].amount):
res_users_obj = self.pool.get('res.users')
res_currency_obj = self.pool.get('res.currency')
company_currency_id = res_users_obj.browse(cursor, user, user,
context=context).company_id.currency_id.id
if not currency_id:
currency_id = company_currency_id
cursor.execute('SELECT sum(debit-credit) \
FROM account_move_line \
WHERE (reconcile_id is null) \
AND partner_id = %s \
AND account_id=%s', (partner_id, account_id))
res = cursor.fetchone()
balance = res and res[0] or 0.0
pgres = cursor.fetchone()
balance = pgres and pgres[0] or 0.0
balance = res_currency_obj.compute(cursor, user, company_currency_id,
balance = res_currency_obj.compute(cursor, user, company_currency_id,
currency_id, balance, context=context)
return {'value': {'amount': balance, 'account_id': account_id}}
res['value']['amount'] = balance
return res
def _reconcile_amount(self, cursor, user, ids, name, args, context=None):
if not ids:
@ -633,7 +638,7 @@ class account_bank_statement_line(osv.osv):
'note': fields.text('Notes'),
'reconcile_amount': fields.function(_reconcile_amount,
string='Amount reconciled', method=True, type='float'),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of bank statement line."),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of bank statement lines."),
}
_defaults = {
'name': lambda self,cr,uid,context={}: self.pool.get('ir.sequence').get(cr, uid, 'account.bank.statement.line'),

View File

@ -478,9 +478,11 @@
<act_window domain="[('journal_id','=',active_id),('state','!=','draft'),('reconciled','=',False)]" id="act_account_journal_2_account_invoice_opened" name="Unpaid invoices" res_model="account.invoice" src_model="account.journal"/>
<act_window domain="[('account_analytic_id', '=', active_id)]" id="act_account_analytic_account_2_account_invoice_line" name="Invoice lines" res_model="account.invoice.line" src_model="account.analytic.account"/>
<!-- Partners inherited form -->
<act_window domain="[('partner_id', '=', partner_id), ('account_id.type', 'in', ['receivable', 'payable']), ('reconcile_id','=',False)]" id="act_account_invoice_account_move_unreconciled" name="Unreconciled Receivables &amp; Payables" res_model="account.move.line" src_model="account.invoice"/>
<!-- Partners inherited form -->
<record id="view_invoice_partner_info_form" model="ir.ui.view">
<field name="name">res.partner.invoice.info.inherit</field>
<field name="model">res.partner</field>

View File

@ -577,11 +577,12 @@ class account_move_line(osv.osv):
merges_rec = []
for line in self.browse(cr, uid, ids, context):
if line.reconcile_id:
raise osv.except_osv(_('Already Reconciled'), _('Already Reconciled'))
raise osv.except_osv(_('Warning'), _('Already Reconciled!'))
if line.reconcile_partial_id:
for line2 in line.reconcile_partial_id.line_partial_ids:
if not line2.reconcile_id:
merges.append(line2.id)
if line2.id not in merges:
merges.append(line2.id)
total += (line2.debit or 0.0) - (line2.credit or 0.0)
merges_rec.append(line.reconcile_partial_id.id)
else:
@ -774,6 +775,17 @@ class account_move_line(osv.osv):
result['fields'] = self.fields_get(cr, uid, fields, context)
return result
def _check_moves(self, cr, uid, context):
# use the first move ever created for this journal and period
cr.execute('select id, state, name from account_move where journal_id=%s and period_id=%s order by id limit 1', (context['journal_id'],context['period_id']))
res = cr.fetchone()
if res:
if res[1] != 'draft':
raise osv.except_osv(_('UserError'),
_('The account move (%s) for centralisation ' \
'has been confirmed!') % res[2])
return res
def unlink(self, cr, uid, ids, context={}, check=True):
self._update_check(cr, uid, ids, context)
result = False
@ -809,7 +821,7 @@ class account_move_line(osv.osv):
return True
def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True):
if not context:
if context is None:
context={}
if vals.get('account_tax_id', False):
raise osv.except_osv(_('Unable to change tax !'), _('You can not change the tax, you should remove and recreate lines !'))
@ -825,6 +837,24 @@ class account_move_line(osv.osv):
if vals.get('date', False):
todo_date = vals['date']
del vals['date']
for line in self.browse(cr, uid, ids,context=context):
ctx = context.copy()
if ('journal_id' not in ctx):
if line.move_id:
ctx['journal_id'] = line.move_id.journal_id.id
else:
ctx['journal_id'] = line.journal_id.id
if ('period_id' not in ctx):
if line.move_id:
ctx['period_id'] = line.move_id.period_id.id
else:
ctx['period_id'] = line.period_id.id
#Check for centralisation
journal = self.pool.get('account.journal').browse(cr, uid, ctx['journal_id'], context=ctx)
if journal.centralisation:
self._check_moves(cr, uid, context=ctx)
result = super(account_move_line, self).write(cr, uid, ids, vals, context)
if check:
@ -891,14 +921,9 @@ class account_move_line(osv.osv):
is_new_move = False
if not move_id:
if journal.centralisation:
# use the first move ever created for this journal and period
cr.execute('select id, state, name from account_move where journal_id=%s and period_id=%s order by id limit 1', (context['journal_id'],context['period_id']))
res = cr.fetchone()
#Check for centralisation
res = self._check_moves(cr, uid, context)
if res:
if res[1] != 'draft':
raise osv.except_osv(_('UserError'),
_('The Ledger Posting (%s) for centralisation ' \
'has been confirmed!') % res[2])
vals['move_id'] = res[0]
if not vals.get('move_id', False):
@ -926,7 +951,7 @@ class account_move_line(osv.osv):
break
if journal.account_control_ids and not ok:
for a in journal.account_control_ids:
if a.id==vals['account_id']:
if a.id == vals['account_id']:
ok = True
break
if (account.currency_id) and 'amount_currency' not in vals and account.currency_id.id <> company_currency:
@ -941,7 +966,7 @@ class account_move_line(osv.osv):
if not ok:
raise osv.except_osv(_('Bad account !'), _('You can not use this general account in this journal !'))
if 'analytic_account_id' in vals and vals['analytic_account_id']:
if vals.get('analytic_account_id',False):
if journal.analytic_journal_id:
vals['analytic_lines'] = [(0,0, {
'name': vals['name'],
@ -961,8 +986,8 @@ class account_move_line(osv.osv):
result = super(osv.osv, self).create(cr, uid, vals, context)
# CREATE Taxes
if 'account_tax_id' in vals and vals['account_tax_id']:
tax_id=tax_obj.browse(cr,uid,vals['account_tax_id'])
if vals.get('account_tax_id',False):
tax_id = tax_obj.browse(cr, uid, vals['account_tax_id'])
total = vals['debit'] - vals['credit']
if journal.refund_journal:
base_code = 'ref_base_code_id'
@ -978,7 +1003,7 @@ class account_move_line(osv.osv):
tax_sign = 'tax_sign'
tmp_cnt = 0
for tax in tax_obj.compute(cr,uid,[tax_id],total,1.00):
for tax in tax_obj.compute(cr, uid, [tax_id], total, 1.00):
#create the base movement
if tmp_cnt == 0:
if tax[base_code]:
@ -1031,7 +1056,7 @@ class account_move_line(osv.osv):
# if context and ('__last_update' in context):
# del context['__last_update']
# self.pool.get('account.move').write(cr, uid, [move_id], {'date':vals['date']}, context=context)
if check and not context.get('no_store_function'):
if check and ((not context.get('no_store_function')) or journal.entry_posted):
tmp = self.pool.get('account.move').validate(cr, uid, [vals['move_id']], context)
if journal.entry_posted and tmp:
self.pool.get('account.move').button_validate(cr,uid, [vals['move_id']],context)

View File

@ -531,7 +531,10 @@
<field name="create_date" select="1"/>
<field name="type" select="1"/>
</group>
<separator colspan="4" string="Reconcile Entries"/>
<field colspan="4" name="line_id" nolabel="1"/>
<separator colspan="4" string="Partial Reconcile Entries"/>
<field colspan="4" name="line_partial_ids" nolabel="1"/>
</form>
</field>
</record>
@ -551,6 +554,7 @@
<field name="code"/>
<field name="sum"/>
<field name="sum_period"/>
<field name="company_id"/>
</tree>
</field>
</record>
@ -562,7 +566,7 @@
<form string="Account Tax Code">
<field name="name" select="1"/>
<field name="code" select="1"/>
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
<field name="company_id" select="1"/>
<field name="notprintable"/>
<field name="parent_id" select="1"/>
<field name="sign"/>
@ -648,9 +652,9 @@
</page>
<page groups="base.group_extended" string="Special Computation">
<separator colspan="4" string="Compute Code (if type=code)"/>
<field colspan="4" name="python_compute" nolabel="1" attrs="{'readonly':[('type','!=','code')]}"/>
<field colspan="4" name="python_compute" nolabel="1" attrs="{'readonly':[('type','!=','code')],'required':[('type','=','code')]}"/>
<separator colspan="4" string="Applicable Code (if type=code)"/>
<field colspan="4" name="python_applicable" nolabel="1" attrs="{'readonly':[('applicable_type','=','true')]}"/>
<field colspan="4" name="python_applicable" nolabel="1" attrs="{'readonly':[('applicable_type','=','true')], 'required':[('applicable_type','=','code')]}"/>
</page>
</notebook>
</form>
@ -1453,9 +1457,11 @@
<act_window domain="[('journal_id', '=', active_id)]" id="act_account_journal_2_account_move_line" name="Entry lines" res_model="account.move.line" src_model="account.journal"/>
<act_window domain="[('partner_id', '=', active_id), ('account_id.type', 'in', ['receivable', 'payable']), ('reconcile_id','=',False)]" id="act_account_partner_account_move_unreconciled" name="Receivables &amp; Payables" res_model="account.move.line" src_model="res.partner"/>
<act_window domain="[('partner_id', '=', active_id), ('account_id.type', 'in', ['receivable', 'payable']), ('reconcile_id','=',False)]" id="act_account_partner_account_move_unreconciled" name="Unreconciled Receivables &amp; Payables" res_model="account.move.line" src_model="res.partner"/>
<act_window domain="[('partner_id', '=', active_id)]" id="act_account_partner_account_move" name="All account entries" res_model="account.move.line" src_model="res.partner"/>
<act_window domain="[('partner_id', '=', active_id), ('account_id.type', 'in', ['receivable', 'payable'])]" id="act_account_partner_account_move_all" name="Receivables &amp; Payables" res_model="account.move.line" src_model="res.partner"/>
<act_window domain="[('partner_id', '=', active_id)]" id="act_account_partner_account_move" name="All Account Entries" res_model="account.move.line" src_model="res.partner"/>
<record id="view_account_addtmpl_wizard_form" model="ir.ui.view">
<field name="name">Account Add wizard</field>

View File

@ -23,8 +23,8 @@ import time
import decimal_precision as dp
import netsvc
from osv import fields, osv, orm
import ir
import pooler
from tools import config
from tools.translate import _
@ -333,7 +333,7 @@ class account_invoice(osv.osv):
raise orm.except_orm(_('Configuration Error!'),
_('There is no Accounting Journal of type Sale/Purchase defined!'))
else:
raise
raise orm.except_orm(_('UnknownError'), str(e))
def unlink(self, cr, uid, ids, context=None):
invoices = self.read(cr, uid, ids, ['state'])
@ -350,7 +350,7 @@ class account_invoice(osv.osv):
# res = self.pool.get('res.partner').address_get(cr, uid, [part], ['invoice'])
# return [{}]
def onchange_partner_id(self, cr, uid, ids, type, partner_id,
date_invoice=False, payment_term=False, partner_bank_id=False, company_id=False):
date_invoice=False, payment_term=False, partner_bank=False, company_id=False):
invoice_addr_id = False
contact_addr_id = False
partner_payment_term = False
@ -415,7 +415,7 @@ class account_invoice(osv.osv):
else:
result['value']['date_due'] = False
if partner_bank_id != bank_id:
if partner_bank != bank_id:
to_update = self.onchange_partner_bank(cr, uid, ids, bank_id)
result['value'].update(to_update['value'])
return result
@ -450,7 +450,7 @@ class account_invoice(osv.osv):
def onchange_invoice_line(self, cr, uid, ids, lines):
return {}
def onchange_partner_bank(self, cursor, user, ids, partner_bank_id):
def onchange_partner_bank(self, cursor, user, ids, partner_bank):
return {'value': {}}
def onchange_company_id(self, cr, uid, ids, company_id, part_id, type, invoice_line, currency_id):
@ -650,6 +650,16 @@ class account_invoice(osv.osv):
self.write(cr, uid, [inv.id], res['value'])
return True
def finalize_invoice_move_lines(self, cr, uid, invoice_browse, move_lines):
"""finalize_invoice_move_lines(cr, uid, invoice, move_lines) -> move_lines
Hook method to be overridden in additional modules to verify and possibly alter the
move lines to be created by an invoice, for special cases.
:param invoice_browse: browsable record of the invoice that is generating the move lines
:param move_lines: list of dictionaries with the account.move.lines (as for create())
:return: the (possibly updated) final move_lines to create for this invoice
"""
return move_lines
def check_tax_lines(self, cr, uid, inv, compute_taxes, ait_obj):
if not inv.tax_line:
for tax in compute_taxes.values():
@ -912,7 +922,12 @@ class account_invoice(osv.osv):
# will be automatically deleted too
account_move_obj.unlink(cr, uid, [i['move_id'][0]])
if i['payment_ids']:
self.pool.get('account.move.line').write(cr, uid, i['payment_ids'], {'reconcile_partial_id': False})
account_move_line_obj = self.pool.get('account.move.line')
pay_ids = account_move_line_obj.browse(cr, uid , i['payment_ids'])
for move_line in pay_ids:
if move_line.reconcile_partial_id and move_line.reconcile_partial_id.line_partial_ids:
raise osv.except_osv(_('Error !'), _('You cannot cancel the Invoice which is Partially Paid! You need to unreconcile concerned payment entries!'))
self.write(cr, uid, ids, {'state':'cancel', 'move_id':False})
self._log_event(cr, uid, ids,-1.0, 'Cancel Invoice')
return True
@ -1147,7 +1162,7 @@ class account_invoice_line(osv.osv):
t = t - (p * l[2].get('quantity'))
taxes = l[2].get('invoice_line_tax_id')
if len(taxes[0]) >= 3 and taxes[0][2]:
taxes=tax_obj.browse(cr, uid, taxes[0][2])
taxes = tax_obj.browse(cr, uid, taxes[0][2])
for tax in tax_obj.compute(cr, uid, taxes, p,l[2].get('quantity'), context.get('address_invoice_id', False), l[2].get('product_id', False), context.get('partner_id', False)):
t = t - tax['amount']
return t
@ -1200,8 +1215,8 @@ class account_invoice_line(osv.osv):
part = self.pool.get('res.partner').browse(cr, uid, partner_id)
fpos = fposition_id and self.pool.get('account.fiscal.position').browse(cr, uid, fposition_id) or False
lang=part.lang
context.update({'lang': lang})
if part.lang:
context.update({'lang': part.lang})
result = {}
res = self.pool.get('product.product').browse(cr, uid, product, context=context)

View File

@ -113,6 +113,7 @@
</form>
<tree string="Bank Details">
<field name="state"/>
<field name="bank"/>
<field name="owner_name"/>
<field name="acc_number"/>
</tree>

View File

@ -54,12 +54,12 @@ class account_analytic_analytic_check(report_sxw.rml_parse):
self.cr.execute("SELECT abs(sum(amount)) AS balance \
FROM account_analytic_line \
WHERE date>=%s AND date<=%s AND amount>0 AND general_account_id = %s", (date1, date2, a['id']))
WHERE date>=%s AND date<=%s AND amount<0 AND general_account_id = %s", (date1, date2, a['id']))
(ad,) = self.cr.fetchone()
ad = ad or 0.0
self.cr.execute("SELECT abs(sum(amount)) AS balance \
FROM account_analytic_line \
WHERE date>=%s AND date<=%s AND amount<0 AND general_account_id = %s", (date1, date2, a['id']))
WHERE date>=%s AND date<=%s AND amount>0 AND general_account_id = %s", (date1, date2, a['id']))
(ac,) = self.cr.fetchone()
ac = ac or 0.0

View File

@ -84,8 +84,8 @@
<paraStyle name="terp_default_Bold_9" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="terp_default_Centre_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="terp_default_Right_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
<images/>
</stylesheet>
<images/>
<story>
<para style="terp_default_8">[[ repeatIn(objects,'o') ]]</para>
<para style="terp_default_8">[[ setLang(o.lang) ]]</para>
@ -177,16 +177,16 @@
<para style="terp_default_Centre_9">[[ line['ref'] ]]</para>
</td>
<td>
<para style="terp_default_Centre_9">[[ line['date_maturity'] ]]</para>
<para style="terp_default_Centre_9">[[ line['date_maturity'] and formatLang(line['date_maturity'],date=True) or '' ]]</para>
</td>
<td>
<para style="terp_default_Right_9">[[ formatLang(line['debit']) and formatLang(line['debit'] * (line['account_id']['type'] == 'payable' and -1 or 1)) ]]</para>
<para style="terp_default_Right_9">[[ (line['account_id']['type'] == 'receivable' and formatLang(line['debit']) or 0) or (line['account_id']['type'] == 'payable' and formatLang(line['credit'] * -1) or ' ') ]]</para>
</td>
<td>
<para style="terp_default_Right_9">[[ formatLang(line['credit']) and formatLang(line['credit'] * (line['account_id']['type'] == 'payable' and -1 or 1)) ]]</para>
<para style="terp_default_Right_9">[[ (line['account_id']['type'] == 'receivable' and formatLang(line['credit']) or 0) or (line['account_id']['type'] == 'payable' and formatLang(line['debit'] * -1) or 0) ]]</para>
</td>
<td>
<para style="terp_default_Right_9">[[ formatLang((line['date_maturity'] &lt; time.strftime('%Y-%m-%d')) and ((line['debit'] - line['credit']) * (line['account_id']['type'] == 'payable' and -1 or 1))) ]]</para>
<para style="terp_default_Right_9">[[ formatLang((line['date_maturity'] &lt; time.strftime('%Y-%m-%d'))) and (line['debit'] - line['credit']) ]]</para>
</td>
<td>
<para style="terp_default_Centre_9">[[ line['blocked'] and 'X' or '' ]]</para>
@ -205,13 +205,13 @@
<para style="terp_default_Bold_9">Sub-Total : </para>
</td>
<td>
<para style="terp_default_Right_9">[[ formatLang((reduce(lambda x, y: x + (y['debit'] * (y['account_id']['type'] == 'payable' and -1 or 1)), getLines(o), 0))) ]]</para>
<para style="terp_default_Right_9">[[ formatLang((reduce(lambda x, y: x + ((y['account_id']['type'] == 'receivable' and y['debit'] or 0) or (y['account_id']['type'] == 'payable' and y['credit'] * -1 or 0)), getLines(o), 0))) ]]</para>
</td>
<td>
<para style="terp_default_Right_9">[[ formatLang((reduce(lambda x ,y: x + (y['credit'] * (y['account_id']['type'] == 'payable' and -1 or 1)), getLines(o), 0))) ]] </para>
<para style="terp_default_Right_9">[[ formatLang((reduce(lambda x, y: x + ((y['account_id']['type'] == 'receivable' and y['credit'] or 0) or (y['account_id']['type'] == 'payable' and y['debit'] * -1 or 0)), getLines(o), 0))) ]] </para>
</td>
<td>
<para style="terp_default_Right_9">[[ formatLang((reduce(lambda x, y: x + ((y['debit'] - y['credit']) * (y['account_id']['type'] == 'payable' and -1 or 1)), filter(lambda x: x['date_maturity'] &lt; time.strftime('%Y-%m-%d'), getLines(o)), 0))) ]]</para>
<para style="terp_default_Right_9">[[ formatLang((reduce(lambda x, y: x + (y['debit'] - y['credit']), filter(lambda x: x['date_maturity'] &lt; time.strftime('%Y-%m-%d'), getLines(o)), 0))) ]]</para>
</td>
<td>
<para style="terp_default_9">
@ -229,7 +229,7 @@
<para style="terp_default_Bold_9">Balance : </para>
</td>
<td>
<para style="terp_default_Right_9">[[ formatLang((reduce(lambda x, y: x +((y['debit'] - y['credit']) * (y['account_id']['type'] == 'payable' and -1 or 1)), getLines(o), 0))) ]]</para>
<para style="terp_default_Right_9">[[ formatLang((reduce(lambda x, y: x +(y['debit'] - y['credit']), getLines(o), 0))) ]]</para>
</td>
<td>
<para style="terp_default_9">
@ -248,9 +248,9 @@
</td>
</tr>
</blockTable>
<para style="terp_default_9">Total amount due: [[ formatLang((reduce(lambda x, y: x + ((y['debit'] - y['credit']) * (y['account_id']['type'] == 'payable' and -1 or 1)), getLines(o), 0))) ]] [[ company.currency_id.name ]].</para>
<para style="terp_default_9">Total amount due: [[ formatLang((reduce(lambda x, y: x + (y['debit'] - y['credit']), getLines(o), 0))) ]] [[ company.currency_id.name ]].</para>
<para style="terp_default_8">
<font color="white"> </font>
</para>
</story>
</document>
</document>

View File

@ -15,8 +15,8 @@
"access_account_move","account.move","model_account_move","account.group_account_user",1,1,1,1
"access_account_move_line","account.move.line","model_account_move_line","account.group_account_user",1,1,1,1
"access_account_move_reconcile","account.move.reconcile","model_account_move_reconcile","account.group_account_user",1,1,1,1
"access_account_tax_code","account.tax.code","model_account_tax_code",,1,0,0,0
"access_account_tax","account.tax","model_account_tax",,1,0,0,0
"access_account_tax_code","account.tax.code","model_account_tax_code","account.group_account_invoice",1,0,0,0
"access_account_tax","account.tax","model_account_tax","account.group_account_invoice",1,0,0,0
"access_account_model","account.model","model_account_model","account.group_account_user",1,1,1,1
"access_account_model_line","account.model.line","model_account_model_line","account.group_account_user",1,1,1,1
"access_account_subscription","account.subscription","model_account_subscription","account.group_account_user",1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
15 access_account_move account.move model_account_move account.group_account_user 1 1 1 1
16 access_account_move_line account.move.line model_account_move_line account.group_account_user 1 1 1 1
17 access_account_move_reconcile account.move.reconcile model_account_move_reconcile account.group_account_user 1 1 1 1
18 access_account_tax_code account.tax.code model_account_tax_code account.group_account_invoice 1 0 0 0
19 access_account_tax account.tax model_account_tax account.group_account_invoice 1 0 0 0
20 access_account_model account.model model_account_model account.group_account_user 1 1 1 1
21 access_account_model_line account.model.line model_account_model_line account.group_account_user 1 1 1 1
22 access_account_subscription account.subscription model_account_subscription account.group_account_user 1 1 1 1

View File

@ -42,7 +42,7 @@ class ir_sequence(osv.osv):
_columns = {
'fiscal_ids' : fields.one2many('account.sequence.fiscalyear', 'sequence_main_id', 'Sequences')
}
def get_id(self, cr, uid, sequence_id, test='id', context={}):
def get_id(self, cr, uid, sequence_id, test='id', context={}):
cr.execute('select id from ir_sequence where '+test+'=%s and active=%s', (sequence_id, True,))
res = cr.dictfetchone()
if res:

View File

@ -21,6 +21,7 @@
from osv import fields, osv
from tools.translate import _
import netsvc
import time
class account_invoice_refund(osv.osv_memory):
@ -29,10 +30,14 @@ class account_invoice_refund(osv.osv_memory):
_name = "account.invoice.refund"
_description = "Invoice Refund"
_columns = {
'date': fields.date('Operation date', required=False),
'date': fields.date('Operation date', required=False, help='This date will be used as the invoice date for Refund Invoice and Period will be chosen accordingly!'),
'period': fields.many2one('account.period', 'Force period', required=False),
'description': fields.char('Description', size=150, required=True),
}
}
_defaults = {
'date': time.strftime('%Y-%m-%d'),
}
def compute_refund(self, cr, uid, ids, mode, context=None):
"""
@ -167,7 +172,7 @@ class account_invoice_refund(osv.osv_memory):
xml_id = 'action_invoice_tree1'
elif inv.type == 'in_invoice':
xml_id = 'action_invoice_tree2'
elif type == 'out_refund':
elif inv.type == 'out_refund':
xml_id = 'action_invoice_tree3'
else:
xml_id = 'action_invoice_tree4'

View File

@ -19,7 +19,6 @@
#
##############################################################################
import time
import datetime
from osv import fields, osv
from tools.translate import _

View File

@ -29,11 +29,17 @@ class account_unreconcile(osv.osv_memory):
obj_move_reconcile = self.pool.get('account.move.reconcile')
if context is None:
context = {}
recs = obj_move_line.read(cr, uid, context['active_ids'], ['reconcile_id',])
recs = filter(lambda x: x['reconcile_id'], recs)
rec_ids = [rec['reconcile_id'][0] for rec in recs]
if len(rec_ids):
obj_move_reconcile.unlink(cr, uid, rec_ids)
recs = pool.get('account.move.line').read(cr, uid, data['ids'], ['reconcile_id','reconcile_partial_id'])
unlink_ids = []
full_recs = filter(lambda x: x['reconcile_id'], recs)
rec_ids = [rec['reconcile_id'][0] for rec in full_recs]
part_recs = filter(lambda x: x['reconcile_partial_id'], recs)
part_rec_ids = [rec['reconcile_partial_id'][0] for rec in part_recs]
unlink_ids += rec_ids
unlink_ids += part_rec_ids
if len(unlink_ids):
pooler.get_pool(cr.dbname).get('account.move.reconcile').unlink(cr, uid, unlink_ids)
return {}
account_unreconcile()
@ -44,10 +50,11 @@ class account_unreconcile_reconcile(osv.osv_memory):
def trans_unrec_reconcile(self, cr, uid, ids, context=None):
obj_move_reconcile = self.pool.get('account.move.reconcile')
rec_ids = context['active_ids']
if context is None:
context = {}
if len(rec_ids):
obj_move_reconcile.unlink(cr, uid, context['active_ids'])
obj_move_reconcile.unlink(cr, uid, rec_ids)
return {}
account_unreconcile_reconcile()

View File

@ -103,6 +103,8 @@ class sale_order_line(osv.osv):
# Method overridden to set the analytic account by default on criterion match
def invoice_line_create(self, cr, uid, ids, context={}):
create_ids = super(sale_order_line,self).invoice_line_create(cr, uid, ids, context)
if not ids:
return create_ids
sale_line_obj = self.browse(cr, uid, ids[0], context)
pool_inv_line = self.pool.get('account.invoice.line')

View File

@ -297,14 +297,15 @@ class account_move_line(osv.osv):
def create_analytic_lines(self, cr, uid, ids, context={}):
super(account_move_line, self).create_analytic_lines(cr, uid, ids, context)
analytic_line_obj = self.pool.get('account.analytic.line')
for line in self.browse(cr, uid, ids, context):
if line.analytics_id:
if not line.journal_id.analytic_journal_id:
raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (line.journal_id.name,))
toremove = self.pool.get('account.analytic.line').search(cr, uid, [('move_id','=',line.id)], context=context)
toremove = analytic_line_obj.search(cr, uid, [('move_id','=',line.id)], context=context)
if toremove:
line.unlink(cr, uid, toremove, context=context)
analytic_line_obj.unlink(cr, uid, toremove, context=context)
for line2 in line.analytics_id.account_ids:
val = (line.credit or 0.0) - (line.debit or 0.0)
amt=val * (line2.rate/100)
@ -321,7 +322,7 @@ class account_move_line(osv.osv):
'journal_id': line.journal_id.analytic_journal_id.id,
'ref': line.ref,
}
ali_id=self.pool.get('account.analytic.line').create(cr,uid,al_vals)
ali_id=analytic_line_obj.create(cr, uid, al_vals, context=context)
return True
account_move_line()

View File

@ -124,7 +124,7 @@
</field>
</record>
<act_window domain="[('partner_id', '=', active_id),('reconcile_id','=',False),('account_id.reconcile', '=', True)]" id="account.act_account_partner_account_move_unreconciled" name="Receivables &amp; Payables" res_model="account.move.line" view="account_move_line_partner_tree"/>
<act_window domain="[('partner_id', '=', active_id),('reconcile_id','=',False),('account_id.reconcile', '=', True),('account_id.type', 'in', ['receivable', 'payable'])]" id="account.act_account_partner_account_move_unreconciled" name="Receivables &amp; Payables" res_model="account.move.line" view="account_move_line_partner_tree"/>
<act_window domain="[('reconcile_id', '=', False),('account_id.type','=','receivable')]" id="act_account_partner_account_move_all" name="All receivable entries" res_model="account.move.line" src_model="" view="account_move_line_partner_tree"/>

View File

@ -25,6 +25,8 @@
<field name="partner_id"/>
<field name="ref"/>
<field name="name"/>
<field name="journal_id"/>
<field name="account_id"/>
<field name="date_maturity"/>
<field name="date"/>
<field name="debit" sum="Total debit"/>
@ -279,7 +281,6 @@
<field name="currency"/>
<field name="bank_id" domain="[('partner_id', '=', partner_id)]"/>
<field name="move_line_id" on_change="onchange_move_line(move_line_id,parent.mode)"/>
<field domain="[('partner_id', '=', partner_id)]" name="bank_id"/>
<field name="create_date"/>
<field name="name"/>
</tree>

View File

@ -104,7 +104,7 @@ class payment_order_create(osv.osv_memory):
# Search for move line to pay:
domain = [('reconcile_id', '=', False),('account_id.type', '=', 'payable'),('amount_to_pay', '>', 0)]
domain = domain + ['|',('date_maturity','<',search_due_date),('date_maturity','=',False)]
domain = domain + ['|',('date_maturity','<=',search_due_date),('date_maturity','=',False)]
line_ids = line_obj.search(cr, uid, domain, context=context)
context.update({'line_ids': line_ids})
model_data_ids = mod_obj.search(cr, uid,[('model','=','ir.ui.view'),('name','=','view_create_payment_order_lines')], context=context)

View File

@ -106,5 +106,3 @@ class account_payment_populate_statement(osv.osv_memory):
return {'type' : 'ir.actions.act_window_close'}
account_payment_populate_statement()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -103,7 +103,7 @@ class account_voucher(osv.osv):
],'Type', readonly=True, select=True , size=128),
'date':fields.date('Date', readonly=True, states={'draft':[('readonly',False)]}),
'journal_id':fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'account_id':fields.many2one('account.account', 'Account', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'account_id':fields.many2one('account.account', 'Account', required=True, readonly=True, states={'draft':[('readonly',False)]}, domain=[('type','<>','view')]),
'payment_ids':fields.one2many('account.voucher.line','voucher_id','Voucher Lines', readonly=False, states={'proforma':[('readonly',True)]}),
'period_id': fields.many2one('account.period', 'Period', required=True, states={'posted':[('readonly',True)]}),
'narration':fields.text('Narration', readonly=True, states={'draft':[('readonly',False)]}, required=True),
@ -167,15 +167,14 @@ class account_voucher(osv.osv):
return {'value':{'account_id':account_id.id}}
def open_voucher(self, cr, uid, ids, context={}):
obj=self.pool.get('account.voucher').browse(cr,uid,ids)
total=0
obj = self.pool.get('account.voucher').browse(cr,uid,ids)
total = 0
for i in obj[0].payment_ids:
total+=i.amount
if total!=0:
self.write(cr,uid,ids,{'amount':total})
self.write(cr, uid, ids, {'state':'proforma'})
total += i.amount
if total != 0:
self.write(cr, uid, ids, {'amount':total, 'state':'proforma'})
else:
raise osv.except_osv('Invalid action !', 'You can not post to Pro-Forma a voucher with Total amount = 0')
raise osv.except_osv('Invalid action !', 'You cannot post to Pro-Forma a voucher with Total amount = 0 !')
return True
def proforma_voucher(self, cr, uid, ids, context={}):
@ -302,9 +301,9 @@ class account_voucher(osv.osv):
name = self.pool.get('ir.sequence').get_id(cr, uid, journal.sequence_id.id)
move = {
'name': name,
'name' : name,
'journal_id': journal_id,
'voucher_type':inv.type,
'type' : inv.type,
'narration' : inv.narration
}
if inv.period_id:
@ -487,7 +486,7 @@ class account_voucher_line(osv.osv):
_columns = {
'voucher_id':fields.many2one('account.voucher', 'Voucher'),
'name':fields.char('Description', size=256, required=True),
'account_id':fields.many2one('account.account','Account', required=True),
'account_id':fields.many2one('account.account','Account', required=True, domain=[('type','<>','view')]),
'partner_id': fields.many2one('res.partner', 'Partner', change_default=True),
'amount':fields.float('Amount'),
'type':fields.selection([('dr','Debit'),('cr','Credit')], 'Type'),

View File

@ -343,7 +343,7 @@ class account_analytic_line(osv.osv):
}
_defaults = {
'date': lambda *a: time.strftime('%Y-%m-%d'),
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.analytic.line', c),
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.analytic.line', context=c),
}
_order = 'date'
account_analytic_line()

View File

@ -100,7 +100,7 @@ class hr_analytic_timesheet(osv.osv):
'for this product: "%s" (id:%d)') % \
(r.product_id.name, r.product_id.id,))
# Compute based on pricetype
amount_unit=self.on_change_unit_amount(cr, uid, ids,
amount_unit = self.on_change_unit_amount(cr, uid, ids,
r.product_id.id, unit_amount, r.product_id.uom_id.id)['value']['amount']
amount = unit_amount * amount_unit
@ -136,7 +136,7 @@ class hr_analytic_timesheet(osv.osv):
'for this product: "%s" (id:%d)') % \
(r.product_id.name, r.product_id.id,))
# Compute based on pricetype
amount_unit=self.on_change_unit_amount(cr, uid, ids,
amount_unit = self.on_change_unit_amount(cr, uid, ids,
r.product_id.id, unit_amount, r.product_id.uom_id.id)['value']['amount']
amount = unit_amount * amount_unit

View File

@ -19,7 +19,6 @@
#
##############################################################################
import netsvc
from osv import fields, osv
class res_partner_contact(osv.osv):
@ -116,22 +115,6 @@ res_partner_contact()
class res_partner_address(osv.osv):
def search(self, cr, user, args, offset=0, limit=None, order=None,
context=None, count=False):
""" search parnter address
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param user: the current user
@param args: list of tuples of form [(name_of_the_field, operator, value), ...].
@param offset: The Number of Results to Pass
@param limit: The Number of Results to Return
@param context: A standard dictionary for contextual values
"""
if context and context.has_key('address_partner_id' ) and context['address_partner_id']:
args.append(('partner_id', '=', context['address_partner_id']))
return super(res_partner_address, self).search(cr, user, args, offset, limit, order, context, count)
#overriding of the name_get defined in base in order to remove the old contact name
def name_get(self, cr, user, ids, context={}):
"""
@ -208,6 +191,8 @@ class res_partner_job(osv.osv):
if arg[2] and not count:
search_arg = ['|', ('first_name', 'ilike', arg[2]), ('name', 'ilike', arg[2])]
contact_ids = contact_obj.search(cr, user, search_arg, offset=offset, limit=limit, order=order, context=context, count=count)
if not contact_ids:
continue
contacts = contact_obj.browse(cr, user, contact_ids, context=context)
for contact in contacts:
job_ids.extend([item.id for item in contact.job_ids])
@ -224,10 +209,10 @@ class res_partner_job(osv.osv):
_order = 'sequence_contact'
_columns = {
'name': fields.related('address_id','partner_id', type='many2one',\
'name': fields.related('address_id', 'partner_id', type='many2one',\
relation='res.partner', string='Partner', help="You may\
enter Address first,Partner will be linked automatically if any."),
'address_id': fields.many2one('res.partner.address','Address', \
'address_id': fields.many2one('res.partner.address', 'Address', domain=[('partner_id', '=', name)], \
help='Address which is linked to the Partner'),
'contact_id': fields.many2one('res.partner.contact','Contact', required=True, ondelete='cascade'),
'function_id': fields.many2one('res.partner.function','Partner Function', \
@ -251,7 +236,34 @@ class res_partner_job(osv.osv):
'sequence_contact' : lambda *a: 0,
'state': lambda *a: 'current',
}
def onchange_partner(self, cr, uid, _, partner_id, context=None):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current user,
@param _: List of IDs,
@partner_id : ID of the Partner selected,
@param context: A standard dictionary for contextual values
"""
return {'value': {'address_id': False}}
def onchange_address(self, cr, uid, _, address_id, context=None):
"""
@@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current user,
@param _: List of IDs,
@address_id : ID of the Address selected,
@param context: A standard dictionary for contextual values
"""
partner_id = False
if address_id:
address = self.pool.get('res.partner.address')\
.browse(cr, uid, address_id, context)
partner_id = address.partner_id.id
return {'value': {'name': partner_id}}
res_partner_job()

View File

@ -52,7 +52,7 @@
<form string="Functions and Addresses">
<group string="Partner" colspan="2" col="4">
<field name="function_id"/>
<field name="address_id" context="{'address_partner_id': name}"/>
<field name="address_id"/>
<field name="name"/>
<field name="date_start" />
<field name="date_stop" />
@ -357,23 +357,19 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Contact Functions">
<notebook>
<page string="General">
<field name="name" select="1"/>
<field name="address_id" select="1" context="{'address_partner_id': name}"/>
<field name="contact_id" select="1"/>
<field name="function_id" select="1"/>
<field name="email" widget="email"/>
<field name="phone"/>
<field name="fax"/>
<field name="extension"/>
<field name="sequence_contact" groups="base.group_user"/>
<field name="sequence_partner" groups="base.group_user"/>
<field name="date_start" groups="base.group_user"/>
<field name="date_stop" groups="base.group_user"/>
<field name="state" />
</page>
</notebook>
<field name="name" select="1" on_change="onchange_partner(name)"/>
<field name="address_id" select="1" attrs="{'required': [('name', '!=', False)]}" on_change="onchange_address(address_id)"/>
<field name="contact_id" select="1"/>
<field name="function_id" select="1"/>
<field name="email" widget="email"/>
<field name="phone"/>
<field name="fax"/>
<field name="extension"/>
<field name="sequence_contact" groups="base.group_user"/>
<field name="sequence_partner" groups="base.group_user"/>
<field name="date_start" groups="base.group_user"/>
<field name="date_stop" groups="base.group_user"/>
<field name="state" />
</form>
</field>
</record>

View File

@ -42,6 +42,17 @@
</field>
</field>
</record>
<record id="view_partner_iban_list" model="ir.ui.view">
<field name="name">res.partner.form.iban.inherit.list</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="type">form</field>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='bank_ids']/tree/field[@name='acc_number']" position="after">
<field name="iban"/>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -19,12 +19,28 @@
#
##############################################################################
from osv import fields, osv
from tools.translate import _
import pooler
from base_module_quality import base_module_quality
class CounterCursor(object):
def __init__(self, real_cursor):
self.cr = real_cursor
self.count = 0
def reset(self):
self.count = 0
def execute(self, query, params=None):
if query.lower().startswith('select '):
self.count += 1
return self.cr.execute(query, params)
def __getattr__(self, attr):
return getattr(self.cr, attr)
class quality_test(base_module_quality.abstract_quality_check):
def __init__(self):
@ -63,6 +79,7 @@ This test checks the speed of the module. Note that at least 5 demo data is need
result_dict = {}
result_dict2 = {}
self.result_details += _("<html>O(1) means that the number of SQL requests to read the object does not depand on the number of objects we are reading. This feature is hardly wished.\n</html>")
ccr = CounterCursor(cr)
for obj, ids in obj_ids.items():
code_base_complexity = 0
code_half_complexity = 0
@ -73,22 +90,22 @@ This test checks the speed of the module. Note that at least 5 demo data is need
list2 = []
if size:
speed_list = []
#we perform the operation twice, and count the number of queries in the second run. This allows to avoid the cache effect. (like translated terms that asks for more queries)
try:
pool.get(obj).read(cr, uid, [ids[0]])
cnt = cr.count
pool.get(obj).read(cr, uid, [ids[0]])
code_base_complexity = cr.count - cnt
pool.get(obj).read(cr, uid, ids[:size/2])
cnt = cr.count
pool.get(obj).read(cr, uid, ids[:size/2])
code_half_complexity = cr.count - cnt
# perform the operation once to put data in cache
pool.get(obj).read(cr, uid, ids)
cnt = cr.count
pool.get(obj).read(cr, uid, ids)
code_size_complexity = cr.count - cnt
ccr.reset()
pool.get(obj).read(ccr, uid, [ids[0]])
code_base_complexity = ccr.count
ccr.reset()
pool.get(obj).read(ccr, uid, ids[:size/2])
code_half_complexity = ccr.count
ccr.reset()
pool.get(obj).read(ccr, uid, ids)
code_size_complexity = ccr.count
except Exception, e:
list2 = [obj, _("Error in Read method")]
speed_list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, _("Error in Read method:" + str(e))]

View File

@ -35,7 +35,7 @@ class report_creator(osv.osv):
#
def export_data(self, cr, uid, ids, fields_to_export, context=None):
if not context:
if context is None:
context = {}
data_l = self.read(cr, uid, ids, ['sql_query'], context)
final_datas = []
@ -61,7 +61,7 @@ class report_creator(osv.osv):
@param Fields: List of field of customer reports form.
@return: Dictionary of Fields
"""
if not context:
if context is None:
context = {}
data = context and context.get('report_id', False) or False
@ -95,7 +95,7 @@ class report_creator(osv.osv):
@param user: the current users ID for security checks,
@return: Dictionary of Fields, arch and toolbar.
"""
if not context:
if context is None:
context = {}
data = context and context.get('report_id', False) or False
@ -116,9 +116,11 @@ class report_creator(osv.osv):
arch = '<?xml version="1.0" encoding="utf-8"?>\n'
if view_type == 'graph':
arch += '<graph string="%s" type="%s" orientation="%s">' % (report.name, report.view_graph_type, report.view_graph_orientation)
orientation_eval = {'horz':'horizontal','vert' :'vertical'}
orientation = eval(report.view_graph_orientation,orientation_eval)
arch +='<graph string="%s" type="%s" orientation="%s">' % (report.name, report.view_graph_type, orientation)
i = 0
for val in ('x','y'):
i = 0
for f in report.field_ids:
if f.graph_mode == val:
if f.field_id.model:
@ -191,7 +193,9 @@ class report_creator(osv.osv):
@param fields: List of fields.
@return: List of Dictionary of form [{name_of_the_field: value, ...}, ...]
"""
data = context and context.get('report_id', False) or False
if context is None:
context = {}
data = context.get('report_id', False)
if (not context) or 'report_id' not in context:
return super(report_creator, self).read(cr, user, ids, fields, context, load)
ctx = context or {}
@ -225,8 +229,9 @@ class report_creator(osv.osv):
@param args: list of tuples of form [(name_of_the_field, operator, value), ...].
@return: List of id
"""
context_id = context and context.get('report_id', False) or False
if context is None:
context = {}
context_id = context.get('report_id', False)
if (not context) or 'report_id' not in context:
return super(report_creator, self).search(cr, user, args, offset, limit, order, context, count)
@ -372,9 +377,10 @@ class report_creator(osv.osv):
t = self.pool.get(f.field_id.model_id.model)._table
if f.group_method == 'group':
fields.append('\t'+t+'.'+f.field_id.name+' as field'+str(i))
groupby.append(t+'.'+f.field_id.name)
else:
fields.append('\t'+f.group_method+'('+t+'.'+f.field_id.name+')'+' as field'+str(i))
groupby.append(t+'.'+f.field_id.name)
i += 1
models = self._path_get(cr, uid, obj.model_ids, obj.filter_ids)
check = self._id_get(cr, uid, ids[0], context)

View File

@ -309,27 +309,32 @@ class PyOpenOffice(object):
return new_c
def sxw2rml(sxw_file, xsl, output='.', save_pict=False):
import libxslt
import libxml2
from lxml import etree
from StringIO import StringIO
tool = PyOpenOffice(output, save_pict = save_pict)
res = tool.unpackNormalize(sxw_file)
styledoc = libxml2.parseDoc(xsl)
style = libxslt.parseStylesheetDoc(styledoc)
doc = libxml2.parseMemory(res,len(res))
result = style.applyStylesheet(doc, None)
root = result.xpathEval("/document/stylesheet")
f = StringIO(xsl)
styledoc = etree.parse(f)
style = etree.XSLT(styledoc)
f = StringIO(res)
doc = etree.parse(f)
result = style(doc)
root = etree.XPathEvaluator(result)("/document/stylesheet")
if root:
root=root[0]
images = libxml2.newNode("images")
images = etree.Element("images")
for img in tool.images:
node = libxml2.newNode('image')
node.setProp('name', img)
node.setContent( base64.encodestring(tool.images[img]))
images.addChild(node)
root.addNextSibling(images)
node = etree.Element('image', name=img)
node.text = base64.encodestring(tool.images[img])
images.append(node)
root.append(images)
try:
xml = style.saveResultToString(result)
xml = str(result)
return xml
except:
return result
@ -349,7 +354,7 @@ if __name__ == "__main__":
import StringIO
fname = sys.argv[1]
f = StringIO.StringIO(file(fname).read())
f = fname
xsl_file = 'normalized_oo2rml.xsl'
z = zipfile.ZipFile(fname,"r")
mimetype = z.read('mimetype')

View File

@ -74,21 +74,26 @@ class base_gtkcontactform(osv.osv_memory):
'contact_me':fields.boolean('Contact Me'),
}
def execute(self, cr, uid, ids, context=None):
company_id = self.pool.get('base.setup.company').search(cr, uid, [])
company_data = self.pool.get('base.setup.company').read(cr, uid, company_id)
company_data = company_data and company_data[0] or False
if context is None:
context = {}
company_id = self.pool.get('base.setup.company').search(cr, uid, [], context=context)
company_data = self.pool.get('base.setup.company').read(cr, uid, company_id, context=context)
company_data = company_data and company_data[0] or {}
country = ''
if company_data and company_data.get('country_id', False):
country = self.pool.get('res.country').read(cr, uid, company_data['country_id'],['name'])['name']
for res in self.read(cr, uid, ids):
if company_data.get('country_id', False):
country = self.pool.get('res.country').read(cr, uid, company_data['country_id'],['name'], context=context)['name']
for res in self.read(cr, uid, ids, context=context):
email = res.get('email','')
result = "\ncompany: "+ str(company_data.get('name',''))
result += "\nname: " + str(res.get('name',''))
result += "\njob: " + str(res.get('job',''))
result = "\ncompany: "+ tools.ustr(company_data.get('name',''))
result += "\nname: " + tools.ustr(res.get('name',''))
result += "\njob: " + tools.ustr(res.get('job',''))
result += "\nphone: " + str(res.get('phone',''))
result += "\ncity: " + str(company_data.get('city',''))
result += "\ncity: " + tools.ustr(company_data.get('city',''))
result += "\ncountry: " + str(country)
result += "\nindustry: " + str(res.get('industry', ''))
result += "\nindustry: " + tools.ustr(res.get('industry', ''))
result += "\ntotal_employees: " + str(res.get('total_employees', ''))
result += "\nplan_use: " + str(res.get('use_openerp', False))
result += "\nalready_using_openerp: " + str(res.get('already_using_openerp', False))

View File

@ -152,5 +152,23 @@ IBAN: BE74 1262 0121 6907 - SWIFT: CPDF BE71 - VAT: BE0477.472.701'''),
context=context)
base_setup_company()
class res_currency(osv.osv):
_inherit = 'res.currency'
def name_get(self, cr, uid, ids, context=None):
if context is None:
context = {}
# We can use the following line,if we want to restrict this name_get for company setup only
# But, its better to show currencies as name(Code).
# if not (context.get('active_model','') == 'ir.actions.todo'):
# return super(res_currency,self).name_get(cr, uid, ids, context=context)
if not len(ids):
return []
if isinstance(ids, (int, long)):
ids = [ids]
reads = self.read(cr, uid, ids, ['name','code'], context, load='_classic_write')
return [(x['id'], tools.ustr(x['name']) + ' (' + tools.ustr(x['code']) + ')') for x in reads]
res_currency()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -10,6 +10,7 @@
<field name="view_id" ref="crm_case_tree_view_leads"/>
<field name="context">{"search_default_user_id":uid,'search_default_current':1}</field>
<field name="search_view_id" ref="crm.view_crm_case_leads_filter"/>
<field name="context">{'search_default_current':1}</field>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_view_leads_all">

View File

@ -47,7 +47,7 @@
name="convert_opportunity"
string="Convert"
help="Convert to Opportunity"
icon="gtk-index"
icon="gtk-index"
type="object"
attrs="{'invisible':[('opportunity_id','!=',False)]}"/>
<newline />

View File

@ -50,7 +50,7 @@
<field name="res_model">crm.meeting</field>
<field name="view_mode">calendar,tree,form,gantt</field>
<field name="view_id" ref="crm_case_calendar_view_meet"/>
<field name="context">{'search_default_current':1,"search_default_user_id":uid}</field>
<field name="context">{"search_default_user_id":uid}</field>
<field name="search_view_id" ref="view_crm_case_meetings_filter"/>
</record>

View File

@ -274,7 +274,7 @@
<field name="user_id" select="1" widget="selection"/>
</group>
<newline/>
<group expand="0" string="Group By..." colspan="16">
<group expand="0" string="Group By..." colspan="16">
<filter string="Date" icon="terp-project"
domain="[]" context="{'group_by':'date'}" />
<filter string="Privacy" icon="terp-crm"

View File

@ -128,7 +128,7 @@
<field name="arch" type="xml">
<group name="logistic" position="inside">
<field name="id" invisible="True"/>
<field name="carrier_id" context="{'order_id':id}"/>
<field name="carrier_id" context="{'order_id':active_id}"/>
</group>
</field>
</record>

View File

@ -55,7 +55,7 @@ class stock_picking(osv.osv):
'weight': fields.function(_cal_weight, method=True, type='float', string='Weight', digits_compute= dp.get_precision('Stock Weight'),
store={
'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20),
'stock.move': (_get_picking_line, ['product_id','product_uos_qty'], 20),
'stock.move': (_get_picking_line, ['product_id','product_qty','product_uom','product_uos_qty'], 20),
}),
}

View File

@ -123,7 +123,7 @@ class abstracted_fs:
def db_list(self):
#return pooler.pool_dic.keys()
s = netsvc.ExportService.getService('db')
result = s.exp_list()
result = s.exp_list(document=True)
self.db_name_list = []
for db_name in result:
db, cr = None, None

View File

@ -177,7 +177,6 @@ class document_directory_content(osv.osv):
fexprs[n.name] = n.expr
if 'uid' not in fields:
print "uid not in ", fields
# FIXME: should pass
return True
for child in parsedCal.getChildren():
@ -189,7 +188,6 @@ class document_directory_content(osv.osv):
if enl =='uid':
uuid = event.value
if not enl in fields:
# print "skip", enl
continue
if fields[enl] and funcs[enl] == 'field':
if ICS_TAGS[enl]=='normal':
@ -216,7 +214,6 @@ class document_directory_content(osv.osv):
# end for
if not uuid:
print "Skipping cal", child
# FIXME: should pass
continue

View File

@ -218,11 +218,13 @@ class event_registration(osv.osv):
args[1]['description']= event.mail_confirm
return super(event_registration, self).write(cr, uid, *args, **argv)
def mail_user_confirm(self,cr,uid,ids):
reg_ids=self.browse(cr,uid,ids)
def mail_user_confirm(self, cr, uid, ids):
reg_ids = self.browse(cr,uid,ids)
for reg_id in reg_ids:
src = reg_id.event_id.reply_to or False
dest = [reg_id.email_from]
dest = []
if reg_id.email_from:
dest += [reg_id.email_from]
if reg_id.email_cc:
dest += [reg_id.email_cc]
if dest and src:
@ -231,11 +233,13 @@ class event_registration(osv.osv):
raise osv.except_osv(_('Error!'), _('You must define a reply-to address in order to mail the participant. You can do this in the Mailing tab of your event. Note that this is also the place where you can configure your event to not send emails automaticly while registering'))
return False
def mail_user(self,cr,uid,ids):
reg_ids=self.browse(cr,uid,ids)
def mail_user(self, cr, uid, ids):
reg_ids = self.browse(cr, uid, ids)
for reg_id in reg_ids:
src = reg_id.event_id.reply_to or False
dest = [reg_id.email_from]
dest = []
if reg_id.email_from:
dest += [reg_id.email_from]
if reg_id.email_cc:
dest += [reg_id.email_cc]
if reg_id.event_id.mail_auto_confirm or reg_id.event_id.mail_auto_registr:

View File

@ -68,8 +68,11 @@ class event_make_invoice(osv.osv_memory):
inv_reject = inv_reject + 1
inv_rej_reason += "ID "+str(reg.id)+": Registration doesn't have any partner to invoice. \n"
continue
partner_address_list = reg.partner_invoice_id and self.pool.get('res.partner').address_get(cr, uid, [reg.partner_invoice_id.id], adr_pref=['invoice'])
partner_address_id = partner_address_list['invoice']
else:
val_invoice = pool_obj.get('account.invoice').onchange_partner_id(cr, uid, [], 'out_invoice', reg.partner_invoice_id.id, False, False)
val_invoice['value'].update({'partner_id': reg.partner_invoice_id.id})
partner_address_id = val_invoice['value']['address_invoice_id']
if not partner_address_id:
inv_reject = inv_reject + 1
inv_rej_reason += "ID "+str(reg.id)+": Registered partner doesn't have an address to make the invoice. \n"
@ -82,8 +85,9 @@ class event_make_invoice(osv.osv_memory):
tax_ids.append(tax.id)
vals = value['value']
c_name = reg.contact_id and ('-' + self.pool.get('res.partner.contact').name_get(cr, uid, [reg.contact_id.id])[0][1]) or ''
vals.update({
'name': reg.name,
'name': reg.invoice_label + '-' + c_name,
'price_unit': reg.unit_price,
'quantity': reg.nb_register,
'product_id':reg.event_id.product_id.id,
@ -91,23 +95,14 @@ class event_make_invoice(osv.osv_memory):
})
inv_line_ids = obj_event_reg._create_invoice_lines(cr, uid, [reg.id], vals)
inv = {
'name': reg.invoice_label,
val_invoice['value'].update({
'origin': reg.invoice_label,
'type': 'out_invoice',
'reference': False,
'account_id': reg.partner_invoice_id.property_account_receivable.id,
'partner_id': reg.partner_invoice_id.id,
'address_invoice_id':partner_address_id,
'address_contact_id':partner_address_id,
'invoice_line': [(6,0,[inv_line_ids])],
'currency_id' :reg.partner_invoice_id.property_product_pricelist.currency_id.id,
'comment': "",
'payment_term':reg.partner_invoice_id.property_payment_term.id,
'fiscal_position': reg.partner_invoice_id.property_account_position.id
}
})
inv_id = inv_obj.create(cr, uid, inv)
inv_id = inv_obj.create(cr, uid, val_invoice['value'])
list_inv.append(inv_id)
obj_event_reg.write(cr, uid, reg.id, {'invoice_id': inv_id, 'state': 'done'})
obj_event_reg._history(cr, uid, [reg.id], 'Invoiced', history=True)

View File

@ -153,7 +153,7 @@
</search>
</field>
</record>
<record id="hr_contract_view_form" model="ir.ui.view">
<field name="name">hr.contract.view.form</field>
<field name="model">hr.contract</field>

View File

@ -21,7 +21,7 @@
#
##############################################################################
import time
import datetime
import pooler
import netsvc
from osv import fields, osv
@ -182,14 +182,14 @@ class hr_holidays(osv.osv):
}
return result
def _get_number_of_days(date_from, date_to):
def _get_number_of_days(self, date_from, date_to):
"""Returns a float equals to the timedelta between two dates given as string."""
DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
from_dt = datetime.datetime.strptime(date_from, DATETIME_FORMAT)
to_dt = datetime.datetime.strptime(date_to, DATETIME_FORMAT)
timedelta = to_dt - from_dt
diff_day = timedelta.days + float(timedelata.seconds) / 86400
diff_day = timedelta.days + float(timedelta.seconds) / 86400
return diff_day
def _update_user_holidays(self, cr, uid, ids):
@ -204,14 +204,16 @@ class hr_holidays(osv.osv):
self.unlink(cr, uid, list_ids)
def _check_date(self, cr, uid, ids):
if ids:
cr.execute('select number_of_days_temp from hr_holidays where id in ('+','.join(map(str, ids))+')')
res = cr.fetchall()
if res and res[0][0] and res[0][0] < 0:
for rec in self.read(cr, uid, ids, ['number_of_days_temp','date_from','date_to']):
if rec['number_of_days_temp'] < 0:
return False
date_from = time.strptime(rec['date_from'], '%Y-%m-%d %H:%M:%S')
date_to = time.strptime(rec['date_to'], '%Y-%m-%d %H:%M:%S')
if date_from > date_to:
return False
return True
_constraints = [(_check_date, 'Start date should not be larger than end date! ', ['number_of_days'])]
_constraints = [(_check_date, 'Start date should not be larger than end date!\nNumber of Days should be greater than 1!', ['number_of_days_temp'])]
def unlink(self, cr, uid, ids, context={}):
leave_obj = self.pool.get('resource.calendar.leaves')
@ -235,7 +237,7 @@ class hr_holidays(osv.osv):
return result
def onchange_date_to(self, cr, uid, ids, date_from, date_to):
return onchange_date_from(cr, uid, ids, date_to, date_from)
return self.onchange_date_from(cr, uid, ids, date_to, date_from)
def onchange_sec_id(self, cr, uid, ids, status, context={}):
warning = {}

View File

@ -60,7 +60,7 @@ class hr_analytic_timesheet(osv.osv):
# if prod_id and unit_amount:
if prod_id:
# find company
company_id=self.pool.get('res.company')._company_default_get(cr, uid, 'account.analytic.line', context)
company_id=self.pool.get('res.company')._company_default_get(cr, uid, 'account.analytic.line', context=context)
res = self.pool.get('account.analytic.line').on_change_unit_amount(cr, uid, id, prod_id, unit_amount,company_id,unit, context)
return res

View File

@ -364,7 +364,7 @@ class hr_timesheet_line(osv.osv):
res[line_id] = False
return res
def _sheet_search(self, cursor, user, obj, name, args, context):
def _sheet_search(self, cursor, user, obj, name, args, context=None):
if not len(args):
return []
sheet_obj = self.pool.get('hr_timesheet_sheet.sheet')
@ -482,7 +482,7 @@ class hr_attendance(osv.osv):
res[line_id] = False
return res
def _sheet_search(self, cursor, user, obj, name, args, context={}):
def _sheet_search(self, cursor, user, obj, name, args, context=None):
if not len(args):
return []
sheet_obj = self.pool.get('hr_timesheet_sheet.sheet')

View File

@ -7029,8 +7029,8 @@
<field name="description">V-EXTRA 0</field>
<field eval="0.00" name="amount"/>
<field name="type">percent</field>
<field name="base_code_id" ref="vat_code_a47"/>
<field name="ref_base_code_id" ref="vat_code_a49"/>
<field name="base_code_id" ref="vat_code_a46"/>
<field name="ref_base_code_id" ref="vat_code_a48"/>
<field name="type_tax_use">sale</field>
</record>
<!-- Purchases VAT -->

View File

@ -36,7 +36,7 @@ class l10n_be_vat_declaration(osv.osv_memory):
'file_save': fields.binary('Save File'),
'ask_resitution': fields.boolean('Ask Restitution'),
'ask_payment': fields.boolean('Ask Payment'),
'client_nihil': fields.boolean('Last Declaration of Entreprise',help='Thick this case only if it concerns only the last statement on the civil or cessation of activity'),
'client_nihil': fields.boolean('Last Declaration of Enterprise',help='Tick this case only if it concerns only the last statement on the civil or cessation of activity'),
}
_defaults = {

View File

@ -14,11 +14,11 @@
<field name="arch" type="xml">
<form string="Select Period">
<group colspan="4" >
<field name="period_id" select="1"/>
<field name="ask_resitution"/>
<field name="ask_payment"/>
<field name="client_nihil"/>
<button colspan="1" name="create_xml" string="Create XML" type="object"/>
<field name="period_id" select="1"/>
<field name="ask_resitution"/>
<field name="ask_payment"/>
<field name="client_nihil"/>
<button colspan="1" name="create_xml" string="Create XML" type="object" default_focus="1"/>
</group>
<separator string="XML Flie has been Created." colspan="4"/>
<group colspan="4" >

View File

@ -28,7 +28,7 @@ import decimal_precision as dp
STATE = [
('none', 'Non Member'),
('canceled', 'Canceled Member'),
('canceled', 'Cancelled Member'),
('old', 'Old Member'),
('waiting', 'Waiting Member'),
('invoiced', 'Invoiced Member'),
@ -162,8 +162,9 @@ class membership_line(osv.osv):
res = {}
for line in self.browse(cr, uid, ids):
cr.execute('''
SELECT i.state FROM
account_invoice i WHERE
SELECT i.state, i.id FROM
account_invoice i
WHERE
i.id = (
SELECT l.invoice_id FROM
account_invoice_line l WHERE
@ -186,6 +187,10 @@ class membership_line(osv.osv):
state = 'invoiced'
elif istate == 'paid':
state = 'paid'
inv = self.pool.get('account.invoice').browse(cr, uid, fetched[1])
for payment in inv.payment_ids:
if payment.invoice and payment.invoice.type == 'out_refund':
state = 'canceled'
elif istate == 'cancel':
state = 'canceled'
res[line.id] = state
@ -253,11 +258,15 @@ class Partner(osv.osv):
s = 4
if partner_data.member_lines:
for mline in partner_data.member_lines:
if mline.date_from <= today and mline.date_to >= today:
if mline.date_to >= today:
if mline.account_invoice_line and mline.account_invoice_line.invoice_id:
mstate = mline.account_invoice_line.invoice_id.state
if mstate == 'paid':
s = 0
inv = mline.account_invoice_line.invoice_id
for payment in inv.payment_ids:
if payment.invoice.type == 'out_refund':
s = 2
break
elif mstate == 'open' and s!=0:
s = 1
@ -332,14 +341,12 @@ class Partner(osv.osv):
'''Return the cancel date of membership'''
res = {}
member_line_obj = self.pool.get('membership.membership_line')
for partner_id in ids:
line_id = member_line_obj.search(cr, uid, [('partner', '=', partner_id)],
limit=1, order='date_cancel')
if line_id:
res[partner_id] = member_line_obj.read(cr, uid, line_id[0],
['date_cancel'])['date_cancel']
else:
res[partner_id] = False
for partner in self.browse(cr, uid, ids, context=context):
res[partner.id] = False
if partner.membership_state == 'canceled':
line_id = member_line_obj.search(cr, uid, [('partner', '=', partner.id)],limit=1, order='date_cancel')
if line_id:
res[partner.id] = member_line_obj.read(cr, uid, line_id[0],['date_cancel'])['date_cancel']
return res
def _get_partners(self, cr, uid, ids, context={}):
@ -349,20 +356,23 @@ class Partner(osv.osv):
ids+=ids2
return ids
def __get_membership_state(self, *args, **kwargs):
return self._membership_state(*args, **kwargs)
_columns = {
'associate_member': fields.many2one('res.partner', 'Associate member'),
'member_lines': fields.one2many('membership.membership_line', 'partner', 'Membership'),
'free_member': fields.boolean('Free member'),
'membership_amount': fields.float(
'Membership amount', digites=(16, 2),
'Membership amount', digits=(16, 2),
help='The price negociated by the partner'),
'membership_state': fields.function(
_membership_state, method = True,
__get_membership_state, method = True,
string = 'Current membership state', type = 'selection',
selection = STATE ,store = {
'account.invoice':(_get_invoice_partner,['state'], 10),
'membership.membership_line':(_get_partner_id,['state'], 10),
'res.partner':(_get_partners, ['free_member', 'membership_state'], 10)
'res.partner':(_get_partners, ['free_member', 'membership_state','associate_member'], 10)
}
),
'membership_start': fields.function(
@ -388,7 +398,7 @@ class Partner(osv.osv):
_membership_cancel, method = True,
string = 'Cancel membership date', type='date',
store = {
'account.invoice':(_get_invoice_partner,['state'], 10),
'account.invoice':(_get_invoice_partner,['state'], 11),
'membership.membership_line':(_get_partner_id,['state'], 10),
'res.partner':(lambda self,cr,uid,ids,c={}:ids, ['free_member'], 10)
}
@ -412,7 +422,16 @@ class Partner(osv.osv):
_constraints = [
(_check_recursion, 'Error ! You can not create recursive associated members.', ['associate_member'])
]
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
if context is None:
context = {}
default = default.copy()
default['member_lines'] = []
return super(Partner, self).copy(cr, uid, id, default, context)
Partner()
class product_template(osv.osv):
@ -547,80 +566,6 @@ class ReportPartnerMemberYear(osv.osv):
ReportPartnerMemberYear()
class ReportPartnerMemberYearNew(osv.osv):
'''New Membership by Years'''
_name = 'report.partner_member.year_new'
_description = __doc__
_auto = False
_rec_name = 'year'
_columns = {
'year': fields.char('Year', size='4', readonly=True, select=1),
'canceled_number': fields.integer('Canceled', readonly=True),
'waiting_number': fields.integer('Waiting', readonly=True),
'invoiced_number': fields.integer('Invoiced', readonly=True),
'paid_number': fields.integer('Paid', readonly=True),
'canceled_amount': fields.float('Canceled', digits=(16, 2), readonly=True),
'waiting_amount': fields.float('Waiting', digits=(16, 2), readonly=True),
'invoiced_amount': fields.float('Invoiced', digits=(16, 2), readonly=True),
'paid_amount': fields.float('Paid', digits=(16, 2), readonly=True),
'currency': fields.many2one('res.currency', 'Currency', readonly=True,
select=2),
}
def init(self, cr):
'''Create the view'''
cr.execute("""
CREATE OR REPLACE VIEW report_partner_member_year AS (
SELECT
MIN(id) AS id,
COUNT(ncanceled) as canceled_number,
COUNT(npaid) as paid_number,
COUNT(ninvoiced) as invoiced_number,
COUNT(nwaiting) as waiting_number,
SUM(acanceled) as canceled_amount,
SUM(apaid) as paid_amount,
SUM(ainvoiced) as invoiced_amount,
SUM(awaiting) as waiting_amount,
year,
currency
FROM (SELECT
CASE WHEN ai.state = 'cancel' THEN ml.id END AS ncanceled,
CASE WHEN ai.state = 'paid' THEN ml.id END AS npaid,
CASE WHEN ai.state = 'open' THEN ml.id END AS ninvoiced,
CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
THEN ml.id END AS nwaiting,
CASE WHEN ai.state = 'cancel'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS acanceled,
CASE WHEN ai.state = 'paid'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS apaid,
CASE WHEN ai.state = 'open'
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS ainvoiced,
CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
ELSE 0 END AS awaiting,
TO_CHAR(ml.date_from, 'YYYY') AS year,
ai.currency_id AS currency,
MIN(ml.id) AS id
FROM membership_membership_line ml
JOIN (account_invoice_line ail
LEFT JOIN account_invoice ai
ON (ail.invoice_id = ai.id))
ON (ml.account_invoice_line = ail.id)
JOIN res_partner p
ON (ml.partner = p.id)
GROUP BY TO_CHAR(ml.date_from, 'YYYY'), ai.state,
ai.currency_id, ml.id) AS foo
GROUP BY year, currency)
""")
ReportPartnerMemberYear()
class ReportPartnerMemberYearNew(osv.osv):
'''New Membership by Years'''
@ -703,28 +648,30 @@ ReportPartnerMemberYearNew()
class account_invoice_line(osv.osv):
_inherit='account.invoice.line'
def write(self, cr, uid, ids, vals, context=None):
if not context:
context={}
res = super(account_invoice_line, self).write(cr, uid, ids, vals, context=context)
member_line_obj = self.pool.get('membership.membership_line')
for line in self.browse(cr, uid, ids):
ml_ids = member_line_obj.search(cr, uid, [('account_invoice_line','=',line.id)])
if line.product_id and line.product_id.membership and not ml_ids:
# Product line has changed to a membership product
date_from = line.product_id.membership_date_from
date_to = line.product_id.membership_date_to
if line.invoice_id.date_invoice > date_from and line.invoice_id.date_invoice < date_to:
date_from = line.invoice_id.date_invoice
line_id = member_line_obj.create(cr, uid, {
'partner': line.invoice_id.partner_id.id,
'date_from': date_from,
'date_to': date_to,
'account_invoice_line': line.id,
})
if line.product_id and not line.product_id.membership and ml_ids:
# Product line has changed to a non membership product
member_line_obj.unlink(cr, uid, ml_ids, context=context)
if line.invoice_id.type == 'out_invoice':
ml_ids = member_line_obj.search(cr, uid, [('account_invoice_line','=',line.id)])
if line.product_id and line.product_id.membership and not ml_ids:
# Product line has changed to a membership product
date_from = line.product_id.membership_date_from
date_to = line.product_id.membership_date_to
if line.invoice_id.date_invoice > date_from and line.invoice_id.date_invoice < date_to:
date_from = line.invoice_id.date_invoice
line_id = member_line_obj.create(cr, uid, {
'partner': line.invoice_id.partner_id.id,
'date_from': date_from,
'date_to': date_to,
'account_invoice_line': line.id,
})
if line.product_id and not line.product_id.membership and ml_ids:
# Product line has changed to a non membership product
member_line_obj.unlink(cr, uid, ml_ids, context=context)
return res
def unlink(self, cr, uid, ids, context=None):
@ -739,20 +686,21 @@ class account_invoice_line(osv.osv):
def create(self, cr, uid, vals, context={}):
result = super(account_invoice_line, self).create(cr, uid, vals, context)
line = self.browse(cr, uid, result)
member_line_obj = self.pool.get('membership.membership_line')
ml_ids = member_line_obj.search(cr, uid, [('account_invoice_line','=',line.id)])
if line.product_id and line.product_id.membership and not ml_ids:
# Product line is a membership product
date_from = line.product_id.membership_date_from
date_to = line.product_id.membership_date_to
if line.invoice_id.date_invoice > date_from and line.invoice_id.date_invoice < date_to:
date_from = line.invoice_id.date_invoice
line_id = member_line_obj.create(cr, uid, {
'partner': line.invoice_id.partner_id and line.invoice_id.partner_id.id or False,
'date_from': date_from,
'date_to': date_to,
'account_invoice_line': line.id,
})
if line.invoice_id.type == 'out_invoice':
member_line_obj = self.pool.get('membership.membership_line')
ml_ids = member_line_obj.search(cr, uid, [('account_invoice_line','=',line.id)])
if line.product_id and line.product_id.membership and not ml_ids:
# Product line is a membership product
date_from = line.product_id.membership_date_from
date_to = line.product_id.membership_date_to
if line.invoice_id.date_invoice > date_from and line.invoice_id.date_invoice < date_to:
date_from = line.invoice_id.date_invoice
line_id = member_line_obj.create(cr, uid, {
'partner': line.invoice_id.partner_id and line.invoice_id.partner_id.id or False,
'date_from': date_from,
'date_to': date_to,
'account_invoice_line': line.id,
})
return result
account_invoice_line()

View File

@ -53,8 +53,8 @@
<page string="Membership">
<field name="membership" readonly="0"/>
<newline/>
<field name="membership_date_from" readonly="0"/>
<field name="membership_date_to" readonly="0"/>
<field name="membership_date_from" readonly="0" attrs="{'required':[('membership','=',True)]}"/>
<field name="membership_date_to" readonly="0" attrs="{'required':[('membership','=',True)]}"/>
</page>
</page>
</field>

View File

@ -170,7 +170,7 @@
<field name="product_qty">1.0</field>
<field name="routing_id" ref="mrp_routing_2"/>
<field name="type">normal</field>
<field model="product.product" name="product_id" search="[('default_code','=','CPU_GEN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_cpu_gen"/>
</record>
<record id="mrp_bom_1" model="mrp.bom">
@ -179,21 +179,21 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="routing_id" ref="mrp_routing_0"/>
<field model="product.product" name="product_id" search="[('default_code','=','PC2')]"/>
<field model="product.product" name="product_id" ref="product.product_product_pc2" />
</record>
<record id="mrp_bom_2" model="mrp.bom">
<field name="name">Assembly Medium PC</field>
<field name="sequence">8</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field model="product.product" name="product_id" search="[('default_code','=','PC3')]"/>
<field model="product.product" name="product_id" ref="product.product_product_pc3"/>
</record>
<record id="mrp_bom_3" model="mrp.bom">
<field name="name">Assembly Customizable PC</field>
<field name="sequence">11</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field model="product.product" name="product_id" search="[('default_code','=','PC4')]"/>
<field model="product.product" name="product_id" ref="product.product_product_pc4"/>
</record>
<record id="mrp_bom_4" model="mrp.bom">
<field name="name">HDD on demand</field>
@ -201,7 +201,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
<field model="product.product" name="product_id" search="[('default_code','=','HDD_GEN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_20"/>
</record>
<record id="mrp_bom_5" model="mrp.bom">
<field name="name">RAM on demand</field>
@ -209,7 +209,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
<field model="product.product" name="product_id" search="[('default_code','=','RAM_GEN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_21"/>
</record>
<record id="mrp_bom_6" model="mrp.bom">
<field name="name">HDD on demand</field>
@ -217,7 +217,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
<field model="product.product" name="product_id" search="[('default_code','=','HDD_GEN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_20"/>
</record>
<record id="mrp_bom_7" model="mrp.bom">
<field name="name">HDD on demand</field>
@ -225,7 +225,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
<field model="product.product" name="product_id" search="[('default_code','=','HDD_GEN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_20"/>
</record>
<record id="mrp_bom_8" model="mrp.bom">
<field name="name">HDD Seagate</field>
@ -233,7 +233,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field model="product.product" name="product_id" search="[('default_code','=','HDD1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_hdd1"/>
</record>
<record id="mrp_bom_9" model="mrp.bom">
<field name="name">Assembly Basic PC</field>
@ -242,14 +242,14 @@
<field name="product_qty">1.0</field>
<field name="routing_id" ref="mrp_routing_0"/>
<field name="type">normal</field>
<field model="product.product" name="product_id" search="[('default_code','=','PC1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_pc1"/>
</record>
<record id="mrp_bom_10" model="mrp.bom">
<field name="name">Complete PC with peripherals</field>
<field name="sequence">33</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field model="product.product" name="product_id" search="[('default_code','=','PC0')]"/>
<field model="product.product" name="product_id" ref="product.product_product_23"/>
</record>
<record id="mrp_bom_11" model="mrp.bom">
<field name="name">RAM on demand</field>
@ -257,7 +257,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="type">phantom</field>
<field model="product.product" name="product_id" search="[('default_code','=','RAM_GEN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_23"/>
</record>
<record id="mrp_bom_13" model="mrp.bom">
@ -265,7 +265,7 @@
<field name="sequence">38</field>
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field model="product.product" name="product_id" search="[('default_code','=','CPU2')]"/>
<field model="product.product" name="product_id" ref="product.product_product_cpu3"/>
</record>
<record id="mrp_bom_kit" model="mrp.bom">
@ -276,7 +276,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_10"/>
<field model="product.product" name="product_id" search="[('default_code','=','MOU')]"/>
<field model="product.product" name="product_id" ref="product.product_product_25"/>
</record>
<record id="mrp_bom_clavier" model="mrp.bom">
<field name="name">Keyboard</field>
@ -284,7 +284,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_kit"/>
<field model="product.product" name="product_id" search="[('default_code','=','KEYA')]"/>
<field model="product.product" name="product_id" ref="product.product_product_24"/>
</record>
<record id="mrp_bom_mouse" model="mrp.bom">
<field name="name">Mouse</field>
@ -292,7 +292,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_kit"/>
<field model="product.product" name="product_id" search="[('default_code','=','MOU')]"/>
<field model="product.product" name="product_id" ref="product.product_product_25"/>
</record>
<record id="mrp_bom_16" model="mrp.bom">
<field name="name">Moon PC</field>
@ -300,7 +300,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_10"/>
<field model="product.product" name="product_id" search="[('default_code','=','PC1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_pc1"/>
</record>
<record id="mrp_bom_18" model="mrp.bom">
<field name="name">Mainboard ASUStek A7N8X</field>
@ -308,7 +308,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_13"/>
<field model="product.product" name="product_id" search="[('default_code','=','MB2')]"/>
<field model="product.product" name="product_id" ref="product.product_product_mb2"/>
</record>
<record id="mrp_bom_19" model="mrp.bom">
<field name="name">Processor AMD Athlon 2200+</field>
@ -316,7 +316,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_13"/>
<field model="product.product" name="product_id" search="[('default_code','=','CPU2')]"/>
<field model="product.product" name="product_id" ref="product.product_product_cpu2"/>
</record>
<record id="mrp_bom_1900" model="mrp.bom">
<field name="name">Regular Case Fan</field>
@ -324,7 +324,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_13"/>
<field model="product.product" name="product_id" search="[('default_code','=','FAN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_fan"/>
</record>
<record id="mrp_bom_23" model="mrp.bom">
<field name="name">DDR 256MB PC333</field>
@ -332,7 +332,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_11"/>
<field model="product.product" name="product_id" search="[('default_code','=','RAM')]"/>
<field model="product.product" name="product_id" ref="product.product_product_ram"/>
</record>
<record id="mrp_bom_1901" model="mrp.bom">
<field name="name">DDR 512MB PC400</field>
@ -340,7 +340,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_13"/>
<field model="product.product" name="product_id" search="[('default_code','=','RAM512')]"/>
<field model="product.product" name="product_id" ref="product.product_product_ram512"/>
</record>
<record id="mrp_bom_22" model="mrp.bom">
<field name="name">DDR 1024MB PC400</field>
@ -348,7 +348,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_5"/>
<field model="product.product" name="product_id" search="[('default_code','=','RAM512')]"/>
<field model="product.product" name="product_id" ref="product.product_product_ram512"/>
</record>
<record id="mrp_bom_24" model="mrp.bom">
<field name="name">HDD Seagate 7200.8 80GB</field>
@ -356,7 +356,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_7"/>
<field model="product.product" name="product_id" search="[('default_code','=','HDD3')]"/>
<field model="product.product" name="product_id" ref="product.product_product_hdd3"/>
</record>
<record id="mrp_bom_25" model="mrp.bom">
<field name="name">HDD Seagate 7200.8 120GB</field>
@ -365,7 +365,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_4"/>
<field model="product.product" name="product_id" search="[('default_code','=','HDD1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_hdd1"/>
</record>
<record id="mrp_bom_26" model="mrp.bom">
<field name="name">RAM on demand</field>
@ -373,7 +373,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_3"/>
<field model="product.product" name="product_id" search="[('default_code','=','RAM_GEN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_21"/>
</record>
<record id="mrp_bom_27" model="mrp.bom">
<field name="name">HDD on demand</field>
@ -381,7 +381,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_3"/>
<field model="product.product" name="product_id" search="[('default_code','=','HDD_GEN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_20"/>
</record>
<record id="mrp_bom_28" model="mrp.bom">
<field name="name">ATX middle-size case</field>
@ -390,7 +390,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_3"/>
<field model="product.product" name="product_id" search="[('default_code','=','TOW1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_tow1"/>
</record>
<record id="mrp_bom_29" model="mrp.bom">
<field name="name">Processor on demand</field>
@ -399,7 +399,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_3"/>
<field model="product.product" name="product_id" search="[('default_code','=','CPU_GEN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_cpu_gen"/>
</record>
<record id="mrp_bom_30" model="mrp.bom">
<field name="name">ATX Middle-size case</field>
@ -408,7 +408,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_2"/>
<field model="product.product" name="product_id" search="[('default_code','=','TOW1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_tow1"/>
</record>
<record id="mrp_bom_31" model="mrp.bom">
<field name="name">HDD Seagate 7200.8 80GB</field>
@ -417,7 +417,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_2"/>
<field model="product.product" name="product_id" search="[('default_code','=','HDD1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_hdd1"/>
</record>
<record id="mrp_bom_32" model="mrp.bom">
<field name="name">High speed processor config</field>
@ -426,7 +426,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_2"/>
<field model="product.product" name="product_id" search="[('default_code','=','CPU2')]"/>
<field model="product.product" name="product_id" ref="product.product_product_cpu2"/>
</record>
<record id="mrp_bom_33" model="mrp.bom">
<field name="name">HDD Seagate 7200.8 120GB</field>
@ -435,7 +435,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_6"/>
<field model="product.product" name="product_id" search="[('default_code','=','HDD2')]"/>
<field model="product.product" name="product_id" ref="product.product_product_hdd2"/>
</record>
<record id="mrp_bom_34" model="mrp.bom">
<field name="name">Regular processor config</field>
@ -444,7 +444,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_1"/>
<field model="product.product" name="product_id" search="[('default_code','=','CPU_GEN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_cpu_gen"/>
</record>
<record id="mrp_bom_35" model="mrp.bom">
<field name="name">ATX middle-size case</field>
@ -453,7 +453,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_1"/>
<field model="product.product" name="product_id" search="[('default_code','=','TOW1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_tow1"/>
</record>
<record id="mrp_bom_36" model="mrp.bom">
<field name="name">HDD Seagate 7200.8 120GB</field>
@ -462,7 +462,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_1"/>
<field model="product.product" name="product_id" search="[('default_code','=','HDD2')]"/>
<field model="product.product" name="product_id" ref="product.product_product_hdd2"/>
</record>
<record id="mrp_bom_processor" model="mrp.bom">
<field name="name">processor</field>
@ -471,7 +471,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_0"/>
<field model="product.product" name="product_id" search="[('default_code','=','CPU1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_cpu1"/>
</record>
<record id="mrp_bom_38" model="mrp.bom">
<field name="name">mainboard</field>
@ -480,7 +480,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_0"/>
<field model="product.product" name="product_id" search="[('default_code','=','MB1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_mb1"/>
</record>
<record id="mrp_bom_fan" model="mrp.bom">
<field name="name">fan</field>
@ -489,7 +489,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_0"/>
<field model="product.product" name="product_id" search="[('default_code','=','FAN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_fan"/>
</record>
<record id="mrp_bom_ram" model="mrp.bom">
<field name="name">RAM</field>
@ -498,7 +498,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_0"/>
<field model="product.product" name="product_id" search="[('default_code','=','RAM')]"/>
<field model="product.product" name="product_id" ref="product.product_product_ram"/>
</record>
<record id="mrp_bom_41" model="mrp.bom">
<field name="name">Regular processor config</field>
@ -507,7 +507,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_9"/>
<field model="product.product" name="product_id" search="[('default_code','=','CPU_GEN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_cpu_gen"/>
</record>
<record id="mrp_bom_42" model="mrp.bom">
<field name="name">HDD Seagate 7200.8 80GB</field>
@ -516,7 +516,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_9"/>
<field model="product.product" name="product_id" search="[('default_code','=','HDD1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_hdd1"/>
</record>
<record id="mrp_bom_43" model="mrp.bom">
<field name="name">ATX Middle-size case</field>
@ -525,7 +525,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_9"/>
<field model="product.product" name="product_id" search="[('default_code','=','TOW1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_tow1"/>
</record>
<record id="mrp_bom_kit2" model="mrp.bom">
@ -536,7 +536,7 @@
<field name="product_qty">1.0</field>
<field name="type">normal</field>
<field name="bom_id" ref="mrp_bom_9"/>
<field model="product.product" name="product_id" search="[('default_code','=','KIT0')]"/>
<field model="product.product" name="product_id" ref="product.product_product_26"/>
</record>
<record id="mrp_bom_mouse2" model="mrp.bom">
<field name="name">Mouse</field>
@ -544,7 +544,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_kit2"/>
<field model="product.product" name="product_id" search="[('default_code','=','MOU')]"/>
<field model="product.product" name="product_id" ref="product.product_product_25"/>
</record>
<record id="mrp_bom_clavier2" model="mrp.bom">
<field name="name">Keyboard</field>
@ -552,7 +552,7 @@
<field name="product_uom" ref="product.product_uom_unit"/>
<field name="product_qty">1.0</field>
<field name="bom_id" ref="mrp_bom_kit2"/>
<field model="product.product" name="product_id" search="[('default_code','=','KEYA')]"/>
<field model="product.product" name="product_id" ref="product.product_product_24"/>
</record>
</data>

View File

@ -9,7 +9,7 @@
<field name="product_min_qty">5.0</field>
<field model="product.uom" name="product_uom" search="[]"/>
<field model="stock.warehouse" name="warehouse_id" search="[]"/>
<field model="product.product" name="product_id" search="[('default_code','=','MB1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_mb1"/>
<field name="location_id" ref="stock.stock_location_stock"/>
</record>
<record id="stock_warehouse_orderpoint_1" model="stock.warehouse.orderpoint">
@ -17,7 +17,7 @@
<field name="product_min_qty">10.0</field>
<field model="product.uom" name="product_uom" search="[]"/>
<field model="stock.warehouse" name="warehouse_id" search="[]"/>
<field model="product.product" name="product_id" search="[('default_code','=','CPU1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_cpu1"/>
<field name="location_id" ref="stock.stock_location_stock"/>
</record>
<record id="stock_warehouse_orderpoint_2" model="stock.warehouse.orderpoint">
@ -25,7 +25,7 @@
<field name="product_min_qty">10.0</field>
<field model="product.uom" name="product_uom" search="[]"/>
<field model="stock.warehouse" name="warehouse_id" search="[]"/>
<field model="product.product" name="product_id" search="[('default_code','=','HDD1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_hdd1"/>
<field name="location_id" ref="stock.stock_location_stock"/>
</record>
<record id="stock_warehouse_orderpoint_3" model="stock.warehouse.orderpoint">
@ -33,7 +33,7 @@
<field name="product_min_qty">10.0</field>
<field model="product.uom" name="product_uom" search="[]"/>
<field model="stock.warehouse" name="warehouse_id" search="[]"/>
<field model="product.product" name="product_id" search="[('default_code','=','FAN')]"/>
<field model="product.product" name="product_id" ref="product.product_product_fan"/>
<field name="location_id" ref="stock.stock_location_stock"/>
</record>
<record id="stock_warehouse_orderpoint_4" model="stock.warehouse.orderpoint">
@ -41,7 +41,7 @@
<field name="product_min_qty">3.0</field>
<field model="product.uom" name="product_uom" search="[]"/>
<field model="stock.warehouse" name="warehouse_id" search="[]"/>
<field model="product.product" name="product_id" search="[('default_code','=','PC1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_pc1"/>
<field name="location_id" ref="stock.stock_location_stock"/>
</record>
<record id="stock_warehouse_orderpoint_5" model="stock.warehouse.orderpoint">
@ -49,7 +49,7 @@
<field name="product_min_qty">10.0</field>
<field model="product.uom" name="product_uom" search="[]"/>
<field model="stock.warehouse" name="warehouse_id" search="[]"/>
<field model="product.product" name="product_id" search="[('default_code','=','TOW1')]"/>
<field model="product.product" name="product_id" ref="product.product_product_tow1"/>
<field name="location_id" ref="stock.stock_location_stock"/>
</record>
</data>

View File

@ -27,6 +27,77 @@ import ir
import netsvc
import time
class stock_warehouse_orderpoint(osv.osv):
"""
Defines Minimum stock rules.
"""
_name = "stock.warehouse.orderpoint"
_description = "Orderpoint minimum rule"
_columns = {
'name': fields.char('Name', size=32, required=True),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the orderpoint without removing it."),
'logic': fields.selection([('max','Order to Max'),('price','Best price (not yet active!)')], 'Reordering Mode', required=True),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True, ondelete="cascade"),
'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="cascade"),
'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade', domain=[('type','=','product')]),
'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
'product_min_qty': fields.float('Min Quantity', required=True,
help="When the virtual stock goes belong the Min Quantity, Open ERP generates "\
"a procurement to bring the virtual stock to the Max Quantity."),
'product_max_qty': fields.float('Max Quantity', required=True,
help="When the virtual stock goes belong the Min Quantity, Open ERP generates "\
"a procurement to bring the virtual stock to the Max Quantity."),
'qty_multiple': fields.integer('Qty Multiple', required=True,
help="The procurement quantity will by rounded up to this multiple."),
'procurement_id': fields.many2one('mrp.procurement', 'Latest procurement', ondelete="set null"),
'company_id': fields.many2one('res.company','Company',required=True),
}
_defaults = {
'active': lambda *a: 1,
'logic': lambda *a: 'max',
'qty_multiple': lambda *a: 1,
'name': lambda x,y,z,c: x.pool.get('ir.sequence').get(y,z,'mrp.warehouse.orderpoint') or '',
'product_uom': lambda sel, cr, uid, context: context.get('product_uom', False),
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.warehouse.orderpoint', context=c)
}
_sql_constraints = [
('qty_multiple_check', 'CHECK( qty_multiple > 0 )', _('Qty Multiple must be greater than zero.')),
]
def onchange_warehouse_id(self, cr, uid, ids, warehouse_id, context={}):
""" Finds location id for changed warehouse.
@param warehouse_id: Changed id of warehouse.
@return: Dictionary of values.
"""
if warehouse_id:
w = self.pool.get('stock.warehouse').browse(cr, uid, warehouse_id, context)
v = {'location_id': w.lot_stock_id.id}
return {'value': v}
return {}
def onchange_product_id(self, cr, uid, ids, product_id, context={}):
""" Finds UoM for changed product.
@param product_id: Changed id of product.
@return: Dictionary of values.
"""
if product_id:
prod = self.pool.get('product.product').browse(cr,uid,product_id)
v = {'product_uom': prod.uom_id.id}
return {'value': v}
return {}
def copy(self, cr, uid, id, default=None,context={}):
if not default:
default = {}
default.update({
'name': self.pool.get('ir.sequence').get(cr, uid, 'mrp.warehouse.orderpoint') or '',
})
return super(stock_warehouse_orderpoint, self).copy(cr, uid, id, default, context)
stock_warehouse_orderpoint()
class StockMove(osv.osv):
_inherit = 'stock.move'

View File

@ -20,8 +20,6 @@
##############################################################################
from osv import fields, osv
from tools.translate import _
import netsvc
class mrp_product_produce(osv.osv_memory):
_name = "mrp.product.produce"

View File

@ -27,19 +27,15 @@
'description': """
This module allows Just In Time computation of procurement orders.
If you install this module, you will not have to run the procurement scheduler
manually anymore, or wait for it to execute.
Each procurement order (resulting from a sale order, for instance) will be computed
when confirmed, without waiting for the procurement scheduler to run.
Warning: this does not take into account minimum stock rules (order points), which still
require to run the appropriate scheduler, or wait for it to run nightly.
Note that the procurement computation can be resource-intensive, so you may
want to be careful with this, depending on your mrp configuration and system
usage.
If you install this module, you will not have to run the regular procurement
scheduler anymore (but you still need to run the minimum order point rule
scheduler, or for example let it run daily.)
All procurement orders will be processed immediately, which could in some
cases entail a small performance impact.
It may also increase your stock size because products are reserved as soon
as possible. In that case, you can not use priorities any more.
as possible and the scheduler time range is not taken into account anymore.
In that case, you can not use priorities any more on the different picking.
""",

View File

@ -185,7 +185,7 @@ class mrp_production(osv.osv):
def action_production_end(self, cr, uid, ids):
obj=self.browse(cr,uid,ids)[0]
for workcenter_line in obj.workcenter_lines:
tmp=self.pool.get('mrp.production.workcenter.line').action_done(cr,uid,[workcenter_line.id])
tmp = self.pool.get('mrp.production.workcenter.line').action_done(cr,uid,[workcenter_line.id])
return super(mrp_production,self).action_production_end(cr,uid,ids)
def action_in_production(self, cr, uid, ids):

View File

@ -334,7 +334,7 @@ class mrp_procurement(osv.osv):
self.write(cr, uid, [procurement.id], {'move_id': id, 'close_move': 1})
else:
# TODO: check this
if procurement.procure_method == 'make_to_stock' and procurement.move_id.state in ('waiting',):
if procurement.procure_method == 'make_to_stock' and procurement.move_id.state in ('waiting','draft'):
id = move_obj.write(cr, uid, [procurement.move_id.id], {'state':'confirmed'})
self.write(cr, uid, ids, {'state': 'confirmed', 'message': ''})
return True

View File

@ -197,7 +197,7 @@ class mrp_procurement(osv.osv):
if reste > 0:
qty += op.qty_multiple - reste
newdate = DateTime.now() + DateTime.RelativeDateTime(
days=int(op.product_id.seller_delay))
days = int(op.product_id.seller_delay))
if op.product_id.supply_method == 'buy':
location_id = op.warehouse_id.lot_input_id
elif op.product_id.supply_method == 'produce':

View File

@ -346,12 +346,14 @@ class mrp_repair(osv.osv):
}
invoice_obj.write(cr, uid, [inv_id], invoice_vals, context=context)
else:
a = repair.partner_id.property_account_receivable.id
if not repair.partner_id.property_account_receivable:
raise osv.except_osv(_('Error !'), _('No account defined for partner "%s".') % repair.partner_id.name )
account_id = repair.partner_id.property_account_receivable.id
inv = {
'name': repair.name,
'origin':repair.name,
'type': 'out_invoice',
'account_id': a,
'account_id': account_id,
'partner_id': repair.partner_id.id,
'address_invoice_id': repair.address_id.id,
'currency_id': repair.pricelist_id.currency_id.id,
@ -368,11 +370,19 @@ class mrp_repair(osv.osv):
name = repair.name + '-' + operation.name
else:
name = operation.name
if operation.product_id.property_account_income:
account_id = operation.product_id.property_account_income
elif operation.product_id.categ_id.property_account_income_categ:
account_id = operation.product_id.categ_id.property_account_income_categ.id
else:
raise osv.except_osv(_('Error !'), _('No account defined for product "%s".') % operation.product_id.name )
invoice_line_id = inv_line_obj.create(cr, uid, {
'invoice_id': inv_id,
'name': name,
'origin': repair.name,
'account_id': operation.product_id and operation.product_id.property_account_income and operation.product_id.property_account_income.id,
'account_id': account_id,
'quantity': operation.product_uom_qty,
'invoice_line_tax_id': [(6,0,[x.id for x in operation.tax_id])],
'uos_id': operation.product_uom.id,

View File

@ -19,7 +19,6 @@
#
##############################################################################
import netsvc
from osv import osv,fields
from tools.translate import _

View File

@ -59,18 +59,20 @@ class mrp_production(osv.osv):
_inherit= 'mrp.production'
def action_confirm(self, cr, uid, ids):
picking_id=super(mrp_production,self).action_confirm(cr, uid, ids)
for production in self.browse(cr, uid, ids):
source = production.product_id.product_tmpl_id.property_stock_production.id
for sub_product in production.bom_id.sub_products:
qty1 = sub_product.product_qty
qty2 = production.product_uos and production.product_uos_qty or False
if sub_product.subproduct_type=='variable':
picking_id=super(mrp_production,self).action_confirm(cr, uid, ids)
for production in self.browse(cr, uid, ids):
source = production.product_id.product_tmpl_id.property_stock_production.id
if not production.bom_id:
continue
for sub_product in production.bom_id.sub_products:
qty1 = sub_product.product_qty
qty2 = production.product_uos and production.product_uos_qty or False
if sub_product.subproduct_type=='variable':
if production.product_qty:
qty1 *= production.product_qty / (production.bom_id.product_qty or 1.0)
if production.product_uos_qty:
qty2 *= production.product_uos_qty / (production.bom_id.product_uos_qty or 1.0)
data = {
data = {
'name':'PROD:'+production.name,
'date_planned': production.date_planned,
'product_id': sub_product.product_id.id,
@ -83,9 +85,9 @@ class mrp_production(osv.osv):
'move_dest_id': production.move_prod_id.id,
'state': 'waiting',
'production_id':production.id
}
sub_prod_ids=self.pool.get('stock.move').create(cr, uid,data)
return picking_id
}
sub_prod_ids=self.pool.get('stock.move').create(cr, uid,data)
return picking_id
mrp_production()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -241,7 +241,7 @@ class product_pricelist(osv.osv):
price = currency_obj.compute(cr, uid,
price_type.currency_id.id, res['currency_id'],
product_obj.price_get(cr, uid, [prod_id],
price_type.field)[prod_id], round=False)
price_type.field)[prod_id], round=False, context=context)
if price:
price_limit = price

View File

@ -280,7 +280,7 @@ class product_template(osv.osv):
help='Used by companies that manage two units of measure: invoicing and inventory management. For example, in food industries, you will manage a stock of ham but invoice in Kg. Keep empty to use the default UOM.'),
'uos_coeff': fields.float('UOM -> UOS Coeff', digits=(16,4),
help='Coefficient to convert UOM to UOS\n'
' uom = uos * coeff'),
' uos = uom * coeff'),
'mes_type': fields.selection((('fixed', 'Fixed'), ('variable', 'Variable')), 'Measure Type', required=True),
'seller_delay': fields.function(_calc_seller_delay, method=True, type='integer', string='Supplier Lead Time', help="This is the average delay in days between the purchase order confirmation and the reception of goods for this product and for the default supplier. It is used by the scheduler to order requests based on reordering delays."),
'seller_ids': fields.one2many('product.supplierinfo', 'product_id', 'Partners'),

View File

@ -164,7 +164,7 @@
<field name="categ_id" ref="product_category_10"/>
</record>
<record id="product_product_cpu3" model="product.product">
<field name="default_code">CPU2</field>
<field name="default_code">CPU3</field>
<field name="list_price">150.0</field>
<field name="standard_price">100.0</field>
<field name="uom_id" ref="product_uom_unit"/>
@ -303,7 +303,7 @@
<field name="categ_id" ref="product_category_10"/>
</record>
<record id="product_product_22" model="product.product">
<field name="default_code">CPU_GEN</field>
<field name="default_code">CPU_DEM</field>
<field name="supply_method">produce</field>
<field name="list_price">150.0</field>
<field name="standard_price">100.0</field>

View File

@ -14,7 +14,7 @@
<field name="view_mode">tree,calendar</field>
<field name="view_id" ref="project_issue_tree_view"/>
<field name="domain" eval="[('categ_id','=',ref('bug_categ'))]"/>
<field name="context">{"search_default_user_id":uid,"search_default_current_bugs":1,"search_default_project_id":project_id}</field>
<field name="context">{"search_default_user_id": uid, "search_default_my_bugs":1,"search_default_current_bugs":1,"search_default_project_id":project_id}</field>
<field name="search_view_id" ref="view_project_issue_filter"/>
</record>
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_view0">

View File

@ -93,7 +93,6 @@
domain="[('section_id.user_id.company_id','=',uid)]"
help="My company"/>
</field>
<field name="user_id" select="1" widget="selection"/>
</group>
<newline/>

View File

@ -223,7 +223,7 @@
<field name="res_model">project.phase</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar,gantt</field>
<field name="context">{"search_default_responsible_id":uid}</field>
<field name="context">{'search_default_responsible_id':uid}</field>
<field name="search_view_id" ref="view_project_phase_search"/>
</record>

View File

@ -32,7 +32,7 @@ When installed, this module will automatically create a new task
for each procurement order line, when the corresponding product
meets the following characteristics:
* Type = Service
* Procurement method (Order fulfillment) = MTO (make to order)
* Procurement method (Order fulfilment) = MTO (make to order)
* Supply/Procurement method = Produce
The new task is created outside of any existing project, but

View File

@ -29,27 +29,53 @@ class mrp_procurement(osv.osv):
def action_produce_assign_service(self, cr, uid, ids, context={}):
for procurement in self.browse(cr, uid, ids):
sline = self.pool.get('sale.order.line')
sale_ids = sline.search(cr, uid, [('procurement_id','=',procurement.id)], context)
content = ''
sale_order = self.pool.get('sale.order')
so_ref = procurement.name.split(':')[0]
order_ids = sale_order.search(cr, uid, [('name','=',so_ref)], context)
if order_ids:
sale_ids = sale_order.read(cr, uid, order_ids[0],['order_line'],context=context)['order_line']
else:
so_ref = procurement.origin.split(':')[0]
sale_ids = sline.search(cr, uid, [('procurement_id','=',procurement.id)], context)
l = None
project_id = None
analytic_account_id = False
partner_id = False
for line in sline.browse(cr, uid, sale_ids, context=context):
content += (line.notes or '')
l = line
partner_id = line.order_id.partner_id.id
if line.order_id.project_id:
analytic_account_id = line.order_id.project_id.id
partner_id = line.order_id.partner_id.id
content+="\n\n"+line.order_id.project_id.complete_name
break
# Creating a project for task.Project is created from Procurement.
proj_name = tools.ustr(procurement.name)
proj_name = tools.ustr(so_ref)
proj_exist_id = self.pool.get('project.project').search(cr, uid, [('name','=',proj_name)], context=context)
if not proj_exist_id:
project_id = self.pool.get('project.project').create(cr, uid, {'name':proj_name})
project_id = self.pool.get('project.project').create(cr, uid, {'name':proj_name,'category_id':analytic_account_id, 'partner_id':partner_id})
else:
project_id = proj_exist_id[0]
self.write(cr, uid, [procurement.id], {'state':'running'})
name_task = ('','')
if procurement.product_id.type == 'service':
proc_name = procurement.name
if procurement.origin == proc_name:
proc_name = procurement.product_id.name
name_task = (procurement.origin, proc_name or '')
else:
name_task = (procurement.product_id.name or procurement.origin, procurement.name or '')
task_id = self.pool.get('project.task').create(cr, uid, {
'name': '%s:%s' %(procurement.product_id.name or procurement.origin, procurement.name or ''),
'name': '%s:%s' % name_task,
'date_deadline': procurement.date_planned,
'planned_hours': procurement.product_qty,
'remaining_hours': procurement.product_qty,

View File

@ -51,7 +51,7 @@
'process/purchase_process.xml',
'report/purchase_report_view.xml',
],
'demo_xml': ['purchase_demo.xml'],
'demo_xml': ['purchase_demo.xml','purchase_unit_test.xml'],
'installable': True,
'active': False,
'certificate': '0057234283549',

View File

@ -162,7 +162,7 @@ class purchase_order(osv.osv):
"In this case, it will remove the warehouse link and set the customer location."
),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', states={'posted':[('readonly',True)]}),
'location_id': fields.many2one('stock.location', 'Destination', required=True),
'location_id': fields.many2one('stock.location', 'Destination', required=True, domain=[('usage','<>','view')]),
'pricelist_id':fields.many2one('product.pricelist', 'Pricelist', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)],'done':[('readonly',True)]}, help="The pricelist sets the currency used for this purchase order. It also computes the supplier price for the selected products/quantities."),
'state': fields.selection([('draft', 'Request for Quotation'), ('wait', 'Waiting'), ('confirmed', 'Waiting Supplier Ack'), ('approved', 'Approved'),('except_picking', 'Shipping Exception'), ('except_invoice', 'Invoice Exception'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, help="The state of the purchase order or the quotation request. A quotation is a purchase order in a 'Draft' state. Then the order has to be confirmed by the user, the state switch to 'Confirmed'. Then the supplier must confirm the order to change the state to 'Approved'. When the purchase order is paid and received, the state becomes 'Done'. If a cancel action occurs in the invoice or in the reception of goods, the state becomes in exception.", select=True),
'order_line': fields.one2many('purchase.order.line', 'order_id', 'Order Lines', states={'approved':[('readonly',True)],'done':[('readonly',True)]}),
@ -414,6 +414,7 @@ class purchase_order(osv.osv):
'purchase_id': order.id,
'company_id': order.company_id.id,
})
todo_moves = []
for order_line in order.order_line:
if not order_line.product_id:
continue
@ -437,8 +438,9 @@ class purchase_order(osv.osv):
})
if order_line.move_dest_id:
self.pool.get('stock.move').write(cr, uid, [order_line.move_dest_id.id], {'location_id':order.location_id.id})
self.pool.get('stock.move').action_confirm(cr, uid, [move])
self.pool.get('stock.move').force_assign(cr,uid, [move])
todo_moves.append(move)
self.pool.get('stock.move').action_confirm(cr, uid, todo_moves)
self.pool.get('stock.move').force_assign(cr, uid, todo_moves)
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
return picking_id
@ -516,6 +518,7 @@ class purchase_order(osv.osv):
'state': 'draft',
'order_line': {},
'notes': '%s' % (porder.notes or '',),
'fiscal_position': porder.fiscal_position and porder.fiscal_position.id or False,
})
else:
#order_infos['name'] += ', %s' % porder.name

View File

@ -8,7 +8,7 @@
<field name="pricelist_id" ref="list0"/>
<field name="partner_id" search="[]" model="res.partner"/>
<field name="partner_address_id" search="[]" model="res.partner.address"/>
<field name="location_id" search="[]" model="stock.location"/>
<field name="location_id" ref="stock.stock_location_stock"/>
</record>
<record model="purchase.order.line" id="test_purchase_1_line_1">
<field name="order_id" ref="test_purchase_1"/>
@ -63,10 +63,10 @@
<function model="account.invoice" name="pay_and_reconcile">
<value model="purchase.order" eval="[obj(ref('test_purchase_1')).invoice_id.id]" />
<value eval="1164" />
<value search="[('type', '=', 'cash')]" model="account.account"/>
<value eval="ref('account.cash')"/>
<value eval="ref('account.period_' + str(int(time.strftime('%m'))))" />
<value eval="ref('account.bank_journal')" />
<value search="[('type', '=', 'cash')]" model="account.account"/>
<value eval="ref('account.cash')"/>
<value eval="ref('account.period_' + str(int(time.strftime('%m'))))" />
<value eval="ref('account.bank_journal')" />
</function>

View File

@ -1,11 +1,18 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_purchase_order","purchase.order","model_purchase_order","purchase.group_purchase_user",1,1,1,1
"access_purchase_order_line","purchase.order.line","model_purchase_order_line","purchase.group_purchase_user",1,1,1,1
"access_stock_location_purchase_user","stock.location purchase_user","stock.model_stock_location","purchase.group_purchase_user",1,0,0,0
"access_stock_warehouse_purchase_user","stock.warehouse purchase_user","stock.model_stock_warehouse","purchase.group_purchase_user",1,0,0,0
"access_stock_picking_purchase_user","stock.picking purchase_user","stock.model_stock_picking","purchase.group_purchase_user",1,1,1,1
"access_stock_move_purchase_user","stock.move purchase_user","stock.model_stock_move","purchase.group_purchase_user",1,1,1,1
"access_purchase_order_stock_worker","purchase.order stock_worker","model_purchase_order","stock.group_stock_user",1,0,0,0
"access_purchase_order_line_stock_worker","purchase.order.line stock_worker","model_purchase_order_line","stock.group_stock_user",1,0,0,0
"access_account_tax_purchase_user","account.tax purchase_user","account.model_account_tax","purchase.group_purchase_user",1,0,0,0
"access_stock_location_purchase_user","stock.location","stock.model_stock_location","purchase.group_purchase_user",1,0,0,0
"access_stock_warehouse_purchase_user","stock.warehouse","stock.model_stock_warehouse","purchase.group_purchase_user",1,0,0,0
"access_stock_picking_purchase_user","stock.picking","stock.model_stock_picking","purchase.group_purchase_user",1,1,1,1
"access_stock_move_purchase_user","stock.move","stock.model_stock_move","purchase.group_purchase_user",1,1,1,1
"access_purchase_order_stock_worker","purchase.order","model_purchase_order","stock.group_stock_user",1,0,0,0
"access_purchase_order_line_stock_worker","purchase.order.line","model_purchase_order_line","stock.group_stock_user",1,0,0,0
"access_account_tax_purchase_user","account.tax","account.model_account_tax","purchase.group_purchase_user",1,0,0,0
"access_report_purchase_order","purchase.report","model_purchase_report","purchase.group_purchase_manager",1,0,0,0
"access_purchase_order_manager","purchase.order","model_purchase_order","purchase.group_purchase_manager",1,1,1,1
"access_purchase_order_line_manager","purchase.order.line","model_purchase_order_line","purchase.group_purchase_manager",1,1,1,1
"access_stock_location_purchase_user_manager","stock.location","stock.model_stock_location","purchase.group_purchase_manager",1,0,0,0
"access_stock_warehouse_purchase_user_manager","stock.warehouse","stock.model_stock_warehouse","purchase.group_purchase_manager",1,0,0,0
"access_stock_picking_purchase_user_manager","stock.picking","stock.model_stock_picking","purchase.group_purchase_manager",1,1,1,1
"access_stock_move_purchase_user_manager","stock.move","stock.model_stock_move","purchase.group_purchase_manager",1,1,1,1
"access_account_tax_purchase_user_manager","account.tax","account.model_account_tax","purchase.group_purchase_manager",1,0,0,0

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_purchase_order purchase.order model_purchase_order purchase.group_purchase_user 1 1 1 1
3 access_purchase_order_line purchase.order.line model_purchase_order_line purchase.group_purchase_user 1 1 1 1
4 access_stock_location_purchase_user stock.location purchase_user stock.location stock.model_stock_location purchase.group_purchase_user 1 0 0 0
5 access_stock_warehouse_purchase_user stock.warehouse purchase_user stock.warehouse stock.model_stock_warehouse purchase.group_purchase_user 1 0 0 0
6 access_stock_picking_purchase_user stock.picking purchase_user stock.picking stock.model_stock_picking purchase.group_purchase_user 1 1 1 1
7 access_stock_move_purchase_user stock.move purchase_user stock.move stock.model_stock_move purchase.group_purchase_user 1 1 1 1
8 access_purchase_order_stock_worker purchase.order stock_worker purchase.order model_purchase_order stock.group_stock_user 1 0 0 0
9 access_purchase_order_line_stock_worker purchase.order.line stock_worker purchase.order.line model_purchase_order_line stock.group_stock_user 1 0 0 0
10 access_account_tax_purchase_user account.tax purchase_user account.tax account.model_account_tax purchase.group_purchase_user 1 0 0 0
11 access_report_purchase_order purchase.report model_purchase_report purchase.group_purchase_manager 1 0 0 0
12 access_purchase_order_manager purchase.order model_purchase_order purchase.group_purchase_manager 1 1 1 1
13 access_purchase_order_line_manager purchase.order.line model_purchase_order_line purchase.group_purchase_manager 1 1 1 1
14 access_stock_location_purchase_user_manager stock.location stock.model_stock_location purchase.group_purchase_manager 1 0 0 0
15 access_stock_warehouse_purchase_user_manager stock.warehouse stock.model_stock_warehouse purchase.group_purchase_manager 1 0 0 0
16 access_stock_picking_purchase_user_manager stock.picking stock.model_stock_picking purchase.group_purchase_manager 1 1 1 1
17 access_stock_move_purchase_user_manager stock.move stock.model_stock_move purchase.group_purchase_manager 1 1 1 1
18 access_account_tax_purchase_user_manager account.tax account.model_account_tax purchase.group_purchase_manager 1 0 0 0

View File

@ -134,7 +134,7 @@
<tr>
<td>
<para style="terp_default_Bold_9">Shipping address :</para>
<para style="terp_default_9">[[ o.partner_id.name ]] [[ o.partner_id.title or '' ]]</para>
<para style="terp_default_9">[[ o.partner_id.title or '' ]] [[ o.partner_id.name ]]</para>
<para style="terp_default_9">[[ o.partner_shipping_id.title or '' ]] [[ o.partner_shipping_id.name ]]</para>
<para style="terp_default_9">[[ o.partner_shipping_id.street ]]</para>
<para style="terp_default_9">[[ o.partner_shipping_id.street2 or '' ]]</para>
@ -144,10 +144,10 @@
<font color="white"> </font>
</para>
<para style="terp_default_Bold_9">Invoice address :</para>
<para style="terp_default_9">[[ o.partner_invoice_id.title or '' ]] [[ o.partner_invoice_id.name or '' ]] </para>
<para style="terp_default_9">[[ o.partner_invoice_id.title or '' ]] [[ o.partner_invoice_id.name or '' ]]</para>
<para style="terp_default_9">[[ o.partner_invoice_id.street ]] [[ o.partner_invoice_id.street2 and (', %s' % o.partner_invoice_id.street2 or '') ]]</para>
<para style="terp_default_9">[[ o.partner_invoice_id.zip or '' ]] [[ o.partner_invoice_id.city or '' ]]</para>
<para style="terp_default_9">[[ o.partner_invoice_id.state_id and o.partner_invoice_id.state_id.name or '' ]] [[ o.partner_invoice_id.country_id and o.partner_invoice_id.country_id.name or '' ]]</para>
<para style="terp_default_9">[[ o.partner_invoice_id.state_id and o.partner_invoice_id.state_id.name or '' ]][[ o.partner_invoice_id.country_id and o.partner_invoice_id.country_id.name or '' ]]</para>
</td>
<td>
<para style="terp_default_8">
@ -155,7 +155,7 @@
</para>
</td>
<td>
<para style="terp_default_9">[[ o.partner_id.name ]] [[ o.partner_id.title or '' ]]</para>
<para style="terp_default_9">[[ o.partner_id.title or '' ]] [[ o.partner_id.name ]]</para>
<para style="terp_default_9">[[ o.partner_order_id.title or '' ]] [[ o.partner_order_id.name ]]</para>
<para style="terp_default_9">[[ o.partner_order_id.street ]]</para>
<para style="terp_default_9">[[ o.partner_order_id.street2 or '' ]]</para>
@ -187,7 +187,8 @@
<para style="terp_tblheader_General_Centre">Your Reference </para>
</td>
<td>
<para style="terp_tblheader_General_Centre">[[ o.state=='draft' and 'Quotation Date' or 'Date Ordered' ]]</para>
<para style="terp_tblheader_General_Centre">[[ o.state=='draft' and removeParentNode('para') ]] Date Ordered</para>
<para style="terp_tblheader_General_Centre">[[ o.state &lt;&gt; 'draft' and removeParentNode('para') ]] Quotation Date</para>
</td>
<td>
<para style="terp_tblheader_General_Centre">Our Salesman </para>
@ -240,7 +241,7 @@
</blockTable>
<section>
<para style="terp_default_1">[[repeatIn(o.order_line,'line')]]</para>
<blockTable colWidths="208.0,99.0,43.0,21.0,59.0,43.0,65.0" style="Table5">
<blockTable colWidths="207.0,99.0,43.0,21.0,59.0,43.0,65.0" style="Table5">
<tr>
<td>
<para style="terp_default_9">[[ line.name ]]</para>
@ -370,4 +371,4 @@
<font color="white"> </font>
</para>
</story>
</document>
</document>

View File

@ -106,17 +106,19 @@ class sale_order(osv.osv):
for id in ids:
res[id] = [0.0, 0.0]
cr.execute('''SELECT
p.sale_id,sum(m.product_qty), m.state
p.sale_id,sum(m.product_qty), mp.state as mp_state
FROM
stock_move m
LEFT JOIN
stock_picking p on (p.id=m.picking_id)
LEFT JOIN
mrp_procurement mp on (mp.move_id=m.id)
WHERE
p.sale_id = ANY(%s) GROUP BY m.state, p.sale_id''',(ids,))
for oid, nbr, state in cr.fetchall():
if state == 'cancel':
p.sale_id = ANY(%s) GROUP BY mp.state, p.sale_id''',(ids,))
for oid, nbr, mp_state in cr.fetchall():
if mp_state == 'cancel':
continue
if state == 'done':
if mp_state == 'done':
res[oid][0] += nbr or 0.0
res[oid][1] += nbr or 0.0
else:
@ -434,7 +436,7 @@ class sale_order(osv.osv):
'currency_id': order.pricelist_id.currency_id.id,
'comment': order.note,
'payment_term': pay_term,
'fiscal_position': order.partner_id.property_account_position.id,
'fiscal_position': order.fiscal_position.id or order.partner_id.property_account_position.id,
'date_invoice' : context.get('date_invoice',False),
'company_id' : order.company_id.id,
}
@ -508,18 +510,14 @@ class sale_order(osv.osv):
def action_invoice_end(self, cr, uid, ids, context=None):
if context is None:
context = {}
for order in self.browse(cr, uid, ids, context=context):
val = {'invoiced': True}
if order.state == 'invoice_except':
val['state'] = 'progress'
for line in order.order_line:
towrite = []
if line.state == 'exception':
towrite.append(line.id)
if towrite:
self.pool.get('sale.order.line').write(cr, uid, towrite, {'state': 'confirmed'}, context=context)
self.write(cr, uid, [order.id], val)
self.pool.get('sale.order.line').write(cr, uid, [line.id], {'state': 'confirmed'}, context=context)
if order.state == 'invoice_except':
self.write(cr, uid, [order.id], {'state' : 'progress'}, context=context)
return True
@ -1072,7 +1070,7 @@ class sale_order_line(osv.osv):
'product_uos':
[('category_id', '=', uos_category_id)]}
elif uos: # only happens if uom is False
elif uos and not uom: # only happens if uom is False
result['product_uom'] = product_obj.uom_id and product_obj.uom_id.id
result['product_uom_qty'] = qty_uos / product_obj.uos_coeff
result['th_weight'] = result['product_uom_qty'] * product_obj.weight
@ -1117,7 +1115,7 @@ class sale_order_line(osv.osv):
uom=False, qty_uos=0, uos=False, name='', partner_id=False,
lang=False, update_tax=True, date_order=False):
res = self.product_id_change(cursor, user, ids, pricelist, product,
qty=0, uom=uom, qty_uos=qty_uos, uos=uos, name=name,
qty=qty, uom=uom, qty_uos=qty_uos, uos=uos, name=name,
partner_id=partner_id, lang=lang, update_tax=update_tax,
date_order=date_order)
if 'product_uom' in res['value']:

View File

@ -160,8 +160,6 @@
</group>
</page>
<page groups="base.group_extended" string="Extra Info">
<field groups="product.group_uos" name="product_uos_qty" on_change="uos_change(product_uos, product_uos_qty, product_id)"/>
<field groups="product.group_uos" name="product_uos"/>
<field name="th_weight"/>
<field name="address_allotment_id"/>
<!-- <separator colspan="4" string="Properties"/>-->
@ -192,7 +190,7 @@
<group col="8" colspan="5">
<field name="amount_untaxed" sum="Untaxed amount"/>
<field name="amount_tax"/>
<field name="amount_total" sum="Total amount"/>
<field name="amount_total"/>
<button name="button_dummy" states="draft" string="Compute" type="object" icon="gtk-execute"/>
</group>
<group col="13" colspan="4">
@ -239,7 +237,7 @@
</page>
<page string="History" groups="base.group_extended">
<separator colspan="4" string="Related invoices"/>
<field colspan="4" name="invoice_ids" nolabel="1"/>
<field colspan="4" name="invoice_ids" nolabel="1" context="{'form_view_ref':'account.invoice_form'}"/>
<field colspan="4" name="picking_ids" nolabel="1"/>
</page>
</notebook>

View File

@ -63,11 +63,8 @@ class stock_picking(osv.osv):
user, picking)
def _get_comment_invoice(self, cursor, user, picking):
if picking.sale_id and picking.sale_id.note:
if picking.note:
return picking.note + '\n' + picking.sale_id.note
else:
return picking.sale_id.note
if picking.note or (picking.sale_id and picking.sale_id.note):
return picking.note or picking.sale_id.note
return super(stock_picking, self)._get_comment_invoice(cursor, user,
picking)
@ -139,6 +136,10 @@ class stock_picking(osv.osv):
sale_lines = picking.sale_id.order_line
invoice_created = invoices[result[picking.id]]
for inv in invoice_obj.browse(cursor, user, [invoice_created.id], context=context):
if not inv.fiscal_position:
invoice_obj.write(cursor, user, [inv.id], {'fiscal_position': picking.sale_id.fiscal_position.id}, context=context)
if picking.sale_id.client_order_ref:
inv_name = picking.sale_id.client_order_ref + " : " + invoice_created.name
invoice_obj.write(cursor, user, [invoice_created.id], {'name': inv_name}, context=context)
@ -188,6 +189,19 @@ class stock_picking(osv.osv):
})
return result
def action_cancel(self, cr, uid, ids, context={}):
res = super(stock_picking, self).action_cancel(cr, uid, ids, context=context)
for pick in self.browse(cr, uid, ids, context):
call_ship_end = True
if pick.sale_id:
for picks in pick.sale_id.picking_ids:
if picks.state not in ('done','cancel'):
call_ship_end = False
break
if call_ship_end:
self.pool.get('sale.order').action_ship_end(cr, uid, [pick.sale_id.id], context)
return res
stock_picking()

View File

@ -20,11 +20,7 @@
##############################################################################
from osv import fields, osv
from service import web_services
import wizard
import netsvc
import ir
import pooler
from tools.translate import _
class sale_order_line_make_invoice(osv.osv_memory):
_name = "sale.order.line.make.invoice"
@ -82,7 +78,7 @@ class sale_order_line_make_invoice(osv.osv_memory):
'currency_id' : order.pricelist_id.currency_id.id,
'comment': order.note,
'payment_term': pay_term,
'fiscal_position': order.partner_id.property_account_position.id
'fiscal_position': order.fiscal_position.id or order.partner_id.property_account_position.id,
}
inv_id = self.pool.get('account.invoice').create(cr, uid, inv)
return inv_id
@ -110,6 +106,8 @@ class sale_order_line_make_invoice(osv.osv_memory):
wf_service.trg_validate(uid, 'sale.order', line.order_id.id, 'all_lines', cr)
sales_order_obj.write(cr,uid,[line.order_id.id],{'state' : 'progress'})
if not invoices:
raise osv.except_osv(_('Warning'),_('Invoice cannot be created for this Sale Order Line due to one of the following reasons:\n1.The state of this sale order line is either "draft" or "cancel"!\n2.The Sale Order Line is Invoiced!'))
for result in invoices.values():
order = result[0][0].order_id
il = map(lambda x: x[1], result)

View File

@ -22,9 +22,6 @@ from osv import fields, osv
from service import web_services
from tools.translate import _
import ir
import netsvc
import pooler
import wizard
class sale_advance_payment_inv(osv.osv_memory):
@ -95,7 +92,7 @@ class sale_advance_payment_inv(osv.osv_memory):
'currency_id' :sale.pricelist_id.currency_id.id,
'comment': '',
'payment_term':sale.payment_term.id,
'fiscal_position': sale.partner_id.property_account_position.id
'fiscal_position': sale.fiscal_position.id or sale.partner_id.property_account_position.id
}
inv_id = inv_obj.create(cr, uid, inv)

View File

@ -44,7 +44,7 @@ sale_fields = {
'relation': 'res.partner',
'help': 'Use this partner if there is no partner on the case'},
'picking_policy': {'string': 'Picking Policy', 'type': 'selection',
'selection': [('direct','Direct Delivery'),('one','All at once')]},
'selection': [('direct', 'Partial Delivery'), ('one', 'Complete Delivery')]},
'products': {'string': 'Products', 'type': 'many2many',
'relation': 'product.product'},
'analytic_account': {'string': 'Analytic Account', 'type': 'many2one',
@ -116,14 +116,19 @@ class make_sale(wizard.interface):
if data['form']['analytic_account']:
vals['project_id'] = data['form']['analytic_account']
vals.update( sale_obj.onchange_partner_id(cr, uid, [], partner_id).get('value',{}) )
new_id = sale_obj.create(cr, uid, vals)
for product_id in data['form']['products'][0][2]:
value = sale_line_obj.product_id_change(cr, uid, [], pricelist,
product_id, qty=1, partner_id=partner_id, fiscal_position=fpos)['value']
value['product_id'] = product_id
value['order_id'] = new_id
value['tax_id'] = [(6,0,value['tax_id'])]
sale_line_obj.create(cr, uid, value)
if data['form']['products']:
for product_id in data['form']['products'][0][2]:
value = {
'price_unit': 0.0,
'product_id': product_id,
'order_id': new_id,
}
value.update( sale_line_obj.product_id_change(cr, uid, [], pricelist,product_id, qty=1, partner_id=partner_id, fiscal_position=fpos)['value'] )
value['tax_id'] = [(6,0,value['tax_id'])]
sale_line_obj.create(cr, uid, value)
case_obj.write(cr, uid, [case.id], {'ref': 'sale.order,%s' % new_id})
new_ids.append(new_id)

View File

@ -201,7 +201,7 @@
<para style="terp_default_9">[[line.product_id.code ]] [[ line.product_id and line.product_id.name or '']]</para>
</td>
<td>
<para style="terp_default_Centre_9">[[ (line.prodlot_id and (line.prodlot_id.name + '/' + line.prodlot_id.ref)) or ' ' ]]</para>
<para style="terp_default_Centre_9">[[ (line.prodlot_id and (line.prodlot_id.name + (line.prodlot_id.ref and ('/' + line.prodlot_id.ref) or ''))) or ' ' ]]</para>
</td>
<td>
<para style="terp_default_Right_9">[[ formatLang(line.product_qty) ]]</para>

View File

@ -22,6 +22,7 @@
from osv import osv, fields
from tools.translate import _
import tools
from tools.sql import drop_view_if_exists
#
# Check if it works with UoM ???
@ -38,7 +39,7 @@ class stock_report_prodlots(osv.osv):
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'stock_report_prodlots')
drop_view_if_exists(cr, 'stock_report_prodlots')
cr.execute("""
create or replace view stock_report_prodlots as (
select max(id) as id,
@ -94,7 +95,7 @@ class stock_report_tracklots(osv.osv):
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'stock_report_tracklots')
drop_view_if_exists(cr, 'stock_report_prodlots')
cr.execute("""
create or replace view stock_report_tracklots as (
@ -149,7 +150,7 @@ class report_stock_lines_date(osv.osv):
'date': fields.datetime('Latest Inventory Date'),
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'report_stock_lines_date')
drop_view_if_exists(cr, 'stock_report_prodlots')
cr.execute("""
create or replace view report_stock_lines_date as (
select

View File

@ -861,15 +861,23 @@ class stock_picking(osv.osv):
return True
def unlink(self, cr, uid, ids, context=None):
move_obj = self.pool.get('stock.move')
if not context:
context = {}
for pick in self.browse(cr, uid, ids, context=context):
if pick.state in ['done','cancel']:
raise osv.except_osv(_('Error'), _('You cannot remove the picking which is in %s state !')%(pick.state,))
elif pick.state in ['confirmed','assigned']:
elif pick.state in ['confirmed','assigned', 'draft']:
ids2 = [move.id for move in pick.move_lines]
context.update({'call_unlink':True})
self.pool.get('stock.move').action_cancel(cr, uid, ids2, context)
else:
continue
ctx = context.copy()
ctx.update({'call_unlink':True})
if pick.state != 'draft':
#Cancelling the move in order to affect Virtual stock of product
move_obj.action_cancel(cr, uid, ids2, ctx)
#Removing the move
move_obj.unlink(cr, uid, ids2, ctx)
return super(stock_picking, self).unlink(cr, uid, ids, context=context)
def do_partial(self, cr, uid, ids, partial_datas, context={}):
@ -1613,6 +1621,8 @@ class stock_move(osv.osv):
return True
def unlink(self, cr, uid, ids, context=None):
if context is None:
context = {}
for move in self.browse(cr, uid, ids, context=context):
if move.state != 'draft':
raise osv.except_osv(_('UserError'),
@ -1743,7 +1753,7 @@ class stock_move(osv.osv):
@ return: Consumed lines
'''
if not context:
if context is None:
context = {}
if quantity <= 0:
@ -2053,9 +2063,9 @@ class stock_warehouse(osv.osv):
# 'partner_id': fields.many2one('res.partner', 'Owner'),
'company_id': fields.many2one('res.company','Company',required=True,select=1),
'partner_address_id': fields.many2one('res.partner.address', 'Owner Address'),
'lot_input_id': fields.many2one('stock.location', 'Location Input', required=True),
'lot_stock_id': fields.many2one('stock.location', 'Location Stock', required=True),
'lot_output_id': fields.many2one('stock.location', 'Location Output', required=True),
'lot_input_id': fields.many2one('stock.location', 'Location Input', required=True, domain=[('usage','<>','view')]),
'lot_stock_id': fields.many2one('stock.location', 'Location Stock', required=True, domain=[('usage','<>','view')]),
'lot_output_id': fields.many2one('stock.location', 'Location Output', required=True, domain=[('usage','<>','view')]),
}
_defaults = {
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.inventory', context=c),

View File

@ -639,7 +639,7 @@
<separator colspan="4" string="Move Information"/>
<field name="location_id" select="1" domain="[('usage','=','internal')]"/>
<field name="location_dest_id" select="1" domain="[('usage','=','internal')]"/>
<field colspan="4" context="location=location_id" name="product_id" on_change="onchange_product_id(product_id, location_id, location_dest_id)" select="1"/>
<field colspan="4" context="location=location_id" name="product_id" on_change="onchange_product_id(product_id, location_id, location_dest_id, parent.address_id)" select="1"/>
<field name="product_qty" select="1" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
<field name="product_uom" select="1"/>
<field groups="product.group_uos" name="product_uos" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
@ -648,7 +648,7 @@
<field invisible="1" name="date"/>
<field name="date_planned"/>
<field name="address_id" select="1" context="{'contact_display':'partner'}"/>
<field groups="base.group_extended" name="product_packaging"/>
<field groups="base.group_extended" name="product_packaging" domain="[('product_id','=',product_id)]"/>
<field name="prodlot_id" groups="base.group_extended"
context="{'location_id':location_id, 'product_id':product_id}"
domain="[('product_id','=?',product_id)]"
@ -660,7 +660,7 @@
<button name="%(move_scrap)d" string="Scrap Move Line" type="action" icon="gtk-justify-fill"/>
<separator colspan="4" string="Move State"/>
<field name="state" select="1"/>
<group>
<group colspan="2">
<button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
<button name="cancel_assign" states="assigned" string="Cancel Availability" type="object" icon="gtk-no"/>
<button name="action_cancel" states="assigned" string="Cancel" type="object" icon="gtk-cancel"/>
@ -789,7 +789,7 @@
<separator colspan="4" string="Move Information"/>
<field name="location_id" select="1" domain="[('usage','=','internal')]"/>
<field name="location_dest_id" select="1" domain="[('usage','&lt;&gt;','view')]"/>
<field colspan="4" context="location=location_id" name="product_id" on_change="onchange_product_id(product_id, location_id, location_dest_id)" select="1"/>
<field colspan="4" context="location=location_id" name="product_id" on_change="onchange_product_id(product_id, location_id, location_dest_id, parent.address_id)" select="1"/>
<field name="product_qty" select="1" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
<field name="product_uom" select="1"/>
<field groups="product.group_uos" name="product_uos" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
@ -797,7 +797,7 @@
<field colspan="4" invisible="1" name="name" select="1"/>
<field invisible="1" name="date"/>
<field name="date_planned"/>
<field groups="base.group_extended" name="product_packaging"/>
<field groups="base.group_extended" name="product_packaging" domain="[('product_id','=',product_id)]"/>
<field name="prodlot_id" groups="base.group_extended"
context="{'location_id':location_id, 'product_id':product_id}"
domain="[('product_id','=?',product_id)]"
@ -805,7 +805,7 @@
<field groups="base.group_extended" name="tracking_id" select="1"/>
<separator colspan="4" string="Move State"/>
<field name="state" select="1"/>
<group>
<group colspan="2">
<button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
<button name="cancel_assign" states="assigned" string="Cancel Availability" type="object" icon="gtk-find"/>
<button name="action_cancel" states="assigned" string="Cancel" type="object" icon="gtk-cancel"/>
@ -967,7 +967,7 @@
<separator colspan="4" string="Move Information"/>
<field name="location_id" select="1" domain="[('usage','=','internal')]"/>
<field name="location_dest_id" select="1" domain="[('usage','&lt;&gt;','view')]"/>
<field colspan="4" context="location=location_id" name="product_id" on_change="onchange_product_id(product_id, location_id, location_dest_id)" select="1"/>
<field colspan="4" context="location=location_id" name="product_id" on_change="onchange_product_id(product_id, location_id, location_dest_id, parent.address_id)" select="1"/>
<field name="product_qty" select="1" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)" />
<field name="product_uom" select="1"/>
<field groups="product.group_uos" name="product_uos" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
@ -975,7 +975,7 @@
<field colspan="4" invisible="1" name="name" select="1"/>
<field invisible="1" name="date"/>
<field name="date_planned"/>
<field groups="base.group_extended" name="product_packaging"/>
<field groups="base.group_extended" name="product_packaging" domain="[('product_id','=',product_id)]"/>
<field name="prodlot_id" select="1" groups="base.group_extended"
context="{'location_id':location_id, 'product_id':product_id}"
domain="[('product_id','=?',product_id)]"
@ -985,7 +985,7 @@
<button name="%(track_line)d" string="Split in production lots" type="action" icon="gtk-justify-fill"/>
<separator colspan="4" string="Move State"/>
<field name="state" select="1"/>
<group>
<group colspan="2">
<button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
<button name="cancel_assign" states="assigned" string="Cancel Availability" type="object" icon="gtk-no"/>
<button name="action_cancel" states="assigned" string="Cancel" type="object" icon="gtk-cancel"/>
@ -1139,7 +1139,7 @@
<separator colspan="4" string="Move Information"/>
<field name="location_id" select="1" domain="[('usage','&lt;&gt;','view')]"/>
<field domain="[('usage','=','internal')]" name="location_dest_id" select="1"/>
<field colspan="4" context="location=location_id" name="product_id" on_change="onchange_product_id(product_id, location_id, location_dest_id)" select="1"/>
<field colspan="4" context="location=location_id" name="product_id" on_change="onchange_product_id(product_id, location_id, location_dest_id, parent.address_id)" select="1"/>
<field name="product_qty" select="1" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
<field name="product_uom" select="1"/>
<field groups="product.group_uos" name="product_uos" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
@ -1148,7 +1148,7 @@
<field groups="base.group_extended" name="date_planned"/>
<newline/>
<newline/>
<field groups="base.group_extended" name="product_packaging"/>
<field groups="base.group_extended" name="product_packaging" domain="[('product_id','=',product_id)]"/>
<newline/>
<field name="prodlot_id" select="1" groups="base.group_extended"
context="{'location_id':location_id, 'product_id':product_id}"
@ -1160,7 +1160,7 @@
<button groups="base.group_extended" name="%(track_line)d" string="Split in production lots" type="action" icon="gtk-justify-fill"/>
<separator colspan="4" string="Move State"/>
<field name="state" select="1"/>
<group>
<group colspan="2">
<button name="force_assign" states="confirmed" string="Force Availability" type="object" icon=""/>
<button name="cancel_assign" states="assigned" string="Cancel Availability" type="object" icon=""/>
<button name="action_cancel" states="assigned" string="Cancel" type="object" icon=""/>
@ -1327,7 +1327,7 @@
<group colspan="2" col="2">
<separator colspan="2" string="Move Information"/>
<field name="name"/>
<field name="product_id" select="1" on_change="onchange_product_id(product_id,location_id,location_dest_id)"/>
<field name="product_id" select="1" on_change="onchange_product_id(product_id, location_id, location_dest_id, parent.address_id)"/>
<field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
<field name="product_uom" string="Unit Of Measure" widget="selection"/>
<field name="product_uos" groups="base.group_extended" />
@ -1451,7 +1451,7 @@
<separator colspan="4" string="Move Information"/>
<field name="location_id"/>
<field name="location_dest_id"/>
<field colspan="4" name="product_id" on_change="onchange_product_id(product_id,location_id,location_dest_id)"/>
<field colspan="4" name="product_id" on_change="onchange_product_id(product_id, location_id, location_dest_id, parent.address_id)"/>
<field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
<field name="product_uom"/>
<field name="product_uos"/>

View File

@ -41,7 +41,7 @@ class stock_invoice_onshipping(osv.osv_memory):
'invoice_date': fields.date('Invoiced date'),
}
def _get_type(self, cr, uid, context):
def _get_type(self, cr, uid, context=None):
"""
To get invoice type
@ -53,10 +53,12 @@ class stock_invoice_onshipping(osv.osv_memory):
@return: invoice type
"""
"""
if context is None:
context = {}
picking_obj = self.pool.get('stock.picking')
usage = 'customer'
pick = picking_obj.browse(cr, uid, context['active_id'])
pick = picking_obj.browse(cr, uid, context['active_id'], context=context)
if pick.invoice_state == 'invoiced':
raise osv.except_osv(_('UserError'), _('Invoice is already created.'))
if pick.invoice_state == 'none':
@ -112,7 +114,7 @@ class stock_invoice_onshipping(osv.osv_memory):
context=context)
invoice_ids = res.values()
if not invoice_ids:
raise osv.except_osv(_('Error'), _('Invoice is not created'))
raise osv.except_osv(_('Error'), _('Invoice is not created'))
if type == 'out_invoice':
xml_id = 'action_invoice_tree1'
@ -124,12 +126,12 @@ class stock_invoice_onshipping(osv.osv_memory):
xml_id = 'action_invoice_tree4'
result = mod_obj._get_id(cr, uid, 'account', xml_id)
id = mod_obj.read(cr, uid, result, ['res_id'])
result = act_obj.read(cr, uid, id['res_id'])
id = mod_obj.read(cr, uid, result, ['res_id'], context=context)
result = act_obj.read(cr, uid, id['res_id'], context=context)
result['res_id'] = invoice_ids
result['context'] = context
return result
stock_invoice_onshipping()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -38,7 +38,7 @@ class stock_split_move_line(osv.osv_memory):
res = super(stock_split_move_line, self).default_get(cr, uid, fields, context=context)
record_id = context and context.get('active_id', False) or False
pick_obj = self.pool.get('stock.picking')
pick = pick_obj.browse(cr, uid, record_id)
pick = pick_obj.browse(cr, uid, record_id, context=context)
for m in [line for line in pick.move_lines]:
res['move%s'%(m.id)] = m.product_qty
return res
@ -57,7 +57,7 @@ class stock_split_move_line(osv.osv_memory):
if record_id:
pick_obj = self.pool.get('stock.picking')
try:
pick = pick_obj.browse(cr, uid, record_id)
pick = pick_obj.browse(cr, uid, record_id, context=context)
for m in [line for line in pick.move_lines]:
if 'move%s' % m.id not in self._columns:
self._columns['move%s' % m.id] = fields.float(string=m.product_id.name)
@ -79,7 +79,7 @@ class stock_split_move_line(osv.osv_memory):
record_id = context and context.get('active_id', False) or False
assert record_id,'Active ID not found'
pick_obj = self.pool.get('stock.picking')
pick = pick_obj.browse(cr, uid, record_id)
pick = pick_obj.browse(cr, uid, record_id, context=context)
arch_lst = ['<?xml version="1.0"?>', '<form string="Split lines">', '<label string="Indicate here the quantity of the new line. A quantity of zero will not split the line." colspan="4"/>']
for m in [line for line in pick.move_lines]:
quantity = m.product_qty
@ -106,10 +106,10 @@ class stock_split_move_line(osv.osv_memory):
move_obj = self.pool.get('stock.move')
record_id = context and context.get('active_id', False) or False
pick_obj = self.pool.get('stock.picking')
pick = pick_obj.browse(cr, uid, record_id)
pick = pick_obj.browse(cr, uid, record_id, context=context)
data = self.read(cr, uid, ids[0])
move_ids = [m.id for m in [line for line in pick.move_lines]]
for move in move_obj.browse(cr, uid, move_ids):
for move in move_obj.browse(cr, uid, move_ids, context=context):
quantity = data['move%s' % move.id]
if 0 < quantity < move.product_qty:
new_qty = move.product_qty - quantity

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
##############################################################################
#
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
@ -15,7 +15,7 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
@ -49,7 +49,7 @@ class res_partner(osv.osv):
'picking_warn' : lambda *a: 'no-message',
'invoice_warn' : lambda *a: 'no-message',
}
res_partner()
@ -73,11 +73,11 @@ class sale_order(osv.osv):
}
result = super(sale_order, self).onchange_partner_id(cr, uid, ids, part)
if result.get('warning',False):
warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title']
warning['message'] = message and message + ' ' + result['warning']['message'] or result['warning']['message']
return {'value': result.get('value',{}), 'warning':warning}
sale_order()
@ -101,21 +101,20 @@ class purchase_order(osv.osv):
'message': message
}
result = super(purchase_order, self).onchange_partner_id(cr, uid, ids, part)
if result.get('warning',False):
warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title']
warning['message'] = message and message + ' ' + result['warning']['message'] or result['warning']['message']
return {'value': result.get('value',{}), 'warning':warning}
purchase_order()
class account_invoice(osv.osv):
_inherit = 'account.invoice'
def onchange_partner_id(self, cr, uid, ids, type, partner_id,
date_invoice=False, payment_term=False, partner_bank_id=False):
date_invoice=False, payment_term=False, partner_bank=False, company_id=False):
if not partner_id:
return {'value': {
'address_contact_id': False ,
@ -131,7 +130,7 @@ class account_invoice(osv.osv):
if partner.invoice_warn != 'no-message':
if partner.invoice_warn == 'block':
raise osv.except_osv(_('Alert for %s !') % (partner.name), partner.invoice_warn_msg)
title = _("Warning for %s") % partner.name
message = partner.invoice_warn_msg
warning = {
@ -139,19 +138,19 @@ class account_invoice(osv.osv):
'message': message
}
result = super(account_invoice, self).onchange_partner_id(cr, uid, ids, type, partner_id,
date_invoice=False, payment_term=False, partner_bank_id=False)
date_invoice=False, payment_term=False, partner_bank=False)
if result.get('warning',False):
warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title']
warning['message'] = message and message + ' ' + result['warning']['message'] or result['warning']['message']
return {'value': result.get('value',{}), 'warning':warning}
account_invoice()
class stock_picking(osv.osv):
_inherit = 'stock.picking'
def onchange_partner_in(self, cr, uid, context, partner_id=None):
if not partner_id:
return {}
@ -172,9 +171,9 @@ class stock_picking(osv.osv):
if result.get('warning',False):
warning['title'] = title and title +' & '+ result['warning']['title'] or result['warning']['title']
warning['message'] = message and message + ' ' + result['warning']['message'] or result['warning']['message']
return {'value': result.get('value',{}), 'warning':warning}
stock_picking()
class product_product(osv.osv):
@ -185,12 +184,12 @@ class product_product(osv.osv):
'purchase_line_warn' : fields.selection(WARNING_MESSAGE,'Purchase Order Line', help=WARNING_HELP),
'purchase_line_warn_msg' : fields.text('Message for Purchase Order Line'),
}
_defaults = {
'sale_line_warn' : lambda *a: 'no-message',
'purchase_line_warn' : lambda *a: 'no-message',
}
product_product()
class sale_order_line(osv.osv):
@ -204,11 +203,11 @@ class sale_order_line(osv.osv):
return {'value': {'th_weight' : 0, 'product_packaging': False,
'product_uos_qty': qty}, 'domain': {'product_uom': [],
'product_uos': []}}
product_obj = self.pool.get('product.product')
product_obj = self.pool.get('product.product')
product_info = product_obj.browse(cr, uid, product)
title = False
message = False
if product_info.sale_line_warn != 'no-message':
if product_info.sale_line_warn == 'block':
raise osv.except_osv(_('Alert for %s !') % (product_info.name), product_info.sale_line_warn_msg)
@ -216,7 +215,7 @@ class sale_order_line(osv.osv):
message = product_info.sale_line_warn_msg
warning['title'] = title
warning['message'] = message
result = super(sale_order_line, self).product_id_change( cr, uid, ids, pricelist, product, qty,
uom, qty_uos, uos, name, partner_id,
lang, update_tax, date_order, packaging, fiscal_position, flag)
@ -227,9 +226,9 @@ class sale_order_line(osv.osv):
if result.get('warning',False):
warning['title'] = title and title +' & '+result['warning']['title'] or result['warning']['title']
warning['message'] = message and message +'\n\n'+result['warning']['message'] or result['warning']['message']
return {'value': result.get('value',{}), 'warning':warning}
sale_order_line()
class purchase_order_line(osv.osv):
@ -239,11 +238,11 @@ class purchase_order_line(osv.osv):
warning = {}
if not product:
return {'value': {'price_unit': 0.0, 'name':'','notes':'', 'product_uom' : False}, 'domain':{'product_uom':[]}}
product_obj = self.pool.get('product.product')
product_obj = self.pool.get('product.product')
product_info = product_obj.browse(cr, uid, product)
title = False
message = False
if product_info.purchase_line_warn != 'no-message':
if product_info.purchase_line_warn == 'block':
raise osv.except_osv(_('Alert for %s !') % (product_info.name), product_info.purchase_line_warn_msg)
@ -251,16 +250,16 @@ class purchase_order_line(osv.osv):
message = product_info.purchase_line_warn_msg
warning['title'] = title
warning['message'] = message
result = super(purchase_order_line, self).product_id_change(cr, uid, ids, pricelist, product, qty, uom,
partner_id, date_order, fiscal_position)
if result.get('warning',False):
warning['title'] = title and title +' & '+result['warning']['title'] or result['warning']['title']
warning['message'] = message and message +'\n\n'+result['warning']['message'] or result['warning']['message']
return {'value': result.get('value',{}), 'warning':warning}
purchase_order_line()