1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
28 from osv import fields, osv
29 from tools.translate import _
31 _email_summary_form = """<?xml version="1.0"?>
32 <form string="Summary">
33 <field name="summary" height="300" width="800"/>
36 _email_summary_fields = {
37 'summary': {'string': 'Summary', 'type': 'text', 'required': False, 'readonly': True},
40 _followup_wizard_screen1_form = """<?xml version="1.0"?>
41 <form string="Follow-up and Date Selection">
42 <field name="followup_id"/>
46 _followup_wizard_screen1_fields = {
47 'date': {'string': 'Follow-up Sending Date', 'type': 'date', 'required': True, 'help':"This field allow you to select a forecast date to plan your follow-ups"},
48 'followup_id': {'string': 'Follow-up', 'type':'many2one', 'relation':'account_followup.followup', 'required': True,},
53 _followup_wizard_all_form = """<?xml version="1.0"?>
54 <form string="Select partners" colspan="4">
56 <page string="Partner Selection">
57 <separator string="Select partners to remind" colspan="4"/>
58 <field name="partner_ids" colspan="4" nolabel="1"/>
60 <page string="Email Settings">
61 <field name="email_conf" colspan="4"/>
62 <field name="partner_lang" colspan="4"/>
63 <field name="email_subject" colspan="4"/>
64 <separator string="Email body" colspan="4" attrs="{'readonly':[('partner_lang','=',True)]}"/>
65 <field name="email_body" colspan="4" nolabel="1"/>
66 <separator string="Legend" colspan="4"/>
68 <label string="%(partner_name)s: Partner name" colspan="2"/>
69 <label string="%(user_signature)s: User name" colspan="2"/>
70 <label string="%(followup_amount)s: Total Amount Due" colspan="2"/>
71 <label string="%(date)s: Current Date" colspan="2"/>
72 <label string="%(company_name)s: User's Company name" colspan="2"/>
73 <label string="%(company_currency)s: User's Company Currency" colspan="2"/>
74 <label string="%(heading)s: Move line header" colspan="2"/>
75 <label string="%(line)s: Account Move lines" colspan="2"/>
80 _followup_wizard_all_fields = {
85 'relation': 'account_followup.stat',
88 'string': "Send email confirmation",
92 'string' : "Email Subject",
95 'default': 'Invoices Reminder'
98 'string': "Send Email in Partner Language",
101 'help':'Do not change message text, if you want to send email in partner language, or configre from company'
104 'string': "Email body",
109 Dear %(partner_name)s,
111 Please find in attachment a reminder of all your unpaid invoices, for a total amount due of:
113 %(followup_amount).2f %(company_currency)s
124 class followup_all_print(wizard.interface):
125 def _update_partners(self, cr, uid, data, context):
126 to_update = data['form']['to_update']
127 for id in to_update.keys():
129 "UPDATE account_move_line "\
130 "SET followup_line_id=%s, followup_date=%s "\
133 data['form']['date'], int(id),))
136 def _sendmail(self ,cr, uid, data, context):
137 if data['form']['email_conf']:
142 pool = pooler.get_pool(cr.dbname)
143 data_user = pool.get('res.users').browse(cr,uid,uid)
144 line_obj = pool.get('account_followup.stat')
145 move_lines = line_obj.browse(cr,uid,data['form']['partner_ids'][0][2])
148 for line in move_lines:
149 partners.append(line.name)
150 dict_lines[line.name.id] =line
151 for partner in partners:
152 ids_lines = pool.get('account.move.line').search(cr,uid,[('partner_id','=',partner.id),('reconcile_id','=',False),('account_id.type','in',['receivable'])])
153 data_lines = pool.get('account.move.line').browse(cr,uid,ids_lines)
154 followup_data = dict_lines[partner.id]
157 for adr in partner.address:
158 if adr.type=='contact':
161 if (not dest) and adr.type=='default':
164 src = tools.config.options['email_from']
165 if not data['form']['partner_lang']:
166 body = data['form']['email_body']
169 cxt['lang'] = partner.lang
170 body = pool.get('res.users').browse(cr, uid, uid, context=cxt).company_id.follow_up_msg
172 total_amt = followup_data.debit - followup_data.credit
176 subtotal_maturity = 0.0
178 l = '--------------------------------------------------------------------------------------------------------------------------'
179 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
182 if i.date_maturity < time.strftime('%Y-%m-%d') and (i.debit - i.credit):
183 maturity = i.debit - i.credit
184 subtotal_due = subtotal_due + i.debit
185 subtotal_paid = subtotal_paid + i.credit
186 subtotal_maturity = subtotal_maturity + int(maturity)
187 balance = balance + (i.debit - i.credit)
188 move_line = move_line + (i.date).rjust(10) + '\t'+ (i.name).rjust(10) + '\t'+ (i.ref or '').rjust(10) + '\t' + (i.date_maturity or '').rjust(10) + '\t' + str(i.debit).rjust(10) + '\t' + str(i.credit).rjust(10) + '\t' + str(maturity).rjust(10) + '\t' + str(i.blocked).rjust(10) + '\n'
189 move_line = move_line + l + '\n'+ '\t\t\t' + 'Sub total'.rjust(35) + '\t' + (str(subtotal_due) or '').rjust(10) + '\t' + (str(subtotal_paid) or '').rjust(10) + '\t' + (str(subtotal_maturity) or '').rjust(10)+ '\n'
190 move_line = move_line + '\t\t\t' + 'Balance'.rjust(33) + '\t' + str(balance).rjust(10) + '\n' + l
192 'partner_name':partner.name,
193 'followup_amount':total_amt,
194 'user_signature':data_user.name,
195 'company_name':data_user.company_id.name,
196 'company_currency':data_user.company_id.currency_id.name,
199 'date':time.strftime('%Y-%m-%d'),
202 sub = tools.ustr(data['form']['email_subject'])
205 tools.email_send(src,dest,sub,body)
206 msg_sent += partner.name + '\n'
208 msg += partner.name + '\n'
211 summary = _("All E-mails have been successfully sent to Partners:.\n\n") + msg_sent
213 msg_unsent = _("E-Mail not sent to following Partners, Email not available !\n\n") + msg_unsent
214 msg_sent = msg_sent and _("\n\nE-Mail sent to following Partners successfully. !\n\n") + msg_sent
215 line = '=========================================================================='
216 summary = msg_unsent + line + msg_sent
217 return {'summary' : summary}
219 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.'}
221 def _get_partners(self, cr, uid, data, context):
222 pool = pooler.get_pool(cr.dbname)
224 "SELECT l.partner_id, l.followup_line_id,l.date_maturity, l.date, l.id "\
225 "FROM account_move_line AS l "\
226 "LEFT JOIN account_account AS a "\
227 "ON (l.account_id=a.id) "\
228 "WHERE (l.reconcile_id IS NULL) "\
229 "AND (a.type='receivable') "\
230 "AND (l.state<>'draft') "\
231 "AND (l.partner_id is NOT NULL) "\
234 move_lines = cr.fetchall()
237 fup_id = data['form']['followup_id']
239 current_date = datetime.date(*time.strptime(data['form']['date'],
243 "FROM account_followup_followup_line "\
244 "WHERE followup_id=%s "\
245 "ORDER BY sequence", (fup_id,))
246 for result in cr.dictfetchall():
247 delay = datetime.timedelta(days=result['delay'])
248 fups[old] = (current_date - delay, result['id'])
249 if result['start'] == 'end_of_month':
250 fups[old][0].replace(day=1)
253 fups[old] = (datetime.date(datetime.MAXYEAR, 12, 31), old)
257 for partner_id, followup_line_id, date_maturity,date, id in move_lines:
260 if followup_line_id not in fups:
263 if date_maturity <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
264 if partner_id not in partner_list:
265 partner_list.append(partner_id)
266 to_update[str(id)] = fups[followup_line_id][1]
267 elif date and date <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
268 if partner_id not in partner_list:
269 partner_list.append(partner_id)
270 to_update[str(id)] = fups[followup_line_id][1]
272 message = pool.get('res.users').browse(cr, uid, uid, context=context).company_id.follow_up_msg
274 return {'partner_ids': partner_list, 'to_update': to_update, 'email_body':message}
276 def _get_screen1_values(self, cr, uid, data, context):
277 pool = pooler.get_pool(cr.dbname)
278 company_id = pool.get('res.users').browse(cr, uid, uid).company_id.id
279 tmp = pool.get('account_followup.followup').search(cr, uid, [('company_id', '=', company_id)])
280 followup = tmp and tmp[0] or False
281 return {'date': time.strftime('%Y-%m-%d'), 'followup_id': followup}
285 'actions': [_get_screen1_values],
286 'result': {'type': 'form',
287 'arch': _followup_wizard_screen1_form,
288 'fields': _followup_wizard_screen1_fields,
291 ('next', 'Continue'),
296 'actions': [_get_partners],
297 'result': {'type': 'form',
298 'arch': _followup_wizard_all_form,
299 'fields': _followup_wizard_all_fields,
302 ('print','Print Follow Ups & Send Mails'),
307 'actions': [_update_partners],
308 'result': {'type': 'print',
309 'report':'account_followup.followup.print',
313 'actions': [_sendmail],
314 'result': {'type': 'form',
315 'arch': _email_summary_form,
316 'fields': _email_summary_fields,
317 'state':[('end','Ok')]
322 followup_all_print('account_followup.followup.print.all')
325 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: