c6ddae7978002bfcc3e30b3491eb8016df55668b
[odoo/odoo.git] / addons / account_followup / wizard / wizard_followup_print.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
6 #    $Id$
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU General Public License as published by
10 #    the Free Software Foundation, either version 3 of the License, or
11 #    (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU General Public License for more details.
17 #
18 #    You should have received a copy of the GNU General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 ##############################################################################
22
23 import wizard
24 import datetime
25 import pooler
26 import time
27
28 import tools
29 from osv import fields, osv
30 from tools.translate import _
31
32 _email_summary_form = """<?xml version="1.0"?>
33 <form string="Summary">
34     <field name="summary" height="300" width="800"/>
35 </form>"""
36
37 _email_summary_fields = {
38     'summary': {'string': 'Summary', 'type': 'text', 'required': False, 'readonly': True},
39 }
40
41 _followup_wizard_screen1_form = """<?xml version="1.0"?>
42 <form string="Follow-up and Date Selection">
43     <field name="followup_id"/>
44     <field name="date"/>
45 </form>"""
46
47 _followup_wizard_screen1_fields = {
48     '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"},
49     'followup_id': {'string': 'Follow-up', 'type':'many2one', 'relation':'account_followup.followup', 'required': True,},
50 }
51
52
53
54 _followup_wizard_all_form = """<?xml version="1.0"?>
55 <form string="Select partners" colspan="4">
56     <notebook>
57         <page string="Partner Selection">
58             <separator string="Select partners to remind" colspan="4"/>
59             <field name="partner_ids" colspan="4" nolabel="1"/>
60         </page>
61         <page string="Email Settings">
62             <field name="email_conf" colspan="4"/>
63             <field name="partner_lang" colspan="4"/>
64             <field name="email_subject" colspan="4"/>
65             <separator string="Email body" colspan="4" attrs="{'readonly':[('partner_lang','=',True)]}"/>
66             <field name="email_body" colspan="4" nolabel="1"/>
67             <separator string="Legend" colspan="4"/>
68
69             <label string="%(partner_name)s: Partner name" colspan="2"/>
70             <label string="%(user_signature)s: User name" colspan="2"/>
71             <label string="%(followup_amount)s: Total Amount Due" colspan="2"/>
72             <label string="%(date)s: Current Date" colspan="2"/>
73             <label string="%(company_name)s: User's Company name" colspan="2"/>
74             <label string="%(company_currency)s: User's Company Currency" colspan="2"/>
75             <label string="%(heading)s: Move line header" colspan="2"/>
76             <label string="%(line)s: Account Move lines" colspan="2"/>
77         </page>
78     </notebook>
79 </form>"""
80
81 _followup_wizard_all_fields = {
82     'partner_ids': {
83         'string': "Partners",
84         'type': 'many2many',
85         'required': True,
86         'relation': 'account_followup.stat',
87     },
88     'email_conf': {
89         'string': "Send email confirmation",
90         'type': 'boolean',
91     },
92     'email_subject' : {
93         'string' : "Email Subject",
94         'type' : "char",
95         'size': 64,
96         'default': 'Invoices Reminder'
97         },
98     'partner_lang':{
99         'string': "Send Email in Partner Language",
100         'type': 'boolean',
101         'default':True,
102         'help':'Do not change message text, if you want to send email in partner language, or configre from company'
103     },
104     'email_body': {
105         'string': "Email body",
106         'type': 'text',
107         'default': '''
108 Date : %(date)s
109
110 Dear %(partner_name)s,
111
112 Please find in attachment a reminder of all your unpaid invoices, for a total amount due of:
113
114 %(followup_amount).2f %(company_currency)s
115
116
117 Thanks,
118 --
119 %(user_signature)s
120 %(company_name)s
121         '''
122     }
123 }
124
125 class followup_all_print(wizard.interface):
126     def _update_partners(self, cr, uid, data, context):
127         to_update = data['form']['to_update']
128         for id in to_update.keys():
129             if to_update[id]['partner_id'] in data['form']['partner_ids'][0][2]:
130                 cr.execute(
131                     "UPDATE account_move_line "\
132                     "SET followup_line_id=%s, followup_date=%s "\
133                     "WHERE id=%s",
134                     (to_update[id]['level'],
135                     data['form']['date'], int(id),))
136         return {}
137
138     def _sendmail(self ,cr, uid, data, context):
139         if data['form']['email_conf']:
140             mail_notsent = ''
141             msg_sent = ''
142             msg_unsent = ''
143             count = 0
144             pool = pooler.get_pool(cr.dbname)
145             data_user = pool.get('res.users').browse(cr,uid,uid)
146             line_obj = pool.get('account_followup.stat')
147             move_lines = line_obj.browse(cr,uid,data['form']['partner_ids'][0][2])
148             partners = []
149             dict_lines = {}
150             for line in move_lines:
151                 partners.append(line.name)
152                 dict_lines[line.name.id] =line
153             for partner in partners:
154                 ids_lines = pool.get('account.move.line').search(cr,uid,[('partner_id','=',partner.id),('reconcile_id','=',False),('account_id.type','in',['receivable'])])
155                 data_lines = pool.get('account.move.line').browse(cr,uid,ids_lines)
156                 followup_data = dict_lines[partner.id]
157                 dest = False
158                 if partner.address:
159                     for adr in partner.address:
160                         if adr.type=='contact':
161                             if adr.email:
162                                 dest = [adr.email]
163                         if (not dest) and adr.type=='default':
164                             if adr.email:
165                                 dest = [adr.email]
166                 src = tools.config.options['email_from']
167                 if not data['form']['partner_lang']:
168                     body = data['form']['email_body']
169                 else:
170                     cxt = context.copy()
171                     cxt['lang'] = partner.lang
172                     body = pool.get('res.users').browse(cr, uid, uid, context=cxt).company_id.follow_up_msg
173                     
174                 total_amt = followup_data.debit - followup_data.credit
175                 move_line = ''
176                 subtotal_due = 0.0
177                 subtotal_paid = 0.0
178                 subtotal_maturity = 0.0
179                 balance = 0.0
180                 l = '--------------------------------------------------------------------------------------------------------------------------'
181                 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                 for i in data_lines:
183                     maturity = 0.00
184                     if i.date_maturity < time.strftime('%Y-%m-%d') and (i.debit - i.credit):
185                         maturity = i.debit - i.credit
186                     subtotal_due = subtotal_due + i.debit
187                     subtotal_paid = subtotal_paid + i.credit
188                     subtotal_maturity = subtotal_maturity + int(maturity)
189                     balance = balance + (i.debit - i.credit)
190                     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'
191                 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'
192                 move_line = move_line + '\t\t\t' + 'Balance'.rjust(33) + '\t' + str(balance).rjust(10) + '\n' + l
193                 val = {
194                     'partner_name':partner.name,
195                     'followup_amount':total_amt,
196                     'user_signature':data_user.name,
197                     'company_name':data_user.company_id.name,
198                     'company_currency':data_user.company_id.currency_id.name,
199                     'line':move_line,
200                     'heading': head,
201                     'date':time.strftime('%Y-%m-%d'),
202                 }
203                 body = body%val
204                 sub = tools.ustr(data['form']['email_subject'])
205                 msg = ''
206                 if dest:
207                     tools.email_send(src,dest,sub,body)
208                     msg_sent += partner.name + '\n'
209                 else:
210                     msg += partner.name + '\n'
211                     msg_unsent += msg
212             if not msg_unsent:
213                 summary = _("All E-mails have been successfully sent to Partners:.\n\n") + msg_sent
214             else:
215                 msg_unsent = _("E-Mail not sent to following Partners, Email not available !\n\n") + msg_unsent
216                 msg_sent = msg_sent and _("\n\nE-Mail sent to following Partners successfully. !\n\n") + msg_sent
217                 line = '=========================================================================='
218                 summary = msg_unsent + line + msg_sent
219             return {'summary' : summary}
220         else:
221             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.'}
222
223     def _get_partners(self, cr, uid, data, context):
224         pool = pooler.get_pool(cr.dbname)
225         cr.execute(
226             "SELECT l.partner_id, l.followup_line_id,l.date_maturity, l.date, l.id "\
227             "FROM account_move_line AS l "\
228                 "LEFT JOIN account_account AS a "\
229                 "ON (l.account_id=a.id) "\
230             "WHERE (l.reconcile_id IS NULL) "\
231                 "AND (a.type='receivable') "\
232                 "AND (l.state<>'draft') "\
233                 "AND (l.partner_id is NOT NULL) "\
234                 "AND (a.active) "\
235             "ORDER BY l.date")
236         move_lines = cr.fetchall()
237         old = None
238         fups = {}
239         fup_id = data['form']['followup_id']
240
241         current_date = datetime.date(*time.strptime(data['form']['date'],
242             '%Y-%m-%d')[:3])
243         cr.execute(
244             "SELECT * "\
245             "FROM account_followup_followup_line "\
246             "WHERE followup_id=%s "\
247             "ORDER BY sequence", (fup_id,))
248         for result in cr.dictfetchall():
249             delay = datetime.timedelta(days=result['delay'])
250             fups[old] = (current_date - delay, result['id'])
251             if result['start'] == 'end_of_month':
252                 fups[old][0].replace(day=1)
253             old = result['id']
254
255         fups[old] = (datetime.date(datetime.MAXYEAR, 12, 31), old)
256
257         partner_list = []
258         to_update = {}
259         for partner_id, followup_line_id, date_maturity,date, id in move_lines:
260             if not partner_id:
261                 continue
262             if followup_line_id not in fups:
263                 continue
264             if date_maturity:
265                 if date_maturity <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
266                     if partner_id not in partner_list:
267                         partner_list.append(partner_id)
268                     to_update[str(id)]= {'level': fups[followup_line_id][1], 'partner_id': partner_id}
269             elif date and date <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
270                 if partner_id not in partner_list:
271                     partner_list.append(partner_id)
272                 to_update[str(id)]= {'level': fups[followup_line_id][1], 'partner_id': partner_id}
273         
274         message = pool.get('res.users').browse(cr, uid, uid, context=context).company_id.follow_up_msg
275         
276         return {'partner_ids': partner_list, 'to_update': to_update, 'email_body':message}
277
278     def _get_screen1_values(self, cr, uid, data, context):
279         pool = pooler.get_pool(cr.dbname)
280         company_id = pool.get('res.users').browse(cr, uid, uid).company_id.id
281         tmp = pool.get('account_followup.followup').search(cr, uid, [('company_id', '=', company_id)])
282         followup = tmp and tmp[0] or False
283         return {'date': time.strftime('%Y-%m-%d'), 'followup_id': followup}
284
285     states = {
286         'init': {
287             'actions': [_get_screen1_values],
288             'result': {'type': 'form',
289                 'arch': _followup_wizard_screen1_form,
290                 'fields': _followup_wizard_screen1_fields,
291                 'state': [
292                     ('end', 'Cancel'),
293                     ('next', 'Continue'),
294                 ]
295             },
296         },
297         'next': {
298             'actions': [_get_partners],
299             'result': {'type': 'form',
300                 'arch': _followup_wizard_all_form,
301                 'fields': _followup_wizard_all_fields,
302                 'state': [
303                     ('end','Cancel'),
304                     ('print','Print Follow Ups & Send Mails'),
305                 ]
306             },
307         },
308         'print': {
309             'actions': [_update_partners],
310             'result': {'type': 'print',
311                 'report':'account_followup.followup.print',
312                 'state':'summary'},
313         },
314         'summary': {
315             'actions': [_sendmail],
316             'result': {'type': 'form',
317                 'arch': _email_summary_form,
318                 'fields': _email_summary_fields,
319                 'state':[('end','Ok')]
320             },
321         },
322     }
323
324 followup_all_print('account_followup.followup.print.all')
325
326
327 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
328