bzr revid: solanki.priyesh@gmail.com-20081208121024-1izsduuh2f8c7wcp
This commit is contained in:
Priyesh
2008-12-08 17:40:24 +05:30
45 changed files with 1167 additions and 457 deletions
+57 -98
View File
@@ -1232,6 +1232,7 @@ class account_tax(osv.osv):
'include_base_amount': fields.boolean('Include in base amount', help="Indicate if the amount of tax must be included in the base amount for the computation of the next taxes"),
'company_id': fields.many2one('res.company', 'Company', required=True),
'description': fields.char('Internal Name',size=32),
'price_include': fields.boolean('Tax Included in Price', help="Check this is the price you use on the product and invoices is including this tax.")
}
def name_get(self, cr, uid, ids, context={}):
@@ -1254,6 +1255,7 @@ class account_tax(osv.osv):
'applicable_type': lambda *a: 'true',
'type': lambda *a: 'percent',
'amount': lambda *a: 0,
'price_include': lambda *a: 0,
'active': lambda *a: 1,
'sequence': lambda *a: 1,
'tax_group': lambda *a: 'vat',
@@ -1286,11 +1288,8 @@ class account_tax(osv.osv):
for tax in taxes:
# we compute the amount for the current tax object and append it to the result
if tax.type=='percent':
amount = cur_price_unit * tax.amount
res.append({'id':tax.id,
data = {'id':tax.id,
'name':tax.name,
'amount':amount,
'account_collected_id':tax.account_collected_id.id,
'account_paid_id':tax.account_paid_id.id,
'base_code_id': tax.base_code_id.id,
@@ -1303,47 +1302,21 @@ class account_tax(osv.osv):
'price_unit': cur_price_unit,
'tax_code_id': tax.tax_code_id.id,
'ref_tax_code_id': tax.ref_tax_code_id.id,
})
}
res.append(data)
if tax.type=='percent':
amount = cur_price_unit * tax.amount
data['amount'] = amount
elif tax.type=='fixed':
res.append({'id':tax.id,
'name':tax.name,
'amount':tax.amount,
'account_collected_id':tax.account_collected_id.id,
'account_paid_id':tax.account_paid_id.id,
'base_code_id': tax.base_code_id.id,
'ref_base_code_id': tax.ref_base_code_id.id,
'sequence': tax.sequence,
'base_sign': tax.base_sign,
'tax_sign': tax.tax_sign,
'ref_base_sign': tax.ref_base_sign,
'ref_tax_sign': tax.ref_tax_sign,
'price_unit': 1,
'tax_code_id': tax.tax_code_id.id,
'ref_tax_code_id': tax.ref_tax_code_id.id,})
data['amount'] = tax.amount
elif tax.type=='code':
address = address_id and self.pool.get('res.partner.address').browse(cr, uid, address_id) or None
localdict = {'price_unit':cur_price_unit, 'address':address, 'product':product, 'partner':partner}
exec tax.python_compute in localdict
amount = localdict['result']
res.append({
'id': tax.id,
'name': tax.name,
'amount': amount,
'account_collected_id': tax.account_collected_id.id,
'account_paid_id': tax.account_paid_id.id,
'base_code_id': tax.base_code_id.id,
'ref_base_code_id': tax.ref_base_code_id.id,
'sequence': tax.sequence,
'base_sign': tax.base_sign,
'tax_sign': tax.tax_sign,
'ref_base_sign': tax.ref_base_sign,
'ref_tax_sign': tax.ref_tax_sign,
'price_unit': cur_price_unit,
'tax_code_id': tax.tax_code_id.id,
'ref_tax_code_id': tax.ref_tax_code_id.id,
})
amount2 = res[-1]['amount']
data['amount'] = amount
amount2 = data['amount']
if len(tax.child_ids):
if tax.child_depend:
del res[-1]
@@ -1369,86 +1342,72 @@ class account_tax(osv.osv):
r['amount'] *= quantity
return res
def _unit_compute_inv(self, cr, uid, taxes, price_unit, address_id=None, product=None, partner=None,tax_parent_tot=0.0):
def _unit_compute_inv(self, cr, uid, taxes, price_unit, address_id=None, product=None, partner=None):
taxes = self._applicable(cr, uid, taxes, price_unit, address_id, product, partner)
res = []
taxes.reverse()
cur_price_unit=price_unit
for tax in taxes:
# we compute the amount for the current tax object and append it to the result
tax_parent_tot = 0.0
for tax in taxes:
if (tax.type=='percent') and not tax.include_base_amount:
tax_parent_tot+=tax.amount
for tax in taxes:
if tax.type=='percent':
amount = cur_price_unit - (cur_price_unit / (1 + tax.amount))
res.append({'id':tax.id,
'name':tax.name,
'amount':amount,
'account_collected_id':tax.account_collected_id.id,
'account_paid_id':tax.account_paid_id.id,
'base_code_id': tax.base_code_id.id,
'ref_base_code_id': tax.ref_base_code_id.id,
'sequence': tax.sequence,
'base_sign': tax.base_sign,
'tax_sign': tax.tax_sign,
'ref_base_sign': tax.ref_base_sign,
'ref_tax_sign': tax.ref_tax_sign,
'price_unit': cur_price_unit - amount,
'tax_code_id': tax.tax_code_id.id,
'ref_tax_code_id': tax.ref_tax_code_id.id,})
if tax.include_base_amount:
amount = cur_price_unit - (cur_price_unit / (1 + tax.amount))
else:
amount = (cur_price_unit / (1 + tax_parent_tot)) * tax.amount
elif tax.type=='fixed':
res.append({'id':tax.id,
'name':tax.name,
'amount':tax.amount,
'account_collected_id':tax.account_collected_id.id,
'account_paid_id':tax.account_paid_id.id,
'base_code_id': tax.base_code_id.id,
'ref_base_code_id': tax.ref_base_code_id.id,
'sequence': tax.sequence,
'base_sign': tax.base_sign,
'tax_sign': tax.tax_sign,
'ref_base_sign': tax.ref_base_sign,
'ref_tax_sign': tax.ref_tax_sign,
'price_unit': 1,
'tax_code_id': tax.tax_code_id.id,
'ref_tax_code_id': tax.ref_tax_code_id.id,})
amount = tax.amount
elif tax.type=='code':
address = address_id and self.pool.get('res.partner.address').browse(cr, uid, address_id) or None
localdict = {'price_unit':cur_price_unit, 'address':address, 'product':product, 'partner':partner}
exec tax.python_compute_inv in localdict
amount = localdict['result']
res.append({
'id': tax.id,
'name': tax.name,
'amount': amount,
'account_collected_id': tax.account_collected_id.id,
'account_paid_id': tax.account_paid_id.id,
'base_code_id': tax.base_code_id.id,
'ref_base_code_id': tax.ref_base_code_id.id,
'sequence': tax.sequence,
'base_sign': tax.base_sign,
'tax_sign': tax.tax_sign,
'ref_base_sign': tax.ref_base_sign,
'ref_tax_sign': tax.ref_tax_sign,
'price_unit': cur_price_unit - amount,
'tax_code_id': tax.tax_code_id.id,
'ref_tax_code_id': tax.ref_tax_code_id.id,
})
amount2 = res[-1]['amount']
if tax.include_base_amount:
cur_price_unit -= amount
todo = 0
else:
todo = 1
res.append({
'id': tax.id,
'todo': todo,
'name': tax.name,
'amount': amount,
'account_collected_id': tax.account_collected_id.id,
'account_paid_id': tax.account_paid_id.id,
'base_code_id': tax.base_code_id.id,
'ref_base_code_id': tax.ref_base_code_id.id,
'sequence': tax.sequence,
'base_sign': tax.base_sign,
'tax_sign': tax.tax_sign,
'ref_base_sign': tax.ref_base_sign,
'ref_tax_sign': tax.ref_tax_sign,
'price_unit': cur_price_unit,
'tax_code_id': tax.tax_code_id.id,
'ref_tax_code_id': tax.ref_tax_code_id.id,
})
if len(tax.child_ids):
if tax.child_depend:
del res[-1]
amount = price_unit
else:
amount = amount2
for t in tax.child_ids:
parent_tax = self._unit_compute_inv(cr, uid, [t], amount, address_id, product, partner)
res.extend(parent_tax)
if tax.include_base_amount:
cur_price_unit-=amount
taxes.reverse()
parent_tax = self._unit_compute_inv(cr, uid, tax.child_ids, amount, address_id, product, partner)
res.extend(parent_tax)
total = 0.0
for r in res:
if r['todo']:
total += r['amount']
for r in res:
r['price_unit'] -= total
r['todo'] = 0
return res
def compute_inv(self, cr, uid, taxes, price_unit, quantity, address_id=None, product=None, partner=None):
+1 -1
View File
@@ -66,7 +66,7 @@ class account_bank_statement(osv.osv):
else:
if line.account_id.id == \
statement.journal_id.default_credit_account_id.id:
res[statement.id] += res_currency_obj.compute(cursor,
res[statement.id] -= res_currency_obj.compute(cursor,
user, company_currency_id, currency_id,
line.credit, context=context)
if statement.state == 'draft':
+2
View File
@@ -557,6 +557,7 @@
<field name="arch" type="xml">
<tree string="Account Tax">
<field name="name"/>
<field name="price_include"/>
<field name="description"/>
</tree>
</field>
@@ -588,6 +589,7 @@
<label colspan="2" nolabel="1" string="Keep empty to use the expense account"/>
<field groups="base.group_extended" name="child_depend"/>
<field groups="base.group_extended" name="sequence"/>
<field groups="base.group_extended" name="price_include"/>
<newline/>
<field colspan="4" groups="base.group_extended" name="child_ids"/>
</page>
+56 -22
View File
@@ -31,24 +31,20 @@ from tools import config
from tools.translate import _
class account_invoice(osv.osv):
def _amount_untaxed(self, cr, uid, ids, name, args, context={}):
id_set=",".join(map(str,ids))
cr.execute("SELECT s.id,COALESCE(SUM(l.price_subtotal),0)::decimal(16,2) AS amount FROM account_invoice s LEFT OUTER JOIN account_invoice_line l ON (s.id=l.invoice_id) WHERE s.id IN ("+id_set+") GROUP BY s.id ")
res=dict(cr.fetchall())
return res
def _amount_tax(self, cr, uid, ids, name, args, context={}):
id_set=",".join(map(str,ids))
cr.execute("SELECT s.id,COALESCE(SUM(l.amount),0)::decimal(16,2) AS amount FROM account_invoice s LEFT OUTER JOIN account_invoice_tax l ON (s.id=l.invoice_id) WHERE s.id IN ("+id_set+") GROUP BY s.id ")
res=dict(cr.fetchall())
return res
def _amount_total(self, cr, uid, ids, name, args, context={}):
untax = self._amount_untaxed(cr, uid, ids, name, args, context)
tax = self._amount_tax(cr, uid, ids, name, args, context)
def _amount_all(self, cr, uid, ids, name, args, context={}):
res = {}
for id in ids:
res[id] = untax.get(id,0.0) + tax.get(id,0.0)
print ids
for invoice in self.browse(cr,uid,ids, context=context):
res[invoice.id] = {
'amount_untaxed': 0.0,
'amount_tax': 0.0,
'amount_total': 0.0
}
for line in invoice.invoice_line:
res[invoice.id]['amount_untaxed'] += line.price_subtotal
for line in invoice.tax_line:
res[invoice.id]['amount_tax'] += line.amount
res[invoice.id]['amount_total'] = res[invoice.id]['amount_tax'] + res[invoice.id]['amount_untaxed']
return res
def _get_journal(self, cr, uid, context):
@@ -118,6 +114,20 @@ class account_invoice(osv.osv):
res[id]=[x for x in l if x <> line.id]
return res
def _get_invoice_line(self, cr, uid, ids, context={}):
result = {}
for line in self.pool.get('account.invoice.line').browse(cr, uid, ids, context=context):
print '\t', line.invoice_id
result[line.invoice_id.id] = True
print result
return result.keys()
def _get_invoice_tax(self, cr, uid, ids, context={}):
result = {}
for tax in self.pool.get('account.invoice.tax').browse(cr, uid, ids, context=context):
result[tax.invoice_id.id] = True
return result.keys()
def _compute_lines(self, cr, uid, ids, name, args, context={}):
result = {}
for invoice in self.browse(cr, uid, ids, context):
@@ -178,18 +188,42 @@ class account_invoice(osv.osv):
'tax_line': fields.one2many('account.invoice.tax', 'invoice_id', 'Tax Lines', readonly=True, states={'draft':[('readonly',False)]}),
'move_id': fields.many2one('account.move', 'Invoice Movement', readonly=True, help="Link to the automatically generated account moves."),
'amount_untaxed': fields.function(_amount_untaxed, method=True, digits=(16,2),string='Untaxed', store=True),
'amount_tax': fields.function(_amount_tax, method=True, digits=(16,2), string='Tax', store=True),
'amount_total': fields.function(_amount_total, method=True, digits=(16,2), string='Total', store=True),
'amount_untaxed': fields.function(_amount_all, method=True, digits=(16,2),string='Untaxed',
store={
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, None, 10),
'account.invoice.tax': (_get_invoice_tax, None, 10),
'account.invoice.line': (_get_invoice_line, None, 10),
},
multi='all'),
'amount_tax': fields.function(_amount_all, method=True, digits=(16,2), string='Tax',
store={
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, None, 10),
'account.invoice.tax': (_get_invoice_tax, None, 10),
'account.invoice.line': (_get_invoice_line, None, 10),
},
multi='all'),
'amount_total': fields.function(_amount_all, method=True, digits=(16,2), string='Total',
store={
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, None, 10),
'account.invoice.tax': (_get_invoice_tax, None, 10),
'account.invoice.line': (_get_invoice_line, None, 10),
},
multi='all'),
'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}),
'journal_id': fields.many2one('account.journal', 'Journal', required=True,readonly=True, states={'draft':[('readonly',False)]}),
'company_id': fields.many2one('res.company', 'Company', required=True),
'check_total': fields.float('Total', digits=(16,2), states={'open':[('readonly',True)],'close':[('readonly',True)]}),
'reconciled': fields.function(_reconciled, method=True, string='Paid/Reconciled', type='boolean', store=True, help="The account moves of the invoice have been reconciled with account moves of the payment(s)."),
'reconciled': fields.function(_reconciled, method=True, string='Paid/Reconciled', type='boolean',
store=True, help="The account moves of the invoice have been reconciled with account moves of the payment(s)."),
'partner_bank': fields.many2one('res.partner.bank', 'Bank Account',
help='The bank account to pay to or to be paid from'),
'move_lines':fields.function(_get_lines , method=True,type='many2many' , relation='account.move.line',string='Move Lines'),
'residual': fields.function(_amount_residual, method=True, digits=(16,2),string='Residual', store=True, help="Remaining amount due."),
'residual': fields.function(_amount_residual, method=True, digits=(16,2),string='Residual',
store={
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, None, 12),
'account.invoice.tax': (_get_invoice_tax, None, 12),
},
help="Remaining amount due."),
'payment_ids': fields.function(_compute_lines, method=True, relation='account.move.line', type="many2many", string='Payments'),
'move_name': fields.char('Account Move', size=64),
}
+2 -2
View File
@@ -106,11 +106,11 @@
<para style="P18">
<font color="white"> </font>
</para>
<para style="P18">Exception made if there was a mistake of ours, it seems that the following bills staid unpaid. Please, take appropriate measures in order to carry out this payment in the next 8 days.</para>
<para style="P18">According to our accounting, the following Invoices are unpaid. Could you please verify on your side, and take appropriate measures to pay the balance due in the next 8 days.</para>
<para style="P18">
<font color="white"> </font>
</para>
<para style="P18">Would your payment have been carried out after this mail was sent, please consider the present one as void. Do not hesitate to contact our accounting departement at (+32).10.68.94.39.</para>
<para style="P18">If the payment has been very recently made i.e. as this reminder was issued, consider this reminder as void. Do not hesitate to contact our accounting department for further queries.</para>
<para style="P18">
<font color="white"> </font>
</para>
+62 -76
View File
@@ -26,42 +26,12 @@ from osv import fields, osv
import ir
class account_invoice(osv.osv):
def _amount_untaxed(self, cr, uid, ids, name, args, context={}):
res = {}
for invoice in self.browse(cr,uid,ids):
if invoice.price_type == 'tax_included':
res[invoice.id] = reduce( lambda x, y: x+y.price_subtotal, invoice.invoice_line,0)
else:
res[invoice.id] = super(account_invoice, self)._amount_untaxed(cr, uid, [invoice.id], name, args, context)[invoice.id]
return res
def _amount_tax(self, cr, uid, ids, name, args, context={}):
res = {}
for invoice in self.browse(cr,uid,ids):
if invoice.price_type == 'tax_included':
res[invoice.id] = reduce( lambda x, y: x+y.amount, invoice.tax_line,0)
else:
res[invoice.id] = super(account_invoice, self)._amount_tax(cr, uid, [invoice.id], name, args, context)[invoice.id]
return res
def _amount_total(self, cr, uid, ids, name, args, context={}):
res = {}
for invoice in self.browse(cr,uid,ids):
if invoice.price_type == 'tax_included':
res[invoice.id]= invoice.amount_untaxed + invoice.amount_tax
else:
res[invoice.id] = super(account_invoice, self)._amount_total(cr, uid, [invoice.id], name, args, context)[invoice.id]
return res
_inherit = "account.invoice"
_columns = {
'price_type': fields.selection([('tax_included','Tax included'),
('tax_excluded','Tax excluded')],
'Price method', required=True, readonly=True,
states={'draft':[('readonly',False)]}),
'amount_untaxed': fields.function(_amount_untaxed, digits=(16,2), method=True,string='Untaxed Amount'),
'amount_tax': fields.function(_amount_tax, method=True, string='Tax', store=True),
'amount_total': fields.function(_amount_total, method=True, string='Total', store=True),
}
_defaults = {
'price_type': lambda *a: 'tax_excluded',
@@ -70,47 +40,51 @@ account_invoice()
class account_invoice_line(osv.osv):
_inherit = "account.invoice.line"
def _amount_line(self, cr, uid, ids, name, args, context={}):
def _amount_line2(self, cr, uid, ids, name, args, context={}):
"""
Return the subtotal excluding taxes with respect to price_type.
"""
res = {}
tax_obj = self.pool.get('account.tax')
res = super(account_invoice_line, self)._amount_line(cr, uid, ids, name, args, context)
res2 = res.copy()
res_init = super(account_invoice_line, self)._amount_line(cr, uid, ids, name, args, context)
for line in self.browse(cr, uid, ids):
res[line.id] = {
'price_subtotal': 0.0,
'price_subtotal_incl': 0.0,
'data': []
}
if not line.quantity:
res[line.id] = 0.0
continue
if line.invoice_id and line.invoice_id.price_type == 'tax_included':
product_taxes = None
if line.invoice_id:
product_taxes = []
if line.product_id:
if line.invoice_id.type in ('out_invoice', 'out_refund'):
product_taxes = line.product_id.taxes_id
product_taxes = filter(lambda x: x.price_include, line.product_id.taxes_id)
else:
product_taxes = line.product_id.supplier_taxes_id
if product_taxes:
for tax in tax_obj.compute_inv(cr, uid, product_taxes, res[line.id]/line.quantity, line.quantity):
res[line.id] = res[line.id] - round(tax['amount'], 2)
product_taxes = filter(lambda x: x.price_include, line.product_id.supplier_taxes_id)
if ((set(product_taxes) == set(line.invoice_line_tax_id)) or not product_taxes) and (line.invoice_id.price_type == 'tax_included'):
res[line.id]['price_subtotal_incl'] = res_init[line.id]
else:
for tax in tax_obj.compute_inv(cr, uid,line.invoice_line_tax_id, res[line.id]/line.quantity, line.quantity):
res[line.id] = res[line.id] - round(tax['amount'], 2)
if name == 'price_subtotal_incl' and line.invoice_id and line.invoice_id.price_type == 'tax_included':
prod_taxe_ids = None
line_taxe_ids = None
if product_taxes:
prod_taxe_ids = [ t.id for t in product_taxes ]
prod_taxe_ids.sort()
line_taxe_ids = [ t.id for t in line.invoice_line_tax_id ]
line_taxe_ids.sort()
if product_taxes and prod_taxe_ids == line_taxe_ids:
res[line.id] = res2[line.id]
elif not line.product_id:
res[line.id] = res2[line.id]
else:
for tax in tax_obj.compute(cr, uid, line.invoice_line_tax_id, res[line.id]/line.quantity, line.quantity):
res[line.id] = res[line.id] + tax['amount']
res[line.id]= round(res[line.id], 2)
res[line.id]['price_subtotal'] = res_init[line.id]
for tax in tax_obj.compute_inv(cr, uid, product_taxes, res_init[line.id]/line.quantity, line.quantity):
res[line.id]['price_subtotal'] = res[line.id]['price_subtotal'] - round(tax['amount'], 2)
else:
res[line.id]['price_subtotal'] = res_init[line.id]
if res[line.id]['price_subtotal']:
res[line.id]['price_subtotal_incl'] = res[line.id]['price_subtotal']
for tax in tax_obj.compute(cr, uid, line.invoice_line_tax_id, res[line.id]['price_subtotal']/line.quantity, line.quantity):
res[line.id]['price_subtotal_incl'] = res[line.id]['price_subtotal_incl'] + tax['amount']
res[line.id]['data'].append( tax)
else:
res[line.id]['price_subtotal'] = res[line.id]['price_subtotal_incl']
for tax in tax_obj.compute_inv(cr, uid, line.invoice_line_tax_id, res[line.id]['price_subtotal_incl']/line.quantity, line.quantity):
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'], 2)
res[line.id]['price_subtotal_incl']= round(res[line.id]['price_subtotal_incl'], 2)
return res
def _price_unit_default(self, cr, uid, context={}):
@@ -125,9 +99,17 @@ class account_invoice_line(osv.osv):
return super(account_invoice_line, self)._price_unit_default(cr, uid, context)
return 0
def _get_invoice(self, cr, uid, ids, context):
result = {}
for inv in self.pool.get('account.invoice').browse(cr, uid, ids, context=context):
for line in inv.invoice_line:
result[line.id] = True
return result.keys()
_columns = {
'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal w/o tax', store=True),
'price_subtotal_incl': fields.function(_amount_line, method=True, string='Subtotal'),
'price_subtotal': fields.function(_amount_line2, method=True, string='Subtotal w/o tax', multi='amount',
store={'account.invoice':(_get_invoice,['price_type']), 'account.invoice.line': (lambda self,cr,uid,ids,c={}: ids, None)}),
'price_subtotal_incl': fields.function(_amount_line2, method=True, string='Subtotal', multi='amount',
store={'account.invoice':(_get_invoice,['price_type']), 'account.invoice.line': (lambda self,cr,uid,ids,c={}: ids, None)}),
}
_defaults = {
@@ -147,32 +129,36 @@ class account_invoice_line(osv.osv):
'account_analytic_id':line.account_analytic_id.id,
}
def product_id_change_unit_price_inv(self, cr, uid, tax_id, price_unit, qty, address_invoice_id, product, partner_id, context={}):
if context.get('price_type', False) == 'tax_included':
return {'price_unit': price_unit,'invoice_line_tax_id': tax_id}
else:
return super(account_invoice_line, self).product_id_change_unit_price_inv(cr, uid, tax_id, price_unit, qty, address_invoice_id, product, partner_id, context=context)
def product_id_change(self, cr, uid, ids, product, uom, qty=0, name='', type='out_invoice', partner_id=False, price_unit=False, address_invoice_id=False, price_type='tax_excluded', context={}):
context.update({'price_type': price_type})
return super(account_invoice_line, self).product_id_change(cr, uid, ids, product, uom, qty, name, type, partner_id, price_unit, address_invoice_id, context=context)
# TODO: check why ?
#
# def product_id_change_unit_price_inv(self, cr, uid, tax_id, price_unit, qty, address_invoice_id, product, partner_id, context={}):
# if context.get('price_type', False) == 'tax_included':
# return {'price_unit': price_unit,'invoice_line_tax_id': tax_id}
# else:
# return super(account_invoice_line, self).product_id_change_unit_price_inv(cr, uid, tax_id, price_unit, qty, address_invoice_id, product, partner_id, context=context)
#
# def product_id_change(self, cr, uid, ids, product, uom, qty=0, name='', type='out_invoice', partner_id=False, price_unit=False, address_invoice_id=False, price_type='tax_excluded', context={}):
# context.update({'price_type': price_type})
# return super(account_invoice_line, self).product_id_change(cr, uid, ids, product, uom, qty, name, type, partner_id, price_unit, address_invoice_id, context=context)
account_invoice_line()
class account_invoice_tax(osv.osv):
_inherit = "account.invoice.tax"
def compute(self, cr, uid, invoice_id):
def compute(self, cr, uid, invoice_id, context={}):
inv = self.pool.get('account.invoice').browse(cr, uid, invoice_id)
line_ids = map(lambda x: x.id, inv.invoice_line)
tax_grouped = {}
tax_obj = self.pool.get('account.tax')
cur_obj = self.pool.get('res.currency')
inv = self.pool.get('account.invoice').browse(cr, uid, invoice_id)
cur = inv.currency_id
if inv.price_type=='tax_excluded':
return super(account_invoice_tax,self).compute(cr, uid, invoice_id)
for line in inv.invoice_line:
for tax in tax_obj.compute_inv(cr, uid, line.invoice_line_tax_id, (line.price_unit * (1-(line.discount or 0.0)/100.0)), line.quantity, inv.address_invoice_id.id, line.product_id, inv.partner_id):
data = self.pool.get('account.invoice.line')._amount_line2(cr, uid, [line.id], [], [], context)[line.id]
for tax in data['data']:
val={}
val['invoice_id'] = inv.id
val['name'] = tax['name']
+4 -5
View File
@@ -20,13 +20,12 @@
#
##############################################################################
{
"name" : "India Accounting",
"name" : "Accounting - Voucher Management",
"version" : "1.0",
"author" : "Tiny",
"description": """
India Accounting module includes all the basic requirenment of
Basic Accounting, plus new things which available are
* Indian Account Chart
India Accounting module includes all the basic requirenment of
Basic Accounting, plus new things which available are:
* New Invoice - (Local, Retail)
* Invoice Report
* Tax structure
@@ -51,4 +50,4 @@
],
"active": False,
"installable": True
}
}
+11 -12
View File
@@ -1,9 +1,9 @@
<?xml version="1.0"?>
<terp>
<openerp>
<data>
<report id="report_account_voucher"
string="Voucher Report (Cr/Dr)"
string="Voucher Report"
model="account.voucher"
name="voucher.cash_receipt"
rml="account_voucher/report/report_voucher.rml"
@@ -11,15 +11,14 @@
header = "False"
menu="True"/>
<report id="report_account_voucher_amt"
string="Voucher Report"
model="account.voucher"
name="voucher.cash_amount"
rml="account_voucher/report/report_voucher_amount.rml"
auto="False"
header = "False"
menu="True"/>
<!-- <report id="report_account_voucher_amt"-->
<!-- string="Voucher Report"-->
<!-- model="account.voucher"-->
<!-- name="voucher.cash_amount"-->
<!-- rml="account_voucher/report/report_voucher_amount.rml"-->
<!-- auto="False"-->
<!-- header = "False"-->
<!-- menu="True"/>-->
</data>
</terp>
</openerp>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<terp>
<openerp>
<data>
<wizard
@@ -17,4 +17,4 @@
type="wizard"
/>
</data>
</terp>
</openerp>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<terp>
<openerp>
<data>
<record id="wkf_voucher" model="workflow">
@@ -72,4 +72,4 @@
<field name="signal">open_voucher</field>
</record>
</data>
</terp>
</openerp>
@@ -180,7 +180,7 @@
<blockTable colWidths="251.0,110.0,115.0" style="Table2">
<tr>
<td>
<para style="P11">[[ (move_ids.partner_id and move_ids.partner_id.name) or '']] :</para>
<para style="P11">[[ (move_ids.partner_id and move_ids.partner_id.name) or 'Account']] :</para>
<para style="P28">[[ move_ids.account_id.name ]] </para>
<para style="P31">[[ get_ref(voucher.id,move_ids) ]]</para>
</td>
+12 -16
View File
@@ -29,6 +29,16 @@ from mx.DateTime import RelativeDateTime
from tools import config
type2journal = {
'rec_voucher':'cash',
'bank_rec_voucher':'cash',
'pay_voucher': 'cash',
'bank_pay_voucher':'cash',
'cont_voucher':'cash',
'journal_sale_voucher':'sale',
'journal_pur_voucher':'purchase'
}
class account_voucher(osv.osv):
def _get_period(self, cr, uid, context):
periods = self.pool.get('account.period').find(cr, uid)
@@ -45,9 +55,9 @@ class account_voucher(osv.osv):
return [('none', 'Free Reference')]
def _get_journal(self, cr, uid, context):
type_inv = context #.get('type', 'rec_voucher')
type2journal = {'rec_voucher': 'cash', 'bank_rec_voucher': 'cash','pay_voucher': 'cash','bank_pay_voucher': 'cash', 'cont_voucher': 'cash','journal_sale_voucher': 'sale','journal_pur_voucher': 'purchase' }
type_inv = context.get('type', 'rec_voucher')
journal_obj = self.pool.get('account.journal')
res = False
res = journal_obj.search(cr, uid, [('type', '=', type2journal.get(type_inv, 'cash'))], limit=1)
if res:
return res[0]
@@ -99,18 +109,6 @@ class account_voucher(osv.osv):
'move_ids':fields.many2many('account.move.line', 'voucher_id', 'account_id', 'rel_account_move', 'Real Entry'),
}
# def get_bank(self, cr, uid, context={}):
# type = context.get('type', 'bank_payment')
# journal = self.pool.get('account.journal')
# if type == 'bank_payment':
# id = journal.search(cr, uid, [('name','ilike','Bank')])
# return id
# elif type == 'cash_payment':
# id = journal.search(cr, uid, [('name','ilike','Cash')])
# return id
#
# return 3
_defaults = {
#'journal_id':get_bank,
'state': lambda *a: 'draft',
@@ -123,8 +121,6 @@ class account_voucher(osv.osv):
self.pool.get('res.users').browse(cr, uid, uid,
context=context).company_id.id,
'currency_id': _get_currency,
}
def _get_analytic_lines(self, cr, uid, id):
+2 -2
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<terp>
<openerp>
<data>
<record model="ir.ui.view" id="view_voucher_tree">
<field name="name">account.voucher.tree</field>
@@ -293,4 +293,4 @@
<menuitem name="Financial Management/Voucher Entries/Other Vouchers/Journal Purchase Voucher" id="menu_action_view_jour_pur_voucher_form" action="action_view_jour_pur_voucher_form"/>
</data>
</terp>
</openerp>
+24
View File
@@ -0,0 +1,24 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 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 wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+44
View File
@@ -0,0 +1,44 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 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/>.
#
##############################################################################
{
"name" : "Module Merger",
"version" : "1.0",
"author" : "Tiny",
"website" : "http://tinyerp.com",
"category" : "Generic Modules/Base",
"description": """
* The wizard asks a many2many of modules
* And then generate a module which is the merge of all selected modules
* The new module is provided as a .zip file
The merge will works in all situations:
* Merging all .py files with the same name in the new module
* merging all .xml files and take care of id's.
""",
"depends" : ["base"],
"init_xml" : [ ],
"demo_xml" : [ ],
"update_xml" : [ "base_module_merge_wizard.xml" ],
"installable": True
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,20 @@
<?xml version="1.0"?>
<openerp>
<data>
<wizard
id="wizard_base_module_merger"
string="Merge module"
model="ir.module.module"
multi="True"
name="base_module_merge.module_merge"/>
<menuitem
parent="base.menu_management"
type="wizard"
action="wizard_base_module_merger"
id="menu_wizard_base_module_merger"/>
</data>
</openerp>
@@ -20,15 +20,6 @@
#
##############################################################################
from osv import fields, osv
import base_module_merge
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
#class res_partner(osv.osv):
# _name = 'res.partner'
# _inherit = 'res.partner'
# _columns = {
# 'sales': fields.one2many('sale.order', 'partner_id', 'Sales'),
# }
#
#res_partner()
#
@@ -0,0 +1,302 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 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 wizard
import osv
import pooler
import tools
import os
from xml.dom import minidom
info_start_form = '''<?xml version="1.0"?>
<form string="Module Merging">
<field name="modules_list" colspan="4"/>
</form>'''
info_start_fields = {
'modules_list': {'string':'Modules', 'type':'many2many','relation':'ir.module.module','help':'Select Modules which you want to merge in single module'},
}
intro_start_form = '''<?xml version="1.0"?>
<form string="Module Recording">
<separator string="Module Information" colspan="4"/>
<field name="name"/>
<field name="directory_name"/>
<field name="version"/>
<field name="author"/>
<field name="website" colspan="4"/>
<field name="category" colspan="4"/>
<field name="data_kind"/>
<newline/>
<field name="description" colspan="4"/>
</form>'''
intro_start_fields = {
'name': {'string':'Module Name', 'type':'char', 'size':64, 'required':True},
'directory_name': {'string':'Directory Name', 'type':'char', 'size':32, 'required':True},
'version': {'string':'Version', 'type':'char', 'size':16, 'required':True},
'author': {'string':'Author', 'type':'char', 'size':64, 'default': lambda *args: 'Tiny', 'required':True},
'category': {'string':'Category', 'type':'char', 'size':64, 'default': lambda *args: 'Vertical Modules/Parametrization', 'required':True},
'website': {'string':'Documentation URL', 'type':'char', 'size':64, 'default': lambda *args: 'http://tinyerp.com', 'required':True},
'description': {'string':'Full Description', 'type':'text', 'required':True},
'data_kind': {'string':'Type of Data', 'type':'selection', 'selection':[('demo','Demo Data'),('update','Normal Data')], 'required':True, 'default': lambda *args:'update'},
}
intro_save_form = '''<?xml version="1.0"?>
<form string="Module Recording">
<separator string="Module successfully created !" colspan="4"/>
<field name="module_filename"/>
<newline/>
<field name="module_file"/>
<separator string="Information" colspan="4"/>
<label string="If you think your module could interrest others people, we'd like you to publish it on TinyERP.com, in the 'Modules' section. You can do it through the website or using features of the 'base_module_publish' module." colspan="4" align="0.0"/>
<label string="Thanks in advance for your contribution." colspan="4" align="0.0"/>
</form>'''
intro_save_fields = {
'module_file': {'string': 'Module .zip File', 'type':'binary', 'readonly':True},
'module_filename': {'string': 'Filename', 'type':'char', 'size': 64, 'readonly':True},
}
import zipfile
from zipfile import PyZipFile, ZIP_DEFLATED
import StringIO
import base64
class base_module_merge(wizard.interface):
def _zip_writestr(self,file_name,data):
info = zipfile.ZipInfo(file_name)
info.compress_type = zipfile.ZIP_DEFLATED
info.external_attr = 2175008768
self.archive.writestr(info,data)
return True
def _remove_prefix_ref(self,fromurl,path):
infile=tools.file_open(os.path.join(fromurl,path))
xml=infile.read()
mydom = minidom.parseString(xml)
for child in mydom.getElementsByTagName("field"):
for attr in child.attributes.keys():
if attr=='ref':
old=child.getAttribute(attr)
if len(old.split('.')) > 1:
if old.split('.')[0] in self.dependencies:
child.setAttribute(attr,old.split('.')[1])
return mydom.toxml()
def _parse_init(self,path,filename):
res=[]
path=os.path.join(path,filename)
infile=open(path,'r')
for i in infile:
i=i.strip()
if len(i)>0:
if i[0]!="#":
res.append( i.strip().split('\n')[0])
infile.close()
return res
def _zippy(self,archive, fromurl, path, src=True):
if path!='':
url = os.path.join(fromurl, path)
else:
url=fromurl
if os.path.isdir(url):
if path.split('/')[-1].startswith('.'):
return False
for fname in os.listdir(url):
self._zippy(self.archive, fromurl, path and os.path.join(path, fname) or fname, src=src)
else:
if src:
exclude = ['pyo', 'pyc']
else:
exclude = ['py','pyo','pyc']
if (path.split('.')[-1] not in exclude):
if os.path.basename(path)=='__init__.py':
datas=self._parse_init(fromurl,path)
if path in self.dict_init:
self.dict_init[path]+=datas
else:
self.dict_init[path]=datas
return True
if os.path.basename(path)=='__terp__.py':
terp_file=os.path.join(fromurl,path)
terp_info=eval(tools.file_open(terp_file).read())
self.init_xml+=terp_info['init_xml']
self.demo_xml+=terp_info['demo_xml']
self.update_xml+=terp_info['update_xml']
return True
try:
info = self.archive.getinfo(path)
except KeyError:
if path.split('.')[-1] == 'xml':
xml_doc=self._remove_prefix_ref(fromurl,path)
xml_doc = xml_doc.encode("utf-8")
self._zip_writestr(path, xml_doc)
else:
file_data=tools.file_open(os.path.join(fromurl, path)).read()
self._zip_writestr(path, file_data)
else:
path2=os.path.split(fromurl)[-1]
new_path=path2+'_'+os.path.split(path)[-1]
if len(os.path.split(path))>1:
new_path=os.path.join(os.path.split(path)[0],new_path)
if path.split('.')[-1] == 'xml':
xml_doc=self._remove_prefix_ref(fromurl,path)
xml_doc = xml_doc.encode("utf-8")
self._zip_writestr(new_path, xml_doc)
if len(os.path.split(path))>1:
terp_file=os.path.join(fromurl,'__terp__.py')
terp_info=eval(tools.file_open(terp_file).read())
if os.path.basename(path) in terp_info['init_xml']:
print "in init_xml",new_path
self.init_xml+=[os.path.basename(new_path)]
elif os.path.basename(path) in terp_info['demo_xml']:
print "in demo_xml",new_path
self.demo_xml+=[os.path.basename(new_path)]
elif os.path.basename(path) in terp_info['update_xml']:
print "in update_xml",new_path
self.update_xml+=[os.path.basename(new_path)]
else:
file_data=tools.file_open(os.path.join(fromurl, path)).read()
self._zip_writestr(new_path, file_data)
if new_path.split('.')[-1] == 'py':
new_import='import '+os.path.basename(new_path).split('.')[0]
if os.path.dirname(path)=='':
dict_key='__init__.py'
else:
dict_key=os.path.join(os.path.dirname(path),'__init__.py')
if dict_key in self.dict_init:
self.dict_init[dict_key]+=[new_import]
else:
self.dict_init[dict_key]=[new_import]
return True
def rec_depend(self,cr, uid, ids, data, context=None, level=50):
pool = pooler.get_pool(cr.dbname)
dep_obj=pool.get('ir.module.module.dependency')
if level<1:
raise Exception, 'Recursion error in modules dependencies !'
for module in pool.get('ir.module.module').browse(cr, uid, ids):
dep_ids = dep_obj.search(cr, uid, [('module_id', '=', module.id)])
if dep_ids:
ids2 = []
for dep in dep_obj.browse(cr, uid, dep_ids):
dep_name=pool.get('ir.module.module').search(cr, uid, [('name','=',dep.name)])
ids2.append(dep_name[0])
self.rec_depend(cr, uid, ids2, data, context, level-1)
if module.name not in data['form']['dependencies']:
data['form']['dependencies'].append(module.name)
return True
def _compute_dependencies(self, cr, uid, data, context):
data['form']['dependencies']=[]
self.rec_depend(cr,uid,data['form']['modules_list'][0][2],data,context)
self.dependencies=data['form']['dependencies']
pool = pooler.get_pool(cr.dbname)
return {}
def _create_module(self, cr, uid, data, context):
self.dict_init={}
self.init_xml=[]
self.demo_xml=[]
self.update_xml=[]
self.archname = StringIO.StringIO('wb')
self.archive = zipfile.ZipFile(self.archname, "w", ZIP_DEFLATED)
for module in self.dependencies:
ad = tools.config['addons_path']
url = os.path.join(ad, module)
if not os.path.isdir(url):
url=url+'.zip'
self._zippy(self.archive, url, '', src=True)
dname = data['form']['directory_name']
data['form']['depen']=[]
data['form']['init_xml']=reduce(lambda l, x: x not in l and l.append(x) or l, self.init_xml, [])
data['form']['demo_xml']=reduce(lambda l, x: x not in l and l.append(x) or l, self.demo_xml, [])
data['form']['update_xml']=reduce(lambda l, x: x not in l and l.append(x) or l, self.update_xml, [])
_terp = """{
"name" : "%(name)s",
"version" : "%(version)s",
"author" : "%(author)s",
"website" : "%(website)s",
"category" : "%(category)s",
"description":\"\"\"%(description)s\"\"\",
"depends" : %(depen)s,
"init_xml" : %(init_xml)s,
"demo_xml" : %(demo_xml)s,
"update_xml" : %(update_xml)s,
"active": True,
"installable": True
} """ % data['form']
for name,datastr in self.dict_init.items():
self.dict_init[name]=reduce(lambda l, x: x not in l and l.append(x) or l, self.dict_init[name], [])
init_data='\n'.join(self.dict_init[name])
self._zip_writestr(name, init_data)
self._zip_writestr('__terp__.py', _terp)
self.archive.close()
return {
'module_file': base64.encodestring(self.archname.getvalue()),
'module_filename': data['form']['directory_name']+'-'+data['form']['version']+'.zip'
}
states = {
'init': {
'actions': [],
'result': {
'type':'form',
'arch':info_start_form,
'fields': info_start_fields,
'state':[
('end', 'Cancel', 'gtk-cancel'),
('info', 'Continue', 'gtk-ok'),
]
}
},
'info': {
'actions': [_compute_dependencies],
'result': {
'type':'form',
'arch':intro_start_form,
'fields': intro_start_fields,
'state':[
('end', 'Cancel', 'gtk-cancel'),
('save', 'Continue', 'gtk-ok'),
]
}
},
'save': {
'actions': [_create_module],
'result': {
'type':'form',
'arch':intro_save_form,
'fields': intro_save_fields,
'state':[
('end', 'Close', 'gtk-ok'),
]
}
}
}
base_module_merge('base_module_merge.module_merge')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1
View File
@@ -21,6 +21,7 @@
##############################################################################
import base_module_quality
import wizard
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+3 -3
View File
@@ -23,13 +23,13 @@
"name" : "Base module quality",
"author" : "Tiny",
"version" : "1.0",
"depends" : ["base", "product"],
"depends" : ["base",],
"description": "Sample module to check the quality",
"init_xml" : [],
"update_xml" : ["base_module_quality_view.xml"],
"update_xml" : ["base_module_quality_wizard.xml"],
"category" : "Tiny Specific Modules/Base module quality",
"active": False,
"installable": False
"installable": True
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,27 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 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 netsvc
from osv import fields, osv
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<wizard id="base_module_quality" model="ir.module.module" name="base.module.quality" string="Check the Quality of module"/>
</data>
</openerp>
@@ -0,0 +1,27 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 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 module_quality_check
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,82 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 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 wizard
import pooler
import osv
import netsvc
import sys
import tools
import os
import pylint
form_check = '''<?xml version="1.0"?>
<form string="Quality check">
<field name="test" />
</form>'''
fields_check = {
'test': {
'string':'Tests', 'type':'selection', 'required':True,
'selection': [('pylint', 'Pylint'), ('othertest','other')],
'default': lambda *args: 'pylint'
},
}
view_form = """<?xml version="1.0"?>
<form string="Check quality">
<field name="module_info" nolabel="1" colspan="4" height="150" width="400"/>
</form>"""
view_field = {
"module_info": {'type': 'text', 'string': 'check quality', 'readonly':True},
}
class wiz_quality_check(wizard.interface):
def _check(self, cr, uid, data, context):
if data['form']['test'] == 'pylint':
pool=pooler.get_pool(cr.dbname)
module_data = pool.get('ir.module.module').browse(cr, uid, data['ids'])
from pylint_test import pylint_test
ad = tools.config['addons_path']
url = os.path.join(ad, module_data[0].name)
result = pylint_test._test_pylint(self, url)
string_ret = ''
for i in result:
string_ret = string_ret + i + ':\n' + result[i]
return {'module_info':string_ret}
states = {
'init': {
'actions': [],
'result': {'type':'form', 'arch':form_check, 'fields':fields_check, 'state':[('end','Cancel'),('do','Do Test')]}
},
'do': {
'actions': [_check],
'result': {'type':'form', 'arch':view_form, 'fields':view_field, 'state':[('end','Ok')]},
},
}
wiz_quality_check('base.module.quality')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,25 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 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 pylint_test
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -0,0 +1,69 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 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 netsvc
from osv import fields, osv
import os
def _test_pylint(self, url, add_folder=None):
list_files = os.listdir(url)
new_list = []
subfolder = {}
for i in list_files:
if os.path.isdir(i):
path = os.path.join(url, i)
new_list.append(os.listdir(path))
res = _test_pylint(self, path, add_folder=i)
subfolder.update(res)
dict_files = {}
for file in list_files:
if file.split('.')[-1] == 'py':
save_file = file.split('.')[0]+".txt"
file_path = os.path.join(url, file)
os.system('pylint '+file_path+'>> '+save_file+' ')
a2 = os.system('cat '+save_file+' | tail -4 >> temp.txt')
os.system('rm '+save_file+' ')
fp = open('temp.txt','r')
result = fp.read()
fp.close()
str_result = ''
try:
for line in result:
str_result = str_result + line
finally:
fp = open('temp.txt','w')
fp.write('')
fp.close()
if str_result.startswith('Global'):
if add_folder:
dict_files[add_folder + '/' + file] = str_result
else:
dict_files[file] = str_result
os.system(' rm temp.txt ')
dict_files.update(subfolder)
return dict_files
#
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-1
View File
@@ -94,7 +94,6 @@ class node_class(object):
if test_nodename.find('/'):
test_nodename=test_nodename.replace('/', '_')
path = self.path+'/'+test_nodename
#path = self.path+'/'+self.object2.name + (content.suffix or '') + (content.extension or '')
if not nodename:
n = node_class(self.cr, self.uid,path, self.object2, False, content=content, type='content', root=False)
res2.append( n)
+1 -1
View File
@@ -437,7 +437,7 @@ class Partner(osv.osv):
# 'membership_state': fields.function(_membership_state, method=True, string='Current membership state',
# type='selection', selection=STATE, fnct_search=_membership_state_search),
'membership_state': fields.function(_membership_state, method=True, string='Current membership state',
type='selection',selection=STATE,store={'account.invoice':(['state'],_membership_state_search_inv)}),
type='selection',selection=STATE,store={'account.invoice':(_membership_state_search_inv,['state'])}),
# 'associate_member': fields.many2one('res.partner', 'Associate member'),
'free_member': fields.boolean('Free member'),
'membership_start': fields.function(_membership_start, method=True,
+18 -21
View File
@@ -132,40 +132,37 @@ class mrp_procurement(osv.osv):
warehouse_obj = self.pool.get('stock.warehouse')
wf_service = netsvc.LocalService("workflow")
cr.execute('select id from stock_warehouse')
warehouses = [x for x, in cr.fetchall()]
warehouse_ids = warehouse_obj.search(cr, uid, [], context=context)
cr.execute('select id from product_product')
products_id = [x for x, in cr.fetchall()]
products = dict(zip(products_id, product_obj.browse(cr, uid, products_id, context)))
for warehouse in warehouses:
v_stock = product_obj._product_virtual_available(cr, uid, products_id, None, {'warehouse': warehouse})
cr.execute("select lot_stock_id from stock_warehouse")
location_ids_str = ','.join([str(id) for id, in cr.fetchall()])
stock_locations = warehouse_obj.read(cr, uid, [warehouse], ['lot_input_id', 'lot_stock_id'])[0]
for prod_id, available in v_stock.items():
if available >= 0:
for warehouse in warehouse_obj.browse(cr, uid, warehouse_ids, context=context):
context['warehouse'] = warehouse
for product in self.pool.get('product.product').browse(cr, uid, products_id, context=context):
if product.virtual_available>=0.0:
continue
newdate = DateTime.now() + DateTime.RelativeDateTime(days=products[prod_id].seller_delay)
if products[prod_id].supply_method == 'buy':
location_id = stock_locations['lot_input_id'][0]
elif products[prod_id].supply_method == 'produce':
location_id = stock_locations['lot_stock_id'][0]
newdate = DateTime.now()
if product.supply_method == 'buy':
location_id = warehouse.lot_input_id.id
elif product.supply_method == 'produce':
location_id = warehouse.lot_stock_id.id
else:
continue
proc_id = proc_obj.create(cr, uid, {
'name': 'PROC:Automatic OP for product:%s' % products[prod_id].name,
'name': 'PROC:Automatic OP for product:%s' % product.name,
'origin': 'SCHEDULER',
'date_planned': newdate.strftime('%Y-%m-%d'),
'product_id': prod_id,
'product_qty': -available,
'product_uom': products[prod_id].uom_id.id,
'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'),
'product_id': product.id,
'product_qty': -product.virtual_available,
'product_uom': product.uom_id.id,
'location_id': location_id,
'procure_method': 'make_to_order',
})
wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)
wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_check', cr)
def _procure_orderpoint_confirm(self, cr, uid, automatic=False,\
use_new_cursor=False, context=None, user_id=False):
'''
+1 -1
View File
@@ -30,7 +30,7 @@ parameter_form = '''<?xml version="1.0"?>
</form>'''
parameter_fields = {
'automatic': {'string': 'Automatic orderpoint', 'type': 'boolean', 'help': 'Triggers an automatic procurement for all products that have a virtual stock under 0.', 'default': lambda *a: False},
'automatic': {'string': 'Automatic orderpoint', 'type': 'boolean', 'help': 'Triggers an automatic procurement for all products that have a virtual stock under 0. You should probably not use this option, we suggest using a MTO configuration on products.', 'default': lambda *a: False},
}
def _procure_calculation_all(self, db_name, uid, data, context):
+1 -1
View File
@@ -294,7 +294,7 @@ class mrp_operations_operation(osv.osv):
'code_id':fields.many2one('mrp_operations.operation.code','Code',required=True),
'date_start': fields.datetime('Start Date'),
'date_finished': fields.datetime('End Date'),
'order_date': fields.function(_get_order_date,method=True,string='Order Date',type='date',store={'mrp.production':(['date_planned'],_order_date_search_production)}),
'order_date': fields.function(_get_order_date,method=True,string='Order Date',type='date',store={'mrp.production':(_order_date_search_production,['date_planned'])}),
}
_defaults={
'date_start': lambda *a:DateTime.now().strftime('%Y-%m-%d %H:%M:%S')
+165
View File
@@ -70,6 +70,19 @@
<blockTableStyle id="Table6">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
<<<<<<< TREE
<lineStyle kind="LINEBELOW" colorName="#000000" start="0,-1" stop="0,-1"/>
<lineStyle kind="LINEBELOW" colorName="#000000" start="1,-1" stop="1,-1"/>
<lineStyle kind="LINEBELOW" colorName="#000000" start="2,-1" stop="2,-1"/>
<lineStyle kind="LINEBELOW" colorName="#000000" start="3,-1" stop="3,-1"/>
<lineStyle kind="LINEBELOW" colorName="#000000" start="4,-1" stop="4,-1"/>
<lineStyle kind="LINEBELOW" colorName="#000000" start="5,-1" stop="5,-1"/>
</blockTableStyle>
<blockTableStyle id="Table7">
<blockAlignment value="LEFT"/>
<blockValign value="TOP"/>
<lineStyle kind="LINEBELOW" colorName="#000000" start="3,1" stop="-1,-1"/>
=======
<lineStyle kind="LINEBELOW" colorName="#cccccc" start="0,-1" stop="0,-1"/>
<lineStyle kind="LINEBELOW" colorName="#cccccc" start="1,-1" stop="1,-1"/>
<lineStyle kind="LINEBELOW" colorName="#cccccc" start="2,-1" stop="2,-1"/>
@@ -86,6 +99,7 @@
<lineStyle kind="LINEABOVE" colorName="#000000" start="1,2" stop="1,2"/>
<lineStyle kind="LINEABOVE" colorName="#000000" start="2,2" stop="2,2"/>
<lineStyle kind="LINEABOVE" colorName="#000000" start="3,2" stop="3,2"/>
>>>>>>> MERGE-SOURCE
</blockTableStyle>
<blockTableStyle id="Table8">
<blockAlignment value="LEFT"/>
@@ -111,6 +125,29 @@
<paraStyle name="P15" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
<paraStyle name="P16" fontName="Helvetica" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P17" fontName="Helvetica-Bold" fontSize="10.0" leading="13" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
<<<<<<< TREE
<paraStyle name="P18" fontName="Helvetica-Bold" fontSize="10.0" leading="13" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
<paraStyle name="P19" fontName="Helvetica-Bold" fontSize="10.0" leading="13" alignment="RIGHT" spaceBefore="6.0" spaceAfter="6.0"/>
<paraStyle name="P20" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P21" fontName="Helvetica-Oblique" fontSize="2.0" leading="3" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P22" fontName="Helvetica-Bold" fontSize="9.0" leading="11"/>
<paraStyle name="P23" fontName="Helvetica"/>
<paraStyle name="P24" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT"/>
<paraStyle name="P25" fontName="Helvetica" fontSize="9.0" leading="11" alignment="RIGHT"/>
<paraStyle name="P26" fontName="Helvetica" fontSize="9.0" leading="11" alignment="RIGHT"/>
<paraStyle name="P27" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P28" fontName="Helvetica" fontSize="2.0" leading="3" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P29" fontName="Times-Roman"/>
<paraStyle name="P30" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT"/>
<paraStyle name="P31" fontName="Helvetica" fontSize="9.0" leading="11" alignment="RIGHT"/>
<paraStyle name="P32" fontName="Helvetica" fontSize="9.0" leading="11" alignment="RIGHT"/>
<paraStyle name="P33" fontName="Helvetica" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P34" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P35" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P36" fontName="Helvetica" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P37" fontName="Helvetica-Oblique" fontSize="2.0" leading="3" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P38" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
=======
<paraStyle name="P18" fontName="Helvetica-Bold" fontSize="10.0" leading="13" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
<paraStyle name="P19" fontName="Helvetica-Bold" fontSize="10.0" leading="13" alignment="RIGHT" spaceBefore="6.0" spaceAfter="6.0"/>
<paraStyle name="P20" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
@@ -124,6 +161,7 @@
<paraStyle name="P28" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT"/>
<paraStyle name="P29" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
<paraStyle name="P30" fontName="Helvetica" fontSize="2.0" leading="3" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
>>>>>>> MERGE-SOURCE
<paraStyle name="Standard" fontName="Times-Roman"/>
<paraStyle name="Text body" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/>
<paraStyle name="Heading" fontName="Helvetica" fontSize="8.0" leading="10" spaceBefore="12.0" spaceAfter="6.0"/>
@@ -277,17 +315,32 @@
</tr>
</blockTable>
<section>
<<<<<<< TREE
<para style="P28"/>
<para style="P27">Operation Line(s)</para>
<blockTable colWidths="26.0,142.0,153.0,95.0,52.0,69.0" style="Table5">
=======
<para style="P30">
<font color="white"> </font>
</para>
<para style="P29">Operation Line(s)</para>
<blockTable colWidths="28.0,145.0,150.0,96.0,51.0,69.0" style="Table5">
>>>>>>> MERGE-SOURCE
<tr>
<td>
<para style="P4"><font face="Times-Roman" size="2.0">[[ repeatIn(o.operations,'line') ]]</font>Add [[ ((line.type == 'add') or removeParentNode('para')) and '' ]] </para>
<para style="P4">Remove [[ ((line.type == 'remove') or removeParentNode('para')) and '' ]]</para>
</td>
<td>
<<<<<<< TREE
<para style="P3">[[ line.name ]]</para>
</td>
<td>
<para style="P6">[[ ','.join(map( lambda x: x.name, line.tax_id)) or '0.00' ]]</para>
</td>
<td>
<para style="P20">[[ line.product_uom_qty or '0.00' ]] [[ line.product_uom.name ]] </para>
=======
<para style="P3">[[ line.name ]][[ (line.to_invoice==True) or removeParentNode('tr') ]]</para>
</td>
<td>
@@ -295,6 +348,7 @@
</td>
<td>
<para style="P20">[[ line.product_uom_qty or '0.00' ]] [[ line.product_uom.name ]]</para>
>>>>>>> MERGE-SOURCE
</td>
<td>
<para style="P1">[[ line.price_unit ]]</para>
@@ -305,11 +359,30 @@
</tr>
</blockTable>
</section>
<<<<<<< TREE
<para style="P22">Fees Line(s)</para>
<para style="P21">
<font color="white"> </font>
</para>
=======
<para style="P23">Fees Line(s)</para>
<para style="P21"/>
>>>>>>> MERGE-SOURCE
<blockTable colWidths="28.0,145.0,150.0,96.0,51.0,69.0" style="Table6">
<tr>
<td>
<<<<<<< TREE
<para style="P21">[[ repeatIn(o.fees_lines,'fees') ]]</para>
</td>
<td>
<para style="P3">[[ fees.name ]]</para>
</td>
<td>
<para style="P6">[[ ','.join(map( lambda x: x.name, fees.tax_id)) or '0.00' ]]</para>
</td>
<td>
<para style="P20">[[ fees.product_uom_qty or '0.00' ]] [[ fees.product_uom.name ]] </para>
=======
<para style="P21">[[ repeatIn(o.fees_lines,'fees') ]]</para>
</td>
<td>
@@ -320,6 +393,7 @@
</td>
<td>
<para style="P20">[[ fees.product_uom_qty or '0.00' ]] [[ fees.product_uom.name ]] </para>
>>>>>>> MERGE-SOURCE
</td>
<td>
<para style="P1">[[ fees.price_unit ]]</para>
@@ -329,6 +403,92 @@
</td>
</tr>
</blockTable>
<<<<<<< TREE
<blockTable colWidths="90.0,90.0,221.0,57.0,54.0,28.0" style="Table7">
<tr>
<td>
<para style="Table Contents">
<font color="white"> </font>
</para>
</td>
<td>
<para style="Table Contents">
<font color="white"> </font>
</para>
</td>
<td>
<para style="Table Contents">
<font color="white"> </font>
</para>
</td>
<td>
<para style="P24">Net Total :</para>
</td>
<td>
<para style="P25">[[ o.amount_untaxed or '0.00' ]]</para>
</td>
<td>
<para style="P25">[[ o.pricelist_id.currency_id.name ]]</para>
</td>
</tr>
<tr>
<td>
<para style="Table Contents">
<font color="white"> </font>
</para>
</td>
<td>
<para style="Table Contents">
<font color="white"> </font>
</para>
</td>
<td>
<para style="Table Contents">
<font color="white"> </font>
</para>
</td>
<td>
<para style="P24">Taxes:</para>
</td>
<td>
<para style="P25">[[ o.amount_tax or '0.00']]</para>
</td>
<td>
<para style="P25">[[ o.pricelist_id.currency_id.name ]]</para>
</td>
</tr>
<tr>
<td>
<para style="Table Contents">
<font color="white"> </font>
</para>
</td>
<td>
<para style="Table Contents">
<font color="white"> </font>
</para>
</td>
<td>
<para style="Table Contents">
<font color="white"> </font>
</para>
</td>
<td>
<para style="P24">Total :</para>
</td>
<td>
<para style="P26">[[ total(o) ]]</para>
</td>
<td>
<para style="P25">[[ o.pricelist_id.currency_id.name ]]</para>
</td>
</tr>
</blockTable>
<para style="P29">
<font color="white"> </font>
</para>
<para style="P29">
=======
<para style="P22">
<font color="white"> </font>
</para>
@@ -389,6 +549,7 @@
<font color="white"> </font>
</para>
<para style="Standard">
>>>>>>> MERGE-SOURCE
<font color="white"> </font>
</para>
<blockTable colWidths="534.0" style="Table8">
@@ -398,8 +559,12 @@
</td>
</tr>
</blockTable>
<<<<<<< TREE
<para style="P23"/>
=======
<para style="P24">
<font color="white"> </font>
</para>
>>>>>>> MERGE-SOURCE
</story>
</document>
+2 -2
View File
@@ -210,7 +210,7 @@
<field name="remaining_hours" widget="float_time"/>
<group col="4" colspan="4">
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
<button icon="gtk-ok" name="compute_hours" string="Compute" type="object"/>
<button icon="gtk-ok" name="compute_hours" string="Update" type="object"/>
</group>
</form>
</field>
@@ -250,7 +250,7 @@
<field name="delay_hours" widget="float_time"/>
<group col="3" colspan="2">
<field name="remaining_hours" select="2" widget="float_time" attrs="{'readonly':[('state','!=','draft')]}" colspan="2"/>
<button name="%(action_config_compute_remaining)d" string="Compute" type="action" colspan="1" target="new"/>
<button name="%(action_config_compute_remaining)d" string="Review" type="action" colspan="1" target="new" attrs="{'invisible':[('state','=','draft')]}"/>
</group>
<field name="effective_hours" widget="float_time"/>
@@ -6,3 +6,4 @@
"access_project_task_manager","project.task manager","model_project_task","project.group_project_manager",1,1,1,1
"access_project_task","project.task","model_project_task","project.group_project_user",1,1,1,1
"access_project_task_work","project.task.work","model_project_task_work","project.group_project_user",1,1,1,1
"access_config_compute_remaining","project.config.compute.remaining","model_config_compute_remaining","project.group_project_manager",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
6 access_project_task_manager project.task manager model_project_task project.group_project_manager 1 1 1 1
7 access_project_task project.task model_project_task project.group_project_user 1 1 1 1
8 access_project_task_work project.task.work model_project_task_work project.group_project_user 1 1 1 1
9 access_config_compute_remaining project.config.compute.remaining model_config_compute_remaining project.group_project_manager 1 1 1 1
+3 -1
View File
@@ -466,7 +466,9 @@ class purchase_order_line(osv.osv):
'date': date_order,
})[pricelist]
dt = (DateTime.now() + DateTime.RelativeDateTime(days=prod['seller_delay'] or 0.0)).strftime('%Y-%m-%d %H:%M:%S')
prod_name = self.pool.get('product.product').name_get(cr, uid, [product], context=context)[0][1]
context['partner_id'] = partner_id
prod_name = self.pool.get('product.product').browse(cr, uid,product, context=context).partner_ref
res = {'value': {'price_unit': price, 'name':prod_name, 'taxes_id':prod['supplier_taxes_id'], 'date_planned': dt,'notes':prod['description_purchase'], 'product_uom': uom}}
domain = {}
-1
View File
@@ -26,7 +26,6 @@
import sale
import stock
import partner
import product
import wizard
+23 -29
View File
@@ -60,38 +60,29 @@ class sale_order(osv.osv):
})
return super(sale_order, self).copy(cr, uid, id, default, context)
def _amount_untaxed(self, cr, uid, ids, field_name, arg, context):
res = {}
cur_obj=self.pool.get('res.currency')
for sale in self.browse(cr, uid, ids):
res[sale.id] = 0.0
for line in sale.order_line:
res[sale.id] += line.price_subtotal
cur = sale.pricelist_id.currency_id
res[sale.id] = cur_obj.round(cr, uid, cur, res[sale.id])
return res
def _amount_line_tax(self, cr, uid, line, context={}):
val = 0.0
for c in self.pool.get('account.tax').compute(cr, uid, line.tax_id, line.price_unit * (1-(line.discount or 0.0)/100.0), line.product_uom_qty, line.order_id.partner_invoice_id.id, line.product_id, line.order_id.partner_id):
val+= c['amount']
return val
def _amount_tax(self, cr, uid, ids, field_name, arg, context):
def _amount_all(self, cr, uid, ids, field_name, arg, context):
res = {}
cur_obj=self.pool.get('res.currency')
for order in self.browse(cr, uid, ids):
val = 0.0
res[order.id] = {
'amount_untaxed': 0.0,
'amount_tax': 0.0,
'amount_total': 0.0,
}
val = val1 = 0.0
cur=order.pricelist_id.currency_id
for line in order.order_line:
for c in self.pool.get('account.tax').compute(cr, uid, line.tax_id, line.price_unit * (1-(line.discount or 0.0)/100.0), line.product_uom_qty, order.partner_invoice_id.id, line.product_id, order.partner_id):
val+= c['amount']
res[order.id]=cur_obj.round(cr, uid, cur, val)
return res
def _amount_total(self, cr, uid, ids, field_name, arg, context):
res = {}
untax = self._amount_untaxed(cr, uid, ids, field_name, arg, context)
tax = self._amount_tax(cr, uid, ids, field_name, arg, context)
cur_obj=self.pool.get('res.currency')
for id in ids:
order=self.browse(cr, uid, [id])[0]
cur=order.pricelist_id.currency_id
res[id] = cur_obj.round(cr, uid, cur, untax.get(id, 0.0) + tax.get(id, 0.0))
val1 += line.price_subtotal
val += self._amount_line_tax(cr, uid, line, context)
res[order.id]['amount_tax']=cur_obj.round(cr, uid, cur, val)
res[order.id]['amount_untaxed']=cur_obj.round(cr, uid, cur, val1)
res[order.id]['amount_total']=res[order.id]['amount_untaxed'] + res[order.id]['amount_tax']
return res
def _picked_rate(self, cr, uid, ids, name, arg, context=None):
@@ -231,9 +222,12 @@ class sale_order(osv.osv):
'invoiced': fields.function(_invoiced, method=True, string='Paid',
fnct_search=_invoiced_search, type='boolean'),
'note': fields.text('Notes'),
'amount_untaxed': fields.function(_amount_untaxed, method=True, string='Untaxed Amount'),
'amount_tax': fields.function(_amount_tax, method=True, string='Taxes', store=True),
'amount_total': fields.function(_amount_total, method=True, string='Total', store=True),
'amount_untaxed': fields.function(_amount_all, method=True, string='Untaxed Amount',
store=True, multi='sums'),
'amount_tax': fields.function(_amount_all, method=True, string='Taxes', store=True, multi='sums'),
'amount_total': fields.function(_amount_all, method=True, string='Total', store=True, multi='sums'),
'invoice_quantity': fields.selection([('order','Ordered Quantities'),('procurement','Shipped Quantities')], 'Invoice on', help="The sale order will automatically create the invoice proposition (draft invoice). Ordered and delivered quantities may not be the same. You have to choose if you invoice based on ordered or shipped quantities. If the product is a service, shipped quantities means hours spent on the associated tasks.",required=True),
'payment_term' : fields.many2one('account.payment.term', 'Payment Term'),
}
+16 -1
View File
@@ -31,6 +31,10 @@ import time
from StringIO import StringIO
from HTMLParser import HTMLParser
class Wiki(osv.osv):
_name="wiki.wiki"
Wiki()
class WikiGroup(osv.osv):
_name = "wiki.groups"
_description="Wiki Groups"
@@ -44,11 +48,22 @@ class WikiGroup(osv.osv):
'create_date':fields.datetime("Created Date", select=True),
'template': fields.text('Wiki Template'),
'section': fields.boolean("Make Section ?"),
'home':fields.many2one('wiki.wiki', 'Pages')
}
WikiGroup()
class GroupLink(osv.osv):
_name = "wiki.groups.link"
_description="Wiki Groups Links"
_rec_name = 'action_id'
_columns={
'group_id':fields.many2one('wiki.groups', 'Parent Group', ondelete='set null'),
'action_id': fields.many2one('ir.ui.menu', 'Menu')
}
GroupLink()
class Wiki(osv.osv):
_name="wiki.wiki"
_inherit="wiki.wiki"
_description="Wiki Page"
_order = 'section,create_date desc'
_columns={
+1
View File
@@ -8,6 +8,7 @@
<wizard
id="wizard_group_menu_create"
string="Create Menu"
menu="True"
name="wiki.create.menu"/>
<record model="ir.ui.view" id="wiki_group_tree">
+1
View File
@@ -1,3 +1,4 @@
import open_page
import create_menu
import show_diff
import make_index
+15 -12
View File
@@ -20,7 +20,6 @@
#
##############################################################################
import time
import wizard
import osv
@@ -31,31 +30,35 @@ section_form = '''<?xml version="1.0"?>
<separator string="Menu Information" colspan="4"/>
<field name="menu_name"/>
<field name="menu_parent_id"/>
<field name="page" colspan="4" domain="[('group_id','=', active_id)]"/>
</form>'''
section_fields = {
'menu_name': {'string':'Menu Name', 'type':'char', 'required':True, 'size':64},
'menu_parent_id': {'string':'Parent Menu', 'type':'many2one', 'relation':'ir.ui.menu', 'required':True},
'page': {'string':'Group Home Page', 'type':'many2one', 'relation':'wiki.wiki'},
}
def wiki_menu_create(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
group = pool.get('wiki.groups').browse(cr, uid, data['id'])
action_id = pool.get('ir.actions.wizard').search(cr, uid, [('wiz_name','=','wiki.wiki.page.open')])
action_id = pool.get('ir.actions.act_window').create(cr, uid, {
'name': group.name,
'view_type':'form',
'view_mode':"tree,form",
'context': "{'group_id':%d, 'section':%d}" % (group.id, group.section),
'domain': "[('group_id','child_of',[%d])]" % (group.id,),
'res_model': 'wiki.wiki'
})
pool.get('ir.ui.menu').create(cr, uid, {
menu_id = pool.get('ir.ui.menu').create(cr, uid, {
'name': data['form']['menu_name'],
'parent_id': data['form']['menu_parent_id'],
'icon': 'STOCK_JUSTIFY_FILL',
'action': 'ir.actions.act_window,'+str(action_id)
'icon': 'STOCK_DIALOG_QUESTION',
'action': 'ir.actions.wizard,'+str(action_id[0])
}, context)
home = data['form']['page']
group_id = data['id']
res = {
'home':home,
}
pool.get('wiki.groups').write(cr, uid, [data['id']], res)
pool.get('wiki.groups.link').create(cr, uid, {'group_id':group_id, 'action_id':menu_id})
return {}
class wizard_create_menu(wizard.interface):
+67
View File
@@ -0,0 +1,67 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 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 wizard
import netsvc
import time
import pooler
from osv import osv
from tools.translate import _
class wiz_timesheet_open(wizard.interface):
def _open_wiki_page(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
menu_id = data['id']
group_ids = pool.get('wiki.groups.link').search(cr, uid, [('action_id','=',menu_id)])
group = pool.get('wiki.groups.link').browse(cr, uid, group_ids[0])
value = {
'context': "{'group_id':%d}" % (group.group_id.id),
'domain': "[('group_id','child_of',[%s])]" % (group.group_id.id),
'name': 'Wiki Page',
'view_type': 'form',
'view_mode': 'form,tree',
'res_model': 'wiki.wiki',
'view_id': False,
'type': 'ir.actions.act_window',
}
if group.group_id.home:
value['res_id'] = group.group_id.home.id
else:
value['view_type'] = 'form'
value['view_mode'] = 'tree,form'
return value
states = {
'init' : {
'actions' : [],
'result' : {'type':'action', 'action':_open_wiki_page, 'state':'end'}
}
}
wiz_timesheet_open('wiki.wiki.page.open')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-133
View File
@@ -1,133 +0,0 @@
def sort(data, index):
for i in range(len(data)):
j = i + 1
for j in range(len(data)-1):
d1 = data[i].split('.')
d2 = data[j].split('.')
l1 = len(d1)
l2 = len(d2)
max = 0
if l1 < l2:
max = l1
elif l2 < l1:
max = l2
else:
max = l1
if max == 1:
if int(d1[0]) == int(d2[0]):
if len(d1) < len(d2):
tmp = data[i]
data[i] = data[j]
data[j] = tmp
continue
for p in range(0, max):
val1 = val2 = 0
try:
val1 = int(d1[p])
except:
val1 = 0
try:
val2 = int(d2[p])
except:
val2 = 0
if val1 < val2:
tmp = data[i]
data[i] = data[j]
data[j] = tmp
if data[i].startswith(data[j]):
tmp = data[i]
tmp = tmp.replace(data[j],'')
def group(data):
gp = {}
for i in range(len(data)):
d1 = data[i].split('.')[0]
if gp.has_key(d1):
gp[d1].append(data[i])
else:
gp[d1] = [data[i]]
return gp
def max(data):
max = 0
for i in range(len(data)):
d = str(data[i]).split('.')
if len(d) > max:
max = len(d)
return max
def toint(data):
for i in range(len(data)):
data[i] = int(data[i])
def rearrange(key, groups):
i = 1
new = {}
for ky in key:
new[i] = groups[str(ky)]
i += 1
return new
def reindex(key, groups):
if groups[0] != key:
groups[0] = key
lvl_group = {}
level = max(groups)
for i in range(len(groups)):
dg = str(groups[i]).split('.')
index = len(dg)
if lvl_group.has_key(str(index)):
lvl_group[str(index)].append(groups[i])
else:
lvl_group[str(index)] = [groups[i]]
for i in range(2, level+1):
ixd = 1
gps = lvl_group[str(i)]
for j in range(len(gps)):
dt = gps[j].split('.')
new =""
for k in range(i-1):
new += str(dt[k])
new += '.'
new += str(ixd)
ixd += 1
gps[j] = new
print lvl_group
if __name__ == '__main__':
data = ['1', '10.1', '10.3', '1.1', '1.2.3', '1.7', '3.1.8', '1.2.2', '1.2.10', '1.3', '1.4', '2', '20.2', '2.1', '2.2', '3', '3.1', '1.2.1', '2.1.2']
sort(data, 0)
grp = group(data)
for gp in grp:
loop = max(grp[gp])
for lp in range(1, loop):
sort(grp[gp],lp)
key = grp.keys()
toint(key)
key.sort()
groups = rearrange(key, grp)
new_data = []
for key in groups:
new_data.extend(groups[key])
#print groups[key]
print 'XXXXXXXXXXXXXXXXX : ', new_data
# print groups
#
+6
View File
@@ -25,5 +25,11 @@
string="Create Index"
name="wiki.make.index"
model="wiki.wiki"/>
<wizard
id="wizard_open_page"
string="Open Page"
name="wiki.wiki.page.open"
model="wiki.wiki"/>
</data>
</openerp>