+16
-15
@@ -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"),
|
||||
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
@@ -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')
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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 & 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)
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<=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 & Invoices">
|
||||
<page string="Delivery & 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','<>','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<=current_date" string="Purchase Order Line">
|
||||
<tree colors="red:date_planned<=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"/>
|
||||
|
||||
@@ -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': [],
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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})
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)]"
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user