bzr revid: hda@tinyerp.com-20091001120743-ccchg1bds3iu2hb3
This commit is contained in:
HDA (OpenERP)
2009-10-01 17:37:43 +05:30
50 changed files with 770 additions and 195 deletions
+16 -15
View File
@@ -30,6 +30,7 @@ import pooler
import mx.DateTime
from mx.DateTime import RelativeDateTime, now, DateTime, localtime
from tools import config
class account_payment_term(osv.osv):
_name = "account.payment.term"
@@ -53,11 +54,11 @@ class account_payment_term(osv.osv):
result = []
for line in pt.line_ids:
if line.value == 'fixed':
amt = round(line.value_amount, 2)
amt = round(line.value_amount, int(config['price_accuracy']))
elif line.value == 'procent':
amt = round(value * line.value_amount, 2)
amt = round(value * line.value_amount, int(config['price_accuracy']))
elif line.value == 'balance':
amt = round(amount, 2)
amt = round(amount, int(config['price_accuracy']))
if amt:
next_date = mx.DateTime.strptime(date_ref, '%Y-%m-%d') + RelativeDateTime(days=line.days)
if line.days2 < 0:
@@ -267,9 +268,9 @@ class account_account(osv.osv):
'child_parent_ids': fields.one2many('account.account','parent_id','Children'),
'child_consol_ids': fields.many2many('account.account', 'account_account_consol_rel', 'child_id', 'parent_id', 'Consolidated Children'),
'child_id': fields.function(_get_child_ids, method=True, type='many2many', relation="account.account", string="Child Accounts"),
'balance': fields.function(__compute, digits=(16, 2), method=True, string='Balance', multi='balance'),
'credit': fields.function(__compute, digits=(16, 2), method=True, string='Credit', multi='balance'),
'debit': fields.function(__compute, digits=(16, 2), method=True, string='Debit', multi='balance'),
'balance': fields.function(__compute, digits=(16, int(config['price_accuracy'])), method=True, string='Balance', multi='balance'),
'credit': fields.function(__compute, digits=(16, int(config['price_accuracy'])), method=True, string='Credit', multi='balance'),
'debit': fields.function(__compute, digits=(16, int(config['price_accuracy'])), method=True, string='Debit', multi='balance'),
'reconcile': fields.boolean('Reconcile', help="Check this if the user is allowed to reconcile entries in this account."),
'shortcut': fields.char('Shortcut', size=12),
'tax_ids': fields.many2many('account.tax', 'account_account_tax_default_rel',
@@ -743,7 +744,7 @@ class account_move(osv.osv):
'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
'to_check': fields.boolean('To Be Verified'),
'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner"),
'amount': fields.function(_amount_compute, method=True, string='Amount', digits=(16,2)),
'amount': fields.function(_amount_compute, method=True, string='Amount', digits=(16,int(config['price_accuracy']))),
'date': fields.date('Date', required=True),
'type': fields.selection([
('pay_voucher','Cash Payment'),
@@ -1109,7 +1110,7 @@ class account_tax_code(osv.osv):
for rec in record.child_ids:
amount += _rec_get(rec) * rec.sign
return amount
res[record.id] = round(_rec_get(record), 2)
res[record.id] = round(_rec_get(record), int(config['price_accuracy']))
return res
def _sum_year(self, cr, uid, ids, name, args, context):
@@ -1380,9 +1381,9 @@ class account_tax(osv.osv):
total = 0.0
for r in res:
if r.get('balance',False):
r['amount'] = round(r['balance'] * quantity, 2) - total
r['amount'] = round(r['balance'] * quantity, int(config['price_accuracy'])) - total
else:
r['amount'] = round(r['amount'] * quantity, 2)
r['amount'] = round(r['amount'] * quantity, int(config['price_accuracy']))
total += r['amount']
return res
@@ -1477,9 +1478,9 @@ class account_tax(osv.osv):
total = 0.0
for r in res:
if r.get('balance',False):
r['amount'] = round(r['balance'] * quantity, 2) - total
r['amount'] = round(r['balance'] * quantity, int(config['price_accuracy'])) - total
else:
r['amount'] = round(r['amount'] * quantity, 2)
r['amount'] = round(r['amount'] * quantity, int(config['price_accuracy']))
total += r['amount']
return res
account_tax()
@@ -1545,9 +1546,9 @@ class account_model_line(osv.osv):
_columns = {
'name': fields.char('Name', size=64, required=True),
'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the resources from lower sequences to higher ones"),
'quantity': fields.float('Quantity', digits=(16,2), help="The optional quantity on entries"),
'debit': fields.float('Debit', digits=(16,2)),
'credit': fields.float('Credit', digits=(16,2)),
'quantity': fields.float('Quantity', digits=(16, int(config['price_accuracy'])), help="The optional quantity on entries"),
'debit': fields.float('Debit', digits=(16, int(config['price_accuracy']))),
'credit': fields.float('Credit', digits=(16, int(config['price_accuracy']))),
'account_id': fields.many2one('account.account', 'Account', required=True, ondelete="cascade"),
+1 -1
View File
@@ -52,7 +52,7 @@
<form string="Invoice Line">
<notebook>
<page string="Line">
<field name="product_id" on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position)" select="1"/>
<field name="product_id" on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit)" select="1"/>
<field name="uos_id"/>
<field name="quantity" select="1"/>
<field name="price_unit" select="1"/>
+4 -2
View File
@@ -28,6 +28,8 @@ from tools.translate import _
import mx.DateTime
from mx.DateTime import RelativeDateTime, now, DateTime, localtime
import tools
class account_move_line(osv.osv):
_name = "account.move.line"
_description = "Entry lines"
@@ -908,7 +910,7 @@ class account_move_line(osv.osv):
'move_id': vals['move_id'],
'journal_id': vals['journal_id'],
'period_id': vals['period_id'],
'name': vals['name']+' '+tax['name'],
'name': tools.ustr(vals['name'] or '') + ' ' + tools.ustr(tax['name'] or ''),
'date': vals['date'],
'partner_id': vals.get('partner_id',False),
'ref': vals.get('ref',False),
@@ -927,7 +929,7 @@ class account_move_line(osv.osv):
'move_id': vals['move_id'],
'journal_id': vals['journal_id'],
'period_id': vals['period_id'],
'name': vals['name']+' '+tax['name'],
'name': tools.ustr(vals['name'] or '') + ' ' + tools.ustr(tax['name'] or ''),
'date': vals['date'],
'partner_id': vals.get('partner_id',False),
'ref': vals.get('ref',False),
+1 -1
View File
@@ -25,7 +25,7 @@ from osv import fields, osv
class res_company(osv.osv):
_inherit = "res.company"
_columns = {
'overdue_msg' : fields.text('Overdue Payments Message'),
'overdue_msg' : fields.text('Overdue Payments Message', translate=True),
}
_defaults = {
+13 -13
View File
@@ -233,21 +233,21 @@ 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_all, method=True, digits=(16,2),string='Untaxed',
'amount_untaxed': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])),string='Untaxed',
store={
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line'], 20),
'account.invoice.tax': (_get_invoice_tax, None, 20),
'account.invoice.line': (_get_invoice_line, ['price_unit','invoice_line_tax_id','quantity','discount'], 20),
},
multi='all'),
'amount_tax': fields.function(_amount_all, method=True, digits=(16,2), string='Tax',
'amount_tax': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Tax',
store={
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line'], 20),
'account.invoice.tax': (_get_invoice_tax, None, 20),
'account.invoice.line': (_get_invoice_line, ['price_unit','invoice_line_tax_id','quantity','discount'], 20),
},
multi='all'),
'amount_total': fields.function(_amount_all, method=True, digits=(16,2), string='Total',
'amount_total': fields.function(_amount_all, method=True, digits=(16, int(config['price_accuracy'])), string='Total',
store={
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line'], 20),
'account.invoice.tax': (_get_invoice_tax, None, 20),
@@ -257,7 +257,7 @@ class account_invoice(osv.osv):
'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)]}),
'check_total': fields.float('Total', digits=(16, int(config['price_accuracy'])), states={'open':[('readonly',True)],'close':[('readonly',True)]}),
'reconciled': fields.function(_reconciled, method=True, string='Paid/Reconciled', type='boolean',
store={
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, None, 50), # Check if we can remove ?
@@ -267,7 +267,7 @@ class account_invoice(osv.osv):
'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',
'residual': fields.function(_amount_residual, method=True, digits=(16, int(config['price_accuracy'])),string='Residual',
store={
'account.invoice': (lambda self, cr, uid, ids, c={}: ids, ['invoice_line'], 50),
'account.invoice.tax': (_get_invoice_tax, None, 50),
@@ -435,7 +435,7 @@ class account_invoice(osv.osv):
for taxe in ait_obj.compute(cr, uid, id, context=context).values():
ait_obj.create(cr, uid, taxe)
# Update the stored value (fields.function), so we write to trigger recompute
self.pool.get('account.invoice').write(cr, uid, ids, {}, context=context)
self.pool.get('account.invoice').write(cr, uid, ids, {'invoice_line':[]}, context=context)
# self.pool.get('account.invoice').write(cr, uid, ids, {}, context=context)
return True
@@ -916,7 +916,7 @@ class account_invoice_line(osv.osv):
cur = line.invoice_id.currency_id
res[line.id] = cur_obj.round(cr, uid, cur, res[line.id])
else:
res[line.id] = round(line.price_unit * line.quantity * (1-(line.discount or 0.0)/100.0),2)
res[line.id] = round(line.price_unit * line.quantity * (1-(line.discount or 0.0)/100.0),int(config['price_accuracy']))
return res
@@ -948,9 +948,9 @@ class account_invoice_line(osv.osv):
'product_id': fields.many2one('product.product', 'Product', ondelete='set null'),
'account_id': fields.many2one('account.account', 'Account', required=True, domain=[('type','<>','view'), ('type', '<>', 'closed')], help="The income or expense account related to the selected product."),
'price_unit': fields.float('Unit Price', required=True, digits=(16, int(config['price_accuracy']))),
'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal',store=True),
'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal',store=True, type="float", digits=(16, int(config['price_accuracy']))),
'quantity': fields.float('Quantity', required=True),
'discount': fields.float('Discount (%)', digits=(16,2)),
'discount': fields.float('Discount (%)', digits=(16, int(config['price_accuracy']))),
'invoice_line_tax_id': fields.many2many('account.tax', 'account_invoice_line_tax', 'invoice_line_id', 'tax_id', 'Taxes', domain=[('parent_id','=',False)]),
'note': fields.text('Notes'),
'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic Account'),
@@ -1100,15 +1100,15 @@ class account_invoice_tax(osv.osv):
'invoice_id': fields.many2one('account.invoice', 'Invoice Line', ondelete='cascade', select=True),
'name': fields.char('Tax Description', size=64, required=True),
'account_id': fields.many2one('account.account', 'Tax Account', required=True, domain=[('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')]),
'base': fields.float('Base', digits=(16,2)),
'amount': fields.float('Amount', digits=(16,2)),
'base': fields.float('Base', digits=(16,int(config['price_accuracy']))),
'amount': fields.float('Amount', digits=(16,int(config['price_accuracy']))),
'manual': fields.boolean('Manual'),
'sequence': fields.integer('Sequence'),
'base_code_id': fields.many2one('account.tax.code', 'Base Code', help="The account basis of the tax declaration."),
'base_amount': fields.float('Base Code Amount', digits=(16,2)),
'base_amount': fields.float('Base Code Amount', digits=(16,int(config['price_accuracy']))),
'tax_code_id': fields.many2one('account.tax.code', 'Tax Code', help="The tax basis of the tax declaration."),
'tax_amount': fields.float('Tax Code Amount', digits=(16,2)),
'tax_amount': fields.float('Tax Code Amount', digits=(16,int(config['price_accuracy']))),
}
def base_change(self, cr, uid, ids, base,currency_id=False,company_id=False,date_invoice=False):
cur_obj = self.pool.get('res.currency')
+7 -1
View File
@@ -35,6 +35,7 @@ class Overdue(report_sxw.rml_parse):
'adr_get' : self._adr_get,
'getLines' : self._lines_get,
'tel_get' : self._tel_get,
'message' : self._message,
})
self.context = context
def _adr_get(self, partner, type):
@@ -80,7 +81,12 @@ class Overdue(report_sxw.rml_parse):
('state', '<>', 'draft'), ('reconcile_id', '=', False)])
movelines = moveline_obj.browse(self.cr, self.uid, movelines)
return movelines
def _message(self, obj, company):
company_pool = pooler.get_pool(self.cr.dbname).get('res.company')
message = company_pool.browse(self.cr, self.uid, company.id, {'lang':obj.lang}).overdue_msg
return message
report_sxw.report_sxw('report.account.overdue', 'res.partner',
'addons/account/report/overdue.rml', parser=Overdue)
+1 -1
View File
@@ -127,7 +127,7 @@
<para style="terp_default_9">
<font color="white"> </font>
</para>
<para style="terp_default_9">[[ company.overdue_msg ]]</para>
<para style="terp_default_9">[[ message(o, company) ]]</para>
<para style="terp_default_9">
<font color="white"> </font>
</para>
+1
View File
@@ -217,6 +217,7 @@ class partner_balance(report_sxw.rml_parse):
"JOIN account_account ac ON (l.account_id = ac.id)" \
"WHERE ac.type IN " + self.ACCOUNT_TYPE + " " \
"AND l.date IN (" + self.date_lst_string + ") " \
"AND ac.company_id = "+ str(data['form']['company_id']) +" " \
"GROUP BY p.id, p.ref, p.name,l.account_id,ac.name,ac.code " \
"ORDER BY l.account_id,p.name")
res = self.cr.dictfetchall()
@@ -192,21 +192,24 @@ def _data_save(self, cr, uid, data, context):
})
pool.get('account.move.line').create(cr, uid, move)
offset += limit
ids = pool.get('account.move.line').search(cr, uid, [('journal_id','=',new_journal.id),
('period_id.fiscalyear_id','=',old_fyear.id)])
('period_id.fiscalyear_id','=',new_fyear.id)])
context['fy_closing'] = True
if not ids:
raise wizard.except_wizard(_('UserError'),
_('The old fiscal year does not have any entry to reconcile!'))
pool.get('account.move.line').reconcile(cr, uid, ids, context=context)
if ids:
pool.get('account.move.line').reconcile(cr, uid, ids, context=context)
new_period = data['form']['period_id']
ids = pool.get('account.journal.period').search(cr, uid, [('journal_id','=',new_journal.id),('period_id','=',new_period)])
if ids:
cr.execute('UPDATE account_fiscalyear ' \
if not ids:
ids = [pool.get('account.journal.period').create(cr, uid, {
'name': (new_journal.name or '')+':'+(period.code or ''),
'journal_id': new_journal.id,
'period_id': period.id
})]
cr.execute('UPDATE account_fiscalyear ' \
'SET end_journal_period_id = %s ' \
'WHERE id = %s', (ids[0], new_fyear.id))
'WHERE id = %s', (ids[0], old_fyear.id))
return {}
class wiz_journal_close(wizard.interface):
@@ -163,7 +163,7 @@ class account_analytic_plan_instance(osv.osv):
<newline/>"""%(i,tools.to_xml(line.name),tools.to_xml(line.name),line.root_analytic_id and line.root_analytic_id.id or 0)
i+=1
res['arch'] += "</form>"
doc = dom.minidom.parseString(res['arch'])
doc = dom.minidom.parseString(res['arch'].encode('utf8'))
xarch, xfields = self._view_look_dom_arch(cr, uid, doc, view_id, context=context)
res['arch'] = xarch
res['fields'] = xfields
+1
View File
@@ -53,6 +53,7 @@
'wizard/wizard_view.xml',
'followup_report_view.xml',
'followup_view.xml',
'followup_data.xml'
],
'demo_xml': ['followup_demo.xml'],
'installable': True,
+23
View File
@@ -55,6 +55,29 @@ class account_move_line(osv.osv):
}
account_move_line()
class res_company(osv.osv):
_inherit = "res.company"
_columns = {
'follow_up_msg' : fields.text('Follow-up Message', translate=True),
}
_defaults = {
'overdue_msg': lambda *a: '''
Date : %(date)s
Dear %(partner_name)s,
Please find in attachment a reminder of all your unpaid invoices, for a total amount due of:
%(followup_amount).2f %(company_currency)s
Thanks,
--
%(user_signature)s
%(company_name)s
'''
}
res_company()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+19
View File
@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<openerp>
<data>
<record model="res.company" id="base.main_company">
<field name="follow_up_msg">Date : %(date)s
Dear %(partner_name)s,
Please find in attachment a reminder of all your unpaid invoices, for a total amount due of:
%(followup_amount).2f %(company_currency)s
Thanks,
--
%(user_signature)s
%(company_name)s</field>
</record>
</data>
</openerp>
+12 -2
View File
@@ -125,7 +125,6 @@
</field>
</record>
<act_window domain="[('partner_id', '=', active_id),('reconcile_id','=',False),('account_id.reconcile', '=', True)]" id="account.act_account_partner_account_move_unreconciled" name="Receivables &amp; Payables" res_model="account.move.line" view="account_move_line_partner_tree"/>
<act_window domain="[('reconcile_id', '=', False),('account_id.type','=','receivable')]" id="act_account_partner_account_move_all" name="All receivable entries" res_model="account.move.line" src_model="" view="account_move_line_partner_tree"/>
@@ -136,6 +135,17 @@
<menuitem action="act_account_partner_account_move_payable_all" id="menu_account_move_open_unreconcile_payable" parent="account_followup.menu_action_followup_stat"/>
<record model="ir.ui.view" id="view_company_inherit_followup_form">
<field name="name">res.company.followup.form.inherit</field>
<field name="inherit_id" ref="account.view_company_inherit_form"/>
<field name="model">res.company</field>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="overdue_msg" nolabel="1" colspan ="4" position="after">
<separator string="Follow-up Message" colspan="4"/>
<field name="follow_up_msg" nolabel="1" colspan ="4"/>
</field>
</field>
</record>
</data>
</openerp>
@@ -60,8 +60,9 @@ _followup_wizard_all_form = """<?xml version="1.0"?>
</page>
<page string="Email Settings">
<field name="email_conf" colspan="4"/>
<field name="partner_lang" colspan="4"/>
<field name="email_subject" colspan="4"/>
<separator string="Email body" colspan="4"/>
<separator string="Email body" colspan="4" attrs="{'readonly':[('partner_lang','=',True)]}"/>
<field name="email_body" colspan="4" nolabel="1"/>
<separator string="Legend" colspan="4"/>
@@ -94,6 +95,12 @@ _followup_wizard_all_fields = {
'size': 64,
'default': 'Invoices Reminder'
},
'partner_lang':{
'string': "Send Email in Partner Language",
'type': 'boolean',
'default':True,
'help':'Do not change message text, if you want to send email in partner language, or configre from company'
},
'email_body': {
'string': "Email body",
'type': 'text',
@@ -156,7 +163,13 @@ class followup_all_print(wizard.interface):
if adr.email:
dest = [adr.email]
src = tools.config.options['smtp_user']
body=data['form']['email_body']
if not data['form']['partner_lang']:
body = data['form']['email_body']
else:
cxt = context.copy()
cxt['lang'] = partner.lang
body = pool.get('res.users').browse(cr, uid, uid, context=cxt).company_id.follow_up_msg
total_amt = followup_data.debit - followup_data.credit
move_line = ''
subtotal_due = 0.0
@@ -166,7 +179,7 @@ class followup_all_print(wizard.interface):
l = '--------------------------------------------------------------------------------------------------------------------------'
head = l+ '\n' + 'Date'.rjust(10) + '\t' + 'Description'.rjust(10) + '\t' + 'Ref'.rjust(10) + '\t' + 'Maturity date'.rjust(10) + '\t' + 'Due'.rjust(10) + '\t' + 'Paid'.rjust(10) + '\t' + 'Maturity'.rjust(10) + '\t' + 'Litigation'.rjust(10) + '\n' + l
for i in data_lines:
maturity = ''
maturity = 0.00
if i.date_maturity < time.strftime('%Y-%m-%d') and (i.debit - i.credit):
maturity = i.debit - i.credit
subtotal_due = subtotal_due + i.debit
@@ -187,7 +200,7 @@ class followup_all_print(wizard.interface):
'date':time.strftime('%Y-%m-%d'),
}
body = body%val
sub = str(data['form']['email_subject'])
sub = tools.ustr(data['form']['email_subject'])
msg = ''
if dest:
tools.email_send(src,dest,sub,body)
@@ -196,15 +209,15 @@ class followup_all_print(wizard.interface):
msg += partner.name + '\n'
msg_unsent += msg
if not msg_unsent:
summary = _("All emails have been successfully sent to Partners:.\n\n") + msg_sent
summary = _("All E-mails have been successfully sent to Partners:.\n\n") + msg_sent
else:
msg_unsent = _("Mail not sent to following Partners, Email not available !\n\n") + msg_unsent
msg_sent = msg_sent and _("\n\nMail sent to following Partners successfully, !\n\n") + msg_sent
msg_unsent = _("E-Mail not sent to following Partners, Email not available !\n\n") + msg_unsent
msg_sent = msg_sent and _("\n\nE-Mail sent to following Partners successfully. !\n\n") + msg_sent
line = '=========================================================================='
summary = msg_unsent + line + msg_sent
return {'summary' : summary}
else:
return {'summary' : '\n\n\nMail not sent to any partner if you want to sent it please tick send email confirmation on wizard'}
return {'summary' : '\n\n\nE-Mail has not been sent to any partner. If you want to send it, please tick send email confirmation on wizard.'}
def _get_partners(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
@@ -256,8 +269,10 @@ class followup_all_print(wizard.interface):
if partner_id not in partner_list:
partner_list.append(partner_id)
to_update[str(id)] = fups[followup_line_id][1]
return {'partner_ids': partner_list, 'to_update': to_update}
message = pool.get('res.users').browse(cr, uid, uid, context=context).company_id.follow_up_msg
return {'partner_ids': partner_list, 'to_update': to_update, 'email_body':message}
def _get_screen1_values(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
@@ -161,6 +161,38 @@ class abstract_quality_check(object):
def add_quatation(self, x_no, y_no):
return x_no/y_no
def get_style(self):
# This function return style tag with specified styles for html pages
style = '''
<style>
.divstyle {
border:1px solid #aaaaaa;
background-color:#f9f9f9;
padding:5px;
}
.tablestyle
{
border:1px dashed gray;
}
.tdatastyle
{
border:0.5px solid gray;
}
.head
{
color: black;
background: none;
font-weight: normal;
margin: 0;
padding-top: .5em;
padding-bottom: .17em;
border-bottom: 1px solid #aaa;
}
}
</style> '''
return style
class module_quality_check(osv.osv):
_name = 'module.quality.check'
_columns = {
@@ -40,7 +40,6 @@ Test checks for fields, views, security rules, dependancy level
return None
def run_test(self, cr, uid, module_path):
pool = pooler.get_pool(cr.dbname)
module_name = module_path.split('/')[-1]
obj_list = self.get_objects(cr, uid, module_name)
@@ -184,9 +183,9 @@ Test checks for fields, views, security rules, dependancy level
def get_result_details(self, dict_obj):
res = ""
if dict_obj != {}:
str_html = '''<html><strong> Fields Result</strong><head></head><body>'''
str_html = '''<html><strong> Fields Result</strong><head>%s</head><body>'''%(self.get_style())
res += str_html
header = ('<tr><th width="200">%s</th><th width="200">%s</th><th width="300">%s</th></tr>', [_('Object Name'), _('Field name'), _('Suggestion')])
header = ('<tr><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th></tr>', [_('Object Name'), _('Field name'), _('Suggestion')])
if not self.error:
for key in dict_obj.keys():
data_list = []
@@ -196,17 +195,18 @@ Test checks for fields, views, security rules, dependancy level
for i in data_list:
count = count + 1
final_dict[key + str(count)] = i
res += '<table>' + self.format_html_table(header, data_list=final_dict) + '</table><br>'
res_str = '<table class="tablestyle">' + self.format_html_table(header, data_list=final_dict) + '</table><br>'
res += res_str.replace('''<td''', '''<td class="tdatastyle" ''')
return res + '</body></html>'
return ""
def get_result_general(self, dict_obj, name=''):
str_html = '''<html><strong> %s Result</strong><head></head><body><table>'''% (name)
header = ('<tr><th>%s</th><th>%s</th></tr>', [_('Object Name'), _('Suggestion')])
str_html = '''<html><strong> %s Result</strong><head>%s</head><body><table class="tablestyle">'''% (name, self.get_style())
header = ('<tr><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th></tr>', [_('Object Name'), _('Suggestion')])
if not self.error:
res = str_html + self.format_html_table(header, data_list=dict_obj) + '</table></body></html>'
res = res.replace('''<td''', '''<td class="tdatastyle" ''')
return res
return ""
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -271,10 +271,11 @@ PEP-8 Test , copyright of py files check, method can not call from loops
return ""
def get_result_general(self, dict_obj):
str_html = '''<html><strong>Result</strong><head></head><body><table>'''
header = ('<tr><th>%s</th><th>%s</th><th>%s</th></tr>', [_('Object Name'), _('Line number'), _('Suggestion')])
str_html = '''<html><strong>Result</strong><head>%s</head><body><table class="tablestyle">'''%(self.get_style())
header = ('<tr><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th></tr>', [_('Object Name'), _('Line number'), _('Suggestion')])
if not self.error:
res = str_html + self.format_html_table(header, data_list=dict_obj) + '</table></body></html>'
res = res.replace('''<td''', '''<td class="tdatastyle" ''')
return res
return ""
@@ -48,11 +48,7 @@ class quality_test(base_module_quality.abstract_quality_check):
score = 0.0
dict_py = {}
flag = False
self.result_details += '''<html>
<head>
<link rel="stylesheet" type="text/css" href="/tg_widgets/openerp/css/wiki.css" media="all">
</head>
<body>'''
self.result_details += '''<html><body><head>%s</head>'''%(self.get_style())
for file_py in list_files:
if file_py.split('.')[-1] == 'py' and not file_py.endswith('__init__.py') and not file_py.endswith('__terp__.py'):
if not flag:
@@ -84,7 +80,19 @@ class quality_test(base_module_quality.abstract_quality_check):
score += 0
#self.result += file + ": "+_("Unable to parse the result. Check the details.")+"\n"
dict_py[file_py] = [file_py, _("Unable to parse the result. Check the details.")]
self.result_details += res.replace('''<div''', '''<div class="wikiwidget readonlyfield"''')
replace_string = ''
replace_string += res
replace_string = replace_string.replace('''<div''', '''<div class="divstyle" ''')
replace_string = replace_string.replace('''<h1''', '''<h1 style="font-size:188%" class="head" ''')
replace_string = replace_string.replace('''<h2''', '''<h2 style="font-size:150%" class="head" ''')
replace_string = replace_string.replace('''<h3''', '''<h3 style="font-size:132%" class="head" ''')
replace_string = replace_string.replace('''<h4''', '''<h4 style="font-size:116%" class="head" ''')
replace_string = replace_string.replace('''<h5''', '''<h5 style="font-size:100%" class="head" ''')
replace_string = replace_string.replace('''<h6''', '''<h6 style="font-size:80%" class="head" ''')
replace_string = replace_string.replace('''<table''', '''<table class="tablestyle" ''')
replace_string = replace_string.replace('''<th''', '''<th class="tdatastyle" ''')
replace_string = replace_string.replace('''<td''', '''<td class="tdatastyle" ''')
self.result_details += replace_string
if not flag:
self.error = True
@@ -104,5 +112,4 @@ class quality_test(base_module_quality.abstract_quality_check):
return self.format_table(header, data_list=dict_py)
return ""
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -64,6 +64,9 @@ This test checks the speed of the module. Note that at least 5 demo data is need
result_dict2 = {}
self.result_details += _("<html>O(1) means that the number of SQL requests to read the object does not depand on the number of objects we are reading. This feature is hardly wished.\n</html>")
for obj, ids in obj_ids.items():
code_base_complexity = 0
code_half_complexity = 0
code_size_complexity = 0
obj_counter += 1
ids = ids[:100]
size = len(ids)
@@ -71,34 +74,38 @@ This test checks the speed of the module. Note that at least 5 demo data is need
if size:
speed_list = []
#we perform the operation twice, and count the number of queries in the second run. This allows to avoid the cache effect. (like translated terms that asks for more queries)
pool.get(obj).read(cr, uid, [ids[0]])
cnt = cr.count
pool.get(obj).read(cr, uid, [ids[0]])
code_base_complexity = cr.count - cnt
try:
pool.get(obj).read(cr, uid, [ids[0]])
cnt = cr.count
pool.get(obj).read(cr, uid, [ids[0]])
code_base_complexity = cr.count - cnt
pool.get(obj).read(cr, uid, ids[:size/2])
cnt = cr.count
pool.get(obj).read(cr, uid, ids[:size/2])
code_half_complexity = cr.count - cnt
pool.get(obj).read(cr, uid, ids[:size/2])
cnt = cr.count
pool.get(obj).read(cr, uid, ids[:size/2])
code_half_complexity = cr.count - cnt
pool.get(obj).read(cr, uid, ids)
cnt = cr.count
pool.get(obj).read(cr, uid, ids)
code_size_complexity = cr.count - cnt
if size < 5:
speed_list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, _("Warning! Not enough demo data")]
list2 = [obj, _("No enough data")]
pool.get(obj).read(cr, uid, ids)
cnt = cr.count
pool.get(obj).read(cr, uid, ids)
code_size_complexity = cr.count - cnt
except Exception, e:
list2 = [obj, _("Error in Read method")]
speed_list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, _("Error in Read method:" + str(e))]
else:
if code_size_complexity <= (code_base_complexity + size):
complexity = _("O(1)")
score += 1
list2 = [obj, _("Efficient")]
if size < 5:
speed_list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, _("Warning! Not enough demo data")]
list2 = [obj, _("No enough data")]
else:
complexity = _("O(n) or worst")
list2 = [obj, _("Not Efficient")]
if code_size_complexity <= (code_base_complexity + size):
complexity = _("O(1)")
score += 1
list2 = [obj, _("Efficient")]
else:
complexity = _("O(n) or worst")
list2 = [obj, _("Not Efficient")]
speed_list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, complexity]
speed_list = [obj, size, code_base_complexity, code_half_complexity, code_size_complexity, complexity]
else:
speed_list = [obj, size, "", "", "", _("Warning! Object has no demo data")]
list2 = [obj, _("No data")]
@@ -118,10 +125,11 @@ This test checks the speed of the module. Note that at least 5 demo data is need
return ""
def get_result_details(self, dict_speed):
str_html = '''<html><head></head><body><table border="1">'''
header = ('<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>', [_('Object Name'), _('N (Number of Records)'), _('1'), _('N/2'), _('N'), _('Reading Complexity')])
str_html = '''<html><head>%s</head><body><table class="tablestyle">'''%(self.get_style())
header = ('<tr><th class="tdatastyle" >%s</th><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th></tr>', [_('Object Name'), _('N (Number of Records)'), _('1'), _('N/2'), _('N'), _('Reading Complexity')])
if not self.error:
res = str_html + self.format_html_table(header, data_list=dict_speed) + '</table></body></html>'
res = res.replace('''<td''', '''<td class="tdatastyle" ''')
return res
return ""
@@ -23,6 +23,7 @@ import os
from tools.translate import _
from base_module_quality import base_module_quality
import pooler
class quality_test(base_module_quality.abstract_quality_check):
@@ -135,7 +136,6 @@ This test checks if the module satisfy tiny structure
self.module_score += final_score
self.score = self.module_score / (self.count)
self.result = self.get_result({ module_name: [module_name, int(self.score*100)]})
# self.result_details += self.get_result_details(self.result_dict)
return None
def run_test(self, cr, uid, module_path):
@@ -170,12 +170,12 @@ This test checks if the module satisfy tiny structure
return score
def get_result_details(self, dict_struct):
str_html = '''<html><head></head><body><table>'''
header = ('<tr><th>%s</th><th>%s</th></tr>', [_('File Name'), _('Feedback about structure of module')])
str_html = '''<html><head>%s</head><body><table class="tablestyle">'''%(self.get_style())
header = ('<tr><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th></tr>', [_('File Name'), _('Feedback about structure of module')])
if not self.error:
res = str_html + self.format_html_table(header, data_list=dict_struct) + '</table></body></html>'
res = res.replace('''<td''', '''<td class="tdatastyle" ''')
return res
return ""
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -26,7 +26,6 @@ import re
import tools
from tools.translate import _
from base_module_quality import base_module_quality
import pooler
class quality_test(base_module_quality.abstract_quality_check):
@@ -116,6 +115,7 @@ class quality_test(base_module_quality.abstract_quality_check):
if result_dict1 or result_dict1:
score = round((feel_good_factor) / float(feel_good_factor + feel_bad_factor), 2)
self.result_details += self.get_result_details(result_dict)
self.result_details += self.get_result_details(result_dict1)
return [_('__terp__.py file'), score]
@@ -137,10 +137,11 @@ class quality_test(base_module_quality.abstract_quality_check):
def get_result_details(self, dict_terp):
if dict_terp:
str_html = '''<html><head></head><body><table border="1">'''
header = ('<tr><th>%s</th><th>%s</th></tr>', [_('Tag Name'), _('Feed back About terp file of Module')])
str_html = '''<html><head>%s</head><body><table class="tablestyle">'''%(self.get_style())
header = ('<tr><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th></tr>', [_('Tag Name'), _('Feed back About terp file of Module')])
if not self.error:
res = str_html + self.format_html_table(header, data_list=dict_terp) + '</table><newline/></body></html>'
res = res.replace('''<td''', '''<td class="tdatastyle" ''')
return res
return ""
@@ -23,6 +23,4 @@
import module_quality_check
import quality_save_report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -134,10 +134,11 @@ class quality_test(base_module_quality.abstract_quality_check):
return ""
def get_result_details(self, dict_wf):
str_html = '''<html><head></head><body><table border="1">'''
header = ('<tr><th>%s</th><th>%s</th></tr>', [_('Object Name'), _('Feed back About Workflow of Module')])
str_html = '''<html><head>%s</head><body><table class="tablestyle">'''%(self.get_style())
header = ('<tr><th class="tdatastyle">%s</th><th class="tdatastyle">%s</th></tr>', [_('Object Name'), _('Feed back About Workflow of Module')])
if not self.error:
res = str_html + self.format_html_table(header, data_list=dict_wf) + '</table><newline/></body></html>'
res = res.replace('''<td''', '''<td class="tdatastyle" ''')
return res
return ""
@@ -51,7 +51,7 @@ from tools.translate import _
class report_creator(osv.osv):
_name = "base_report_creator.report"
_description = "Report"
model_set_id = False
#
# Should request only used fields
#
@@ -131,7 +131,9 @@ class report_creator(osv.osv):
if (not context) or 'report_id' not in context:
return super(report_creator, self).read(cr, user, ids, fields, context, load)
ctx = context or {}
wp = [self._id_get(cr, user, context['report_id'], context)+(' in (%s)' % (','.join(map(lambda x: "'"+str(x)+"'",ids))))]
wp = ''
if self.model_set_id:
wp = [self._id_get(cr, user, context['report_id'], context)+(' in (%s)' % (','.join(map(lambda x: "'"+str(x)+"'",ids))))]
report = self._sql_query_get(cr, user, [context['report_id']], 'sql_query', None, ctx, where_plus = wp)
sql_query = report[context['report_id']]
cr.execute(sql_query)
+1 -1
View File
@@ -58,7 +58,7 @@
<record id="ir_cron_crm_action" model="ir.cron">
<field name="name">Check cases rules</field>
<field name="interval_number">1</field>
<field name="interval_number">4</field>
<field name="interval_type">hours</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
+6 -17
View File
@@ -125,16 +125,7 @@ class node_class(object):
def get_translation(self,value,lang):
result = value
pool = pooler.get_pool(self.cr.dbname)
translation_ids = pool.get('ir.translation').search(self.cr, self.uid, [('value','=',value),('lang','=',lang),('type','=','model')])
if len(translation_ids):
tran_id = translation_ids[0]
translation = pool.get('ir.translation').read(self.cr, self.uid, tran_id, ['res_id','name'])
res_model,field_name = tuple(translation['name'].split(','))
res_id = translation['res_id']
res = pool.get(res_model).read(self.cr, self.uid, res_id, [field_name])
if res:
result = res[field_name]
#TODO : to get translation term
return result
def directory_list_for_child(self,nodename,parent=False):
@@ -346,12 +337,9 @@ class document_directory(osv.osv):
object: the object.directory or object.directory.content
object2: the other object linked (if object.directory.content)
"""
def get_object(self, cr, uid, uri, context={}):
lang = context.get('lang',False)
if not lang:
user = self.pool.get('res.users').browse(cr, uid, uid)
lang = user.context_lang
context['lang'] = lang
def get_object(self, cr, uid, uri, context={}):
#TODO : set user's context_lang in context
context.update({'lang':False})
if not uri:
return node_class(cr, uid, '', False, context=context, type='database')
turi = tuple(uri)
@@ -667,6 +655,7 @@ class document_file(osv.osv):
vals['res_id']=context.get('default_res_id',False)
if not vals.get('res_model', False) and context.get('default_res_model',False):
vals['res_model']=context.get('default_res_model',False)
if vals.get('res_id', False) and vals.get('res_model',False):
obj_model=self.pool.get(vals['res_model'])
result = obj_model.read(cr, uid, [vals['res_id']], context=context)
@@ -705,7 +694,7 @@ class document_file(osv.osv):
try:
res = content_index(base64.decodestring(datas), vals['datas_fname'], vals.get('content_type', None))
super(document_file,self).write(cr, uid, [result], {
'index_content': res,
'index_content' : res,
})
cr.commit()
except:
+3
View File
@@ -207,8 +207,11 @@ class hr_holidays(osv.osv):
'state':'validate',
}
ids2 = self.pool.get('hr.employee').search(cr, uid, [('user_id','=', uid)])
if ids2:
vals['manager_id'] = ids2[0]
else:
raise osv.except_osv(_('Warning !'),_('Either there is no Employee defined, or no User attached with it.'))
self.write(cr, uid, ids, vals)
return True
@@ -44,7 +44,7 @@ class account_analytic_account(osv.osv):
res = {}
for account in self.browse(cr, uid, ids):
invoiced = {}
cr.execute('select distinct l.invoice_id from hr_analytic_timesheet h left join account_analytic_line l on (h.line_id=l.id) where account_id=1', (account.id,))
cr.execute('select distinct(l.invoice_id) from hr_analytic_timesheet h left join account_analytic_line l on (h.line_id=l.id) where account_id=%s', (account.id,))
invoice_ids = filter(None, map(lambda x: x[0], cr.fetchall()))
for invoice in self.pool.get('account.invoice').browse(cr, uid, invoice_ids, context):
res.setdefault(account.id, 0.0)
@@ -587,7 +587,7 @@ class hr_timesheet_sheet_sheet_day(osv.osv):
sheet_id,
total_timesheet,
total_attendance,
round(cast((total_attendance - total_timesheet) as Numeric),2) AS total_difference
cast(round(cast(total_attendance - total_timesheet as Numeric),2) as Double Precision) AS total_difference
FROM
((
SELECT
+8 -6
View File
@@ -35,7 +35,7 @@ theme.use_color = 1
random.seed(0)
#
# Pinky: Bad code, seems buggy, TO CHECK !
# TODO: Bad code, seems buggy, TO CHECK !
#
class external_pdf(render):
@@ -101,7 +101,7 @@ class report_custom(report_int):
colors = choice_colors(len(ids))
ids_str = ','.join(map(str, ids))
cr.execute(
"SELECT MAX(date_planned) AS stop "\
"SELECT MAX(mrp_production.date_planned) AS stop,MIN(mrp_production.date_planned) AS start "\
"FROM mrp_workcenter, mrp_production, mrp_production_workcenter_line "\
"WHERE mrp_production_workcenter_line.production_id=mrp_production.id "\
"AND mrp_production_workcenter_line.workcenter_id=mrp_workcenter.id "\
@@ -109,8 +109,10 @@ class report_custom(report_int):
"AND mrp_workcenter.id IN (%s)" % ids_str)
res = cr.dictfetchone()
if not res['stop']:
res['stop'] = time.strftime('%Y-%m-%d')
dates = self._compute_dates(datas['form']['time_unit'], time.strftime('%Y-%m-%d'), res['stop'][:10])
res['stop'] = time.strftime('%Y-%m-%d %H:%M:%S')
if not res['start']:
res['start'] = time.strftime('%Y-%m-%d %H:%M:%S')
dates = self._compute_dates(datas['form']['time_unit'], res['start'][:10], res['stop'][:10])
dates_list = dates.keys()
dates_list.sort()
x_index = []
@@ -174,8 +176,8 @@ class report_custom(report_int):
workcenter_num += 1
#plot = bar_plot.T(label=workcenter['name'], data=data, hcol=1, fill_style=fill_style.white, cluster=(color_index,len(ids)))
if (len(data[0]) <= 1):
ar = self._empty_graph(data[0][0])
if (not data) or (len(data[0]) <= 1):
ar = self._empty_graph(time.strftime('%Y-%m-%d'))
ar.draw(can)
# close canvas so that the file is written to "disk"
can.close()
+1 -1
View File
@@ -300,7 +300,7 @@ class mrp_repair(osv.osv):
'invoice_id': inv_id,
'name': name,
'origin':repair.name,
'account_id': a,
'account_id': operation.product_id and operation.product_id.property_account_income and operation.product_id.property_account_income.id,
'quantity' : operation.product_uom_qty,
'invoice_line_tax_id': [(6,0,[x.id for x in operation.tax_id])],
'uos_id' : operation.product_uom.id,
+26 -9
View File
@@ -51,7 +51,18 @@
<field domain="[('type','=','purchase')]" name="pricelist_id"/>
<field name="partner_ref" select="2"/>
<newline/>
<field colspan="4" name="order_line" nolabel="1"/>
<field colspan="4" name="order_line" nolabel="1" mode="tree,form">
<tree colors="red:date_planned&lt;=current_date" string="Purchase Order Lines">
<field name="date_planned"/>
<field name="name"/>
<field name="product_id"/>
<field name="product_qty"/>
<field name="product_uom"/>
<field name="price_unit"/>
<field name="price_subtotal"/>
</tree>
<!-- default form view -->
</field>
<group col="7" colspan="4">
<field name="amount_untaxed" sum="Untaxed amount"/>
<field name="amount_tax"/>
@@ -71,7 +82,7 @@
<button name="invoice_ok" states="except_invoice" string="Manually Corrected" icon="gtk-convert"/>
</group>
</page>
<page string="Delivery &amp; Invoices">
<page string="Delivery &amp; Invoices" groups="account.group_account_user">
<group colspan="2" col="2">
<separator string="Delivery" colspan="2"/>
<field name="dest_address_id" on_change="onchange_dest_address_id(dest_address_id)"/>
@@ -197,7 +208,7 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Purchase Order Line">
<notebook>
<notebook colspan="4">
<page string="Order Line">
<field colspan="4" context="partner_id=parent.partner_id,quantity=product_qty,pricelist=parent.pricelist_id,uom=product_uom,warehouse=parent.warehouse_id" name="product_id" on_change="product_id_change(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order, parent.fiscal_position)"/>
<field context="partner_id=parent.partner_id,quantity=product_qty,pricelist=parent.pricelist_id,uom=product_uom,warehouse=parent.warehouse_id" name="product_qty" on_change="product_id_change(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order, parent.fiscal_position)"/>
@@ -205,17 +216,21 @@
<field colspan="4" name="name"/>
<field name="date_planned"/>
<field name="price_unit"/>
<field name="account_analytic_id"/>
<label colspan="2"/>
<field name="price_subtotal" readonly="1"/>
<field colspan="4" name="taxes_id" domain="[('parent_id','=',False),('type_tax_use','&lt;&gt;','sale')]"/>
</page>
<page string="Notes">
<field colspan="4" name="notes" nolabel="1"/>
</page>
<page string="History" groups="base.group_extended">
<page string="History" groups="base.group_extended,stock.group_stock_user">
<separator colspan="4" string="Stock Moves"/>
<field colspan="4" name="move_ids" nolabel="1" widget="many2many"/>
</page>
</page>
<page string="Invoicing" groups="account.group_account_user">
<field name="account_analytic_id" colspan="4"/>
<separator colspan="4" string="Taxes"/>
<field colspan="4" nolabel="1" name="taxes_id" domain="[('parent_id','=',False),('type_tax_use','!=','sale')]"/>
</page>
</notebook>
</form>
</field>
@@ -226,9 +241,11 @@
<field name="model">purchase.order.line</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree colors="red:date_planned&lt;=current_date" string="Purchase Order Line">
<tree colors="red:date_planned&lt;=current_date" string="Purchase Order Lines">
<field name="order_id"/>
<field name="date_order"/>
<field name="date_planned"/>
<field name="name"/>
<field name="partner_id"/>
<field name="product_id"/>
<field name="product_qty"/>
<field name="product_uom"/>
+3 -3
View File
@@ -102,9 +102,9 @@ def _merge_orders(self, cr, uid, data, context):
else:
#order_infos['name'] += ', %s' % porder.name
if porder.notes:
order_infos['notes'] += ('\n%s' % (porder.notes,))
order_infos['notes'] = (order_infos['notes'] or '') + ('\n%s' % (porder.notes,))
if porder.origin:
order_infos['origin'] = order_infos['origin'] + ' ' + porder.origin
order_infos['origin'] = (order_infos['origin'] or '') + ' ' + porder.origin
for order_line in porder.order_line:
line_key = make_key(order_line, ('name', 'date_planned', 'taxes_id', 'price_unit', 'notes', 'product_id', 'move_dest_id', 'account_analytic_id'))
@@ -161,7 +161,7 @@ class merge_orders(wizard.interface):
states = {
'init': {
'actions': [],
'result': {'type': 'form', 'arch' : merge_form, 'fields' : merge_fields, 'state' : [('end', 'Cancel'), ('merge', 'Merge orders') ]}
'result': {'type': 'form', 'arch': merge_form, 'fields' : merge_fields, 'state' : [('end', 'Cancel'), ('merge', 'Merge orders') ]}
},
'merge': {
'actions': [],
+25
View File
@@ -0,0 +1,25 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import purchase_manual
import wizard
+42
View File
@@ -0,0 +1,42 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Purchase Management - Manual Control of Invoice',
'version': '1.1',
'category': 'Generic Modules/Sales & Purchases',
'description': """Module for purchase management, manual control of invoice""",
'author': 'Tiny',
'website': 'http://www.openerp.com',
'depends': ['purchase'],
'init_xml': [],
'update_xml': [
'purchase_manual_view.xml',
'purchase_manual_wizard.xml',
],
'demo_xml': [],
'installable': True,
'active': False,
# 'certificate': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+78
View File
@@ -0,0 +1,78 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import fields
from osv import osv
import netsvc
class purchase_order_line(osv.osv):
_inherit='purchase.order.line'
_columns = {
'state': fields.selection([('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'Status', required=True, readonly=True),
'invoice_lines': fields.many2many('account.invoice.line', 'purchase_order_line_invoice_rel', 'order_line_id', 'invoice_id', 'Invoice Lines', readonly=True),
'invoiced': fields.boolean('Invoiced', readonly=True),
'partner_id': fields.related('order_id','partner_id',string='Partner',readonly=True,type="many2one", relation="res.partner"),
'date_order': fields.related('order_id','date_order',string='Order Date',readonly=True,type="date")
}
_defaults = {
'state': lambda *args: 'draft',
'invoiced': lambda *a: 0,
}
def copy_data(self, cr, uid, id, default=None, context={}):
print 'copy called'
if not default:
default = {}
default.update({
'state':'draft',
'invoiced':0,
'invoice_lines':[],
})
return super(purchase_order_line, self).copy_data(cr, uid, id, default, context)
def action_confirm(self, cr, uid, ids, context={}):
self.write(cr, uid, ids, {'state': 'confirmed'}, context)
return True
purchase_order_line()
class purchase_order(osv.osv):
_inherit='purchase.order'
def action_invoice_create(self, cr, uid, ids, context={}):
print 'Invoice Create'
res = super(purchase_order, self).action_invoice_create(cr, uid, ids, context)
for po in self.browse(cr, uid, ids, context):
todo = []
for line in po.order_line:
todo.append(line.id)
self.pool.get('purchase.order.line').write(cr, uid, todo, {'invoiced':True}, context)
return res
def wkf_confirm_order(self, cr, uid, ids, context={}):
res = super(purchase_order, self).wkf_confirm_order(cr, uid, ids, context)
todo = []
for po in self.browse(cr, uid, ids, context):
for line in po.order_line:
if line.state=='draft':
todo.append(line.id)
self.pool.get('purchase.order.line').action_confirm(cr, uid, todo, context)
return res
purchase_order()
@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
#
# Define PO Line Views
#
<record id="purchase_order_form" model="ir.ui.view">
<field name="name">purchase.order.form</field>
<field name="model">purchase.order</field>
<field name="type">form</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page[@string='Purchase Order']/field[@name='order_line']/tree/field[@name='price_subtotal']" position="after">
<field name="invoiced"/>
<field name="state"/>
</xpath>
</field>
</record>
<record id="purchase_order_line_form" model="ir.ui.view">
<field name="name">purchase.order.line.form</field>
<field name="model">purchase.order.line</field>
<field name="type">form</field>
<field name="inherit_id" ref="purchase.purchase_order_line_form"/>
<field name="priority">17</field>
<field name="arch" type="xml">
<data>
<xpath expr="/form/notebook/page[@string='Invoicing']" position="inside">
<separator colspan="4" string="Manual Invoices"/>
<field name="invoiced"/>
<newline/>
<field colspan="4" name="invoice_lines" nolabel="1" widget="many2many"/>
</xpath>
<xpath expr="/form/notebook" position="after">
<group>
<field name="state" />
</group>
</xpath>
</data>
</field>
</record>
<record id="purchase_order_line_tree" model="ir.ui.view">
<field name="name">purchase.order.line.tree</field>
<field name="model">purchase.order.line</field>
<field name="type">tree</field>
<field name="inherit_id" ref="purchase.purchase_order_line_tree"/>
<field name="arch" type="xml">
<field name="price_subtotal" position="after">
<field name="invoiced"/>
</field>
</field>
</record>
#
# Inherit PO view to get buttons
#
<record id="purchase_line_form_action" model="ir.actions.act_window">
<field name="name">Purchase Order Lines</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.order.line</field>
<field name="view_mode">tree,form</field>
</record>
<record id="purchase_line_form_action_tree" model="ir.actions.act_window.view">
<field eval="1" name="sequence"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="purchase_order_line_tree"/>
<field name="act_window_id" ref="purchase_line_form_action"/>
</record>
<record id="purchase_line_form_action_form" model="ir.actions.act_window.view">
<field eval="2" name="sequence"/>
<field name="view_mode">form</field>
<field name="view_id" ref="purchase_order_line_form"/>
<field name="act_window_id" ref="purchase_line_form_action"/>
</record>
<menuitem action="purchase_line_form_action" id="menu_purchase_line_form_action" parent="purchase.menu_purchase_root"/>
<record id="purchase_line_form_action2" model="ir.actions.act_window">
<field name="name">Uninvoiced Purchase Order Lines</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.order.line</field>
<field name="domain">[('state','in',('confirmed','done')), ('invoiced','=',False)]</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<record id="purchase_line_form_action_tree2" model="ir.actions.act_window.view">
<field eval="1" name="sequence"/>
<field name="view_mode">tree</field>
<field name="view_id" ref="purchase_order_line_tree"/>
<field name="act_window_id" ref="purchase_line_form_action2"/>
</record>
<record id="purchase_line_form_action_form2" model="ir.actions.act_window.view">
<field eval="2" name="sequence"/>
<field name="view_mode">form</field>
<field name="view_id" ref="purchase_order_line_form"/>
<field name="act_window_id" ref="purchase_line_form_action2"/>
</record>
<menuitem action="purchase_line_form_action2" id="menu_purchase_line_order_draft" parent="menu_purchase_line_form_action"/>
</data>
</openerp>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<wizard
id="wizard_purchase_order_line_invoice"
keyword="client_action_multi"
model="purchase.order.line"
name="purchase.order.line.make_invoice"
multi="True"
string="Invoice Received"/>
</data>
</openerp>
@@ -0,0 +1 @@
import wizard_purchase_line_invoice
@@ -0,0 +1,161 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import wizard
import netsvc
import ir
import pooler
invoice_form = """<?xml version="1.0"?>
<form string="Control invoices">
<separator colspan="4" string="Do you want to generate the supplier invoices ?" />
</form>
"""
invoice_fields = {
}
def _makeInvoices(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
res = False
invoices = {}
def make_invoice(order, lines):
a = order.partner_id.property_account_payable.id
if order.partner_id and order.partner_id.property_payment_term.id:
pay_term = order.partner_id.property_payment_term.id
else:
pay_term = False
inv = {
'name': order.name,
'origin': order.name,
'type': 'in_invoice',
'reference': "P%dPO%d" % (order.partner_id.id, order.id),
'account_id': a,
'partner_id': order.partner_id.id,
'address_invoice_id': order.partner_address_id.id,
'address_contact_id': order.partner_address_id.id,
'invoice_line': [(6,0,lines)],
'currency_id' : order.pricelist_id.currency_id.id,
'comment': order.notes,
'payment_term': pay_term,
'fiscal_position': order.partner_id.property_account_position.id
}
inv_id = pool.get('account.invoice').create(cr, uid, inv)
return inv_id
for line in pool.get('purchase.order.line').browse(cr,uid,data['ids']):
if (not line.invoiced) and (line.state not in ('draft','cancel')):
if not line.order_id.id in invoices:
invoices[line.order_id.id] = []
if line.product_id:
a = line.product_id.product_tmpl_id.property_account_expense.id
if not a:
a = line.product_id.categ_id.property_account_expense_categ.id
if not a:
raise osv.except_osv(_('Error !'),
_('There is no expense account defined ' \
'for this product: "%s" (id:%d)') % \
(line.product_id.name, line.product_id.id,))
else:
a = pool.get('ir.property').get(cr, uid,
'property_account_expense_categ', 'product.category',
context=context)
fpos = line.order_id.fiscal_position or False
a = pool.get('account.fiscal.position').map_account(cr, uid, fpos, a)
inv_id = pool.get('account.invoice.line').create(cr, uid, {
'name': line.name,
'origin': line.order_id.name,
'account_id': a,
'price_unit': line.price_unit,
'quantity': line.product_qty,
'uos_id': line.product_uom.id,
'product_id': line.product_id.id or False,
'invoice_line_tax_id': [(6, 0, [x.id for x in line.taxes_id])],
'note': line.notes,
'account_analytic_id': line.account_analytic_id and line.account_analytic_id.id or False,
})
cr.execute('insert into purchase_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id))
pool.get('purchase.order.line').write(cr, uid, [line.id], {'invoiced': True})
invoices[line.order_id.id].append((line,inv_id))
res = []
for result in invoices.values():
order = result[0][0].order_id
il = map(lambda x: x[1], result)
res.append(make_invoice(order, il))
return {'invoice_ids': res}
return {
'domain': "[('id','in', ["+','.join(map(str,res))+"])]",
'name': _('Supplier Invoices'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.invoice',
'view_id': False,
'context': "{'type':'in_invoice'}",
'type': 'ir.actions.act_window'
}
class line_make_invoice(wizard.interface):
def _open_invoice(self, cr, uid, data, context):
pool_obj = pooler.get_pool(cr.dbname)
model_data_ids = pool_obj.get('ir.model.data').search(cr,uid,[('model','=','ir.ui.view'),('name','=','invoice_supplier_form')])
resource_id = pool_obj.get('ir.model.data').read(cr,uid,model_data_ids,fields=['res_id'])[0]['res_id']
return {
'domain': "[('id','in', ["+','.join(map(str,data['form']['invoice_ids']))+"])]",
'name': 'Invoices',
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.invoice',
'views': [(False,'tree'),(resource_id,'form')],
'context': "{'type':'in_invoice'}",
'type': 'ir.actions.act_window'
}
states = {
'init' : {
'actions': [],
'result': {
'type': 'form',
'arch': invoice_form,
'fields': invoice_fields,
'state': [
('end', 'Cancel'),
('invoice', 'Create invoices')
]
}
},
'invoice' : {
'actions' : [_makeInvoices],
'result' : {'type': 'state', 'state': 'open'}
},
'open': {
'actions': [],
'result': {'type':'action', 'action':_open_invoice, 'state':'end'}
}
}
line_make_invoice("purchase.order.line.make_invoice")
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+1 -1
View File
@@ -47,7 +47,7 @@ class report_project_task_user(osv.osv):
t.user_id,
t.project_id,
sum(planned_hours) as hours_planned,
to_char(avg(date_close::abstime-t.create_date::timestamp), 'DD"d" HH12:MI:SS') as closing_days,
to_char(avg(date_close::abstime-t.create_date::timestamp), 'DD"d" HH24:MI:SS') as closing_days,
sum(w.hours) as hours_effective,
((sum(planned_hours)-sum(w.hours))/count(distinct t.id))::decimal(16,2) as hours_delay
from project_task t
+5 -3
View File
@@ -138,14 +138,16 @@
<para style="terp_default_9">[[ o.partner_shipping_id.title or '' ]] [[ o.partner_shipping_id.name ]]</para>
<para style="terp_default_9">[[ o.partner_shipping_id.street ]]</para>
<para style="terp_default_9">[[ o.partner_shipping_id.street2 or '' ]]</para>
<para style="terp_default_9">[[ o.partner_shipping_id.city or '' ]] [[ o.partner_shipping_id.zip or '' ]]</para>
<para style="terp_default_9">[[ o.partner_shipping_id.zip or '' ]] [[ o.partner_shipping_id.city or '' ]]</para>
<para style="terp_default_9">[[ o.partner_shipping_id.state_id and o.partner_shipping_id.state_id.name or '' ]] [[ o.partner_shipping_id.country_id and o.partner_shipping_id.country_id.name or '' ]]</para>
<para style="terp_default_9">
<font color="white"> </font>
</para>
<para style="terp_default_Bold_9">Invoice address :</para>
<para style="terp_default_9">[[ o.partner_invoice_id.title or '' ]] [[ o.partner_invoice_id.name or '' ]] </para>
<para style="terp_default_9">[[ o.partner_invoice_id.street ]] [[ o.partner_invoice_id.street2 and (', %s' % o.partner_invoice_id.street2 or '') ]]</para>
<para style="terp_default_9">[[ o.partner_invoice_id.zip or '' ]] [[ o.partner_invoice_id.city or '' ]] [[ o.partner_invoice_id.country_id and (', %s' % (o.partner_invoice_id.country_id and o.partner_invoice_id.country_id.name or '')) ]]</para>
<para style="terp_default_9">[[ o.partner_invoice_id.zip or '' ]] [[ o.partner_invoice_id.city or '' ]]</para>
<para style="terp_default_9">[[ o.partner_invoice_id.state_id and o.partner_invoice_id.state_id.name or '' ]] [[ o.partner_invoice_id.country_id and o.partner_invoice_id.country_id.name or '' ]]</para>
</td>
<td>
<para style="terp_default_8">
@@ -185,7 +187,7 @@
<para style="terp_tblheader_General_Centre">Your Reference </para>
</td>
<td>
<para style="terp_tblheader_General_Centre">Date Ordered </para>
<para style="terp_tblheader_General_Centre">[[ o.state=='draft' and 'Quotation Date' or 'Date Ordered' ]]</para>
</td>
<td>
<para style="terp_tblheader_General_Centre">Our Salesman </para>
+5 -5
View File
@@ -374,7 +374,7 @@ class sale_order(osv.osv):
'account_id': a,
'partner_id': order.partner_id.id,
'address_invoice_id': order.partner_invoice_id.id,
'address_contact_id': order.partner_invoice_id.id,
'address_contact_id': order.partner_order_id.id,
'invoice_line': [(6, 0, lines)],
'currency_id': order.pricelist_id.currency_id.id,
'comment': order.note,
@@ -526,7 +526,7 @@ class sale_order(osv.osv):
pending_deliveries = True
if ((not line.procurement_id) or (line.procurement_id.state=='done')) and not pending_deliveries:
finished = True
# finished = True
if line.state != 'done':
write_done_ids.append(line.id)
else:
@@ -560,8 +560,8 @@ class sale_order(osv.osv):
picking_id = False
for line in order.order_line:
proc_id = False
date_planned = DateTime.now() + DateTime.RelativeDateTime(days=line.delay or 0.0)
date_planned = (date_planned - DateTime.RelativeDateTime(days=company.security_lead)).strftime('%Y-%m-%d %H:%M:%S')
date_planned = DateTime.now() + DateTime.DateTimeDeltaFromDays(line.delay or 0.0)
date_planned = (date_planned - DateTime.DateTimeDeltaFromDays(company.security_lead)).strftime('%Y-%m-%d %H:%M:%S')
if line.state == 'done':
continue
if line.product_id and line.product_id.product_tmpl_id.type in ('product', 'consu'):
@@ -835,7 +835,7 @@ class sale_order_line(osv.osv):
'product_id': line.product_id.id or False,
'invoice_line_tax_id': [(6, 0, [x.id for x in line.tax_id])],
'note': line.notes,
'account_analytic_id': line.order_id.project_id.id,
'account_analytic_id': line.order_id.project_id and line.order_id.project_id.id or False,
})
cr.execute('insert into sale_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id))
self.write(cr, uid, [line.id], {'invoiced': True})
+1 -1
View File
@@ -110,7 +110,7 @@
<field domain="[('type','=','sale')]" name="pricelist_id"/>
<field name="project_id" select="2" context="{'partner_id':partner_id, 'contact_id':partner_order_id, 'pricelist_id':pricelist_id, 'default_name':name}"/>
<newline/>
<field colspan="4" mode="tree,graph" name="order_line" nolabel="1" widget="one2many_list">
<field colspan="4" mode="tree,form,graph" name="order_line" nolabel="1" widget="one2many_list">
<form string="Sale Order Lines">
<notebook>
<page string="Order Line">
+27 -27
View File
@@ -30,35 +30,35 @@ class shipping(report_sxw.rml_parse):
super(shipping, self).__init__(cr, uid, name, context)
self.localcontext.update({
'time': time,
'get_address': self._get_address,
'get_address_ship':self._get_address_ship
# 'get_address': self._get_address,
# 'get_address_ship':self._get_address_ship
})
def _get_address(self,data):
self.cr.execute("select sp.id,sp.origin,sp.address_id,so.partner_id,rp.name as name2,so.partner_invoice_id,rpa.name,rpa.street as Street,rpa.city ,rpa.zip,rc.name as country " \
"from sale_order as so, stock_picking as sp,res_partner rp,res_partner_address as rpa,res_country as rc " \
"where sp.origin=so.name " \
"and so.partner_id=rp.id " \
"and so.partner_invoice_id=rpa.id " \
"and rpa.country_id=rc.id " \
"and sp.id=%s", (data.id,))
add=self.cr.dictfetchall()
return add
def _get_address_ship(self,data):
self.cr.execute("select sp.id,sp.origin,sp.address_id,so.partner_id,rp.name as name2,so.partner_shipping_id,rpa.name,rpa.street as Street,rpa.city ,rpa.zip,rc.name as country " \
"from sale_order as so, stock_picking as sp,res_partner rp,res_partner_address as rpa,res_country as rc " \
"where sp.origin=so.name " \
"and so.partner_id=rp.id " \
"and so.partner_shipping_id=rpa.id " \
"and rpa.country_id=rc.id " \
"and sp.id=%s", (data.id,))
ship=self.cr.dictfetchall()
return ship
# def _get_address(self,data):
#
# self.cr.execute("select sp.id,sp.origin,sp.address_id,so.partner_id,rp.name as name2,so.partner_invoice_id,rpa.name,rpa.street as Street,rpa.city ,rpa.zip,rc.name as country " \
# "from sale_order as so, stock_picking as sp,res_partner rp,res_partner_address as rpa,res_country as rc " \
# "where sp.origin=so.name " \
# "and so.partner_id=rp.id " \
# "and so.partner_invoice_id=rpa.id " \
# "and rpa.country_id=rc.id " \
# "and sp.id=%s", (data.id,))
#
# add=self.cr.dictfetchall()
# return add
#
# def _get_address_ship(self,data):
#
# self.cr.execute("select sp.id,sp.origin,sp.address_id,so.partner_id,rp.name as name2,so.partner_shipping_id,rpa.name,rpa.street as Street,rpa.city ,rpa.zip,rc.name as country " \
# "from sale_order as so, stock_picking as sp,res_partner rp,res_partner_address as rpa,res_country as rc " \
# "where sp.origin=so.name " \
# "and so.partner_id=rp.id " \
# "and so.partner_shipping_id=rpa.id " \
# "and rpa.country_id=rc.id " \
# "and sp.id=%s", (data.id,))
#
# ship=self.cr.dictfetchall()
# return ship
# def _sum_total(self,data):
# print "======data=======",data
@@ -123,12 +123,12 @@
<para style="terp_default_9">[[ o.sale_id and o.sale_id.partner_invoice_id and o.sale_id.partner_invoice_id.country_id and o.sale_id.partner_invoice_id.country_id.name or '']]</para>
</td>
<td>
<para style="terp_default_9">[[ o.sale_id and o.sale_id.partner_shipping_id and o.sale_id.partner_shipping_id.partner_id.name or '']]</para>
<para style="terp_default_9">[[ o.sale_id and o.sale_id.partner_shipping_id and o.sale_id.partner_shipping_id.name or '']]</para>
<para style="terp_default_9">[[ o.sale_id and o.sale_id.partner_shipping_id and o.sale_id.partner_shipping_id.street or '']]</para>
<para style="terp_default_9">[[ o.sale_id and o.sale_id.partner_shipping_id and o.sale_id.partner_shipping_id.zip or '']]</para>
<para style="terp_default_9">[[ o.sale_id and o.sale_id.partner_shipping_id and o.sale_id.partner_shipping_id.city or '']]</para>
<para style="terp_default_9">[[ o.sale_id and o.sale_id.partner_shipping_id and o.sale_id.partner_shipping_id.country_id and o.sale_id.partner_shipping_id.country_id.name or '']]</para>
<para style="terp_default_9">[[ o.address_id and o.address_id.partner_id and o.address_id.partner_id.name or '']]</para>
<para style="terp_default_9">[[ o.address_id and o.address_id.name or '']]</para>
<para style="terp_default_9">[[ o.address_id and o.address_id.street or '']]</para>
<para style="terp_default_9">[[ o.address_id and o.address_id.zip or '']]</para>
<para style="terp_default_9">[[ o.address_id and o.address_id.city or '']]</para>
<para style="terp_default_9">[[ o.address_id and o.address_id.country_id and o.address_id.country_id.name or '']]</para>
</td>
</tr>
</blockTable>
+2
View File
@@ -1293,6 +1293,7 @@ class stock_move(osv.osv):
(0, 0, {
'name': move.name,
'quantity': move.product_qty,
'product_id': move.product_id and move.product_id.id or False,
'credit': amount,
'account_id': acc_src,
'ref': ref,
@@ -1300,6 +1301,7 @@ class stock_move(osv.osv):
'partner_id': partner_id}),
(0, 0, {
'name': move.name,
'product_id': move.product_id and move.product_id.id or False,
'quantity': move.product_qty,
'debit': amount,
'account_id': acc_dest,
+1
View File
@@ -1287,6 +1287,7 @@
<field name="address_id" select="2" context="{'contact_display':'partner'}"/>
<newline/>
<field name="picking_id" select="2"/>
<newline/>
<field name="prodlot_id" select="2"
context="{'location_id':location_id, 'product_id':product_id}"
domain="[('product_id','=',product_id)]"
+2
View File
@@ -98,6 +98,8 @@ class subscription_subscription(osv.osv):
def model_copy(self, cr, uid, ids, context={}):
for row in self.read(cr, uid, ids):
if not row.get('cron_id',False):
continue
cron_ids = [row['cron_id'][0]]
remaining = self.pool.get('ir.cron').read(cr, uid, cron_ids, ['numbercall'])[0]['numbercall']
try: