mirror of
https://github.com/OCA/account-financial-tools.git
synced 2025-02-02 12:47:26 +02:00
New API: wizards and corrections
This commit is contained in:
@@ -18,8 +18,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp import models, fields, api
|
||||
from openerp.tools.translate import _
|
||||
from openerp import models, fields, api, _
|
||||
|
||||
|
||||
class AccountInvoice(models.Model):
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
##############################################################################
|
||||
import logging
|
||||
|
||||
from openerp import models, fields, api
|
||||
from openerp.tools.translate import _
|
||||
from openerp import models, fields, api, _
|
||||
|
||||
logger = logging.getLogger('credit.line.control')
|
||||
|
||||
@@ -104,15 +103,18 @@ class CreditControlLine(models.Model):
|
||||
required=True,
|
||||
readonly=True)
|
||||
|
||||
account_id = fields.Many2one(related='move_line_id.account_id',
|
||||
account_id = fields.Many2one('account.account',
|
||||
related='move_line_id.account_id',
|
||||
store=True,
|
||||
readonly=True)
|
||||
|
||||
currency_id = fields.Many2one(related='move_line_id.currency_id',
|
||||
currency_id = fields.Many2one('res.currency',
|
||||
related='move_line_id.currency_id',
|
||||
store=True,
|
||||
readonly=True)
|
||||
|
||||
company_id = fields.Many2one(related='move_line_id.company_id',
|
||||
company_id = fields.Many2one('res.company',
|
||||
related='move_line_id.company_id',
|
||||
store=True,
|
||||
readonly=True)
|
||||
|
||||
@@ -123,11 +125,13 @@ class CreditControlLine(models.Model):
|
||||
readonly=True,
|
||||
states={'draft': [('readonly', False)]})
|
||||
|
||||
policy_id = fields.Many2one(related='policy_level_id.policy_id',
|
||||
policy_id = fields.Many2one('credit.control.policy',
|
||||
related='policy_level_id.policy_id',
|
||||
store=True,
|
||||
readonly=True)
|
||||
|
||||
level = fields.Integer(related='policy_level_id.level',
|
||||
level = fields.Integer('credit.control.policy.level',
|
||||
related='policy_level_id.level',
|
||||
store=True,
|
||||
readonly=True)
|
||||
|
||||
@@ -176,7 +180,6 @@ class CreditControlLine(models.Model):
|
||||
:returns: recordset of created credit lines
|
||||
"""
|
||||
currency_obj = self.env['res.currency']
|
||||
level_obj = self.env['credit.control.policy.level']
|
||||
user = self.env.user
|
||||
currencies = currency_obj.search([])
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp import models, fields, api
|
||||
from openerp.tools.translate import _
|
||||
from openerp import models, fields, api, _
|
||||
|
||||
|
||||
class CreditControlPolicy(models.Model):
|
||||
@@ -50,8 +49,7 @@ class CreditControlPolicy(models.Model):
|
||||
def _move_lines_domain(self, controlling_date):
|
||||
""" Build the default domain for searching move lines """
|
||||
self.ensure_one()
|
||||
account_ids = [a.id for a in self.account_ids]
|
||||
return [('account_id', 'in', account_ids),
|
||||
return [('account_id', 'in', self.account_ids.ids),
|
||||
('date_maturity', '<=', controlling_date),
|
||||
('reconcile_id', '=', False),
|
||||
('partner_id', '!=', False)]
|
||||
@@ -187,7 +185,7 @@ class CreditControlPolicy(models.Model):
|
||||
cr.execute("SELECT move_line_id FROM credit_control_line"
|
||||
" WHERE policy_id != %s and move_line_id in %s"
|
||||
" AND manually_overridden IS false",
|
||||
(self.id, tuple(line.id for line in lines)))
|
||||
(self.id, tuple(lines.ids)))
|
||||
res = cr.fetchall()
|
||||
if res:
|
||||
return move_line_obj.browse([row[0] for row in res])
|
||||
@@ -341,9 +339,8 @@ class CreditControlPolicyLevel(models.Model):
|
||||
_get_sql_date_part = self._get_sql_date_boundary_for_computation_mode
|
||||
sql += _get_sql_date_part(controlling_date)
|
||||
data_dict = {'controlling_date': controlling_date,
|
||||
'line_ids': tuple(line.id for line in lines),
|
||||
'line_ids': tuple(lines.ids),
|
||||
'delay': self.delay_days}
|
||||
print cr.mogrify(sql, data_dict)
|
||||
cr.execute(sql, data_dict)
|
||||
res = cr.fetchall()
|
||||
if res:
|
||||
@@ -383,7 +380,7 @@ class CreditControlPolicyLevel(models.Model):
|
||||
sql += _get_sql_date_part(controlling_date)
|
||||
previous_level = self._previous_level()
|
||||
data_dict = {'controlling_date': controlling_date,
|
||||
'line_ids': tuple(line.id for line in lines),
|
||||
'line_ids': tuple(lines.ids),
|
||||
'delay': self.delay_days,
|
||||
'previous_level': previous_level.level}
|
||||
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
##############################################################################
|
||||
import logging
|
||||
|
||||
from openerp import models, fields, api
|
||||
from openerp.tools.translate import _
|
||||
from openerp import models, fields, api, _
|
||||
|
||||
logger = logging.getLogger('credit.control.run')
|
||||
|
||||
@@ -102,7 +101,7 @@ class CreditControlRun(models.Model):
|
||||
raise api.Warning(_('Please select a policy'))
|
||||
|
||||
report = ''
|
||||
generated = []
|
||||
generated = cr_line_obj.browse()
|
||||
for policy in policies:
|
||||
if policy.do_nothing:
|
||||
continue
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
#
|
||||
##############################################################################
|
||||
import logging
|
||||
from openerp import models, fields, api
|
||||
from openerp import netsvc
|
||||
from openerp.osv import orm, fields
|
||||
|
||||
logger = logging.getLogger('credit.control.line.mailing')
|
||||
|
||||
|
||||
class CreditCommunication(orm.TransientModel):
|
||||
"""Shell class used to provide a base model to email template and reporting.
|
||||
class CreditCommunication(models.TransientModel):
|
||||
"""Shell class used to provide a base model to email template and reporting
|
||||
Il use this approche in version 7 a browse record
|
||||
will exist even if not saved
|
||||
|
||||
@@ -34,85 +34,64 @@ class CreditCommunication(orm.TransientModel):
|
||||
_name = "credit.control.communication"
|
||||
_description = "credit control communication"
|
||||
_rec_name = 'partner_id'
|
||||
_columns = {
|
||||
'partner_id': fields.many2one(
|
||||
'res.partner',
|
||||
'Partner',
|
||||
required=True
|
||||
),
|
||||
|
||||
'current_policy_level': fields.many2one(
|
||||
'credit.control.policy.level',
|
||||
'Level',
|
||||
required=True
|
||||
),
|
||||
partner_id = fields.Many2one('res.partner', 'Partner', required=True)
|
||||
|
||||
'credit_control_line_ids': fields.many2many(
|
||||
'credit.control.line',
|
||||
rel='comm_credit_rel',
|
||||
string='Credit Lines'
|
||||
),
|
||||
current_policy_level = fields.Many2one('credit.control.policy.level',
|
||||
'Level',
|
||||
required=True)
|
||||
credit_control_line_ids = fields.Many2many('credit.control.line',
|
||||
rel='comm_credit_rel',
|
||||
string='Credit Lines')
|
||||
|
||||
'company_id': fields.many2one(
|
||||
'res.company',
|
||||
'Company',
|
||||
required=True
|
||||
),
|
||||
@api.model
|
||||
def _get_company(self):
|
||||
company_obj = self.env['res.company']
|
||||
return company_obj._company_default_get('credit.control.policy')
|
||||
|
||||
'user_id': fields.many2one('res.users', 'User')
|
||||
}
|
||||
company_id = fields.Many2one('res.company',
|
||||
string='Company',
|
||||
default=_get_company,
|
||||
required=True)
|
||||
user_id = fields.Many2one('res.users',
|
||||
default=lambda self: self.env.user,
|
||||
string='User')
|
||||
|
||||
def _get_comp(self, cr, uid, context=None):
|
||||
return self.pool.get('res.company')._company_default_get(
|
||||
cr, uid,
|
||||
'credit.control.policy',
|
||||
context=context
|
||||
)
|
||||
|
||||
_defaults = {
|
||||
'company_id': _get_comp,
|
||||
'user_id': lambda s, cr, uid, c: uid
|
||||
}
|
||||
|
||||
def get_email(self, cr, uid, com_id, context=None):
|
||||
"""Return a valid email for customer"""
|
||||
if isinstance(com_id, list):
|
||||
assert len(com_id) == 1, "get_email only support one id as param."
|
||||
com_id = com_id[0]
|
||||
form = self.browse(cr, uid, com_id, context=context)
|
||||
contact = form.get_contact_address()
|
||||
@api.multi
|
||||
def get_email(self):
|
||||
""" Return a valid email for customer """
|
||||
self.ensure_one()
|
||||
contact = self.get_contact_address()
|
||||
return contact.email
|
||||
|
||||
def get_contact_address(self, cr, uid, com_id, context=None):
|
||||
pmod = self.pool['res.partner']
|
||||
if isinstance(com_id, list):
|
||||
com_id = com_id[0]
|
||||
form = self.browse(cr, uid, com_id, context=context)
|
||||
part = form.partner_id
|
||||
add_ids = part.address_get(adr_pref=['invoice']) or {}
|
||||
@api.multi
|
||||
@api.returns('res.partner')
|
||||
def get_contact_address(self):
|
||||
self.ensure_one()
|
||||
partner_obj = self.env['res.partner']
|
||||
partner = self.partner_id
|
||||
add_ids = partner.address_get(adr_pref=['invoice']) or {}
|
||||
add_id = add_ids.get('invoice', add_ids.get('default', False))
|
||||
return pmod.browse(cr, uid, add_id, context)
|
||||
return partner_obj.browse(add_id)
|
||||
|
||||
def _get_credit_lines(self, cr, uid, line_ids, partner_id, level_id,
|
||||
context=None):
|
||||
"""Return credit lines related to a partner and a policy level"""
|
||||
cr_line_obj = self.pool.get('credit.control.line')
|
||||
cr_l_ids = cr_line_obj.search(cr,
|
||||
uid,
|
||||
[('id', 'in', line_ids),
|
||||
@api.model
|
||||
@api.returns('credit.control.line')
|
||||
def _get_credit_lines(self, line_ids, partner_id, level_id):
|
||||
""" Return credit lines related to a partner and a policy level """
|
||||
cr_line_obj = self.env['credit.control.line']
|
||||
cr_lines = cr_line_obj.search([('id', 'in', line_ids),
|
||||
('partner_id', '=', partner_id),
|
||||
('policy_level_id', '=', level_id)],
|
||||
context=context)
|
||||
return cr_l_ids
|
||||
('policy_level_id', '=', level_id)])
|
||||
return cr_lines
|
||||
|
||||
def _generate_comm_from_credit_line_ids(self, cr, uid, line_ids,
|
||||
context=None):
|
||||
"""Aggregate credit control line by partner, level, and currency
|
||||
@api.model
|
||||
def _generate_comm_from_credit_lines(self, lines):
|
||||
""" Aggregate credit control line by partner, level, and currency
|
||||
It also generate a communication object per aggregation.
|
||||
"""
|
||||
if not line_ids:
|
||||
if not lines:
|
||||
return []
|
||||
comms = []
|
||||
comms = self.browse()
|
||||
sql = (
|
||||
"SELECT distinct partner_id, policy_level_id, "
|
||||
" credit_control_line.currency_id, "
|
||||
@@ -124,54 +103,46 @@ class CreditCommunication(orm.TransientModel):
|
||||
" ORDER by credit_control_policy_level.level, "
|
||||
" credit_control_line.currency_id"
|
||||
)
|
||||
|
||||
cr.execute(sql, (tuple(line_ids),))
|
||||
cr = self._cr
|
||||
cr.execute(sql, (tuple(lines.ids), ))
|
||||
res = cr.dictfetchall()
|
||||
for level_assoc in res:
|
||||
data = {}
|
||||
data['credit_control_line_ids'] = [
|
||||
(
|
||||
6, 0, self._get_credit_lines(
|
||||
cr, uid, line_ids,
|
||||
level_assoc['partner_id'],
|
||||
level_assoc['policy_level_id'],
|
||||
context=context
|
||||
)
|
||||
)
|
||||
]
|
||||
level_lines = self._get_credit_lines(lines.ids,
|
||||
level_assoc['partner_id'],
|
||||
level_assoc['policy_level_id']
|
||||
)
|
||||
|
||||
data['credit_control_line_ids'] = [(6, 0, level_lines.ids)]
|
||||
data['partner_id'] = level_assoc['partner_id']
|
||||
data['current_policy_level'] = level_assoc['policy_level_id']
|
||||
comm_id = self.create(cr, uid, data, context=context)
|
||||
comms.append(self.browse(cr, uid, comm_id, context=context))
|
||||
comm = self.create(data)
|
||||
comms += comm
|
||||
return comms
|
||||
|
||||
def _generate_emails(self, cr, uid, comms, context=None):
|
||||
"""Generate email message using template related to level"""
|
||||
cr_line_obj = self.pool.get('credit.control.line')
|
||||
email_temp_obj = self.pool.get('email.template')
|
||||
email_message_obj = self.pool.get('mail.mail')
|
||||
att_obj = self.pool.get('ir.attachment')
|
||||
email_ids = []
|
||||
essential_fields = ['subject',
|
||||
'body_html',
|
||||
'email_from',
|
||||
'email_to']
|
||||
|
||||
for comm in comms:
|
||||
# we want to use a local cr in order to send the maximum
|
||||
# of email
|
||||
template = comm.current_policy_level.email_template_id.id
|
||||
email_values = {}
|
||||
cl_ids = [cl.id for cl in comm.credit_control_line_ids]
|
||||
email_values = email_temp_obj.generate_email(cr, uid,
|
||||
template,
|
||||
comm.id,
|
||||
context=context)
|
||||
@api.multi
|
||||
@api.returns('mail.mail')
|
||||
def _generate_emails(self):
|
||||
""" Generate email message using template related to level """
|
||||
email_message_obj = self.env['mail.mail']
|
||||
email_template_obj = self.pool['email.template']
|
||||
att_obj = self.env['ir.attachment']
|
||||
emails = email_message_obj.browse()
|
||||
required_fields = ['subject',
|
||||
'body_html',
|
||||
'email_from',
|
||||
'email_to']
|
||||
cr, uid, context = self.env.cr, self.env.uid, self.env.context
|
||||
for comm in self:
|
||||
template = comm.current_policy_level.email_template_id
|
||||
email_values = email_template_obj.generate_email(cr, uid,
|
||||
template.id,
|
||||
comm.id,
|
||||
context=context)
|
||||
email_values['body_html'] = email_values['body']
|
||||
email_values['type'] = 'email'
|
||||
|
||||
email_id = email_message_obj.create(cr, uid, email_values,
|
||||
context=context)
|
||||
email = email_message_obj.create(email_values)
|
||||
|
||||
state = 'sent'
|
||||
# The mail will not be send, however it will be in the pool, in an
|
||||
@@ -179,16 +150,13 @@ class CreditCommunication(orm.TransientModel):
|
||||
# the credit control line
|
||||
# and put this latter in a `email_error` state we not that we have
|
||||
# a problem with the email
|
||||
if any(not email_values.get(field) for field in essential_fields):
|
||||
if not all(email_values.get(field) for field in required_fields):
|
||||
state = 'email_error'
|
||||
|
||||
cr_line_obj.write(
|
||||
cr, uid, cl_ids,
|
||||
{'mail_message_id': email_id,
|
||||
'state': state},
|
||||
context=context
|
||||
)
|
||||
att_ids = []
|
||||
comm.credit_control_line_ids.write({'mail_message_id': email.id,
|
||||
'state': state})
|
||||
|
||||
attachments = att_obj.browse()
|
||||
for att in email_values.get('attachments', []):
|
||||
attach_fname = att[0]
|
||||
attach_datas = att[1]
|
||||
@@ -197,33 +165,35 @@ class CreditCommunication(orm.TransientModel):
|
||||
'datas': attach_datas,
|
||||
'datas_fname': attach_fname,
|
||||
'res_model': 'mail.mail',
|
||||
'res_id': email_id,
|
||||
'res_id': email.id,
|
||||
'type': 'binary',
|
||||
}
|
||||
att_ids.append(
|
||||
att_obj.create(cr, uid, data_attach,
|
||||
context=context)
|
||||
)
|
||||
email_message_obj.write(cr, uid, [email_id],
|
||||
{'attachment_ids': [(6, 0, att_ids)]},
|
||||
context=context)
|
||||
email_ids.append(email_id)
|
||||
return email_ids
|
||||
attachments += att_obj.create(data_attach)
|
||||
email.write({'attachment_ids': [(6, 0, attachments.ids)]})
|
||||
emails += email
|
||||
return emails
|
||||
|
||||
def _generate_report(self, cr, uid, comms, context=None):
|
||||
"""Will generate a report by inserting mako template
|
||||
@api.multi
|
||||
def _generate_report(self):
|
||||
""" Will generate a report by inserting mako template
|
||||
of related policy template
|
||||
|
||||
"""
|
||||
return ''
|
||||
service = netsvc.LocalService('report.credit_control_summary')
|
||||
ids = [x.id for x in comms]
|
||||
result, format = service.create(cr, uid, ids, {}, {})
|
||||
cr, uid = self.env.cr, self.env.uid
|
||||
result, format = service.create(cr, uid, self.ids, {}, {})
|
||||
return result
|
||||
# TODO
|
||||
# return self.env['report'].get_pdf(self, 'credit_control_summary')
|
||||
|
||||
def _mark_credit_line_as_sent(self, cr, uid, comms, context=None):
|
||||
line_ids = []
|
||||
for comm in comms:
|
||||
line_ids += [x.id for x in comm.credit_control_line_ids]
|
||||
l_obj = self.pool.get('credit.control.line')
|
||||
l_obj.write(cr, uid, line_ids, {'state': 'sent'}, context=context)
|
||||
return line_ids
|
||||
@api.multi
|
||||
@api.returns('credit.control.line')
|
||||
def _mark_credit_line_as_sent(self):
|
||||
line_obj = self.env['credit.control.line']
|
||||
lines = line_obj.browse()
|
||||
for comm in self:
|
||||
lines += comm.credit_control_line_ids
|
||||
|
||||
lines.write({'state': 'sent'})
|
||||
return lines
|
||||
|
||||
@@ -19,71 +19,51 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import orm, fields
|
||||
from openerp.tools.translate import _
|
||||
from openerp import models, fields, api, _
|
||||
|
||||
|
||||
class CreditControlEmailer(orm.TransientModel):
|
||||
"""Send emails for each selected credit control lines."""
|
||||
class CreditControlEmailer(models.TransientModel):
|
||||
""" Send emails for each selected credit control lines. """
|
||||
|
||||
_name = "credit.control.emailer"
|
||||
_description = """Mass credit line emailer"""
|
||||
_rec_name = 'id'
|
||||
|
||||
def _get_line_ids(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
res = False
|
||||
if (context.get('active_model') == 'credit.control.line' and
|
||||
@api.model
|
||||
def _get_line_ids(self):
|
||||
context = self.env.context
|
||||
if not (context.get('active_model') == 'credit.control.line' and
|
||||
context.get('active_ids')):
|
||||
res = self._filter_line_ids(
|
||||
cr, uid,
|
||||
context['active_ids'],
|
||||
context=context
|
||||
)
|
||||
return res
|
||||
return False
|
||||
line_obj = self.env['credit.control.line']
|
||||
lines = line_obj.browse(context['active_id'])
|
||||
return self._filter_lines(lines)
|
||||
|
||||
_columns = {
|
||||
'line_ids': fields.many2many(
|
||||
'credit.control.line',
|
||||
string='Credit Control Lines',
|
||||
domain=[('state', '=', 'to_be_sent'),
|
||||
('channel', '=', 'email')]
|
||||
),
|
||||
}
|
||||
line_ids = fields.Many2many('credit.control.line',
|
||||
string='Credit Control Lines',
|
||||
default=_get_line_ids,
|
||||
domain=[('state', '=', 'to_be_sent'),
|
||||
('channel', '=', 'email')])
|
||||
|
||||
_defaults = {
|
||||
'line_ids': _get_line_ids,
|
||||
}
|
||||
|
||||
def _filter_line_ids(self, cr, uid, active_ids, context=None):
|
||||
"""filter lines to use in the wizard"""
|
||||
line_obj = self.pool.get('credit.control.line')
|
||||
@api.model
|
||||
@api.returns('credit.control.line')
|
||||
def _filter_lines(self, lines):
|
||||
""" filter lines to use in the wizard """
|
||||
line_obj = self.env['credit.control.line']
|
||||
domain = [('state', '=', 'to_be_sent'),
|
||||
('id', 'in', active_ids),
|
||||
('id', 'in', lines.ids),
|
||||
('channel', '=', 'email')]
|
||||
return line_obj.search(cr, uid, domain, context=context)
|
||||
return line_obj.search(domain)
|
||||
|
||||
def email_lines(self, cr, uid, wiz_id, context=None):
|
||||
assert not (isinstance(wiz_id, list) and len(wiz_id) > 1), \
|
||||
"wiz_id: only one id expected"
|
||||
comm_obj = self.pool.get('credit.control.communication')
|
||||
if isinstance(wiz_id, list):
|
||||
wiz_id = wiz_id[0]
|
||||
form = self.browse(cr, uid, wiz_id, context)
|
||||
@api.multi
|
||||
def email_lines(self):
|
||||
self.ensure_one()
|
||||
if not self.line_ids:
|
||||
raise api.Warning(_('No credit control lines selected.'))
|
||||
|
||||
if not form.line_ids:
|
||||
raise orm.except_orm(
|
||||
_('Error'),
|
||||
_('No credit control lines selected.')
|
||||
)
|
||||
comm_obj = self.env['credit.control.communication']
|
||||
|
||||
line_ids = [l.id for l in form.line_ids]
|
||||
filtered_ids = self._filter_line_ids(
|
||||
cr, uid, line_ids, context
|
||||
)
|
||||
comms = comm_obj._generate_comm_from_credit_line_ids(
|
||||
cr, uid, filtered_ids, context=context
|
||||
)
|
||||
comm_obj._generate_emails(cr, uid, comms, context=context)
|
||||
return {}
|
||||
filtered_lines = self._filter_lines(self.line_ids)
|
||||
comms = comm_obj._generate_comm_from_credit_lines(filtered_lines)
|
||||
comms._generate_emails()
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
@@ -18,90 +18,69 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp.osv import orm, fields
|
||||
from openerp.tools.translate import _
|
||||
from openerp import models, fields, api, _
|
||||
|
||||
|
||||
class CreditControlMarker(orm.TransientModel):
|
||||
"""Change the state of lines in mass"""
|
||||
class CreditControlMarker(models.TransientModel):
|
||||
""" Change the state of lines in mass """
|
||||
|
||||
_name = 'credit.control.marker'
|
||||
_description = 'Mass marker'
|
||||
|
||||
def _get_line_ids(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
res = False
|
||||
if (context.get('active_model') == 'credit.control.line' and
|
||||
@api.model
|
||||
def _get_line_ids(self):
|
||||
context = self.env.context
|
||||
if not (context.get('active_model') == 'credit.control.line' and
|
||||
context.get('active_ids')):
|
||||
res = self._filter_line_ids(
|
||||
cr, uid,
|
||||
context['active_ids'],
|
||||
context=context
|
||||
)
|
||||
return res
|
||||
return False
|
||||
line_obj = self.env['credit.control.line']
|
||||
lines = line_obj.browse(context['active_id'])
|
||||
return self._filter_lines(lines)
|
||||
|
||||
_columns = {
|
||||
'name': fields.selection([('ignored', 'Ignored'),
|
||||
('to_be_sent', 'Ready To Send'),
|
||||
('sent', 'Done')],
|
||||
'Mark as',
|
||||
required=True),
|
||||
'line_ids': fields.many2many(
|
||||
'credit.control.line',
|
||||
string='Credit Control Lines',
|
||||
domain="[('state', '!=', 'sent')]"),
|
||||
}
|
||||
name = fields.Selection([('ignored', 'Ignored'),
|
||||
('to_be_sent', 'Ready To Send'),
|
||||
('sent', 'Done')],
|
||||
string='Mark as',
|
||||
default='to_be_sent',
|
||||
required=True)
|
||||
line_ids = fields.Many2many('credit.control.line',
|
||||
string='Credit Control Lines',
|
||||
default=_get_line_ids,
|
||||
domain="[('state', '!=', 'sent')]")
|
||||
|
||||
_defaults = {
|
||||
'name': 'to_be_sent',
|
||||
'line_ids': _get_line_ids,
|
||||
}
|
||||
@api.model
|
||||
@api.returns('credit.control.line')
|
||||
def _filter_lines(self, lines):
|
||||
""" get line to be marked filter done lines """
|
||||
line_obj = self.env['credit.control.line']
|
||||
domain = [('state', '!=', 'sent'), ('id', 'in', lines.ids)]
|
||||
return line_obj.search(domain)
|
||||
|
||||
def _filter_line_ids(self, cr, uid, active_ids, context=None):
|
||||
"""get line to be marked filter done lines"""
|
||||
line_obj = self.pool.get('credit.control.line')
|
||||
domain = [('state', '!=', 'sent'), ('id', 'in', active_ids)]
|
||||
return line_obj.search(cr, uid, domain, context=context)
|
||||
@api.model
|
||||
@api.returns('credit.control.line')
|
||||
def _mark_lines(self, filtered_lines, state):
|
||||
""" write hook """
|
||||
assert state
|
||||
filtered_lines.write({'state': state})
|
||||
return filtered_lines
|
||||
|
||||
def _mark_lines(self, cr, uid, filtered_ids, state, context=None):
|
||||
"""write hook"""
|
||||
line_obj = self.pool.get('credit.control.line')
|
||||
if not state:
|
||||
raise ValueError(_('state can not be empty'))
|
||||
line_obj.write(cr, uid, filtered_ids,
|
||||
{'state': state},
|
||||
context=context)
|
||||
return filtered_ids
|
||||
@api.multi
|
||||
def mark_lines(self):
|
||||
""" Write state of selected credit lines to the one in entry
|
||||
done credit line will be ignored """
|
||||
self.ensure_one()
|
||||
|
||||
def mark_lines(self, cr, uid, wiz_id, context=None):
|
||||
"""Write state of selected credit lines to the one in entry
|
||||
done credit line will be ignored"""
|
||||
assert not (isinstance(wiz_id, list) and len(wiz_id) > 1), \
|
||||
"wiz_id: only one id expected"
|
||||
if isinstance(wiz_id, list):
|
||||
wiz_id = wiz_id[0]
|
||||
form = self.browse(cr, uid, wiz_id, context)
|
||||
if not self.line_ids:
|
||||
raise api.Warning(_('No credit control lines selected.'))
|
||||
|
||||
if not form.line_ids:
|
||||
raise orm.except_orm(
|
||||
_('Error'),
|
||||
_('No credit control lines selected.')
|
||||
)
|
||||
filtered_lines = self._filter_lines(self.line_ids)
|
||||
if not filtered_lines:
|
||||
raise api.Warning(_('No lines will be changed. '
|
||||
'All the selected lines are already done.'))
|
||||
|
||||
line_ids = [l.id for l in form.line_ids]
|
||||
self._mark_lines(filtered_lines, self.name)
|
||||
|
||||
filtered_ids = self._filter_line_ids(cr, uid, line_ids, context)
|
||||
if not filtered_ids:
|
||||
raise orm.except_orm(
|
||||
_('Information'),
|
||||
_('No lines will be changed. '
|
||||
'All the selected lines are already done.')
|
||||
)
|
||||
|
||||
self._mark_lines(cr, uid, filtered_ids, form.name, context)
|
||||
|
||||
return {'domain': unicode([('id', 'in', filtered_ids)]),
|
||||
return {'domain': unicode([('id', 'in', filtered_lines.ids)]),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'view_id': False,
|
||||
|
||||
@@ -19,113 +19,99 @@
|
||||
#
|
||||
##############################################################################
|
||||
import logging
|
||||
from openerp.tools.translate import _
|
||||
from openerp.osv import orm, fields
|
||||
from openerp import models, fields, api, _
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class credit_control_policy_changer(orm.TransientModel):
|
||||
"""Wizard that is run from invoices and allows to set manually a policy
|
||||
class credit_control_policy_changer(models.TransientModel):
|
||||
""" Wizard that is run from invoices and allows to set manually a policy
|
||||
Policy are actually apply to related move lines availabe
|
||||
in selection widget
|
||||
|
||||
"""
|
||||
_name = "credit.control.policy.changer"
|
||||
_columns = {
|
||||
'new_policy_id': fields.many2one('credit.control.policy',
|
||||
'New Policy to Apply',
|
||||
required=True),
|
||||
'new_policy_level_id': fields.many2one('credit.control.policy.level',
|
||||
'New level to apply',
|
||||
required=True),
|
||||
# Only used to provide dynamic filtering on form
|
||||
'do_nothing': fields.boolean('No follow policy'),
|
||||
'move_line_ids': fields.many2many('account.move.line',
|
||||
rel='credit_changer_ml_rel',
|
||||
string='Move line to change'),
|
||||
}
|
||||
|
||||
def _get_default_lines(self, cr, uid, context=None):
|
||||
"""Get default lines for fields move_line_ids
|
||||
new_policy_id = fields.Many2one('credit.control.policy',
|
||||
string='New Policy to Apply',
|
||||
required=True)
|
||||
new_policy_level_id = fields.Many2one('credit.control.policy.level',
|
||||
string='New level to apply',
|
||||
required=True)
|
||||
# Only used to provide dynamic filtering on form
|
||||
do_nothing = fields.Boolean(string='No follow policy')
|
||||
|
||||
@api.model
|
||||
def _get_default_lines(self):
|
||||
""" Get default lines for fields move_line_ids
|
||||
of wizard. Only take lines that are on the same account
|
||||
and move of the invoice and not reconciled
|
||||
|
||||
:return: list of compliant move line ids
|
||||
:return: list of compliant move lines
|
||||
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
context = self.env.context
|
||||
active_ids = context.get('active_ids')
|
||||
selected_line_ids = []
|
||||
inv_model = self.pool['account.invoice']
|
||||
move_line_model = self.pool['account.move.line']
|
||||
invoice_obj = self.env['account.invoice']
|
||||
move_line_obj = self.env['account.move.line']
|
||||
if not active_ids:
|
||||
return False
|
||||
# raise ValueError('No active_ids passed in context')
|
||||
for invoice in inv_model.browse(cr, uid, active_ids, context=context):
|
||||
selected_lines = move_line_obj.browse()
|
||||
for invoice in invoice_obj.browse(active_ids):
|
||||
if invoice.type in ('in_invoice', 'in_refund', 'out_refund'):
|
||||
raise orm.except_orm(
|
||||
_('User error'),
|
||||
_('Please use wizard on cutomer invoices')
|
||||
)
|
||||
raise api.Warning(_('Please use wizard on customer invoices'))
|
||||
|
||||
domain = [('account_id', '=', invoice.account_id.id),
|
||||
('move_id', '=', invoice.move_id.id),
|
||||
('reconcile_id', '=', False)]
|
||||
move_ids = move_line_model.search(cr, uid, domain, context=context)
|
||||
selected_line_ids.extend(move_ids)
|
||||
return selected_line_ids
|
||||
move_lines = move_line_obj.search(domain)
|
||||
selected_lines += move_lines
|
||||
return selected_lines
|
||||
|
||||
_defaults = {'move_line_ids': _get_default_lines}
|
||||
move_line_ids = fields.Many2many('account.move.line',
|
||||
rel='credit_changer_ml_rel',
|
||||
string='Move line to change',
|
||||
default=_get_default_lines)
|
||||
|
||||
def onchange_policy_id(self, cr, uid, ids, new_policy_id, context=None):
|
||||
if not new_policy_id:
|
||||
return {}
|
||||
policy = self.pool['credit.control.policy'].browse(cr, uid,
|
||||
new_policy_id,
|
||||
context=context)
|
||||
return {'value': {'do_nothing': policy.do_nothing}}
|
||||
@api.onchange('new_policy_level_id')
|
||||
def onchange_policy_id(self):
|
||||
if not self.new_policy_id:
|
||||
return
|
||||
self.do_nothing = self.new_policy_id.do_nothing
|
||||
|
||||
def _mark_as_overridden(self, cr, uid, move_lines, context=None):
|
||||
"""Mark `move_lines` related credit control line as overridden
|
||||
@api.model
|
||||
@api.returns('credit.control.line')
|
||||
def _mark_as_overridden(self, move_lines):
|
||||
""" Mark `move_lines` related credit control line as overridden
|
||||
This is done by setting manually_overridden fields to True
|
||||
|
||||
:param move_lines: move line to mark as overridden
|
||||
|
||||
:retun: list of credit line ids that where marked as overridden
|
||||
|
||||
:return: list of credit lines that where marked as overridden
|
||||
"""
|
||||
credit_model = self.pool['credit.control.line']
|
||||
domain = [('move_line_id', 'in', [x.id for x in move_lines])]
|
||||
credits_ids = credit_model.search(cr, uid, domain, context=context)
|
||||
credit_model.write(cr, uid,
|
||||
credits_ids,
|
||||
{'manually_overridden': True},
|
||||
context)
|
||||
return credits_ids
|
||||
credit_obj = self.env['credit.control.line']
|
||||
domain = [('move_line_id', 'in', move_lines.ids)]
|
||||
credit_lines = credit_obj.search(domain)
|
||||
credit_lines.write({'manually_overridden': True})
|
||||
return credit_lines
|
||||
|
||||
def _set_invoice_policy(self, cr, uid, move_line_ids, policy,
|
||||
context=None):
|
||||
"""Force policy on invoice"""
|
||||
invoice_model = self.pool['account.invoice']
|
||||
invoice_ids = set([x.invoice.id for x in move_line_ids if x.invoice])
|
||||
invoice_model.write(cr, uid, list(invoice_ids),
|
||||
{'credit_policy_id': policy.id},
|
||||
context=context)
|
||||
@api.model
|
||||
def _set_invoice_policy(self, move_lines, policy):
|
||||
""" Force policy on invoice """
|
||||
invoice_obj = self.env['account.invoice']
|
||||
invoice_ids = set(line.invoice.id for line in move_lines
|
||||
if line.invoice)
|
||||
invoices = invoice_obj.browse(invoice_ids)
|
||||
invoices.write({'credit_policy_id': policy.id})
|
||||
|
||||
def _check_accounts_policies(self, cr, uid, lines, policy, context=None):
|
||||
policy_obj = self.pool['credit.control.policy']
|
||||
for line in lines:
|
||||
policy_obj.check_policy_against_account(
|
||||
cr, uid,
|
||||
line.account_id.id,
|
||||
policy.id,
|
||||
context=context
|
||||
)
|
||||
@api.model
|
||||
def _check_accounts_policies(self, lines, policy):
|
||||
accounts = set(line.account_id for line in lines)
|
||||
for account in accounts:
|
||||
policy.check_policy_against_account(account)
|
||||
return True
|
||||
|
||||
def set_new_policy(self, cr, uid, wizard_id, context=None):
|
||||
"""Set new policy on an invoice.
|
||||
@api.multi
|
||||
def set_new_policy(self):
|
||||
""" Set new policy on an invoice.
|
||||
|
||||
This is done by creating a new credit control line
|
||||
related to the move line and the policy setted in
|
||||
@@ -134,49 +120,29 @@ class credit_control_policy_changer(orm.TransientModel):
|
||||
:return: ir.actions.act_windows dict
|
||||
|
||||
"""
|
||||
assert len(wizard_id) == 1, "Only one id expected"
|
||||
wizard_id = wizard_id[0]
|
||||
self.ensure_one()
|
||||
credit_line_obj = self.env['credit.control.line']
|
||||
|
||||
credit_line_model = self.pool['credit.control.line']
|
||||
ir_model = self.pool['ir.model.data']
|
||||
ui_act_model = self.pool['ir.actions.act_window']
|
||||
wizard = self.browse(cr, uid, wizard_id, context=context)
|
||||
controlling_date = fields.date.today()
|
||||
self._check_accounts_policies(
|
||||
cr,
|
||||
uid,
|
||||
wizard.move_line_ids,
|
||||
wizard.new_policy_id)
|
||||
self._mark_as_overridden(
|
||||
cr,
|
||||
uid,
|
||||
wizard.move_line_ids,
|
||||
context=context
|
||||
)
|
||||
self._check_accounts_policies(self.move_line_ids, self.new_policy_id)
|
||||
self._mark_as_overridden(self.move_line_ids)
|
||||
# As disscused with business expert
|
||||
# draft lines should be passed to ignored
|
||||
# if same level as the new one
|
||||
# As it is a manual action
|
||||
# We also ignore rounding tolerance
|
||||
generated_ids = None
|
||||
generated_ids = credit_line_model.create_or_update_from_mv_lines(
|
||||
cr, uid, [],
|
||||
[x.id for x in wizard.move_line_ids],
|
||||
wizard.new_policy_level_id.id,
|
||||
controlling_date,
|
||||
check_tolerance=False,
|
||||
context=None
|
||||
)
|
||||
self._set_invoice_policy(cr, uid,
|
||||
wizard.move_line_ids,
|
||||
wizard.new_policy_id,
|
||||
context=context)
|
||||
if not generated_ids:
|
||||
return {}
|
||||
view_id = ir_model.get_object_reference(cr, uid,
|
||||
"account_credit_control",
|
||||
"credit_control_line_action")
|
||||
assert view_id, 'No view found'
|
||||
action = ui_act_model.read(cr, uid, view_id[1], context=context)
|
||||
action['domain'] = [('id', 'in', generated_ids)]
|
||||
create = credit_line_obj.create_or_update_from_mv_lines
|
||||
generated_lines = create(self.move_line_ids,
|
||||
self.new_policy_level_id,
|
||||
controlling_date,
|
||||
check_tolerance=False)
|
||||
self._set_invoice_policy(self.move_line_ids, self.new_policy_id)
|
||||
|
||||
if not generated_lines:
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
action_ref = 'account_credit_control.credit_control_line_action'
|
||||
action = self.env.ref(action_ref)
|
||||
action = action.read()[0]
|
||||
action['domain'] = [('id', 'in', generated_lines.ids)]
|
||||
return action
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
<newline/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="new_policy_id"
|
||||
on_change="onchange_policy_id(new_policy_id)"/>
|
||||
<field name="new_policy_id"/>
|
||||
<field name="do_nothing"
|
||||
invisible="1"/>
|
||||
<field name="new_policy_level_id"
|
||||
|
||||
@@ -20,94 +20,62 @@
|
||||
##############################################################################
|
||||
import base64
|
||||
|
||||
from openerp.osv import orm, fields
|
||||
from openerp.tools.translate import _
|
||||
from openerp import models, fields, api, _
|
||||
|
||||
|
||||
class CreditControlPrinter(orm.TransientModel):
|
||||
"""Print lines"""
|
||||
class CreditControlPrinter(models.TransientModel):
|
||||
""" Print lines """
|
||||
|
||||
_name = "credit.control.printer"
|
||||
_rec_name = 'id'
|
||||
_description = 'Mass printer'
|
||||
|
||||
def _get_line_ids(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
res = False
|
||||
@api.model
|
||||
def _get_line_ids(self):
|
||||
context = self.env.context
|
||||
if context.get('active_model') != 'credit.control.line':
|
||||
return res
|
||||
res = context.get('active_ids', False)
|
||||
return res
|
||||
return False
|
||||
return context.get('active_ids', False)
|
||||
|
||||
_columns = {
|
||||
'mark_as_sent': fields.boolean(
|
||||
'Mark letter lines as sent',
|
||||
help="Only letter lines will be marked."
|
||||
),
|
||||
'report_file': fields.binary('Generated Report', readonly=True),
|
||||
'report_name': fields.char('Report name'),
|
||||
'state': fields.char('state', size=32),
|
||||
'line_ids': fields.many2many(
|
||||
'credit.control.line',
|
||||
string='Credit Control Lines'),
|
||||
}
|
||||
mark_as_sent = fields.Boolean(string='Mark letter lines as sent',
|
||||
default=True,
|
||||
help="Only letter lines will be marked.")
|
||||
report_file = fields.Binary(string='Generated Report', readonly=True)
|
||||
report_name = fields.Char(string='Report name')
|
||||
state = fields.Char(string='state')
|
||||
line_ids = fields.Many2many('credit.control.line',
|
||||
string='Credit Control Lines',
|
||||
default=_get_line_ids)
|
||||
|
||||
_defaults = {
|
||||
'mark_as_sent': True,
|
||||
'line_ids': _get_line_ids,
|
||||
}
|
||||
|
||||
def _filter_line_ids(self, cr, uid, active_ids, context=None):
|
||||
"""filter lines to use in the wizard"""
|
||||
line_obj = self.pool.get('credit.control.line')
|
||||
domain = [('state', '=', 'to_be_sent'),
|
||||
('id', 'in', active_ids),
|
||||
('channel', '=', 'letter')]
|
||||
return line_obj.search(cr, uid, domain, context=context)
|
||||
|
||||
def _credit_line_predicate(self, cr, uid, line_record, context=None):
|
||||
@api.model
|
||||
def _credit_line_predicate(self, line):
|
||||
return True
|
||||
|
||||
def _get_line_ids(self, cr, uid, lines, predicate, context=None):
|
||||
return [l.id for l in lines if predicate(cr, uid, l, context)]
|
||||
@api.model
|
||||
@api.returns('credit.control.line')
|
||||
def _get_lines(self, lines, predicate):
|
||||
return lines.filtered(predicate)
|
||||
|
||||
def print_lines(self, cr, uid, wiz_id, context=None):
|
||||
assert not (isinstance(wiz_id, list) and len(wiz_id) > 1), \
|
||||
"wiz_id: only one id expected"
|
||||
comm_obj = self.pool.get('credit.control.communication')
|
||||
if isinstance(wiz_id, list):
|
||||
wiz_id = wiz_id[0]
|
||||
form = self.browse(cr, uid, wiz_id, context)
|
||||
@api.multi
|
||||
def print_lines(self):
|
||||
self.ensure_one()
|
||||
comm_obj = self.env['credit.control.communication']
|
||||
if not self.line_ids and not self.print_all:
|
||||
raise api.Warning(_('No credit control lines selected.'))
|
||||
|
||||
if not form.line_ids and not form.print_all:
|
||||
raise orm.except_orm(_('Error'),
|
||||
_('No credit control lines selected.'))
|
||||
lines = self._get_lines(self.line_ids, self._credit_line_predicate)
|
||||
|
||||
line_ids = self._get_line_ids(cr,
|
||||
uid,
|
||||
form.line_ids,
|
||||
self._credit_line_predicate,
|
||||
context=context)
|
||||
comms = comm_obj._generate_comm_from_credit_lines(lines)
|
||||
|
||||
comms = comm_obj._generate_comm_from_credit_line_ids(cr, uid, line_ids,
|
||||
context=context)
|
||||
report_file = comm_obj._generate_report(cr, uid, comms,
|
||||
context=context)
|
||||
report_content = comms._generate_report()
|
||||
|
||||
form.write({'report_file': base64.b64encode(report_file),
|
||||
self.write({'report_file': base64.b64encode(report_content),
|
||||
'report_name': ('credit_control_esr_bvr_%s.pdf' %
|
||||
fields.datetime.now()),
|
||||
'state': 'done'})
|
||||
|
||||
if form.mark_as_sent:
|
||||
comm_obj._mark_credit_line_as_sent(cr, uid, comms, context=context)
|
||||
|
||||
return {'type': 'ir.actions.act_window',
|
||||
'res_model': 'credit.control.printer',
|
||||
'view_mode': 'form',
|
||||
'view_type': 'form',
|
||||
'res_id': form.id,
|
||||
'views': [(False, 'form')],
|
||||
'target': 'new',
|
||||
}
|
||||
if self.mark_as_sent:
|
||||
comms._mark_credit_line_as_sent()
|
||||
action = self.get_formview_action()[0]
|
||||
action['target'] = 'new'
|
||||
return action
|
||||
|
||||
Reference in New Issue
Block a user