Merged with client

bzr revid: hda@tinyerp.com-20100216142723-ul7m7do5fpl3r9av
This commit is contained in:
HDA (OpenERP) 2010-02-16 19:57:23 +05:30
commit 284ec3e006
36 changed files with 338 additions and 134 deletions

View File

@ -77,7 +77,10 @@ class account_payment_term_line(osv.osv):
_columns = {
'name': fields.char('Line Name', size=32, required=True),
'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the payment term lines from the lowest sequences to the higher ones"),
'value': fields.selection([('procent', 'Percent'), ('balance', 'Balance'), ('fixed', 'Fixed Amount')], 'Value', required=True, help="""Example: 14 days 2%, 30 days net
'value': fields.selection([('procent', 'Percent'),
('balance', 'Balance'),
('fixed', 'Fixed Amount')], 'Value',
required=True, help="""Example: 14 days 2%, 30 days net
1. Line 1: percent 0.02 14 days
2. Line 2: balance 30 days"""),
@ -204,43 +207,50 @@ class account_account(osv.osv):
#compute for each account the balance/debit/credit from the move lines
accounts = {}
if ids2:
query = self.pool.get('account.move.line')._query_get(cr, uid,
context=context)
aml_query = self.pool.get('account.move.line')._query_get(cr, uid, context=context)
wheres = [""]
if query:
wheres.append(query.strip())
if aml_query:
wheres.append(aml_query.strip())
query = " AND ".join(wheres)
cr.execute("SELECT l.account_id as id, " +\
' , '.join(map(lambda x: mapping[x], field_names)) +
"FROM " \
"account_move_line l " \
"WHERE " \
"l.account_id =ANY(%s) " \
"AND " + query + " " \
"GROUP BY l.account_id",(ids2,))
+ query +
" GROUP BY l.account_id",(ids2,))
for res in cr.dictfetchall():
accounts[res['id']] = res
#for the asked accounts, get from the dictionnary 'accounts' the value of it
# consolidate accounts with direct children
brs = list(self.browse(cr, uid, ids2, context=context))
sums = {}
while brs:
current = brs[0]
can_compute = True
for child in current.child_id:
if child.id not in sums:
can_compute = False
try:
brs.insert(0, brs.pop(brs.index(child)))
except ValueError:
brs.insert(0, child)
if can_compute:
brs.pop(0)
for fn in field_names:
sums.setdefault(current.id, {})[fn] = accounts.get(current.id, {}).get(fn, 0.0)
if current.child_id:
sums[current.id][fn] += sum(sums[child.id][fn] for child in current.child_id)
res = {}
for id in ids:
res[id] = self._get_account_values(cr, uid, id, accounts, field_names, context)
return res
def _get_account_values(self, cr, uid, id, accounts, field_names, context={}):
res = {}.fromkeys(field_names, 0.0)
browse_rec = self.browse(cr, uid, id)
if browse_rec.type == 'consolidation':
ids2 = self.read(cr, uid, [browse_rec.id], ['child_consol_ids'], context)[0]['child_consol_ids']
for t in self.search(cr, uid, [('parent_id', 'child_of', [browse_rec.id])]):
if t not in ids2 and t != browse_rec.id:
ids2.append(t)
for i in ids2:
tmp = self._get_account_values(cr, uid, i, accounts, field_names, context)
for a in field_names:
res[a] += tmp[a]
else:
ids2 = self.search(cr, uid, [('parent_id', 'child_of', [browse_rec.id])])
for i in ids2:
for a in field_names:
res[a] += accounts.get(i, {}).get(a, 0.0)
res[id] = sums[id]
return res
def _get_company_currency(self, cr, uid, ids, field_name, arg, context={}):
@ -259,7 +269,8 @@ class account_account(osv.osv):
if record.child_consol_ids:
for acc in record.child_consol_ids:
result[record.id].append(acc.id)
if acc.id not in result[record.id]:
result[record.id].append(acc.id)
return result
@ -1488,8 +1499,8 @@ class account_tax(osv.osv):
exec tax.python_compute_inv in localdict
amount = localdict['result']
elif tax.type=='balance':
data['amount'] = cur_price_unit - reduce(lambda x,y: y.get('amount',0.0)+x, res, 0.0)
data['balance'] = cur_price_unit
amount = cur_price_unit - reduce(lambda x,y: y.get('amount',0.0)+x, res, 0.0)
# data['balance'] = cur_price_unit
if tax.include_base_amount:

View File

@ -91,7 +91,7 @@ class account_analytic_line(osv.osv):
'account.analytic.line': (lambda self,cr,uid,ids,c={}: ids, ['amount','unit_amount'],10),
},
help="The amount expressed in the related account currency if not equal to the company one."),
'ref': fields.char('Reference', size=32),
'ref': fields.char('Ref.', size=64),
}
_defaults = {
'date': lambda *a: time.strftime('%Y-%m-%d'),

View File

@ -107,7 +107,7 @@ class account_bank_statement(osv.osv):
_name = "account.bank.statement"
_description = "Bank Statement"
_columns = {
'name': fields.char('Name', size=64, required=True),
'name': fields.char('Name', size=64, required=True, states={'confirm': [('readonly', True)]}),
'date': fields.date('Date', required=True,
states={'confirm': [('readonly', True)]}),
'journal_id': fields.many2one('account.journal', 'Journal', required=True,
@ -290,7 +290,14 @@ class account_bank_statement(osv.osv):
torec += map(lambda x: x.id, move.reconcile_id.line_ids)
#try:
if abs(move.reconcile_amount-move.amount)<0.0001:
account_move_line_obj.reconcile(cr, uid, torec, 'statement', writeoff_period_id=st.period_id.id, writeoff_journal_id=st.journal_id.id, context=context)
writeoff_acc_id = False
#There should only be one write-off account!
for entry in move.reconcile_id.line_new_ids:
writeoff_acc_id = entry.account_id.id
break
account_move_line_obj.reconcile(cr, uid, torec, 'statement', writeoff_acc_id=writeoff_acc_id, writeoff_period_id=st.period_id.id, writeoff_journal_id=st.journal_id.id, context=context)
else:
account_move_line_obj.reconcile_partial(cr, uid, torec, 'statement', context)
#except:
@ -339,6 +346,17 @@ class account_bank_statement(osv.osv):
context=context)[0]
return {'value': {'balance_start': balance_start, 'currency': currency}}
def unlink(self, cr, uid, ids, context=None):
stat = self.read(cr, uid, ids, ['state'])
unlink_ids = []
for t in stat:
if t['state'] in ('draft'):
unlink_ids.append(t['id'])
else:
raise osv.except_osv(_('Invalid action !'), _('Cannot delete bank statement which are already confirmed !'))
osv.osv.unlink(self, cr, uid, unlink_ids, context=context)
return True
account_bank_statement()

View File

@ -357,7 +357,7 @@ class account_move_line(osv.osv):
'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade", domain=[('type','<>','view'), ('type', '<>', 'closed')], select=2),
'move_id': fields.many2one('account.move', 'Move', ondelete="cascade", states={'valid':[('readonly',True)]}, help="The move of this entry line.", select=2),
'ref': fields.char('Reference', size=32),
'ref': fields.char('Ref.', size=64),
'statement_id': fields.many2one('account.bank.statement', 'Statement', help="The bank statement used for bank reconciliation", select=1),
'reconcile_id': fields.many2one('account.move.reconcile', 'Reconcile', readonly=True, ondelete='set null', select=2),
'reconcile_partial_id': fields.many2one('account.move.reconcile', 'Partial Reconcile', readonly=True, ondelete='set null', select=2),

View File

@ -62,7 +62,6 @@ your own accounts.
<field name="name">Main Receivable</field>
<field name="code">x 40000</field>
<field name="type">receivable</field>
<field name="user_type" ref="account.account_type_asset"/>
<field eval="ref('minimal_0')" name="parent_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="True" name="reconcile"/>
@ -78,7 +77,6 @@ your own chart of account.
<field name="name">Main Payable</field>
<field name="code">x 440000</field>
<field name="type">payable</field>
<field name="user_type" ref="account.account_type_liability"/>
<field eval="ref('minimal_0')" name="parent_id"/>
<field name="company_id" ref="base.main_company"/>
<field eval="True" name="reconcile"/>
@ -94,7 +92,6 @@ your own chart of account.
<field name="name">Petty Cash</field>
<field name="code">x 570000</field>
<field name="type">other</field>
<field name="user_type" ref="account.account_type_cash_moves"/>
<field eval="ref('minimal_0')" name="parent_id"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_type" ref="account_type_cash_moves"/>
@ -109,7 +106,6 @@ your own chart of account.
<field name="name">Products Purchase</field>
<field name="code">x 600000</field>
<field name="type">other</field>
<field name="user_type" ref="account.account_type_expense"/>
<field eval="ref('minimal_0')" name="parent_id"/>
<field name="company_id" ref="base.main_company"/>
<field name="user_type" ref="account_type_expense"/>
@ -124,7 +120,6 @@ your own chart of account.
<field name="name">Products Sales</field>
<field name="code">x 701000</field>
<field name="type">other</field>
<field name="user_type" ref="account.account_type_income"/>
<field eval="ref('minimal_0')" name="parent_id"/>
<field name="user_type" ref="account_type_income"/>
<field name="company_id" ref="base.main_company"/>

View File

@ -64,9 +64,10 @@ class account_invoice(osv.osv):
user = self.pool.get('res.users').browse(cr, uid, uid)
company_id = context.get('company_id', user.company_id.id)
type2journal = {'out_invoice': 'sale', 'in_invoice': 'purchase', 'out_refund': 'sale', 'in_refund': 'purchase'}
refund_journal = {'out_invoice': False, 'in_invoice': False, 'out_refund': True, 'in_refund': True}
journal_obj = self.pool.get('account.journal')
res = journal_obj.search(cr, uid, [('type', '=', type2journal.get(type_inv, 'sale')),
('company_id', '=', company_id)],
('company_id', '=', company_id),('refund_journal', '=', refund_journal.get(type_inv, False))],
limit=1)
if res:
return res[0]
@ -855,7 +856,7 @@ class account_invoice(osv.osv):
def action_cancel(self, cr, uid, ids, *args):
account_move_obj = self.pool.get('account.move')
invoices = self.read(cr, uid, ids, ['move_id'])
invoices = self.read(cr, uid, ids, ['move_id', 'payment_ids'])
for i in invoices:
if i['move_id']:
account_move_obj.button_cancel(cr, uid, [i['move_id'][0]])
@ -863,6 +864,8 @@ class account_invoice(osv.osv):
# Note that the corresponding move_lines and move_reconciles
# 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})
self.write(cr, uid, ids, {'state':'cancel', 'move_id':False})
self._log_event(cr, uid, ids,-1.0, 'Cancel Invoice')
return True
@ -1231,13 +1234,13 @@ class account_invoice_line(osv.osv):
taxes = res.supplier_taxes_id and res.supplier_taxes_id or (a and self.pool.get('account.account').browse(cr, uid,a).tax_ids or False)
tax_id = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, taxes)
if type in ('in_invoice', 'in_refund'):
to_update = self.product_id_change_unit_price_inv(cr, uid, tax_id, price_unit, qty, address_invoice_id, product, partner_id, context=context)
to_update = self.product_id_change_unit_price_inv(cr, uid, tax_id, price_unit or res.standard_price, qty, address_invoice_id, product, partner_id, context=context)
result.update(to_update)
else:
result.update({'price_unit': res.list_price, 'invoice_line_tax_id': tax_id})
if not name:
result['name'] = res.name
result['name'] = res.partner_ref
domain = {}
result['uos_id'] = uom or res.uom_id.id or False

View File

@ -258,7 +258,7 @@ class general_ledger(rml_parse.rml_parse):
else:
sorttag = 'j.code'
sql = """
SELECT l.id, l.date, j.code,c.code AS currency_code,l.amount_currency,l.ref, l.name , l.debit, l.credit, l.period_id
SELECT l.id, l.date, j.code,c.code AS currency_code,l.amount_currency,l.ref, l.name , COALESCE(l.debit,0) as debit, COALESCE(l.credit,0) as credit, l.period_id
FROM account_move_line as l
LEFT JOIN res_currency c on (l.currency_id=c.id)
JOIN account_journal j on (l.journal_id=j.id)

View File

@ -261,7 +261,7 @@ class general_ledger_landscape(rml_parse.rml_parse):
else:
sorttag = 'j.code'
sql = """
SELECT l.id, l.date, j.code,c.code AS currency_code,l.amount_currency,l.ref, l.name , l.debit, l.credit, l.period_id
SELECT l.id, l.date, j.code,c.code AS currency_code,l.amount_currency,l.ref, l.name , COALESCE(l.debit,0) as debit, COALESCE(l.credit,0) as credit, l.period_id
FROM account_move_line as l
LEFT JOIN res_currency c on (l.currency_id=c.id)
JOIN account_journal j on (l.journal_id=j.id)

View File

@ -30,6 +30,11 @@ class ir_sequence_fiscalyear(osv.osv):
"sequence_main_id": fields.many2one("ir.sequence", 'Main Sequence', required=True, ondelete='cascade'),
"fiscalyear_id": fields.many2one('account.fiscalyear', 'Fiscal Year', required=True, ondelete='cascade')
}
_sql_constraints = [
('main_id', 'CHECK (sequence_main_id != sequence_id)', 'Main Sequence must be different from current !'),
]
ir_sequence_fiscalyear()
class ir_sequence(osv.osv):

View File

@ -65,6 +65,13 @@ def _pay_and_reconcile(self, cr, uid, data, context):
currency_id = journal.currency.id
# Put the paid amount in currency, and the currency, in the context if currency is different from company's currency
context.update({'amount_currency':form['amount'],'currency_id':currency_id})
if invoice.company_id.currency_id.id<>invoice.currency_id.id:
ctx = {'date':data['form']['date']}
amount = cur_obj.compute(cr, uid, invoice.currency_id.id, invoice.company_id.currency_id.id, amount, context=ctx)
currency_id = invoice.currency_id.id
# Put the paid amount in currency, and the currency, in the context if currency is different from company's currency
context.update({'amount_currency':form['amount'],'currency_id':currency_id})
# Take the choosen date
if form.has_key('comment'):
@ -91,7 +98,13 @@ def _wo_check(self, cr, uid, data, context):
# => Ask to a write-off of the difference. This could happen even if both amount are equal,
# because if the currency rate
# Get the amount in company currency for the invoice (according to move lines)
inv_amount_company_currency=invoice.move_id.amount
inv_amount_company_currency = 0
for aml in invoice.move_id.line_id:
if aml.account_id.id == invoice.account_id.id or aml.account_id.type in ('receivable', 'payable'):
inv_amount_company_currency += aml.debit
inv_amount_company_currency -= aml.credit
inv_amount_company_currency = abs(inv_amount_company_currency)
# Get the current amount paid in company currency
if journal.currency and invoice.company_id.currency_id.id<>journal.currency.id:
ctx = {'date':data['form']['date']}

View File

@ -71,7 +71,7 @@ def _search_invoices(obj, cr, uid, data, context):
move_line_id = line_obj.search(cr, uid, args_move_line,context=context)
if move_line_id:
repeated_move_line_ids.append(move_line_id)
repeated_move_line_ids += move_line_id
journal_ids = data['form']['journal_id'][0][2]

View File

@ -36,6 +36,20 @@ class account_invoice(osv.osv):
_defaults = {
'price_type': lambda *a: 'tax_excluded',
}
def refund(self, cr, uid, ids, date=None, period_id=None, description=None):
map_old_new = {}
refund_ids = []
for old_inv_id in ids:
new_id = super(account_invoice,self).refund(cr, uid, ids, date=date, period_id=period_id, description=description)
refund_ids += new_id
map_old_new[old_inv_id] = new_id[0]
for old_inv_id in map_old_new.keys():
old_inv_record = self.read(cr, uid, [old_inv_id], ['price_type'])[0]['price_type']
self.write(cr, uid, [map_old_new[old_inv_id]], {'price_type' : old_inv_record})
return refund_ids
account_invoice()
class account_invoice_line(osv.osv):
@ -85,8 +99,8 @@ class account_invoice_line(osv.osv):
res[line.id]['price_subtotal'] = res[line.id]['price_subtotal'] - tax['amount']
res[line.id]['data'].append( tax)
res[line.id]['price_subtotal']= round(res[line.id]['price_subtotal'], int(config['price_accuracy']))
res[line.id]['price_subtotal_incl']= round(res[line.id]['price_subtotal_incl'], int(config['price_accuracy']))
res[line.id]['price_subtotal']= round(res[line.id]['price_subtotal'], int(config['price_accuracy']))
res[line.id]['price_subtotal_incl']= round(res[line.id]['price_subtotal_incl'], int(config['price_accuracy']))
return res
def _price_unit_default(self, cr, uid, context=None):

View File

@ -62,38 +62,12 @@ class account_account(osv.osv):
'type1':fields.selection([('dr','Debit'),('cr','Credit'),('none','None')], 'Dr/Cr',store=True),
}
def compute_total(self, cr, uid, ids, yr_st_date, yr_end_date, st_date, end_date, field_names, context={}, query=''):
#compute the balance/debit/credit accordingly to the value of field_name for the given account ids
mapping = {
'credit': "COALESCE(SUM(l.credit), 0) as credit ",
'balance': "COALESCE(SUM(l.debit),0) - COALESCE(SUM(l.credit), 0) as balance ",
'debit': "COALESCE(SUM(l.debit), 0) as debit ",
}
#get all the necessary accounts
ids2 = self._get_children_and_consol(cr, uid, ids, context)
acc_set = ",".join(map(str, ids2))
#compute for each account the balance/debit/credit from the move lines
def compute_total(self, cr, uid, ids, yr_st_date, yr_end_date, st_date, end_date, field_names, context={}):
if not (st_date >= yr_st_date and end_date <= yr_end_date):
return {}
accounts = {}
if ids2:
query = self.pool.get('account.move.line')._query_get(cr, uid,
context=context)
cr.execute("SELECT l.account_id as id, " \
+ ' , '.join(map(lambda x: mapping[x], field_names.keys() )) + \
"FROM account_move_line l " \
"WHERE l.account_id IN ("+ acc_set +") " \
"AND " + query + " " \
" AND l.date >= "+"'"+ st_date +"'"+" AND l.date <= "+"'"+ end_date +""+"'"" " \
"GROUP BY l.account_id ")
for res in cr.dictfetchall():
accounts[res['id']] = res
#for the asked accounts, get from the dictionnary 'accounts' the value of it
res = {}
for id in ids:
res[id] = self._get_account_values(cr, uid, id, accounts, field_names, context)
return res
query = "l.date >= '%s' AND l.date <= '%s'" (st_date, end_date)
return self.__compute(cr, uid, ids, field_names, context=context, query=query)
def create(self, cr, uid, vals, context={}):
name=self.search(cr,uid,[('name','ilike',vals['name']),('company_id','=',vals['name'])])
if name:

View File

@ -134,17 +134,29 @@ class res_partner_job(osv.osv):
res = []
for r in self.browse(cr, uid, ids):
funct = r.function_id and (", " + r.function_id.name) or ""
res.append((r.id, self.pool.get('res.partner.contact').name_get(cr, uid, [r.contact_id.id])[0][1] + funct ))
res.append((r.id, self.pool.get('res.partner.contact').name_get(cr, uid, [r.contact_id.id])[0][1] + funct))
return res
def search(self, cr, user, args, offset=0, limit=None, order=None,
context=None, count=False):
def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
job_ids = []
for arg in args:
if arg[0]=='address_id':
if arg[0] == 'address_id':
self._order = 'sequence_partner'
if arg[0]=='contact_id':
elif arg[0] == 'contact_id':
self._order = 'sequence_contact'
return super(res_partner_job,self).search(cr, user, args, offset, limit, order, context, count)
contact_obj = self.pool.get('res.partner.contact')
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)
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])
res = super(res_partner_job,self).search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
if job_ids:
res = list(set(res + job_ids))
return res
_name = 'res.partner.job'
_description ='Contact Partner Function'

View File

@ -54,6 +54,21 @@ class report_creator(osv.osv):
#
# Should request only used fields
#
def export_data(self, cr, uid, ids, fields_to_export, context=None):
data_l = self.read(cr, uid, ids, ['sql_query'], context)
final_datas =[]
for i in data_l:
datas = []
for key,value in i.items():
if key not in fields_to_export:
continue
if isinstance(value,tuple):
datas.append(str(value[1]))
else:
datas.append(str(value))
final_datas += [datas]
return {'datas':final_datas}
def fields_get(self, cr, user, fields=None, context=None):
if (not context) or 'report_id' not in context:
return super(report_creator, self).fields_get(cr, user, fields, context)

View File

@ -84,13 +84,13 @@ def set_field_operator(self,field_name,field_type,search_operator,search_value):
field_search[2] = "("+','.join([str(x) for x in search_value])+")"
else:
field_search[1] = 'ilike'
field_search[2] = "'%"+str(search_value)+"%'"
field_search[2] = "'%%"+str(search_value)+"%%'"
elif search_operator == 'not in':
if field_type=='many2one':
field_search[2] = "("+','.join([str(x) for x in search_value])+")"
else:
field_search[1] = 'not ilike'
field_search[2] = "'%"+str(search_value)+"%'"
field_search[2] = "'%%"+str(search_value)+"%%'"
elif search_operator == '^':
if field_type in char_type:
field_search[1]='~'

View File

@ -193,7 +193,7 @@ class DomApi(DomApiGeneral):
s.appendChild(temp)
c = self.findChildrenByName(s,"style:properties")
c = c[0]
dict = self.style_properties_dict[(s.getAttribute("style:name")).encode("latin-1")] or {}
dict = self.style_properties_dict[(s.getAttribute("style:name")).encode("utf-8")] or {}
for attribute in dict.keys():
c.setAttribute(self.openOfficeStringUtf8(attribute),self.openOfficeStringUtf8(dict[attribute]))
@ -242,7 +242,7 @@ class DomApi(DomApiGeneral):
Caution: in this dict the nodes from two dom apis are merged!"""
for st in (self.styles_dom,self.content_dom):
for s in st.getElementsByTagName("style:style"):
name = s.getAttribute("style:name").encode("latin-1")
name = s.getAttribute("style:name").encode("utf-8")
self.style_dict[name] = s
return True
@ -253,14 +253,14 @@ class DomApi(DomApiGeneral):
res = {}
if self.style_dict[style_name].hasAttribute("style:parent-style-name"):
parent = self.style_dict[style_name].getAttribute("style:parent-style-name").encode("latin-1")
parent = self.style_dict[style_name].getAttribute("style:parent-style-name").encode("utf-8")
res = self.getStylePropertiesDict(parent)
childs = self.style_dict[style_name].childNodes
for c in childs:
if c.nodeType == c.ELEMENT_NODE and c.nodeName.find("properties")>0 :
for attr in c._attrs.keys():
res[attr] = c.getAttribute(attr).encode("latin-1")
res[attr] = c.getAttribute(attr).encode("utf-8")
return res
class PyOpenOffice(object):

View File

@ -22,17 +22,44 @@
import netsvc
from osv import fields,osv
from tools.translate import _
import tools
# Overloaded stock_picking to manage carriers :
class stock_picking(osv.osv):
_name = "stock.picking"
_description = "Picking list"
_inherit = 'stock.picking'
def _cal_weight(self, cr, uid, ids, name, args, context=None):
res = {}
data_picking = self.browse(cr, uid, ids, context)
for picking in data_picking:
total_weight = 0.00
if picking.move_lines:
weight = 0.00
for move in picking.move_lines:
if move.product_id.weight > 0.00:
weight = (move.product_uos_qty * move.product_id.weight)
total_weight += weight
res[picking.id] = total_weight
return res
def _get_picking_line(self, cr, uid, ids, context=None):
result = {}
for line in self.pool.get('stock.move').browse(cr, uid, ids, context=context):
result[line.picking_id.id] = True
return result.keys()
_columns = {
'carrier_id':fields.many2one("delivery.carrier","Carrier"),
'volume': fields.float('Volume'),
'weight': fields.float('Weight'),
}
'weight': fields.function(_cal_weight, method=True, type='float', string='Weight',digits=(16, int(tools.config['price_accuracy'])),
store={
'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20),
'stock.move': (_get_picking_line, ['product_id','product_uos_qty'], 20),
}),
}
def action_invoice_create(self, cursor, user, ids, journal_id=False,
group=False, type='out_invoice', context=None):

View File

@ -25,9 +25,8 @@
<field name="type">form</field>
<field name="arch" type="xml">
<field name="register_prospect" position="after">
<separator string="Remaining Tasks" colspan="4"/>
<field name="task_ids" colspan="4" nolabel="1" widget="one2many_list" >
<tree string="All tasks" colors="red:date_deadline&lt;current_date and state=='draft';blue:date_deadline==current_date and state=='draft';grey:state in ('cancel','done');black:state not in ('cancel','done')">
<tree string="All tasks" colors="red:date_deadline&lt;current_date and state=='draft';blue:date_deadline==current_date and state=='draft';grey:state in ('cancel','done');black:state not in ('cancel','done')">
<field name="sequence"/>
<field name="name"/>
<field name="user_id" />

View File

@ -36,7 +36,7 @@ parameter_form = '''<?xml version="1.0"?>
</form>'''
parameter_fields = {
'project_id': {'string':'Project', 'type':'many2one', 'required':True, 'relation':'project.project', 'domain': [('active','<>',False)]},
'project_id': {'string':'Project', 'type':'many2one', 'required':True, 'relation':'project.project', 'domain': [('active','<>',False),('state','=','template')]},
}
def _create_duplicate(self, cr, uid, data, context):

View File

@ -22,6 +22,7 @@
import price
import workcenter_load
import order
import bom_structure
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,64 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import time
from report import report_sxw
from osv import osv
import pooler
class bom_structure(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context):
super(bom_structure, self).__init__(cr, uid, name, context=context)
self.localcontext.update({
'time': time,
'get_children':self.get_children,
})
def get_children(self, object, level=0):
result = []
def _get_rec(object,level):
for l in object:
res = {}
res['name'] = l.name
res['pname'] = l.product_id.name
res['pqty'] = l.product_qty
res['uname'] = l.product_uom.name
res['code'] = l.code
res['level'] = level
result.append(res)
if l.child_complete_ids:
if level<6:
level += 1
_get_rec(l.child_complete_ids,level)
if level>0 and level<6:
level -= 1
return result
children = _get_rec(object,level)
return children
report_sxw.report_sxw('report.bom.structure','mrp.bom','mrp/report/bom_structure.rml',parser=bom_structure)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -112,20 +112,20 @@
</tr>
</blockTable>
<section>
<para style="terp_default_9">[[ repeatIn(o.bom_lines, 'l') ]]</para>
<para style="terp_default_9">[[ repeatIn(get_children(o.bom_lines), 'l') ]]</para>
<blockTable colWidths="166.0,208.0,79.0,55.0" style="Table1">
<tr>
<td>
<para style="P1">- [[ l.name ]]</para>
<para style="P1"><font color="white">[[ '... '*(l['level']) ]]</font>-[[ l['name'] ]]</para>
</td>
<td>
<para style="P1">[[ l.product_id.name ]]</para>
<para style="P1">[[ l['pname'] ]]</para>
</td>
<td>
<para style="P2">[[ l.product_qty ]] [[ l.product_uom.name ]]</para>
<para style="P2">[[ l['pqty'] ]] [[ l['uname'] ]]</para>
</td>
<td>
<para style="terp_default_Centre_9">[[ l.code ]]</para>
<para style="terp_default_Centre_9">[[ l['code'] ]]</para>
</td>
</tr>
</blockTable>
@ -135,4 +135,4 @@
</section>
</section>
</story>
</document>
</document>

View File

@ -60,7 +60,7 @@ class mrp_procurement(osv.osv):
cr.execute('select id from mrp_procurement where state=%s and procure_method=%s order by priority,date_planned limit 500 offset %s', ('confirmed', 'make_to_order', offset))
ids = map(lambda x: x[0], cr.fetchall())
for proc in procurement_obj.browse(cr, uid, ids):
if (maxdate.strftime('%Y-%m-%d')>=proc.date_planned) or (proc.procure_method=='make_to_order'):
if (maxdate.strftime('%Y-%m-%d')>=proc.date_planned):
wf_service.trg_validate(uid, 'mrp.procurement', proc.id, 'button_check', cr)
else:
offset += 1
@ -83,7 +83,7 @@ class mrp_procurement(osv.osv):
report_ids = []
ids = self.pool.get('mrp.procurement').search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_stock')], offset=offset)
for proc in procurement_obj.browse(cr, uid, ids):
if ((maxdate).strftime('%Y-%m-%d') >= proc.date_planned) or (proc.procure_method=='make_to_order'):
if ((maxdate).strftime('%Y-%m-%d') >= proc.date_planned) :
wf_service.trg_validate(uid, 'mrp.procurement', proc.id, 'button_check', cr)
report_ids.append(proc.id)
else:

View File

@ -714,6 +714,8 @@ class pos_order(osv.osv):
'product_id': line.product_id.id,
'quantity': line.qty,
}
inv_name = self.pool.get('product.product').name_get(cr, uid, [line.product_id.id], context=context)[0][1]
inv_line.update(inv_line_ref.product_id_change(cr, uid, [],
line.product_id.id,
line.product_id.uom_id.id,
@ -721,6 +723,7 @@ class pos_order(osv.osv):
inv_line['price_unit'] = line.price_unit
inv_line['discount'] = line.discount
inv_line['account_id'] = acc
inv_line['name'] = inv_name
inv_line['invoice_line_tax_id'] = ('invoice_line_tax_id' in inv_line)\
and [(6, 0, inv_line['invoice_line_tax_id'])] or []

View File

@ -25,6 +25,7 @@ import netsvc
import wizard
import time
from decimal import Decimal
from tools.translate import _
def _get_journal(self, cr, uid, context):

View File

@ -269,7 +269,7 @@ class product_pricelist_version(osv.osv):
_description = "Pricelist Version"
_columns = {
'pricelist_id': fields.many2one('product.pricelist', 'Price List',
required=True, select=True),
required=True, select=True, ondelete='cascade'),
'name': fields.char('Name', size=64, required=True, translate=True),
'active': fields.boolean('Active',
help="When a version is duplicated it is set to non active, so that the " \
@ -354,10 +354,10 @@ class product_pricelist_item(osv.osv):
_columns = {
'name': fields.char('Rule Name', size=64, help="Explicit rule name for this pricelist line."),
'price_version_id': fields.many2one('product.pricelist.version', 'Price List Version', required=True, select=True),
'product_tmpl_id': fields.many2one('product.template', 'Product Template', ondelete='cascade', help="Sets a template if this rule only apply to a template of product. Keep empty for all products"),
'product_id': fields.many2one('product.product', 'Product', ondelete='cascade', help="Sets a product if this rule only apply to one product. Keep empty for all products"),
'categ_id': fields.many2one('product.category', 'Product Category', ondelete='cascade', help="Sets a category of product if this rule only apply to products of a category and his childs. Keep empty for all products"),
'price_version_id': fields.many2one('product.pricelist.version', 'Price List Version', required=True, select=True, ondelete='cascade'),
'product_tmpl_id': fields.many2one('product.template', 'Product Template', ondelete='cascade', help="Set a template if this rule only apply to a template of product. Keep empty for all products"),
'product_id': fields.many2one('product.product', 'Product', ondelete='cascade', help="Set a product if this rule only apply to one product. Keep empty for all products"),
'categ_id': fields.many2one('product.category', 'Product Category', ondelete='cascade', help="Set a category of product if this rule only apply to products of a category and his childs. Keep empty for all products"),
'min_quantity': fields.integer('Min. Quantity', required=True, help="The rule only applies if the partner buys/sells more than this quantity."),
'sequence': fields.integer('Sequence', required=True, help="Gives the sequence order when displaying a list of pricelist items."),

View File

@ -61,13 +61,14 @@ def _compute_tasks(cr, uid, task_list, date_begin):
res = pooler.get_pool(cr.dbname).get('resource.calendar').interval_get(cr, uid, task.project_id.resource_calendar_id.id, date_start, task.remaining_hours)
for (d1,d2) in res:
tasks[task.id].append((d1, d2, task.name, task.user_id.login))
date_close = tasks[task.id][-1][1]
date_close = tasks[task.id] and tasks[task.id][-1][1] or False
# Store result
users[task.user_id.id] = date_close
sequences.append((task.sequence, date_close))
if date_close>last_date:
last_date=date_close
if date_close:
users[task.user_id.id] = date_close
sequences.append((task.sequence, date_close))
if date_close>last_date:
last_date=date_close
return tasks, last_date
def _compute_project(cr, uid, project, date_begin):

View File

@ -20,6 +20,7 @@
##############################################################################
from osv import fields, osv, orm
import tools
class mrp_procurement(osv.osv):
_name = "mrp.procurement"
@ -37,10 +38,18 @@ class mrp_procurement(osv.osv):
l = line
if line.order_id.project_id:
content+="\n\n"+line.order_id.project_id.complete_name
# Creating a project for task.Project is created from Procurement.
proj_name = tools.ustr(procurement.name)
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})
else:
project_id = proj_exist_id[0]
self.write(cr, uid, [procurement.id], {'state':'running'})
task_id = self.pool.get('project.task').create(cr, uid, {
'name': (procurement.origin or procurement.product_id.name) +': '+(procurement.name or ''),
'name': '%s:%s' %(procurement.product_id.name or procurement.origin, procurement.name or ''),
'date_deadline': procurement.date_planned,
'planned_hours': procurement.product_qty,
'remaining_hours': procurement.product_qty,
@ -52,7 +61,8 @@ class mrp_procurement(osv.osv):
'state': 'draft',
'partner_id': l and l.order_id.partner_id.id or False,
'company_id': procurement.company_id.id,
})
'project_id': project_id,
},context=context)
return task_id
mrp_procurement()

View File

@ -56,6 +56,7 @@ class project_work(osv.osv):
res['product_id'] = emp.product_id.id
res['journal_id'] = emp.journal_id.id
res['general_account_id'] = a
res['product_uom_id'] = emp.product_id.uom_id.id
return res
def create(self, cr, uid, vals, *args, **kwargs):
@ -76,6 +77,7 @@ class project_work(osv.osv):
vals_line['general_account_id'] = result['general_account_id']
vals_line['journal_id'] = result['journal_id']
vals_line['amount'] = 00.0
vals_line['product_uom_id'] = result['product_uom_id']
timeline_id = obj.create(cr, uid, vals_line, {})
# Compute based on pricetype
@ -104,6 +106,7 @@ class project_work(osv.osv):
vals_line['product_id'] = result['product_id']
vals_line['general_account_id'] = result['general_account_id']
vals_line['journal_id'] = result['journal_id']
vals_line['product_uom_id'] = result['product_uom_id']
if 'date' in vals:
vals_line['date'] = vals['date'][:10]
if 'hours' in vals:

View File

@ -216,6 +216,13 @@ class purchase_order(osv.osv):
unlink_ids.append(s['id'])
else:
raise osv.except_osv(_('Invalid action !'), _('Cannot delete Purchase Order(s) which are in %s State!' % s['state']))
# TODO: temporary fix in 5.0, to remove in 5.2 when subflows support
# automatically sending subflow.delete upon deletion
wf_service = netsvc.LocalService("workflow")
for id in unlink_ids:
wf_service.trg_validate(uid, 'purchase.order', id, 'purchase_cancel', cr)
return super(purchase_order, self).unlink(cr, uid, unlink_ids, context=context)
def button_dummy(self, cr, uid, ids, context={}):
@ -294,6 +301,8 @@ class purchase_order(osv.osv):
self.write(cr, uid, ids, {'state':'draft','shipped':0})
wf_service = netsvc.LocalService("workflow")
for p_id in ids:
# Deleting the existing instance of workflow for PO
wf_service.trg_delete(uid, 'purchase.order', p_id, cr)
wf_service.trg_create(uid, 'purchase.order', p_id, cr)
return True

View File

@ -302,20 +302,34 @@ class sale_order(osv.osv):
self.pool.get('sale.order.line').write(cr, uid, line_ids, {'invoiced': False, 'state': 'draft', 'invoice_lines': [(6, 0, [])]})
wf_service = netsvc.LocalService("workflow")
for inv_id in ids:
# Deleting the existing instance of workflow for SO
wf_service.trg_delete(uid, 'sale.order', inv_id, cr)
wf_service.trg_create(uid, 'sale.order', inv_id, cr)
return True
def onchange_partner_id(self, cr, uid, ids, part):
if not part:
return {'value': {'partner_invoice_id': False, 'partner_shipping_id': False, 'partner_order_id': False, 'payment_term': False, 'fiscal_position': False}}
addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['delivery', 'invoice', 'contact'])
part = self.pool.get('res.partner').browse(cr, uid, part)
pricelist = part.property_product_pricelist and part.property_product_pricelist.id or False
payment_term = part.property_payment_term and part.property_payment_term.id or False
fiscal_position = part.property_account_position and part.property_account_position.id or False
val = {'partner_invoice_id': addr['invoice'], 'partner_order_id': addr['contact'], 'partner_shipping_id': addr['delivery'], 'payment_term': payment_term, 'fiscal_position': fiscal_position}
dedicated_salesman = part.user_id and part.user_id.id or uid
val = {
'partner_invoice_id': addr['invoice'],
'partner_order_id': addr['contact'],
'partner_shipping_id': addr['delivery'],
'payment_term': payment_term,
'fiscal_position': fiscal_position,
'user_id': dedicated_salesman,
}
if pricelist:
val['pricelist_id'] = pricelist
return {'value': val}
def shipping_policy_change(self, cr, uid, ids, policy, context={}):
@ -749,28 +763,28 @@ class sale_order_line(osv.osv):
_name = 'sale.order.line'
_description = 'Sale Order line'
_columns = {
'order_id': fields.many2one('sale.order', 'Order Reference', required=True, ondelete='cascade', select=True),
'name': fields.char('Description', size=256, required=True, select=True),
'order_id': fields.many2one('sale.order', 'Order Reference', required=True, ondelete='cascade', select=True, readonly=True, states={'draft':[('readonly',False)]}),
'name': fields.char('Description', size=256, required=True, select=True, readonly=True, states={'draft':[('readonly',False)]}),
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of sale order lines."),
'delay': fields.float('Delivery Lead Time', required=True, help="Number of days between the order confirmation the the shipping of the products to the customer"),
'delay': fields.float('Delivery Lead Time', required=True, help="Number of days between the order confirmation the the shipping of the products to the customer", readonly=True, states={'draft':[('readonly',False)]}),
'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], change_default=True),
'invoice_lines': fields.many2many('account.invoice.line', 'sale_order_line_invoice_rel', 'order_line_id', 'invoice_id', 'Invoice Lines', readonly=True),
'invoiced': fields.boolean('Invoiced', readonly=True),
'procurement_id': fields.many2one('mrp.procurement', 'Requisition'),
'price_unit': fields.float('Unit Price', required=True, digits=(16, int(config['price_accuracy']))),
'price_unit': fields.float('Unit Price', required=True, digits=(16, int(config['price_accuracy'])), readonly=True, states={'draft':[('readonly',False)]}),
'price_net': fields.function(_amount_line_net, method=True, string='Net Price', digits=(16, int(config['price_accuracy']))),
'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal'),
'tax_id': fields.many2many('account.tax', 'sale_order_tax', 'order_line_id', 'tax_id', 'Taxes'),
'type': fields.selection([('make_to_stock', 'from stock'), ('make_to_order', 'on order')], 'Requisition Method', required=True),
'property_ids': fields.many2many('mrp.property', 'sale_order_line_property_rel', 'order_id', 'property_id', 'Properties'),
'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal', digits=(16, int(config['price_accuracy']))),
'tax_id': fields.many2many('account.tax', 'sale_order_tax', 'order_line_id', 'tax_id', 'Taxes', readonly=True, states={'draft':[('readonly',False)]}),
'type': fields.selection([('make_to_stock', 'from stock'), ('make_to_order', 'on order')], 'Requisition Method', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'property_ids': fields.many2many('mrp.property', 'sale_order_line_property_rel', 'order_id', 'property_id', 'Properties', readonly=True, states={'draft':[('readonly',False)]}),
'address_allotment_id': fields.many2one('res.partner.address', 'Allotment Partner'),
'product_uom_qty': fields.float('Quantity (UoM)', digits=(16, 2), required=True),
'product_uom': fields.many2one('product.uom', 'Product UoM', required=True),
'product_uos_qty': fields.float('Quantity (UoS)'),
'product_uom_qty': fields.float('Quantity (UoM)', digits=(16, 2), required=True, readonly=True, states={'draft':[('readonly',False)]}),
'product_uom': fields.many2one('product.uom', 'Product UoM', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'product_uos_qty': fields.float('Quantity (UoS)', readonly=True, states={'draft':[('readonly',False)]}),
'product_uos': fields.many2one('product.uom', 'Product UoS'),
'product_packaging': fields.many2one('product.packaging', 'Packaging'),
'move_ids': fields.one2many('stock.move', 'sale_line_id', 'Inventory Moves', readonly=True),
'discount': fields.float('Discount (%)', digits=(16, 2)),
'discount': fields.float('Discount (%)', digits=(16, 2), readonly=True, states={'draft':[('readonly',False)]}),
'number_packages': fields.function(_number_packages, method=True, type='integer', string='Number Packages'),
'notes': fields.text('Notes', translate=True),
'th_weight': fields.float('Weight'),

View File

@ -107,8 +107,13 @@ class make_sale(wizard.interface):
'partner_shipping_id': partner_addr['delivery'],
'order_policy': 'manual',
'date_order': now(),
'fiscal_position': fpos
'fiscal_position': fpos,
}
if partner_id:
partner = partner_obj.browse(cr, uid, partner_id, context=context)
vals['user_id'] = partner.user_id and partner.user_id.id or uid
if data['form']['analytic_account']:
vals['project_id'] = data['form']['analytic_account']
new_id = sale_obj.create(cr, uid, vals)

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) or ' ' ]]</para>
<para style="terp_default_Centre_9">[[ (line.prodlot_id and (line.prodlot_id.name + '/' + line.prodlot_id.ref)) or ' ' ]]</para>
</td>
<td>
<para style="terp_default_Right_9">[[ formatLang(line.product_qty) ]]</para>

View File

@ -1190,10 +1190,17 @@ class stock_move(osv.osv):
return {'value': result}
def onchange_product_id(self, cr, uid, ids, prod_id=False, loc_id=False, loc_dest_id=False):
def onchange_product_id(self, cr, uid, ids, prod_id=False, loc_id=False, loc_dest_id=False, address_id=False):
if not prod_id:
return {}
product = self.pool.get('product.product').browse(cr, uid, [prod_id])[0]
lang = False
if address_id:
addr_rec = self.pool.get('res.partner.address').browse(cr, uid, address_id)
if addr_rec:
lang = addr_rec.partner_id and addr_rec.partner_id.lang or False
ctx = {'lang': lang}
product = self.pool.get('product.product').browse(cr, uid, [prod_id], context=ctx)[0]
uos_id = product.uos_id and product.uos_id.id or False
result = {
'name': product.partner_ref,

View File

@ -148,7 +148,7 @@ class History(osv.osv):
_order = 'id DESC'
_columns={
'create_date':fields.datetime("Date",select=True),
'text_area':fields.text("Text area",select=True),
'text_area':fields.text("Text area"),
'minor_edit':fields.boolean('This is a major edit ?',select=True),
'summary':fields.char('Summary',size=256, select=True),
'write_uid':fields.many2one('res.users',"Modify By", select=True),