<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Addons modules by CLEARCORP S.A.
#    Copyright (C) 2009-TODAY CLEARCORP S.A. (<http://clearcorp.co.cr>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero 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 Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from datetime import date,datetime
from openerp import models, fields, api, _
from openerp.tools.translate import _
import time
from openerp.exceptions import Warning

class IssueInvoiceWizard(models.TransientModel):
    _name='project.issue.helpdesk.invoice.wizard'
    @api.multi
    def create_invoice_lines_issues(self,issues,invoice_dict,line_detailed):
        account_obj=self.env['account.analytic.account']
        invoice_obj=self.env['account.invoice']
        user = self.env['res.users'].browse(self._uid)
        total_expenses=0.0
        count_lines=1
        count_lines_products=1
        first_line_product=0
        invoices_list=[]
        cont_invoice=0
        limit_lines=user.company_id.maximum_invoice_lines
        if line_detailed==True:
            for issue in issues:
                if issue.timesheet_ids or issue.expense_line_ids and cont_invoice==0:
                    cont_invoice=1
                    break
        if cont_invoice==1 or line_detailed==False:
            inv=invoice_obj.create(invoice_dict)
            invoices_list.append(inv.id)
        for issue in issues:
            for timesheet in issue.timesheet_ids:
                for account_line in timesheet.line_id:
                    if not account_line.invoice_id:
                        total_timesheet=0.0
                        quantity,total_timesheet=account_obj._get_invoice_price(account_line.account_id,account_line.date,timesheet.start_time,timesheet.end_time,issue.product_id.id,issue.categ_id.id,account_line.unit_amount,timesheet.service_type,timesheet.employee_id.id,account_line.to_invoice.id)
                        if account_line.account_id.pricelist_id.currency_id.id != account_line.account_id.company_id.currency_id.id:
                            import_currency_rate=account_line.account_id.pricelist_id.currency_id.get_exchange_rate(account_line.account_id.company_id.currency_id,date.strftime(date.today(), "%Y-%m-%d"))[0]
                        else:
                            import_currency_rate = 1
                        if (timesheet.end_time-timesheet.start_time!=0 or total_timesheet!=0):
                            invoice_line={
                                        'product_id':account_line.product_id.id ,
                                        'name': issue.product_id.description or issue.product_id.name,
                                        'real_quantity':timesheet.end_time-timesheet.start_time,
                                        'quantity':quantity,
                                        'price_unit':total_timesheet*import_currency_rate,
                                        'uos_id':account_line.product_id.uom_id.id,
                                        'discount':account_line.account_id.to_invoice.factor,
                                        'account_analytic_id':account_line.account_id.id,
                                        'reference':timesheet.ticket_number,
                                        'price_subtotal':total_timesheet*quantity,
                                        'invoice_line_tax_id':[(6, 0, [tax.id for tax in account_line.product_id.taxes_id])],
                                        'account_id':issue.product_id.property_account_income.id
                                        }
                            if issue.warranty=='seller':
                                invoice_line['price_unit']=0
                            if count_lines<=limit_lines or limit_lines==0 or limit_lines==-1:
                                inv.write({'invoice_line':[(0,0,invoice_line)]})
                                if issue.issue_number not in inv.origin:
                                    inv.write({'origin':inv.origin + issue.issue_number +'-'})
                                inv.write({'issue_ids':[(4,issue.id)]})
                                count_lines+=1
                            else:
                                if issue.issue_number not in inv.origin:
                                    inv.write({'origin':inv.origin + issue.issue_number})
                                inv=invoice_obj.create(invoice_dict)
                                invoices_list.append(inv.id)
                                count_lines=1
                                inv.write({'invoice_line':[(0,0,invoice_line)]})
                                if issue.issue_number not in inv.origin:
                                    inv.write({'origin':inv.origin + issue.issue_number +'-'})
                                inv.write({'issue_ids':[(4,issue.id)]})
                                count_lines+=1
                        account_line.write({'invoice_id':inv.id})
            for backorder in issue.backorder_ids:
                if backorder.delivery_note_id and backorder.delivery_note_id.state=='done' and backorder.picking_type_id.code=='outgoing' and backorder.invoice_state!='invoiced' and backorder.state=='done':
                    for delivery_note_lines in backorder.delivery_note_id.note_lines:
                        if delivery_note_lines.note_id.currency_id.id != issue.analytic_account_id.company_id.currency_id.id:
                            import_currency_rate=delivery_note_lines.note_id.currency_id.get_exchange_rate(issue.analytic_account_id.company_id.currency_id,date.strftime(date.today(), "%Y-%m-%d"))[0]
                        else:
                            import_currency_rate = 1
                        invoice_line={
                                    'product_id':delivery_note_lines.product_id.id,
                                    'name': delivery_note_lines.product_id.description or delivery_note_lines.product_id.name,
                                    'quantity':delivery_note_lines.quantity,
                                    'real_quantity':delivery_note_lines.quantity,
                                    'uos_id':delivery_note_lines.product_uos.id,
                                    'price_unit':delivery_note_lines.price_unit*import_currency_rate,
                                    'discount':delivery_note_lines.discount,
                                    'invoice_line_tax_id':[(6, 0, [tax.id for tax in delivery_note_lines.taxes_id])],
                                    'account_analytic_id':issue.analytic_account_id.id,
                                    'reference':delivery_note_lines.note_id.name,
                                    'account_id':delivery_note_lines.product_id.property_account_income.id
                                    }
                        if issue.warranty=='seller':
                            invoice_line['price_unit']=0
                        if line_detailed==True:
                            if first_line_product==0:
                                inv_prod=invoice_obj.create(invoice_dict)
                                if issue.issue_number not in inv_prod.origin:
                                    inv_prod.write({'origin':inv_prod.origin + issue.issue_number +'-'})
                                invoices_list.append(inv_prod.id)
                                first_line_product+=1
                            if count_lines_products<=limit_lines or limit_lines==0 or limit_lines==-1:
                                if issue.issue_number not in inv_prod.origin:
                                    inv_prod.write({'origin':inv_prod.origin + issue.issue_number +'-'})
                                inv_prod.write({'invoice_line':[(0,0,invoice_line)]})
                                inv_prod.write({'issue_ids':[(4,issue.id)]})
                                backorder.delivery_note_id.write({'invoice_ids':[(4,inv_prod.id)]})
                                count_lines_products+=1
                            else:
                                if issue.issue_number not in inv_prod.origin:
                                    inv_prod.write({'origin':inv_prod.origin + issue.issue_number})
                                inv_prod=invoice_obj.create(invoice_dict)
                                invoices_list.append(inv_prod.id)
                                count_lines_products=0
                                if issue.issue_number not in inv_prod.origin:
                                    inv_prod.write({'origin':inv_prod.origin + issue.issue_number +'-'})
                                inv_prod.write({'invoice_line':[(0,0,invoice_line)]})
                                inv_prod.write({'issue_ids':[(4,issue.id)]})
                                backorder.delivery_note_id.write({'invoice_ids':[(4,inv_prod.id)]})
                                count_lines_products+=1
                        else:
                            if count_lines<=limit_lines or limit_lines==0 or limit_lines==-1:
                                if issue.issue_number not in inv.origin:
                                    inv.write({'origin':inv.origin + issue.issue_number +'-'})
                                inv.write({'invoice_line':[(0,0,invoice_line)]})
                                inv.write({'issue_ids':[(4,issue.id)]})
                                backorder.delivery_note_id.write({'invoice_ids':[(4,inv.id)]})
                                count_lines+=1
                            else:
                                if issue.issue_number not in inv.origin:
                                    inv.write({'origin':inv.origin + issue.issue_number})
                                inv=invoice_obj.create(invoice_dict)
                                invoices_list.append(inv.id)
                                count_lines=1
                                if issue.issue_number not in inv.origin:
                                    inv.write({'origin':inv.origin + issue.issue_number +'-'})
                                inv.write({'invoice_line':[(0,0,invoice_line)]})
                                inv.write({'issue_ids':[(4,issue.id)]})
                                backorder.delivery_note_id.write({'invoice_ids':[(4,inv.id)]})
                                count_lines+=1
                        backorder.write({'invoice_state':'invoiced'})
                        backorder.move_lines.write({'invoice_state':'invoiced'})
                        backorder.delivery_note_id.write({'state':'invoiced'})
            for expense_line in issue.expense_line_ids:
                if expense_line.expense_id.state=='done' or expense_line.expense_id.state=='paid':
                    for move_lines in expense_line.expense_id.account_move_id.line_id:
                        for lines in move_lines.analytic_lines:
                            if lines.account_id==expense_line.analytic_account and lines.name==expense_line.name and lines.unit_amount==expense_line.unit_quantity and (lines.amount*-1/lines.unit_amount)==expense_line.unit_amount and not lines.invoice_id:
                                factor = self.env['hr_timesheet_invoice.factor'].browse(lines.to_invoice.id)
                                if expense_line.expense_id.currency_id.id != lines.account_id.company_id.currency_id.id:
                                    import_currency_rate=expense_line.expense_id.currency_id.get_exchange_rate(lines.account_id.company_id.currency_id,date.strftime(date.today(), "%Y-%m-%d"))[0]
                                else:
                                    import_currency_rate=1
                                account_exp=lines.product_id.property_account_income.id
                                total_expenses+=((lines.amount*-1)*import_currency_rate)*(100-factor.factor or 0.0) / 100.0
                                lines.write({'invoice_id':inv.id})
            if total_expenses>0:
                invoice_line={
                              'name': _(('Expenses of Issue #') + issue.issue_number),
                              'real_quantity':1,
                              'quantity':1,
                              'price_unit':total_expenses,
                              'account_id':account_exp
                              }
                if issue.warranty=='seller':
                    invoice_line['price_unit']=0
                if count_lines<=limit_lines or limit_lines==0 or limit_lines==-1:
                    if issue.issue_number not in inv.origin:
                        inv.write({'origin':inv.origin + issue.issue_number +'-'})
                    inv.write({'invoice_line':[(0,0,invoice_line)]})
                    inv.write({'issue_ids':[(4,issue.id)]})
                    count_lines+=1
                else:
                    if issue.issue_number not in inv.origin:
                        inv.write({'origin':inv.origin + issue.issue_number})
                    inv=invoice_obj.create(invoice_dict)
                    invoices_list.append(inv.id)
                    count_lines=1
                    if issue.issue_number not in inv.origin:
                        inv.write({'origin':inv.origin + issue.issue_number +'-'})
                    inv.write({'invoice_line':[(0,0,invoice_line)]})
                    inv.write({'issue_ids':[(4,issue.id)]})
                    count_lines+=1
                total_expenses=0
        return invoices_list
    
    @api.multi
    def get_date_due(self,partner):
        account_payment_term_obj = self.env['account.payment.term']
        date_due = False
        if partner.property_payment_term:
            pterm_list= account_payment_term_obj.compute(partner.property_payment_term.id, value=1,date_ref=time.strftime('%Y-%m-%d'))
            if pterm_list:
                pterm_list = [line[0] for line in pterm_list]
                pterm_list.sort()
                date_due = pterm_list[-1]
        return date_due
    @api.multi
    def generate_invoices_issues(self,issues_ids,group,line_detailed):
        issue_obj=self.env['project.issue']
        partner_obj=self.env['res.partner']
        user = self.env['res.users'].browse(self._uid)
        invoices_list=[]
        branch_issue_ids=[]
        partner_issue_ids=[]
        partner_group_ids=[]
        branch_group_ids=[]
        if group==False:
            for issue in issues_ids:
                invoice={
                    'date_invoice':datetime.strftime(datetime.today(), "%Y-%m-%d"),
                    'company_id':issue.analytic_account_id.company_id.id,
                    'currency_id':issue.analytic_account_id.company_id.currency_id.id,
                    'fiscal_position':issue.product_id.manufacturer.property_account_position.id,
                    'origin':_(('Issue #'))
                    }
                ctx = dict(self._context)
                ctx['force_company']=issue.analytic_account_id.company_id.id
                ctx['company_id']=issue.analytic_account_id.company_id.id
                if issue.branch_id and issue.partner_id:
                    invoice['partner_id']=issue.branch_id.id
                    invoice['account_id']=issue.branch_id.property_account_receivable.id
                    invoice['payment_term']=issue.branch_id.property_payment_term.id
                    invoice['date_due']=self.get_date_due(issue.branch_id)
                    ctx['lang']=issue.branch_id.lang
                elif not issue.branch_id and issue.partner_id:
                    invoice['partner_id']=issue.partner_id.id
                    invoice['account_id']=issue.partner_id.property_account_receivable.id
                    invoice['payment_term']=issue.partner_id.property_payment_term.id
                    invoice['date_due']=self.get_date_due(issue.partner_id)
                    ctx['lang']=issue.partner_id.lang
                self = self.with_context(ctx)
                invoices_list+=self.create_invoice_lines_issues(issue,invoice,line_detailed)
        elif group==True:
            for issue in issues_ids:
                if issue.partner_id and issue.branch_id:
                    branch_issue_ids.append(issue.id)
                    if issue.branch_id.id not in branch_group_ids:
                        branch_group_ids.append(issue.branch_id.id)
                elif issue.partner_id and not issue.branch_id:
                    partner_issue_ids.append(issue.id)
                    if issue.partner_id.id not in partner_group_ids:
                        partner_group_ids.append(issue.partner_id.id)
            for partner in partner_group_ids:
                partner_id=partner_obj.browse(partner)
                issue_partner_ids=issue_obj.search([('id','in',partner_issue_ids),('partner_id','=',partner),('branch_id','=',False)],order='categ_id asc,product_id asc,create_date asc')
                invoice={
                        'date_invoice':datetime.strftime(datetime.today(), "%Y-%m-%d"),
                        'company_id':user.company_id.id,
                        'currency_id':user.company_id.currency_id.id,
                        'fiscal_position':partner_id.property_account_position.id,
                        'origin':_(('Issue #')),
                        'partner_id':partner_id.id,
                        'account_id':partner_id.property_account_receivable.id,
                        'payment_term':partner_id.property_payment_term.id,
                        'date_due':self.get_date_due(partner_id)
                        }
                ctx = dict(self._context)
                ctx['force_company']=user.company_id.id
                ctx['company_id']=user.company_id.id
                ctx['lang']=partner_id.lang
                self = self.with_context(ctx)
                invoices_list+=self.create_invoice_lines_issues(issue_partner_ids,invoice,line_detailed)
            for branch in branch_group_ids:
                branch_id=partner_obj.browse(branch)
                issue_branch_ids=issue_obj.search([('id','in',branch_issue_ids),('branch_id','=',branch),('partner_id','!=',False)],order='categ_id asc,product_id asc,create_date asc')
                invoice={
                        'date_invoice':datetime.strftime(datetime.today(), "%Y-%m-%d"),
                        'company_id':user.company_id.id,
                        'currency_id':user.company_id.currency_id.id,
                        'fiscal_position':branch_id.property_account_position.id,
                        'origin':_(('Issue #')),
                        'partner_id':branch_id.id,
                        'account_id':branch_id.property_account_receivable.id,
                        'payment_term':branch_id.property_payment_term.id,
                        'date_due':self.get_date_due(branch_id)
                        }
                ctx = dict(self._context)
                ctx['force_company']=user.company_id.id
                ctx['company_id']=user.company_id.id
                ctx['lang']=branch_id.lang
                self = self.with_context(ctx)
                invoices_list+=self.create_invoice_lines_issues(issue_branch_ids,invoice,line_detailed)
        return invoices_list
    @api.multi
    def generate_invoices_warranty_manufacturer(self,issues_ids,line_detailed):
        journal_obj=self.env['account.journal']
        invoices_list=[]
        for issue in issues_ids:
            journal_id=journal_obj.search([('warranty_manufacturer', '=', True)])
            if not journal_id:
                raise Warning(_('Must configure a journal for warranty manufacturer'))
            invoice={
                    'journal_id':journal_id.id,
                    'partner_id':issue.product_id.manufacturer.id,
                    'account_id':issue.product_id.manufacturer.property_account_receivable.id,
                    'payment_term':issue.product_id.manufacturer.property_payment_term.id,
                    'date_invoice':datetime.strftime(datetime.today(), "%Y-%m-%d"),
                    'name':_(('(Warranty Manufacturer)')),
                    'company_id':issue.analytic_account_id.company_id.id,
                    'currency_id':issue.analytic_account_id.company_id.currency_id.id,
                    'fiscal_position':issue.product_id.manufacturer.property_account_position.id,
                    'date_due':self.get_date_due(issue.product_id.manufacturer),
                    'origin':_(('Issue #'))
                    }
            ctx = dict(self._context)
            ctx['lang']=issue.product_id.manufacturer.lang
            ctx['force_company']=issue.analytic_account_id.company_id.id
            ctx['company_id']=issue.analytic_account_id.company_id.id
            self = self.with_context(ctx)
            invoices_list=self.create_invoice_lines_issues(issue,invoice,line_detailed)
        return invoices_list
    @api.multi
    def generate_invoices(self,issue_ids,issue_list,group,line_detailed):
        issue_obj=self.env['project.issue']
        invoice_obj=self.env['account.invoice']
        invoices_list=[]
        #Issues Warranty Manufaturer
        issues_warranty_manufacturer=issue_obj.search([('warranty','=','manufacturer'),('id','in',issue_list)],order='categ_id asc,product_id asc,create_date asc')
        if issues_warranty_manufacturer:
            invoices_list+=self.generate_invoices_warranty_manufacturer(issues_warranty_manufacturer,line_detailed)
        #Normal Issues
        issues_default=issue_obj.search(['|',('warranty','=',False),('warranty','!=','manufacturer'),('id','in',issue_list)],order='categ_id asc,product_id asc,create_date asc')
        if issues_default:
            invoices_list+=self.generate_invoices_issues(issues_default,group,line_detailed)
        
        for invoice in invoice_obj.browse(invoices_list):
            if invoice.origin[-1:]=='-':
                invoice.write({'origin':invoice.origin[:-1]})
        return invoices_list

    @api.multi
    def validate_issues(self):
        partner_ids=[]
        issue_ids=[]
        model_ids=[]
        issue_obj=self.env['project.issue']
        
        if self.filter=='filter_no':
            issue_ids=issue_obj.search(['|','|',('backorder_ids','!=',False),('expense_line_ids','!=',False),('timesheet_ids','!=',False),('issue_type','!=','preventive check'),('analytic_account_id','!=',False),('stage_id.closed','=',True),('sale_order_id','=',False),('invoice_ids','=',False)],order='categ_id asc,product_id asc,create_date asc')
        elif self.filter=='filter_date':
            issue_ids=issue_obj.search(['|','|',('backorder_ids','!=',False),('expense_line_ids','!=',False),('timesheet_ids','!=',False),('issue_type','!=','preventive check'),('analytic_account_id','!=',False),('stage_id.closed','=',True),('sale_order_id','=',False),('invoice_ids','=',False),('create_date', '>=', self.date_from),('create_date', '<=', self.date_to)],order='categ_id asc,product_id asc,create_date asc')
        elif self.filter=='filter_period':
            issue_ids=issue_obj.search(['|','|',('backorder_ids','!=',False),('expense_line_ids','!=',False),('timesheet_ids','!=',False),('issue_type','!=','preventive check'),('analytic_account_id','!=',False),('stage_id.closed','=',True),('sale_order_id','=',False),('invoice_ids','=',False),('create_date', '>=',self.period_from.date_start),('create_date', '<=',self.period_to.date_stop)],order='categ_id asc,product_id asc,create_date asc')
        elif self.filter=='filter_partner':
            for partner in self.partner_ids:
                partner_ids.append(partner.id)
            issue_ids=issue_obj.search(['&','|','|',('backorder_ids','!=',False),('expense_line_ids','!=',False),('timesheet_ids','!=',False),'|',('partner_id','in',partner_ids),('branch_id','in',partner_ids),('issue_type','!=','preventive check'),('analytic_account_id','!=',False),('stage_id.closed','=',True),('sale_order_id','=',False),('invoice_ids','=',False)],order='categ_id asc,product_id asc,create_date asc')
        elif self.filter=='filter_issue':
            for issue in self.issue_ids:
                issue_ids.append(issue.id)
            issue_ids=issue_obj.search(['|','|',('backorder_ids','!=',False),('expense_line_ids','!=',False),('timesheet_ids','!=',False),('issue_type','!=','preventive check'),('analytic_account_id','!=',False),('stage_id.closed','=',True),('sale_order_id','=',False),('invoice_ids','=',False),('id','in',issue_ids)],order='categ_id asc,product_id asc,create_date asc')
        self.issue_invoice_ids=issue_ids
        self.write({'state':'done'})
        return {
            'name': _('Issues to Invoice'),
            'type': 'ir.actions.act_window',
            'res_model': self._name,
            'view_type': 'form',
            'view_mode': 'form',
            'target': 'new',
            'res_id': self.id,
            }
        
    @api.multi
    def invoice_issues(self):
        issue_list=[]
        invoices_list=[]
        if self.issue_invoice_ids:
            for issue in self.issue_invoice_ids:
                issue_list.append(issue.id)
            invoices_list=self.generate_invoices(self.issue_invoice_ids,issue_list,self.group_customer,self.line_detailed)
        result = self.env['ir.model.data'].get_object_reference('account', 'action_invoice_tree1')
        id = result and result[1] or False
        act_win = self.env['ir.actions.act_window'].search_read([('id','=',id)])[0]
        act_win['domain']=[('id','in',invoices_list),('type','=','out_invoice')]
        act_win['name'] = _('Invoices')
        return act_win
    @api.one
    @api.constrains('date_from','date_to')
    def _check_filter_date(self):
        if self.filter=='filter_date':
            if self.date_from>self.date_to:
                raise Warning(_('Start Date must be less than End Date'))
    @api.constrains('period_from','period_to')
    def _check_filter_period(self):
        if self.filter=='filter_period':
            if self.period_from.date_start>self.period_to.date_stop:
                raise Warning(_('Start Period must be less than End Period'))

    line_detailed=fields.Boolean(string="Product lines separate service lines",default=True)
    group_customer=fields.Boolean( string="Group by customer",default=True)
    filter=fields.Selection([('filter_no','No Filter'),('filter_date','Date'),('filter_period','Period'),('filter_partner','Partner'),('filter_issue','Issue')],string="Filter",required=True,default='filter_no')
    date_from=fields.Date(string="Start Date")
    date_to=fields.Date(string="End Date")
    fiscalyear_id=fields.Many2one('account.fiscalyear',string="Fiscal Year")
    period_to= fields.Many2one('account.period',string="End Period")
    period_from= fields.Many2one('account.period',string="Start Period")
    partner_ids= fields.Many2many('res.partner',string="Customers")
    issue_ids=fields.Many2many('project.issue','project_issue_project_issue_wizard_rel',string="Issues")
    issue_invoice_ids=fields.One2many('project.issue',compute='validate_issues',string="Issues")
    state= fields.Selection([('validate','Validate'),('done','Done')], string='State')
    
    _defaults = {
        'state': 'validate'
    }<commit_msg>[FIX]Change the descriptions of issues invoices<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Addons modules by CLEARCORP S.A.
#    Copyright (C) 2009-TODAY CLEARCORP S.A. (<http://clearcorp.co.cr>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero 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 Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from datetime import date,datetime
from openerp import models, fields, api, _
from openerp.tools.translate import _
import time
from openerp.exceptions import Warning

class IssueInvoiceWizard(models.TransientModel):
    _name='project.issue.helpdesk.invoice.wizard'
    @api.multi
    def create_invoice_lines_issues(self,issues,invoice_dict,line_detailed):
        account_obj=self.env['account.analytic.account']
        invoice_obj=self.env['account.invoice']
        user = self.env['res.users'].browse(self._uid)
        total_expenses=0.0
        count_lines=1
        count_lines_products=1
        first_line_product=0
        invoices_list=[]
        cont_invoice=0
        limit_lines=user.company_id.maximum_invoice_lines
        if line_detailed==True:
            for issue in issues:
                if issue.timesheet_ids or issue.expense_line_ids and cont_invoice==0:
                    cont_invoice=1
                    break
        if cont_invoice==1 or line_detailed==False:
            inv=invoice_obj.create(invoice_dict)
            invoices_list.append(inv.id)
        for issue in issues:
            for timesheet in issue.timesheet_ids:
                for account_line in timesheet.line_id:
                    if not account_line.invoice_id:
                        total_timesheet=0.0
                        quantity,total_timesheet=account_obj._get_invoice_price(account_line.account_id,account_line.date,timesheet.start_time,timesheet.end_time,issue.product_id.id,issue.categ_id.id,account_line.unit_amount,timesheet.service_type,timesheet.employee_id.id,account_line.to_invoice.id)
                        if account_line.account_id.pricelist_id.currency_id.id != account_line.account_id.company_id.currency_id.id:
                            import_currency_rate=account_line.account_id.pricelist_id.currency_id.get_exchange_rate(account_line.account_id.company_id.currency_id,date.strftime(date.today(), "%Y-%m-%d"))[0]
                        else:
                            import_currency_rate = 1
                        if (timesheet.end_time-timesheet.start_time!=0 or total_timesheet!=0):
                            invoice_line={
                                        'product_id':account_line.product_id.id ,
                                        'name': account_line.product_id.description+'-'+issue.product_id.description,
                                        'real_quantity':timesheet.end_time-timesheet.start_time,
                                        'quantity':quantity,
                                        'price_unit':total_timesheet*import_currency_rate,
                                        'uos_id':account_line.product_id.uom_id.id,
                                        'discount':account_line.account_id.to_invoice.factor,
                                        'account_analytic_id':account_line.account_id.id,
                                        'reference':'R#'+timesheet.ticket_number,
                                        'price_subtotal':total_timesheet*quantity,
                                        'invoice_line_tax_id':[(6, 0, [tax.id for tax in account_line.product_id.taxes_id])],
                                        'account_id':issue.product_id.property_account_income.id
                                        }
                            if issue.warranty=='seller':
                                invoice_line['price_unit']=0
                            if count_lines<=limit_lines or limit_lines==0 or limit_lines==-1:
                                inv.write({'invoice_line':[(0,0,invoice_line)]})
                                if issue.issue_number not in inv.origin:
                                    inv.write({'origin':inv.origin + issue.issue_number +'-'})
                                inv.write({'issue_ids':[(4,issue.id)]})
                                count_lines+=1
                            else:
                                if issue.issue_number not in inv.origin:
                                    inv.write({'origin':inv.origin + issue.issue_number})
                                inv=invoice_obj.create(invoice_dict)
                                invoices_list.append(inv.id)
                                count_lines=1
                                inv.write({'invoice_line':[(0,0,invoice_line)]})
                                if issue.issue_number not in inv.origin:
                                    inv.write({'origin':inv.origin + issue.issue_number +'-'})
                                inv.write({'issue_ids':[(4,issue.id)]})
                                count_lines+=1
                        account_line.write({'invoice_id':inv.id})
            for backorder in issue.backorder_ids:
                if backorder.delivery_note_id and backorder.delivery_note_id.state=='done' and backorder.picking_type_id.code=='outgoing' and backorder.invoice_state!='invoiced' and backorder.state=='done':
                    for delivery_note_lines in backorder.delivery_note_id.note_lines:
                        if delivery_note_lines.note_id.currency_id.id != issue.analytic_account_id.company_id.currency_id.id:
                            import_currency_rate=delivery_note_lines.note_id.currency_id.get_exchange_rate(issue.analytic_account_id.company_id.currency_id,date.strftime(date.today(), "%Y-%m-%d"))[0]
                        else:
                            import_currency_rate = 1
                        invoice_line={
                                    'product_id':delivery_note_lines.product_id.id,
                                    'name': issue.product_id.description +'-'+delivery_note_lines.product_id.description,
                                    'quantity':delivery_note_lines.quantity,
                                    'real_quantity':delivery_note_lines.quantity,
                                    'uos_id':delivery_note_lines.product_uos.id,
                                    'price_unit':delivery_note_lines.price_unit*import_currency_rate,
                                    'discount':delivery_note_lines.discount,
                                    'invoice_line_tax_id':[(6, 0, [tax.id for tax in delivery_note_lines.taxes_id])],
                                    'account_analytic_id':issue.analytic_account_id.id,
                                    'reference':'NE#'+delivery_note_lines.note_id.name,
                                    'account_id':delivery_note_lines.product_id.property_account_income.id
                                    }
                        if issue.warranty=='seller':
                            invoice_line['price_unit']=0
                        if line_detailed==True:
                            if first_line_product==0:
                                inv_prod=invoice_obj.create(invoice_dict)
                                if issue.issue_number not in inv_prod.origin:
                                    inv_prod.write({'origin':inv_prod.origin + issue.issue_number +'-'})
                                invoices_list.append(inv_prod.id)
                                first_line_product+=1
                            if count_lines_products<=limit_lines or limit_lines==0 or limit_lines==-1:
                                if issue.issue_number not in inv_prod.origin:
                                    inv_prod.write({'origin':inv_prod.origin + issue.issue_number +'-'})
                                inv_prod.write({'invoice_line':[(0,0,invoice_line)]})
                                inv_prod.write({'issue_ids':[(4,issue.id)]})
                                backorder.delivery_note_id.write({'invoice_ids':[(4,inv_prod.id)]})
                                count_lines_products+=1
                            else:
                                if issue.issue_number not in inv_prod.origin:
                                    inv_prod.write({'origin':inv_prod.origin + issue.issue_number})
                                inv_prod=invoice_obj.create(invoice_dict)
                                invoices_list.append(inv_prod.id)
                                count_lines_products=0
                                if issue.issue_number not in inv_prod.origin:
                                    inv_prod.write({'origin':inv_prod.origin + issue.issue_number +'-'})
                                inv_prod.write({'invoice_line':[(0,0,invoice_line)]})
                                inv_prod.write({'issue_ids':[(4,issue.id)]})
                                backorder.delivery_note_id.write({'invoice_ids':[(4,inv_prod.id)]})
                                count_lines_products+=1
                        else:
                            if count_lines<=limit_lines or limit_lines==0 or limit_lines==-1:
                                if issue.issue_number not in inv.origin:
                                    inv.write({'origin':inv.origin + issue.issue_number +'-'})
                                inv.write({'invoice_line':[(0,0,invoice_line)]})
                                inv.write({'issue_ids':[(4,issue.id)]})
                                backorder.delivery_note_id.write({'invoice_ids':[(4,inv.id)]})
                                count_lines+=1
                            else:
                                if issue.issue_number not in inv.origin:
                                    inv.write({'origin':inv.origin + issue.issue_number})
                                inv=invoice_obj.create(invoice_dict)
                                invoices_list.append(inv.id)
                                count_lines=1
                                if issue.issue_number not in inv.origin:
                                    inv.write({'origin':inv.origin + issue.issue_number +'-'})
                                inv.write({'invoice_line':[(0,0,invoice_line)]})
                                inv.write({'issue_ids':[(4,issue.id)]})
                                backorder.delivery_note_id.write({'invoice_ids':[(4,inv.id)]})
                                count_lines+=1
                        backorder.write({'invoice_state':'invoiced'})
                        backorder.move_lines.write({'invoice_state':'invoiced'})
                        backorder.delivery_note_id.write({'state':'invoiced'})
            for expense_line in issue.expense_line_ids:
                if expense_line.expense_id.state=='done' or expense_line.expense_id.state=='paid':
                    for move_lines in expense_line.expense_id.account_move_id.line_id:
                        for lines in move_lines.analytic_lines:
                            if lines.account_id==expense_line.analytic_account and lines.name==expense_line.name and lines.unit_amount==expense_line.unit_quantity and (lines.amount*-1/lines.unit_amount)==expense_line.unit_amount and not lines.invoice_id:
                                factor = self.env['hr_timesheet_invoice.factor'].browse(lines.to_invoice.id)
                                if expense_line.expense_id.currency_id.id != lines.account_id.company_id.currency_id.id:
                                    import_currency_rate=expense_line.expense_id.currency_id.get_exchange_rate(lines.account_id.company_id.currency_id,date.strftime(date.today(), "%Y-%m-%d"))[0]
                                else:
                                    import_currency_rate=1
                                account_exp=lines.product_id.property_account_income.id
                                total_expenses+=((lines.amount*-1)*import_currency_rate)*(100-factor.factor or 0.0) / 100.0
                                lines.write({'invoice_id':inv.id})
            if total_expenses>0:
                invoice_line={
                              'name': _(('Expenses of Issue #') + issue.issue_number),
                              'real_quantity':1,
                              'quantity':1,
                              'price_unit':total_expenses,
                              'account_id':account_exp
                              }
                if issue.warranty=='seller':
                    invoice_line['price_unit']=0
                if count_lines<=limit_lines or limit_lines==0 or limit_lines==-1:
                    if issue.issue_number not in inv.origin:
                        inv.write({'origin':inv.origin + issue.issue_number +'-'})
                    inv.write({'invoice_line':[(0,0,invoice_line)]})
                    inv.write({'issue_ids':[(4,issue.id)]})
                    count_lines+=1
                else:
                    if issue.issue_number not in inv.origin:
                        inv.write({'origin':inv.origin + issue.issue_number})
                    inv=invoice_obj.create(invoice_dict)
                    invoices_list.append(inv.id)
                    count_lines=1
                    if issue.issue_number not in inv.origin:
                        inv.write({'origin':inv.origin + issue.issue_number +'-'})
                    inv.write({'invoice_line':[(0,0,invoice_line)]})
                    inv.write({'issue_ids':[(4,issue.id)]})
                    count_lines+=1
                total_expenses=0
        return invoices_list
    
    @api.multi
    def get_date_due(self,partner):
        account_payment_term_obj = self.env['account.payment.term']
        date_due = False
        if partner.property_payment_term:
            pterm_list= account_payment_term_obj.compute(partner.property_payment_term.id, value=1,date_ref=time.strftime('%Y-%m-%d'))
            if pterm_list:
                pterm_list = [line[0] for line in pterm_list]
                pterm_list.sort()
                date_due = pterm_list[-1]
        return date_due
    @api.multi
    def generate_invoices_issues(self,issues_ids,group,line_detailed):
        issue_obj=self.env['project.issue']
        partner_obj=self.env['res.partner']
        user = self.env['res.users'].browse(self._uid)
        invoices_list=[]
        branch_issue_ids=[]
        partner_issue_ids=[]
        partner_group_ids=[]
        branch_group_ids=[]
        if group==False:
            for issue in issues_ids:
                invoice={
                    'date_invoice':datetime.strftime(datetime.today(), "%Y-%m-%d"),
                    'company_id':issue.analytic_account_id.company_id.id,
                    'currency_id':issue.analytic_account_id.company_id.currency_id.id,
                    'fiscal_position':issue.product_id.manufacturer.property_account_position.id,
                    'origin':_(('Issue #'))
                    }
                ctx = dict(self._context)
                ctx['force_company']=issue.analytic_account_id.company_id.id
                ctx['company_id']=issue.analytic_account_id.company_id.id
                if issue.branch_id and issue.partner_id:
                    invoice['partner_id']=issue.branch_id.id
                    invoice['account_id']=issue.branch_id.property_account_receivable.id
                    invoice['payment_term']=issue.branch_id.property_payment_term.id
                    invoice['date_due']=self.get_date_due(issue.branch_id)
                    ctx['lang']=issue.branch_id.lang
                elif not issue.branch_id and issue.partner_id:
                    invoice['partner_id']=issue.partner_id.id
                    invoice['account_id']=issue.partner_id.property_account_receivable.id
                    invoice['payment_term']=issue.partner_id.property_payment_term.id
                    invoice['date_due']=self.get_date_due(issue.partner_id)
                    ctx['lang']=issue.partner_id.lang
                self = self.with_context(ctx)
                invoices_list+=self.create_invoice_lines_issues(issue,invoice,line_detailed)
        elif group==True:
            for issue in issues_ids:
                if issue.partner_id and issue.branch_id:
                    branch_issue_ids.append(issue.id)
                    if issue.branch_id.id not in branch_group_ids:
                        branch_group_ids.append(issue.branch_id.id)
                elif issue.partner_id and not issue.branch_id:
                    partner_issue_ids.append(issue.id)
                    if issue.partner_id.id not in partner_group_ids:
                        partner_group_ids.append(issue.partner_id.id)
            for partner in partner_group_ids:
                partner_id=partner_obj.browse(partner)
                issue_partner_ids=issue_obj.search([('id','in',partner_issue_ids),('partner_id','=',partner),('branch_id','=',False)],order='categ_id asc,product_id asc,create_date asc')
                invoice={
                        'date_invoice':datetime.strftime(datetime.today(), "%Y-%m-%d"),
                        'company_id':user.company_id.id,
                        'currency_id':user.company_id.currency_id.id,
                        'fiscal_position':partner_id.property_account_position.id,
                        'origin':_(('Issue #')),
                        'partner_id':partner_id.id,
                        'account_id':partner_id.property_account_receivable.id,
                        'payment_term':partner_id.property_payment_term.id,
                        'date_due':self.get_date_due(partner_id)
                        }
                ctx = dict(self._context)
                ctx['force_company']=user.company_id.id
                ctx['company_id']=user.company_id.id
                ctx['lang']=partner_id.lang
                self = self.with_context(ctx)
                invoices_list+=self.create_invoice_lines_issues(issue_partner_ids,invoice,line_detailed)
            for branch in branch_group_ids:
                branch_id=partner_obj.browse(branch)
                issue_branch_ids=issue_obj.search([('id','in',branch_issue_ids),('branch_id','=',branch),('partner_id','!=',False)],order='categ_id asc,product_id asc,create_date asc')
                invoice={
                        'date_invoice':datetime.strftime(datetime.today(), "%Y-%m-%d"),
                        'company_id':user.company_id.id,
                        'currency_id':user.company_id.currency_id.id,
                        'fiscal_position':branch_id.property_account_position.id,
                        'origin':_(('Issue #')),
                        'partner_id':branch_id.id,
                        'account_id':branch_id.property_account_receivable.id,
                        'payment_term':branch_id.property_payment_term.id,
                        'date_due':self.get_date_due(branch_id)
                        }
                ctx = dict(self._context)
                ctx['force_company']=user.company_id.id
                ctx['company_id']=user.company_id.id
                ctx['lang']=branch_id.lang
                self = self.with_context(ctx)
                invoices_list+=self.create_invoice_lines_issues(issue_branch_ids,invoice,line_detailed)
        return invoices_list
    @api.multi
    def generate_invoices_warranty_manufacturer(self,issues_ids,line_detailed):
        journal_obj=self.env['account.journal']
        invoices_list=[]
        for issue in issues_ids:
            journal_id=journal_obj.search([('warranty_manufacturer', '=', True)])
            if not journal_id:
                raise Warning(_('Must configure a journal for warranty manufacturer'))
            invoice={
                    'journal_id':journal_id.id,
                    'partner_id':issue.product_id.manufacturer.id,
                    'account_id':issue.product_id.manufacturer.property_account_receivable.id,
                    'payment_term':issue.product_id.manufacturer.property_payment_term.id,
                    'date_invoice':datetime.strftime(datetime.today(), "%Y-%m-%d"),
                    'name':_(('(Warranty Manufacturer)')),
                    'company_id':issue.analytic_account_id.company_id.id,
                    'currency_id':issue.analytic_account_id.company_id.currency_id.id,
                    'fiscal_position':issue.product_id.manufacturer.property_account_position.id,
                    'date_due':self.get_date_due(issue.product_id.manufacturer),
                    'origin':_(('Issue #'))
                    }
            ctx = dict(self._context)
            ctx['lang']=issue.product_id.manufacturer.lang
            ctx['force_company']=issue.analytic_account_id.company_id.id
            ctx['company_id']=issue.analytic_account_id.company_id.id
            self = self.with_context(ctx)
            invoices_list=self.create_invoice_lines_issues(issue,invoice,line_detailed)
        return invoices_list
    @api.multi
    def generate_invoices(self,issue_ids,issue_list,group,line_detailed):
        issue_obj=self.env['project.issue']
        invoice_obj=self.env['account.invoice']
        invoices_list=[]
        #Issues Warranty Manufaturer
        issues_warranty_manufacturer=issue_obj.search([('warranty','=','manufacturer'),('id','in',issue_list)],order='categ_id asc,product_id asc,create_date asc')
        if issues_warranty_manufacturer:
            invoices_list+=self.generate_invoices_warranty_manufacturer(issues_warranty_manufacturer,line_detailed)
        #Normal Issues
        issues_default=issue_obj.search(['|',('warranty','=',False),('warranty','!=','manufacturer'),('id','in',issue_list)],order='categ_id asc,product_id asc,create_date asc')
        if issues_default:
            invoices_list+=self.generate_invoices_issues(issues_default,group,line_detailed)
        
        for invoice in invoice_obj.browse(invoices_list):
            if invoice.origin[-1:]=='-':
                invoice.write({'origin':invoice.origin[:-1]})
        return invoices_list

    @api.multi
    def validate_issues(self):
        partner_ids=[]
        issue_ids=[]
        model_ids=[]
        issue_obj=self.env['project.issue']
        
        if self.filter=='filter_no':
            issue_ids=issue_obj.search(['|','|',('backorder_ids','!=',False),('expense_line_ids','!=',False),('timesheet_ids','!=',False),('issue_type','!=','preventive check'),('analytic_account_id','!=',False),('stage_id.closed','=',True),('sale_order_id','=',False),('invoice_ids','=',False)],order='categ_id asc,product_id asc,create_date asc')
        elif self.filter=='filter_date':
            issue_ids=issue_obj.search(['|','|',('backorder_ids','!=',False),('expense_line_ids','!=',False),('timesheet_ids','!=',False),('issue_type','!=','preventive check'),('analytic_account_id','!=',False),('stage_id.closed','=',True),('sale_order_id','=',False),('invoice_ids','=',False),('create_date', '>=', self.date_from),('create_date', '<=', self.date_to)],order='categ_id asc,product_id asc,create_date asc')
        elif self.filter=='filter_period':
            issue_ids=issue_obj.search(['|','|',('backorder_ids','!=',False),('expense_line_ids','!=',False),('timesheet_ids','!=',False),('issue_type','!=','preventive check'),('analytic_account_id','!=',False),('stage_id.closed','=',True),('sale_order_id','=',False),('invoice_ids','=',False),('create_date', '>=',self.period_from.date_start),('create_date', '<=',self.period_to.date_stop)],order='categ_id asc,product_id asc,create_date asc')
        elif self.filter=='filter_partner':
            for partner in self.partner_ids:
                partner_ids.append(partner.id)
            issue_ids=issue_obj.search(['&','|','|',('backorder_ids','!=',False),('expense_line_ids','!=',False),('timesheet_ids','!=',False),'|',('partner_id','in',partner_ids),('branch_id','in',partner_ids),('issue_type','!=','preventive check'),('analytic_account_id','!=',False),('stage_id.closed','=',True),('sale_order_id','=',False),('invoice_ids','=',False)],order='categ_id asc,product_id asc,create_date asc')
        elif self.filter=='filter_issue':
            for issue in self.issue_ids:
                issue_ids.append(issue.id)
            issue_ids=issue_obj.search(['|','|',('backorder_ids','!=',False),('expense_line_ids','!=',False),('timesheet_ids','!=',False),('issue_type','!=','preventive check'),('analytic_account_id','!=',False),('stage_id.closed','=',True),('sale_order_id','=',False),('invoice_ids','=',False),('id','in',issue_ids)],order='categ_id asc,product_id asc,create_date asc')
        self.issue_invoice_ids=issue_ids
        self.write({'state':'done'})
        return {
            'name': _('Issues to Invoice'),
            'type': 'ir.actions.act_window',
            'res_model': self._name,
            'view_type': 'form',
            'view_mode': 'form',
            'target': 'new',
            'res_id': self.id,
            }
        
    @api.multi
    def invoice_issues(self):
        issue_list=[]
        invoices_list=[]
        if self.issue_invoice_ids:
            for issue in self.issue_invoice_ids:
                issue_list.append(issue.id)
            invoices_list=self.generate_invoices(self.issue_invoice_ids,issue_list,self.group_customer,self.line_detailed)
        result = self.env['ir.model.data'].get_object_reference('account', 'action_invoice_tree1')
        id = result and result[1] or False
        act_win = self.env['ir.actions.act_window'].search_read([('id','=',id)])[0]
        act_win['domain']=[('id','in',invoices_list),('type','=','out_invoice')]
        act_win['name'] = _('Invoices')
        return act_win
    @api.one
    @api.constrains('date_from','date_to')
    def _check_filter_date(self):
        if self.filter=='filter_date':
            if self.date_from>self.date_to:
                raise Warning(_('Start Date must be less than End Date'))
    @api.constrains('period_from','period_to')
    def _check_filter_period(self):
        if self.filter=='filter_period':
            if self.period_from.date_start>self.period_to.date_stop:
                raise Warning(_('Start Period must be less than End Period'))

    line_detailed=fields.Boolean(string="Product lines separate service lines",default=True)
    group_customer=fields.Boolean( string="Group by customer",default=True)
    filter=fields.Selection([('filter_no','No Filter'),('filter_date','Date'),('filter_period','Period'),('filter_partner','Partner'),('filter_issue','Issue')],string="Filter",required=True,default='filter_no')
    date_from=fields.Date(string="Start Date")
    date_to=fields.Date(string="End Date")
    fiscalyear_id=fields.Many2one('account.fiscalyear',string="Fiscal Year")
    period_to= fields.Many2one('account.period',string="End Period")
    period_from= fields.Many2one('account.period',string="Start Period")
    partner_ids= fields.Many2many('res.partner',string="Customers")
    issue_ids=fields.Many2many('project.issue','project_issue_project_issue_wizard_rel',string="Issues")
    issue_invoice_ids=fields.One2many('project.issue',compute='validate_issues',string="Issues")
    state= fields.Selection([('validate','Validate'),('done','Done')], string='State')
    
    _defaults = {
        'state': 'validate'
    }
{'fraction_non_alphanumeric': 0.12561677265359197, 'fraction_numerical': 0.0039544701544380915, 'mean_word_length': 2.0145518981904096, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 96, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2896280', 'n_tokens_mistral': 16441, 'n_tokens_neox': 15594, 'n_words': 1852}