12 changed files with 370 additions and 0 deletions
			
			
		| @ -0,0 +1,2 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | import models | ||||
| @ -0,0 +1,17 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | { | ||||
|  |     'name': 'Aged partner filter', | ||||
|  |     'summary': "Aged partners filtered pdf reports", | ||||
|  |     'version': '10.0.1.0', | ||||
|  |     'author': 'Cybrosys Technologies', | ||||
|  |     'website': "http://www.cybrosys.com", | ||||
|  |     'company': 'Cybrosys Techno Solutions', | ||||
|  |     "category": "Accounts", | ||||
|  |     'depends': ['base', 'account', 'sale'], | ||||
|  |     'data': ['views/filter_aged_partners.xml', | ||||
|  |              ], | ||||
|  |     'license': 'LGPL-3', | ||||
|  |     'images': ['static/description/banner.jpg'], | ||||
|  |     'installable': True, | ||||
|  |     'application': True, | ||||
|  | } | ||||
| @ -0,0 +1 @@ | |||||
|  | import filter_aged_partners | ||||
| @ -0,0 +1,270 @@ | |||||
|  | # -*- coding: utf-8 -*- | ||||
|  | import time | ||||
|  | from odoo.tools import float_is_zero | ||||
|  | from datetime import datetime | ||||
|  | from dateutil.relativedelta import relativedelta | ||||
|  | from odoo import  fields, models, _ | ||||
|  | from odoo.exceptions import UserError | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | class FilterAgedPartner(models.TransientModel): | ||||
|  |     _inherit ='account.aged.trial.balance' | ||||
|  | 
 | ||||
|  |     customer = fields.Many2many('res.partner', 'name', string='Customers') | ||||
|  | 
 | ||||
|  |     def _print_report(self, data): | ||||
|  |         # data['form']=super(FilterAgedPartner, self)._print_report(data) | ||||
|  |         res = {} | ||||
|  |         data = self.pre_print_report(data) | ||||
|  |         data['form'].update(self.read(['period_length'])[0]) | ||||
|  |         period_length = data['form']['period_length'] | ||||
|  |         if period_length <= 0: | ||||
|  |             raise UserError(_('You must set a period length greater than 0.')) | ||||
|  |         if not data['form']['date_from']: | ||||
|  |             raise UserError(_('You must set a start date.')) | ||||
|  | 
 | ||||
|  |         start = datetime.strptime(data['form']['date_from'], "%Y-%m-%d") | ||||
|  | 
 | ||||
|  |         for i in range(5)[::-1]: | ||||
|  |             stop = start - relativedelta(days=period_length - 1) | ||||
|  |             res[str(i)] = { | ||||
|  |                 'name': (i != 0 and (str((5 - (i + 1)) * period_length) + '-' + str((5 - i) * period_length)) or ( | ||||
|  |                 '+' + str(4 * period_length))), | ||||
|  |                 'stop': start.strftime('%Y-%m-%d'), | ||||
|  |                 'start': (i != 0 and stop.strftime('%Y-%m-%d') or False), | ||||
|  |             } | ||||
|  |             start = stop - relativedelta(days=1) | ||||
|  |         data['form'].update(res) | ||||
|  |         data['form'].update({'customer': self.customer.ids}) | ||||
|  |         # data=super(FilterAgedPartner, self)._print_report(data) | ||||
|  |         return self.env['report'].with_context(landscape=True).get_action(self, 'account.report_agedpartnerbalance', | ||||
|  |                                                                            data=data) | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | class FilterAgedCustomer(models .AbstractModel): | ||||
|  |     _inherit = 'report.account.report_agedpartnerbalance' | ||||
|  | 
 | ||||
|  |     def _get_partner_move_lines(self, account_type, date_from, target_move, period_length,customer): | ||||
|  |         periods = {} | ||||
|  |         start = datetime.strptime(date_from, "%Y-%m-%d") | ||||
|  |         for i in range(5)[::-1]: | ||||
|  |             stop = start - relativedelta(days=period_length) | ||||
|  |             periods[str(i)] = { | ||||
|  |                 'name': (i != 0 and (str((5-(i+1)) * period_length) + '-' + str((5-i) * period_length)) or ('+'+str(4 * period_length))), | ||||
|  |                 'stop': start.strftime('%Y-%m-%d'), | ||||
|  |                 'start': (i != 0 and stop.strftime('%Y-%m-%d') or False), | ||||
|  |             } | ||||
|  |             start = stop - relativedelta(days=1) | ||||
|  | 
 | ||||
|  |         res = [] | ||||
|  |         total = [] | ||||
|  |         cr = self.env.cr | ||||
|  |         user_company = self.env.user.company_id.id | ||||
|  |         move_state = ['draft', 'posted'] | ||||
|  |         if target_move == 'posted': | ||||
|  |             move_state = ['posted'] | ||||
|  |         arg_list = (tuple(move_state), tuple(account_type)) | ||||
|  |         reconciliation_clause = '(l.reconciled IS FALSE)' | ||||
|  |         cr.execute('SELECT debit_move_id, credit_move_id FROM account_partial_reconcile where create_date > %s', (date_from,)) | ||||
|  |         reconciled_after_date = [] | ||||
|  |         for row in cr.fetchall(): | ||||
|  |             reconciled_after_date += [row[0], row[1]] | ||||
|  |         if reconciled_after_date: | ||||
|  |             reconciliation_clause = '(l.reconciled IS FALSE OR l.id IN %s)' | ||||
|  |             arg_list += (tuple(reconciled_after_date),) | ||||
|  |         arg_list += (date_from, user_company) | ||||
|  |         query = ''' | ||||
|  |             SELECT DISTINCT l.partner_id, UPPER(res_partner.name) | ||||
|  |             FROM account_move_line AS l left join res_partner on l.partner_id = res_partner.id, account_account, account_move am | ||||
|  |             WHERE (l.account_id = account_account.id) | ||||
|  |                 AND (l.move_id = am.id) | ||||
|  |                 AND (am.state IN %s)                 | ||||
|  |                 AND (account_account.internal_type IN %s) | ||||
|  |                 AND ''' + reconciliation_clause + ''' | ||||
|  |                 AND (l.date <= %s) | ||||
|  |                 AND l.company_id = %s | ||||
|  |             ORDER BY UPPER(res_partner.name)''' | ||||
|  |         cr.execute(query, arg_list) | ||||
|  |         partners = cr.dictfetchall() | ||||
|  |         print 'filtered', partners | ||||
|  |         #-------------filter--------------# | ||||
|  |         if customer: | ||||
|  |             for ptnr in partners[:]: | ||||
|  |                 print customer | ||||
|  |                 print 'm', ptnr['partner_id'] | ||||
|  |                 if ptnr['partner_id'] not in customer: | ||||
|  |                     partners.remove(ptnr) | ||||
|  |         #---------------------------------# | ||||
|  | 
 | ||||
|  |         for i in range(7): | ||||
|  |             total.append(0) | ||||
|  | 
 | ||||
|  |         # Build a string like (1,2,3) for easy use in SQL query | ||||
|  |         partner_ids = [partner['partner_id'] for partner in partners if partner['partner_id']] | ||||
|  |         lines = dict((partner['partner_id'] or False, []) for partner in partners) | ||||
|  |         if not partner_ids: | ||||
|  |             return [], [], [] | ||||
|  | 
 | ||||
|  |         # This dictionary will store the not due amount of all partners | ||||
|  |         undue_amounts = {} | ||||
|  |         query = '''SELECT l.id | ||||
|  |                 FROM account_move_line AS l, account_account, account_move am | ||||
|  |                 WHERE (l.account_id = account_account.id) AND (l.move_id = am.id) | ||||
|  |                     AND (am.state IN %s) | ||||
|  |                     AND (account_account.internal_type IN %s) | ||||
|  |                     AND (COALESCE(l.date_maturity,l.date) > %s)\ | ||||
|  |                     AND ((l.partner_id IN %s) OR (l.partner_id IS NULL)) | ||||
|  |                 AND (l.date <= %s) | ||||
|  |                 AND l.company_id = %s''' | ||||
|  |         cr.execute(query, (tuple(move_state), tuple(account_type), date_from, tuple(partner_ids), date_from, user_company)) | ||||
|  |         aml_ids = cr.fetchall() | ||||
|  |         aml_ids = aml_ids and [x[0] for x in aml_ids] or [] | ||||
|  |         for line in self.env['account.move.line'].browse(aml_ids): | ||||
|  |             partner_id = line.partner_id.id or False | ||||
|  |             if partner_id not in undue_amounts: | ||||
|  |                 undue_amounts[partner_id] = 0.0 | ||||
|  |             line_amount = line.balance | ||||
|  |             if line.balance == 0: | ||||
|  |                 continue | ||||
|  |             for partial_line in line.matched_debit_ids: | ||||
|  |                 if partial_line.create_date[:10] <= date_from: | ||||
|  |                     line_amount += partial_line.amount | ||||
|  |             for partial_line in line.matched_credit_ids: | ||||
|  |                 if partial_line.create_date[:10] <= date_from: | ||||
|  |                     line_amount -= partial_line.amount | ||||
|  |             if not self.env.user.company_id.currency_id.is_zero(line_amount): | ||||
|  |                 undue_amounts[partner_id] += line_amount | ||||
|  |                 lines[partner_id].append({ | ||||
|  |                     'line': line, | ||||
|  |                     'amount': line_amount, | ||||
|  |                     'period': 6, | ||||
|  |                 }) | ||||
|  | 
 | ||||
|  |         # Use one query per period and store results in history (a list variable) | ||||
|  |         # Each history will contain: history[1] = {'<partner_id>': <partner_debit-credit>} | ||||
|  |         history = [] | ||||
|  |         for i in range(5): | ||||
|  |             args_list = (tuple(move_state), tuple(account_type), tuple(partner_ids),) | ||||
|  |             dates_query = '(COALESCE(l.date_maturity,l.date)' | ||||
|  | 
 | ||||
|  |             if periods[str(i)]['start'] and periods[str(i)]['stop']: | ||||
|  |                 dates_query += ' BETWEEN %s AND %s)' | ||||
|  |                 args_list += (periods[str(i)]['start'], periods[str(i)]['stop']) | ||||
|  |             elif periods[str(i)]['start']: | ||||
|  |                 dates_query += ' >= %s)' | ||||
|  |                 args_list += (periods[str(i)]['start'],) | ||||
|  |             else: | ||||
|  |                 dates_query += ' <= %s)' | ||||
|  |                 args_list += (periods[str(i)]['stop'],) | ||||
|  |             args_list += (date_from, user_company) | ||||
|  | 
 | ||||
|  |             query = '''SELECT l.id | ||||
|  |                     FROM account_move_line AS l, account_account, account_move am | ||||
|  |                     WHERE (l.account_id = account_account.id) AND (l.move_id = am.id) | ||||
|  |                         AND (am.state IN %s) | ||||
|  |                         AND (account_account.internal_type IN %s) | ||||
|  |                         AND ((l.partner_id IN %s) OR (l.partner_id IS NULL)) | ||||
|  |                         AND ''' + dates_query + ''' | ||||
|  |                     AND (l.date <= %s) | ||||
|  |                     AND l.company_id = %s''' | ||||
|  |             cr.execute(query, args_list) | ||||
|  |             partners_amount = {} | ||||
|  |             aml_ids = cr.fetchall() | ||||
|  |             aml_ids = aml_ids and [x[0] for x in aml_ids] or [] | ||||
|  |             for line in self.env['account.move.line'].browse(aml_ids): | ||||
|  |                 partner_id = line.partner_id.id or False | ||||
|  |                 if partner_id not in partners_amount: | ||||
|  |                     partners_amount[partner_id] = 0.0 | ||||
|  |                 line_amount = line.balance | ||||
|  |                 if line.balance == 0: | ||||
|  |                     continue | ||||
|  |                 for partial_line in line.matched_debit_ids: | ||||
|  |                     if partial_line.create_date[:10] <= date_from: | ||||
|  |                         line_amount += partial_line.amount | ||||
|  |                 for partial_line in line.matched_credit_ids: | ||||
|  |                     if partial_line.create_date[:10] <= date_from: | ||||
|  |                         line_amount -= partial_line.amount | ||||
|  | 
 | ||||
|  |                 if not self.env.user.company_id.currency_id.is_zero(line_amount): | ||||
|  |                     partners_amount[partner_id] += line_amount | ||||
|  |                     lines[partner_id].append({ | ||||
|  |                         'line': line, | ||||
|  |                         'amount': line_amount, | ||||
|  |                         'period': i + 1, | ||||
|  |                         }) | ||||
|  |             history.append(partners_amount) | ||||
|  | 
 | ||||
|  |         for partner in partners: | ||||
|  |             if partner['partner_id'] is None: | ||||
|  |                 partner['partner_id'] = False | ||||
|  |             at_least_one_amount = False | ||||
|  |             values = {} | ||||
|  |             undue_amt = 0.0 | ||||
|  |             if partner['partner_id'] in undue_amounts:  # Making sure this partner actually was found by the query | ||||
|  |                 undue_amt = undue_amounts[partner['partner_id']] | ||||
|  | 
 | ||||
|  |             total[6] = total[6] + undue_amt | ||||
|  |             values['direction'] = undue_amt | ||||
|  |             if not float_is_zero(values['direction'], precision_rounding=self.env.user.company_id.currency_id.rounding): | ||||
|  |                 at_least_one_amount = True | ||||
|  | 
 | ||||
|  |             for i in range(5): | ||||
|  |                 during = False | ||||
|  |                 if partner['partner_id'] in history[i]: | ||||
|  |                     during = [history[i][partner['partner_id']]] | ||||
|  |                 # Adding counter | ||||
|  |                 total[(i)] = total[(i)] + (during and during[0] or 0) | ||||
|  |                 values[str(i)] = during and during[0] or 0.0 | ||||
|  |                 if not float_is_zero(values[str(i)], precision_rounding=self.env.user.company_id.currency_id.rounding): | ||||
|  |                     at_least_one_amount = True | ||||
|  |             values['total'] = sum([values['direction']] + [values[str(i)] for i in range(5)]) | ||||
|  |             ## Add for total | ||||
|  |             total[(i + 1)] += values['total'] | ||||
|  |             values['partner_id'] = partner['partner_id'] | ||||
|  |             if partner['partner_id']: | ||||
|  |                 browsed_partner = self.env['res.partner'].browse(partner['partner_id']) | ||||
|  |                 values['name'] = browsed_partner.name and len(browsed_partner.name) >= 45 and browsed_partner.name[0:40] + '...' or browsed_partner.name | ||||
|  |                 values['trust'] = browsed_partner.trust | ||||
|  |             else: | ||||
|  |                 values['name'] = _('Unknown Partner') | ||||
|  |                 values['trust'] = False | ||||
|  | 
 | ||||
|  |             if at_least_one_amount: | ||||
|  |                 res.append(values) | ||||
|  | 
 | ||||
|  |         return res, total, lines | ||||
|  | 
 | ||||
|  |     def render_html(self, docids, data=None): | ||||
|  |         print 'mymodule' | ||||
|  |         if not data.get('form') or not self.env.context.get('active_model') or not self.env.context.get('active_id'): | ||||
|  |             raise UserError(_("Form content is missing, this report cannot be printed.")) | ||||
|  | 
 | ||||
|  |         total = [] | ||||
|  |         model = self.env.context.get('active_model') | ||||
|  |         docs = self.env[model].browse(self.env.context.get('active_id')) | ||||
|  | 
 | ||||
|  |         target_move = data['form'].get('target_move', 'all') | ||||
|  |         date_from = data['form'].get('date_from', time.strftime('%Y-%m-%d')) | ||||
|  | 
 | ||||
|  |         if data['form']['result_selection'] == 'customer': | ||||
|  |             account_type = ['receivable'] | ||||
|  |         elif data['form']['result_selection'] == 'supplier': | ||||
|  |             account_type = ['payable'] | ||||
|  |         else: | ||||
|  |             account_type = ['payable', 'receivable'] | ||||
|  | 
 | ||||
|  |         movelines, total, dummy = self._get_partner_move_lines(account_type, date_from, target_move, | ||||
|  |                                             data['form']['period_length'], data['form']['customer']) | ||||
|  | 
 | ||||
|  | 
 | ||||
|  | 
 | ||||
|  |         docargs = { | ||||
|  |             'doc_ids': self.ids, | ||||
|  |             'doc_model': model, | ||||
|  |             'data': data['form'], | ||||
|  |             'docs': docs, | ||||
|  |             'time': time, | ||||
|  |             'get_partner_lines': movelines, | ||||
|  |             'get_direction': total, | ||||
|  |         } | ||||
|  |         return self.env['report'].render('account.report_agedpartnerbalance', docargs) | ||||
| After Width: | Height: | Size: 35 KiB | 
| After Width: | Height: | Size: 110 KiB | 
| After Width: | Height: | Size: 50 KiB | 
| After Width: | Height: | Size: 15 KiB | 
| @ -0,0 +1,64 @@ | |||||
|  | <section class="oe_container oe_dark"> | ||||
|  | 		<h2 class="oe_slogan">Aged Partner report with Partner Filter</h2> | ||||
|  |         <h4 class="oe_slogan">Cybrosys Techno Solutions - www.cybrosys.com</h4> | ||||
|  | </section> | ||||
|  | 
 | ||||
|  | <section class="oe_container"> | ||||
|  |     <div class="oe_row oe_spaced"> | ||||
|  |         <h5 class="oe_slogan"><b>You can generate aged partner report from wizard with partner filter</b></h5> | ||||
|  |         <div class="col-md-12"> | ||||
|  |             <div class=" oe_demo oe_picture  oe_screenshot"> | ||||
|  |                 <img src="aged_partnerwizard.png"> | ||||
|  |                 <div class="oe_demo_footer oe_centeralign"style="background-color:rgba(162, 70, 137, 0.7);">Aged partner report wizard</div> | ||||
|  |             </div> | ||||
|  |         </div> | ||||
|  |         <div class="col-md-12"> | ||||
|  |             <div class="oe_row_img oe_demo oe_picture oe_screenshot"> | ||||
|  |                 <img src="partnerfilter.png"> | ||||
|  |                 <div class="oe_demo_footer oe_centeralign"style="background-color:rgba(162, 70, 137, 0.7);">Partner Filter in wizard</div> | ||||
|  |             </div> | ||||
|  |              <div class="oe_row oe_spaced"> | ||||
|  | 	     <h5 class="oe_slogan"><b>This will open partner ledger report wizard with the selected partner. </b></h5> | ||||
|  | 	     <h5 class="oe_slogan"><b>You can add or remove partner from wizard in case of fault selection </b></h5> | ||||
|  | 
 | ||||
|  |             </div> | ||||
|  | 
 | ||||
|  | 
 | ||||
|  |    </section> | ||||
|  | 
 | ||||
|  | <section class="oe_container oe_dark"> | ||||
|  |    	<div class="col-md-12"> | ||||
|  | 	    <div class=" oe_demo oe_picture  oe_screenshot"> | ||||
|  |      		<img src="pdfreport.png"> | ||||
|  | 		<div class="oe_demo_footer oe_centeralign"style="background-color:rgba(162, 70, 137, 0.7);">Aged Partner Report</div> | ||||
|  | 	    </div> | ||||
|  | 	</div> | ||||
|  | 
 | ||||
|  | </section> | ||||
|  | 
 | ||||
|  | <section class="oe_container"> | ||||
|  |     <h2 class="oe_slogan" style="margin-top:20px;" >Need Any Help?</h2> | ||||
|  |     <div class="oe_slogan" style="margin-top:10px !important;"> | ||||
|  |         <div> | ||||
|  |             <a  class="btn btn-primary btn-lg mt8" | ||||
|  |             style="color: #FFFFFF !important;border-radius: 0;" href="https://www.cybrosys.com"><i | ||||
|  |             class="fa fa-envelope"></i> Email </a> <a | ||||
|  |             class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" | ||||
|  |             href="https://www.cybrosys.com/contact/"><i | ||||
|  |             class="fa fa-phone"></i> Contact Us </a> <a | ||||
|  |             class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" | ||||
|  |             href="https://www.cybrosys.com/odoo-customization-and-installation/"><i | ||||
|  |             class="fa fa-check-square"></i> Request Customization </a> | ||||
|  |         </div> | ||||
|  |         <br> | ||||
|  |         <img src="cybro_logo.png" style="width: 190px; margin-bottom: 20px;" class="center-block"> | ||||
|  |         <div> | ||||
|  |           <a href="https://twitter.com/cybrosys" target="_blank"><i class="fa fa-2x fa-twitter" style="color:white;background: #00a0d1;width:35px;"></i></a></td> | ||||
|  |           <a href="https://www.linkedin.com/company/cybrosys-technologies-pvt-ltd" target="_blank"><i class="fa fa-2x fa-linkedin" style="color:white;background: #31a3d6;width:35px;padding-left: 3px;"></i></a></td> | ||||
|  |           <a href="https://www.facebook.com/cybrosystechnologies" target="_blank"><i class="fa fa-2x fa-facebook" style="color:white;background: #3b5998;width:35px;padding-left: 8px;"></i></a></td> | ||||
|  |           <a href="https://plus.google.com/106641282743045431892/about" target="_blank"><i class="fa fa-2x fa-google-plus" style="color:white;background: #c53c2c;width:35px;padding-left: 3px;"></i></a></td> | ||||
|  |           <a href="https://in.pinterest.com/cybrosys" target="_blank"><i class="fa fa-2x fa-pinterest" style="color:white;background: #ac0f18;width:35px;padding-left: 3px;"></i></a></td> | ||||
|  |         </div> | ||||
|  |     </div> | ||||
|  | </section> | ||||
|  | 
 | ||||
| After Width: | Height: | Size: 37 KiB | 
| After Width: | Height: | Size: 29 KiB | 
| @ -0,0 +1,16 @@ | |||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||
|  | <odoo> | ||||
|  |     <data> | ||||
|  |           <record id="partner_filter_form" model="ir.ui.view"> | ||||
|  |            <field name="name">partner.filter.form</field> | ||||
|  |            <field name="model">account.aged.trial.balance</field> | ||||
|  |            <field name="inherit_id" ref="account.account_aged_balance_view" /> | ||||
|  |            <field name="arch" type="xml"> | ||||
|  |                <field name='target_move' position="after"> | ||||
|  |                    <field name="customer" widget="many2many_tags"/> | ||||
|  |                </field > | ||||
|  |            </field> | ||||
|  |         </record> | ||||
|  | 
 | ||||
|  |     </data> | ||||
|  | </odoo> | ||||
					Loading…
					
					
				
		Reference in new issue