merge
bzr revid: solanki.priyesh@gmail.com-20081208121024-1izsduuh2f8c7wcp
This commit is contained in:
+57
-98
@@ -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):
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -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
@@ -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),
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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']
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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>
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
##############################################################################
|
||||
|
||||
import base_module_quality
|
||||
import wizard
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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):
|
||||
'''
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
|
@@ -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 = {}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
import sale
|
||||
import stock
|
||||
import partner
|
||||
import product
|
||||
|
||||
import wizard
|
||||
|
||||
+23
-29
@@ -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
@@ -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={
|
||||
|
||||
@@ -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,3 +1,4 @@
|
||||
import open_page
|
||||
import create_menu
|
||||
import show_diff
|
||||
import make_index
|
||||
@@ -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):
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
#
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user