class payment_file_acc_voucher(models.TransientModel):
    _name = 'payment.file.acc.voucher'

    bank_id = fields.Many2one('res.bank', 'Banco', required=True)
    txt_binary = fields.Binary()
    txt_filename = fields.Char()

    @api.multi
    def generate_file(self):
        for record in self:
            file_txt = StringIO.StringIO()
            items = self._get_data()[0]
            for item in items:
                string = self.set_string(item)
                file_txt.write(upper(string))
            out = base64.encodestring(file_txt.getvalue())
            file_txt.close()
            record.txt_binary = out
            record.txt_filename = 'Pago_Proveedor(%s).txt' % datetime.now(
            ).strftime('%Y%m%d%H%M%S')
            return {
                'name': 'Archivo Generado',
                'view_type': 'form',
                'view_mode': 'form',
                'res_model': 'payment.file.acc.voucher',
                'res_id': record.id,
                'view_id': False,
                'type': 'ir.actions.act_window',
                'domain': [],
                'target': 'new',
                'context': self._context,
            }

    def set_string(self, value):
        space = str()
        if self.bank_id.bic == '10':
            return value['column1'] + '\t' + value['column2'] + '\t' + value['column3'] + '\t' + value['column4'] + '\t' + \
               value['column5'] + '\t' + value['column6'] + '\t' + value['column7'] + '\t' + value['column8'][0: 41] + '\t' + value['column9'] + '\t' + value['column10'] + '\t' + \
               value['column11'] + '\t' + value['column12'] + chr(13) + chr(10)
        elif self.bank_id.bic == '32':
            return value['column1'] + '\t' + value['column2'] + '\t' + value['column3'] + '\t' + value['column4'] + '\t' + \
               value['column5'] + '\t' + value['column6'] + '\t' + value['column7'] + '\t' + value['column8'][0: 41] + '\t' + value['column9'] + '\t' + value['column10'] + '\t' + \
               value['column11'] + '\t' + value['column12'] + chr(13) + chr(10)

    @api.one
    def _get_data(self):
        context = dict(self._context)
        ids = context['active_ids']
        company = self.env['res.users'].browse(self._uid).company_id
        values = list()
        for statement in self.env['account.bank.statement'].browse(ids):
            if statement.to_partner:
                vals = {
                    'column1':
                    'PA',
                    'column2':
                    statement.partner_id.part_number
                    if not statement.partner_id.use_another_id else
                    statement.partner_id.second_identification,
                    'column3':
                    company.currency_id.name,
                    'column4':
                    self.round_complete(statement.balance_start),
                    'column5':
                    self.get_bank_data(statement, statement.bank_account)[0],
                    'column6':
                    self.get_bank_data(statement, statement.bank_account)[1],
                    'column7':
                    self.get_bank_data(statement, statement.bank_account)[2],
                    'column8':
                    self.get_description(statement.name),
                    'column9':
                    self.get_identification(statement.partner_id)[0],
                    'column10':
                    self.get_identification(statement.partner_id)[1],
                    'column11':
                    statement.partner_id.name,
                    'column12':
                    statement.bank_account.bank_bic
                }
                values.append(vals)
            else:
                for line in statement.line_ids:
                    if line.amount > 0.00:
                        vals = {
                            'column1':
                            'PA',
                            'column2':
                            line.partner_id.part_number
                            if not line.partner_id.use_another_id else
                            line.partner_id.second_identification,
                            'column3':
                            company.currency_id.name,
                            'column4':
                            self.round_complete(line.amount),
                            'column5':
                            self.get_bank_data(statement,
                                               line.bank_account_id)[0],
                            'column6':
                            self.get_bank_data(statement,
                                               line.bank_account_id)[1],
                            'column7':
                            self.get_bank_data(statement,
                                               line.bank_account_id)[2],
                            'column8':
                            self.get_description(line.ref),
                            'column9':
                            self.get_identification(line.partner_id)[0],
                            'column10':
                            self.get_identification(line.partner_id)[1],
                            'column11':
                            line.partner_id.name,
                            'column12':
                            line.bank_account_id.bank_bic
                        }
                        values.append(vals)
        return values

    def get_identification(self, partner):
        part_type = str()
        if partner.part_type == 'c':
            part_type = 'C'
        elif partner.part_type == 'r':
            part_type = 'R'
        return part_type, partner.part_number

    def get_description(self, ref):
        return ref

    def round_complete(self, value):
        if value < 0.00:
            value *= -1
        value = round(value, 2)
        value *= 100
        if len(str(value)) < 13:
            string_value = str(int(value))
            while len(string_value) < 13:
                string_value = '0' + string_value
            return string_value
        return str(int(value))

    def get_bank_data(self, statement, bank_account):
        if not statement.bank_account and statement.to_partner:
            raise except_orm(
                'Error!!',
                'El pago %s no tiene selccionada la cuenta bancaria de proveedor'
                % statement.name)
        type = 'CTA'
        type_account = str()
        if bank_account.state == 'AHO':
            type_account = 'AHO'
        elif bank_account.state == 'CTE':
            type_account = 'CTE'
        number = bank_account.acc_number
        return type, type_account, number
Esempio n. 2
0
class ResPartner(models.Model):
    _inherit = 'res.partner'

    dom = "['|',                                      " \
          "  ('on_contact' ,'!=', is_company        )," \
          "  '|',                                     " \
          "   '&',                                    " \
          "    ('on_company' , '=', is_company      )," \
          "    ('on_company' , '=', state=='perjur' )," \
          "   '&',                                    " \
          "    ('on_merchant', '=', state=='pernat' )," \
          "    ('on_merchant', '=', is_company      )]"

    fiscal_id_type = fields.Many2one(
        'res.partner.idtype',
        string=u'Document Type',
        domain=dom,
    )
    fiscal_id = fields.Char(string=u'Document ID',
                            # compute='validateformatcopy',
                            )
    fiscal_id_doc = fields.Binary(string=u'Document Scan',
                                  help="Upload the supporting Document "
                                  "preferably as size-optimized PDF. "
                                  "This might "
                                  "help save disk space and PDF allows "
                                  "you to concatenate multiple documents.")

    @api.one
    @api.onchange(
        'fiscal_id_type',
        'fiscal_id',
        'is_company',
    )
    def validateformatcopy(self):
        # CASE: Current ID Type is not applicable on Merchant
        if self.is_company and self.state == 'pernat':
            if not self.fiscal_id_type.on_merchant:
                # Get the first valid ID type (remember: ordered by sequence)
                self.fiscal_id_type = self.env['res.partner.idtype'].search(
                    [('on_merchant', '=', True)], limit=1).id
                self.fiscal_id = None  # Reset ID value
        # CASE: Current ID Type is not applicable on Company
        if self.is_company and self.state == 'perjur':
            if not self.fiscal_id_type.on_company:
                # Get the first valid ID type (remember: ordered by sequence)
                self.fiscal_id_type = self.env['res.partner.idtype'].search(
                    [('on_company', '=', True)], limit=1).id
                self.fiscal_id = None  # Reset ID value
        # CASE: Current ID Type is not applicable on contact
        if not self.is_company:
            if not self.fiscal_id_type.on_contact:
                # Get the first valid ID type (remember: ordered by sequence)
                self.fiscal_id_type = self.env['res.partner.idtype'].search(
                    [('on_contact', '=', True)], limit=1).id
                self.fiscal_id = None  # Reset ID value
        # If everything is fine, call subclasses
        if self.fiscal_id_type and self.fiscal_id:
            # Function for String Operations
            res = self._validateandformatid()
            if res['output_type'] and res['output_id']:
                self.fiscal_id_type = res['output_type']
                self.fiscal_id = res['output_id']
            # Procedure for Copying
            self._copyid()

    def _validateandformatid(self):
        """
        Hook method to be inherited for custom validation methods.
        :param input_type: the value of the field fiscal_id_type (id); passed
        on by onchange decorator
        :param input_id: the value of the field fiscal_id (string); passed on
        by onchange decorator
        :return: must return a dict with validated and formatted values

        Hint:
        you might not alter the output_type unless you might want to build
        some kind of fiscal_id_type recognition
        based on the input pattern into your hook method. CO###.###.###-#
        CO-VAT (NIT) for example.

        Find below a suggested basic outline.

        """
        return {
            'output_type': self.fiscal_id_type,
            'output_id': self.fiscal_id
        }
        """
        f_type     = self.fiscal_id_type
        f_id       = self.fiscal_id
        is_company = self.is_company

        def default():
            return {'output_type': f_type, 'output_id': f_id}

        return {
            # Define your cases
            # The index to match is self.fiscal_id_type.code
            # Note: You can change this index below.
            # Example assignation using two functions
            # {'output_type': func_type1(), 'output_id': funct_id1()}
            'CODE1': { "put your assignation here" },
            'CODE2': { "put your assignation here" },
        }.get(self.fiscal_id_type.code, default())
        """

    def _copyid(self):
        """
        Hook Method to be inherited for custom copy methods based on the
        document type (id)
        Example Use Case: Copy some local VAT number into the VAT-Field in
        it's international format for compatibility.

        :return: It is a Procedure and therefore has no return value.

        Find below a suggested basic outline.

        """
        """
Esempio n. 3
0
class fds_key_import_wizard(models.TransientModel):
    ''' FDS Postfinance keys import wizard.
        The goal is to import existing key in the database.

        This wizard is called when we click on import FDS authentication keys
        for one FDS.
        This Class inherit from fds_key_generator_wizard.
    '''
    _name = 'fds.key.import.wizard'
    _inherit = 'fds.key.generator.wizard'

    public_key_import_txt = fields.Text(string='Public key',
                                        help='copy/paste your public key')
    private_key_import_txt = fields.Text(string='Private key',
                                         help='copy/paste your private key')
    public_key_import_file = fields.Binary(
        string='Public key',
        help='select one file that contain your public key')
    private_key_import_file = fields.Binary(
        string='Private key',
        help='select one file that contain your private key')

    ##################################
    #         Button action          #
    ##################################
    @api.multi
    def import_keys_button(self):
        ''' Import public and private key then save in the database.
            Called by pressing import button.

            :returns action: configuration for the next wizard's view
            :raises Warning: if missing input information
        '''
        self.ensure_one()

        # check if authentication keys already exist
        self.userkey_exist()

        if self.private_key_import_file and self.public_key_import_file:
            # found 2 import file key
            return self._import_key('file')
        elif self.private_key_import_txt and self.public_key_import_txt:
            # found 2 import text key
            return self._import_key('text')
        elif self.private_key_import_file or self.public_key_import_file:
            # miss 1 import file key
            raise exceptions.Warning('Import key file missing')
        elif self.private_key_import_txt or self.public_key_import_txt:
            # miss 1 import text key
            raise exceptions.Warning('Import key text missing')
        else:
            raise exceptions.Warning('Import key not found')

    ##############################
    #          function          #
    ##############################
    @api.multi
    def _import_key(self, type):
        ''' private function that convert the keys depending on type,
            crypte and save in the database using inherit function (_savekeys).

            :param str type: type of the import "file" or "text"
            :returns action: configuration for the next wizard's view
        '''
        self.ensure_one()

        # convert keys
        auth_key_obj = self.env['fds.authentication.keys']
        if type == 'file':
            pub = base64.b64decode(self.public_key_import_file)
            ppk = base64.b64decode(self.private_key_import_file)
        elif type == 'text':
            pub = self.public_key_import_txt
            ppk = self.private_key_import_txt
        else:
            _logger.error("Bad implementation in fds_key_import_wizard")
            raise exceptions.Warning('Error code. Contact your admin')

        keys = auth_key_obj.import_pairkey(pub, ppk)
        # save values
        self.savekeys(keys[0], keys[1])
        # change view wizard
        self.write({'state': 'generate'})
        return self._do_populate_tasks()
Esempio n. 4
0
class ftz_pos_order_import(models.Model):
    _name = 'ftz_pos_order_import.ftz_pos_order_import'
    # _description = 'Description'

    name = fields.Char(
        string='name',
        size=64,
    )
    upload_file = fields.Binary(string='Upload File', )

    @api.one
    def do_process(self):
        _logger.info("Import Started %s:%s" % ("1", "2"))
        curr_obj = self
        if not curr_obj.upload_file:
            raise UserError(_('Please Choose The File!'))
        file_name = curr_obj.name
        print "curr_obj.name here", curr_obj.name
        print "file namr here", file_name
        fname = str(file_name.split('.')[1])
        print fname
        # if fname not in ['xls','xlsx']:
        # 	raise UserError(_('Please Choose The File With .xls or .xlsx extension and proper format!'))
        # try:
        # file=base64.decodestring(curr_obj.upload_file)
        # # fp = StringIO()
        # fp = BytesIO()
        # fp.write(file)
        # wb = xlrd.open_workbook(file_contents=fp.getvalue())
        # wb.sheet_names()
        # sheet_name=wb.sheet_names()
        # sh = wb.sheet_by_index(0)
        # print sh
        # sh = wb.sheet_by_name(sheet_name[0])
        # print sh
        # n_rows = sh.nrows

        file_data = self.upload_file.decode('base64')
        wb = xlrd.open_workbook(file_contents=file_data)
        sheet_names = wb.sheet_names()

        for sheet_name in sheet_names:
            sh = wb.sheet_by_name(sheet_name)
            num_cols = sh.ncols
            counter = 0
            for row in range(0, sh.nrows):
                if counter == 0: continue
                print('-' * 40)
                print('Row: %s' % row)  # Print row number
                for col in range(0, num_cols):  # Iterate through columns
                    cell_obj = sh.cell(row, col)  # Get cell object by row, col
                    print('Column: [%s] cell_obj: [%s]' % (col, cell_obj))
                counter += 1
                if counter > 10: break
        error

    @api.one
    @api.constrains('name')
    def _check_filename(self):
        if self.upload_file:
            if not self.name: raise ValidationError(_("There is no file"))
        else:
            # Check the file's extension
            tmp = self.name.split('.')
            ext = tmp[len(tmp) - 1]
            print ext
            print ext != 'xls'
            print ext != 'xlsx'
            print type(ext)
            print ext in ['xls', 'xlsx']
            if not ext in ['xls', 'xlsx']:
                raise ValidationError(_("The file must be a excel file"))
Esempio n. 5
0
                return self._logo_image
            finally:
                image_file.close()
        else:
            self._logo_image = base64.encodestring(im.read())
            return self._logo_image

    @api.one
    def _get_image_fn(recs):
        image = recs._get_image()
        for rec in recs:
            rec.config_logo = image

    ### Fields
    link = fields.Char('Original developer', size=128, readonly=True)
    config_logo = fields.Binary(compute='_get_image_fn', string='Image')
    ### ends Fields

    _defaults = {
        'config_logo': _get_image,
        'link': 'http://www.alistek.com',
    }


class docs_config_installer(models.TransientModel):
    _name = 'docs_config.installer'
    _inherit = 'res.config.installer'
    _rec_name = 'host'
    _logo_image = None

    @api.cr_uid_context
Esempio n. 6
0
class home_page(models.Model):
    _name = "home.page"
    _rec_name = "action"

    sequence = fields.Integer(u'序列')
    action = fields.Many2one('ir.actions.act_window', string=u'快捷页面', required='1')
    view_id = fields.Many2one('ir.ui.view', string=u'对应的视图')
    image = fields.Binary(u"显示的图片")
    menu_type = fields.Selection([(u'main', u'主菜单'), (u'top', u'金额汇总'), (u'left', u'快速查看')], string=u'类型', required="1")
    domain = fields.Char(u'页面的过滤', default='[]')
    note_one = fields.Char(u'第一个显示名称')
    compute_field_one = fields.Many2one('ir.model.fields', string=u'需要计算的字段')
    note_two = fields.Char(u'显示名称')
    compute_field_two = fields.Many2one('ir.model.fields', string=u'需要计算的字段')
    compute_type = fields.Selection([(u'sum', u'sum'), (u'average', u'average')], default="sum", string=u"计算类型")
    context = fields.Char(u'动作的上下文')

    @api.onchange('action')
    def onchange_action(self):
        if self.action:
            return {
                'domain': {'view_id': [('model', '=', self.action.res_model), ('type', '=', 'tree')], }
            }

    @api.model
    def get_action_url(self):
        action_url_lsit = {'main': [], 'top': [], 'right': []}

        action_list = self.env['home.page'].search([(1, '=', 1), ('sequence', '!=', 0)], order='sequence')
        for action in action_list:
            if action:
                if action.menu_type == 'main':
                    action_url_lsit['main'].append([action.note_one, action.action.view_mode, action.action.res_model,
                                                    action.action.domain, action.id, action.action.context,
                                                    action.view_id.id, action.action.name])
                elif action.menu_type == 'top':
                    note = ""
                    res_model_objs = self.env[action.action.res_model].search(eval(action.domain or '[]'))
                    if action.compute_field_one and action.compute_field_two:
                        note = "%s  %s <br\> %s  %s" % (action.note_one, sum([res_model_obj[action.compute_field_one.name] for res_model_obj in res_model_objs]),
                                                        action.note_two, sum([res_model_obj[action.compute_field_two.name] for res_model_obj in res_model_objs]))
                    elif action.compute_field_one or action.compute_field_two:
                        field_compute, note = "", ""
                        if action.compute_field_one:
                            field_compute = action.compute_field_one.name
                            note = action.note_one
                        else:
                            field_compute = action.compute_field_two.name
                            note = action.note_two
                        note = "%s  %s" % (note, sum([res_model_obj[field_compute] for res_model_obj in res_model_objs]))

                    else:
                        note = "%s  %s" % (action.note_one, sum([1 for res_model_obj in res_model_objs]))

                    action_url_lsit['top'].append([note, action.action.view_mode, action.action.res_model, action.domain,
                                                   action.context, action.view_id.id, action.action.name])
                else:
                    res_model_objs = self.env[action.action.res_model].search(eval(action.domain or '[]'))
                    action_url_lsit['right'].append(["%s  %s" % (action.note_one, sum([1 for res_model_obj in res_model_objs])),
                                                     action.action.view_mode, action.action.res_model,
                                                     action.domain, action.context, action.view_id.id, action.action.name])
        return action_url_lsit
Esempio n. 7
0
class HrOrientationChecklist(models.Model):
    _name = 'hr.orientation.checklist'
    _inherit = ['mail.thread', 'ir.needaction_mixin']
    _order = 'id asc'
    _rec_name = 'name'
    _description = "Employee Course Modules"

    name = fields.Char(string='Name', required=True, readonly=True)
    responsible_user_id = fields.Many2one(
        'res.users',
        string='Responsible User',
        required=True,
    )
    checklist_state = fields.Selection(
        selection=[('new', 'Ungraded'), \
        ('done', 'Completed'),\
        ('pass', 'Passed'),\
        ('fail', 'Failed'),\
        ('cancel', 'Cancelled')],
        string='Status',
        copy=False,
        default='new',
        track_visibility='onchange'
    )
    checklist_date = fields.Date(string='Date', readonly=True)
    expected_date = fields.Date(
        string='Expected Date',
        default=fields.Date.today(),
        required=True,
    )
    orientation_id = fields.Many2one(
        'hr.orientation',
        string='Training',
        readonly=True,
    )
    company_id = fields.Many2one('res.company',
                                 default=lambda self: self.env.user.company_id,
                                 string='Company',
                                 readonly=True)
    note = fields.Text(
        string='Notes',
        #related='orientation_id.main_configuration_id.main_checklist_ids.note',
        readonly=True,
        store=True,
    )
    attachment_ids1 = fields.Binary(
        string='First Attachment',
        #related='orientation_id.main_configuration_id.main_checklist_ids.attachment_ids1',
        readonly=True,
        store=True,
    )
    attachment_ids2 = fields.Binary(
        string='Second Attachment',
        #related='orientation_id.main_configuration_id.main_checklist_ids.attachment_ids2',
        readonly=True,
        store=True,
    )
    attachment_ids3 = fields.Binary(
        string='Third Attachment',
        #related='orientation_id.main_configuration_id.main_checklist_ids.attachment_ids3',
        readonly=True,
        store=True,
    )
    employee_id = fields.Many2one(
        related='orientation_id.employee_id',
        string='Employee User',
        readonly=True,
        store=True,
    )

    x_orientation_checklist_id = fields.Many2one(
        'hr.orientation.checklist.config',
        string='Course Module ID',
        store=True,
        readyonly=True)

    web_url = fields.Char(
        string='Web URL',
        readonly=True,
    )

    survey_id = fields.Many2one('survey.survey',
                                String='Test/Exam',
                                store=True,
                                readonly=True)
    supervisor = fields.Many2one(related='orientation_id.user_id',
                                 String='Supervisor Name',
                                 store=True,
                                 readonly=True)
    response_id = fields.Many2one(
        'survey.user_input',
        "Response",
        ondelete="set null",
        oldname="response",
        store=True,
        readonly=True,
    )
    survey_score = fields.Float(related='response_id.quizz_score',
                                String='Test Score',
                                store=True,
                                readonly=True)

    @api.one
    def process_survey_result(self):
        if self.survey_score == 0:
            self.write({
                'checklist_state': 'new',
            })
        elif (self.survey_score > 0) and (self.survey_score < 8):
            self.write({
                'checklist_state': 'fail',
            })
        elif self.survey_score >= 8:
            self.write({
                'checklist_state': 'pass',
            })

    @api.multi
    def action_start_survey(self):
        self.ensure_one()
        # create a response and link it to this applicant
        if not self.response_id:
            response = self.env['survey.user_input'].create({
                'survey_id':
                self.survey_id.id,
                'responsible_user_id':
                self.responsible_user_id.id
            })
            self.response_id = response.id
        else:
            response = self.response_id
        # grab the token of the response and start surveying
        return self.survey_id.with_context(
            survey_token=response.token).action_start_survey()

    @api.multi
    def action_print_survey(self):
        """ If response is available then print this response otherwise print survey form (print template of the survey) """
        self.ensure_one()
        if not self.response_id:
            return self.survey_id.action_print_survey()
        else:
            response = self.response_id
            return self.survey_id.with_context(
                survey_token=response.token).action_print_survey()
Esempio n. 8
0
class Image(models.Model):
    _name = "base_multi_image.image"
    _order = "sequence, owner_model, owner_id, id"
    _sql_constraints = [
        ('uniq_name_owner', 'UNIQUE(owner_id, owner_model, name)',
         _('A document can have only one image with the same name.')),
    ]

    owner_id = fields.Integer("Owner", required=True)
    owner_model = fields.Char(required=True)
    storage = fields.Selection([('url', 'URL'), ('file', 'OS file'),
                                ('db', 'Database')],
                               required=True)
    name = fields.Char('Image title', translate=True)
    filename = fields.Char()
    extension = fields.Char('File extension', readonly=True)
    file_db_store = fields.Binary('Image stored in database',
                                  filters='*.png,*.jpg,*.gif')
    path = fields.Char("Image path", help="Image path")
    url = fields.Char('Image remote URL')
    image_main = fields.Binary("Full-sized image", compute="_get_image")
    image_medium = fields.Binary(
        "Medium-sized image",
        compute="_get_image_sizes",
        help="Medium-sized image. It is automatically resized as a "
        "128 x 128 px image, with aspect ratio preserved, only when the "
        "image exceeds one of those sizes. Use this field in form views "
        "or kanban views.")
    image_small = fields.Binary(
        "Small-sized image",
        compute="_get_image_sizes",
        help="Small-sized image. It is automatically resized as a 64 x 64 px "
        "image, with aspect ratio preserved. Use this field anywhere a "
        "small image is required.")
    comments = fields.Text('Comments', translate=True)
    sequence = fields.Integer(default=10)
    show_technical = fields.Boolean(compute="_show_technical")

    @api.multi
    @api.depends('storage', 'path', 'file_db_store', 'url')
    def _get_image(self):
        """Get image data from the right storage type."""
        for s in self:
            s.image_main = getattr(s, "_get_image_from_%s" % s.storage)()

    @api.multi
    @api.depends("owner_id", "owner_model")
    def _show_technical(self):
        """Know if you need to show the technical fields."""
        self.show_technical = all("default_owner_%s" %
                                  f not in self.env.context
                                  for f in ("id", "model"))

    @api.multi
    def _get_image_from_db(self):
        return self.file_db_store

    @api.multi
    def _get_image_from_file(self):
        if self.path and os.path.exists(self.path):
            try:
                with open(self.path, 'rb') as f:
                    return base64.b64encode(f.read())
            except Exception as e:
                _logger.error("Can not open the image %s, error : %s",
                              self.path,
                              e,
                              exc_info=True)
        else:
            _logger.error("The image %s doesn't exist ", self.path)

        return False

    @api.multi
    def _get_image_from_url(self):
        return self._get_image_from_url_cached(self.url)

    @api.model
    @tools.ormcache(skiparg=1)
    def _get_image_from_url_cached(self, url):
        """Allow to download an image and cache it by its URL."""
        if url:
            try:
                (filename, header) = urllib.urlretrieve(url)
                with open(filename, 'rb') as f:
                    return base64.b64encode(f.read())
            except:
                _logger.error("URL %s cannot be fetched", url, exc_info=True)

        return False

    @api.multi
    @api.depends('image_main')
    def _get_image_sizes(self):
        for s in self:
            try:
                image = s.with_context(bin_size=False).image_main
                vals = dict()
                vals["image_medium"] = tools.image_resize_image_medium(
                    image, size=(300, 300))
                vals["image_small"] = tools.image_resize_image_small(image)
            except:
                vals = {"image_medium": False, "image_small": False}
            s.update(vals)

    @api.model
    def _make_name_pretty(self, name):
        return name.replace('_', ' ').capitalize()

    @api.onchange('url')
    def _onchange_url(self):
        if self.url:
            filename = self.url.split('/')[-1]
            self.name, self.extension = os.path.splitext(filename)
            self.name = self._make_name_pretty(self.name)

    @api.onchange('path')
    def _onchange_path(self):
        if self.path:
            self.name, self.extension = os.path.splitext(
                os.path.basename(self.path))
            self.name = self._make_name_pretty(self.name)

    @api.onchange('filename')
    def _onchange_filename(self):
        if self.filename:
            self.name, self.extension = os.path.splitext(self.filename)
            self.name = self._make_name_pretty(self.name)

    @api.constrains('storage', 'url')
    def _check_url(self):
        if self.storage == 'url' and not self.url:
            raise exceptions.ValidationError(
                'You must provide an URL for the image.')

    @api.constrains('storage', 'path')
    def _check_path(self):
        if self.storage == 'file' and not self.path:
            raise exceptions.ValidationError(
                'You must provide a file path for the image.')

    @api.constrains('storage', 'file_db_store')
    def _check_store(self):
        if self.storage == 'db' and not self.file_db_store:
            raise exceptions.ValidationError(
                'You must provide an attached file for the image.')
class ImportInventory(models.TransientModel):
    _name = 'import.inventory'
    _description = 'Import inventory'

    def _get_default_location(self):
        ctx = self._context
        if 'active_id' in ctx:
            inventory_obj = self.env['stock.inventory']
            inventory = inventory_obj.browse(ctx['active_id'])
        return inventory.location_id

    data = fields.Binary('File', required=True)
    name = fields.Char('Filename')
    delimeter = fields.Char('Delimeter',
                            default=',',
                            help='Default delimeter is ","')
    location = fields.Many2one('stock.location',
                               'Default Location',
                               default=_get_default_location,
                               required=True)

    @api.one
    def action_import(self):
        """Load Inventory data from the CSV file."""
        ctx = self._context
        stloc_obj = self.env['stock.location']
        inventory_obj = self.env['stock.inventory']
        inv_imporline_obj = self.env['stock.inventory.import.line']
        product_obj = self.env['product.product']
        if 'active_id' in ctx:
            inventory = inventory_obj.browse(ctx['active_id'])
        if not self.data:
            raise exceptions.Warning(_("You need to select a file!"))
        # Decode the file data
        data = base64.b64decode(self.data)
        file_input = cStringIO.StringIO(data)
        file_input.seek(0)
        location = self.location
        reader_info = []
        if self.delimeter:
            delimeter = str(self.delimeter)
        else:
            delimeter = ','
        reader = csv.reader(file_input,
                            delimiter=delimeter,
                            lineterminator='\r\n')
        try:
            reader_info.extend(reader)
        except Exception:
            raise exceptions.Warning(_("Not a valid file!"))
        keys = reader_info[0]
        # check if keys exist
        if not isinstance(keys, list) or ('code' not in keys
                                          or 'quantity' not in keys):
            raise exceptions.Warning(_("Not 'code' or 'quantity' keys found"))
        del reader_info[0]
        values = {}
        actual_date = fields.Date.today()
        inv_name = self.name + ' - ' + actual_date
        inventory.write({
            'name': inv_name,
            'date': fields.Datetime.now(),
            'imported': True,
            'state': 'confirm'
        })
        for i in range(len(reader_info)):
            val = {}
            field = reader_info[i]
            values = dict(zip(keys, field))
            prod_location = location.id
            if 'location' in values and values['location']:
                locations = stloc_obj.search([('name', '=', values['location'])
                                              ])
                prod_location = locations[:1].id
            prod_lst = product_obj.search([('default_code', '=',
                                            values['code'])])
            if prod_lst:
                val['product'] = prod_lst[0].id
            if 'lot' in values and values['lot']:
                val['lot'] = values['lot']
            val['code'] = values['code']
            val['quantity'] = values['quantity']
            val['location_id'] = prod_location
            val['inventory_id'] = inventory.id
            val['fail'] = True
            val['fail_reason'] = _('No processed')
            inv_imporline_obj.create(val)
Esempio n. 10
0
class PostlogisticsConfigSettings(models.TransientModel):
    _name = 'postlogistics.config.settings'
    _inherit = 'res.config.settings'

    def _default_company(self):
        return self.env.user.company_id

    company_id = fields.Many2one(comodel_name='res.company',
                                 string='Company',
                                 required=True,
                                 default=_default_company)
    wsdl_url = fields.Char(related='company_id.postlogistics_wsdl_url')
    username = fields.Char(related='company_id.postlogistics_username')
    password = fields.Char(related='company_id.postlogistics_password')
    license_ids = fields.One2many(
        related='company_id.postlogistics_license_ids', )
    logo = fields.Binary(related='company_id.postlogistics_logo')
    office = fields.Char(related='company_id.postlogistics_office')

    default_label_layout = fields.Many2one(
        related='company_id.postlogistics_default_label_layout', )
    default_output_format = fields.Many2one(
        related='company_id.postlogistics_default_output_format', )
    default_resolution = fields.Many2one(
        related='company_id.postlogistics_default_resolution', )

    @api.onchange('company_id')
    def onchange_company_id(self):
        # update related fields
        if not self.company_id:
            return
        company = self.company_id

        licenses = company.postlogistics_license_ids
        label_layout = company.postlogistics_default_label_layout
        output_format = company.postlogistics_default_output_format
        resolution = company.postlogistics_default_resolution

        self.username = company.postlogistics_username
        self.password = company.postlogistics_password
        self.license_ids = licenses
        self.logo = company.postlogistics_logo
        self.office = company.postlogistics_office
        self.default_label_layout = label_layout
        self.default_output_format = output_format
        self.default_resolution = resolution

    @api.model
    def _get_delivery_instructions(self, web_service, company, service_code):
        lang = self.env.context.get('lang', 'en')
        service_code_list = service_code.split(',')
        res = web_service.read_delivery_instructions(company,
                                                     service_code_list, lang)
        if 'errors' in res:
            errors = '\n'.join(res['errors'])
            error_message = (_('Could not retrieve Postlogistics delivery'
                               'instructions:\n%s') % errors)
            raise exceptions.Warning(error_message)

        if not res['value']:
            return {}

        if hasattr(res['value'], 'Errors') and res['value'].Errors:
            for error in res['value'].Errors.Error:
                message = '[%s] %s' % (error.Code, error.Message)
            raise exceptions.Warning(message)

        delivery_instructions = {}
        for service in res['value'].DeliveryInstructions:
            service_code = service.PRZL
            delivery_instructions[service_code] = {'name': service.Description}

        return delivery_instructions

    @api.model
    def _update_delivery_instructions(self, web_service, additional_services):
        carrier_option_obj = self.env['delivery.carrier.template.option']

        xmlid = 'delivery_carrier_label_postlogistics.postlogistics'
        postlogistics_partner = self.env.ref(xmlid)

        for service_code, data in additional_services.iteritems():
            options = carrier_option_obj.search([('code', '=', service_code),
                                                 ('postlogistics_type', '=',
                                                  'delivery')])

            if options:
                options.write(data)
            else:
                data.update(code=service_code,
                            postlogistics_type='delivery',
                            partner_id=postlogistics_partner.id)
                carrier_option_obj.create(data)
        lang = self.env.context.get('lang', 'en')
        _logger.info("Updated delivery instructions. [%s]", lang)

    @api.model
    def _get_additional_services(self, web_service, company, service_code):
        lang = self.env.context.get('lang', 'en')
        service_code_list = service_code.split(',')
        res = web_service.read_additional_services(company, service_code_list,
                                                   lang)
        if 'errors' in res:
            errors = '\n'.join(res['errors'])
            error_message = (_('Could not retrieve Postlogistics base '
                               'services:\n%s') % errors)
            raise exceptions.Warning(error_message)

        if not res['value']:
            return {}

        if hasattr(res['value'], 'Errors') and res['value'].Errors:
            for error in res['value'].Errors.Error:
                message = '[%s] %s' % (error.Code, error.Message)
            raise exceptions.Warning(message)

        additional_services = {}
        for service in res['value'].AdditionalService:
            service_code = service.PRZL
            additional_services[service_code] = {'name': service.Description}

        return additional_services

    @api.model
    def _update_additional_services(self, web_service, additional_services):
        carrier_option_obj = self.env['delivery.carrier.template.option']

        xmlid = 'delivery_carrier_label_postlogistics.postlogistics'
        postlogistics_partner = self.env.ref(xmlid)

        for service_code, data in additional_services.iteritems():
            options = carrier_option_obj.search([('code', '=', service_code),
                                                 ('postlogistics_type', '=',
                                                  'additional')])

            if options:
                options.write(data)
            else:
                data.update(code=service_code,
                            postlogistics_type='additional',
                            partner_id=postlogistics_partner.id)
                carrier_option_obj.create(data)
        lang = self.env.context.get('lang', 'en')
        _logger.info("Updated additional services [%s]", lang)

    @api.model
    def _update_basic_services(self, web_service, company, group):
        """ Update of basic services

        A basic service can be part only of one service group

        :return: {additional_services: {<service_code>: service_data}
                  delivery_instructions: {<service_code>: service_data}
                  }

        """
        carrier_option_obj = self.env['delivery.carrier.template.option']

        xmlid = 'delivery_carrier_label_postlogistics.postlogistics'
        postlogistics_partner = self.env.ref(xmlid)
        lang = self.env.context.get('lang', 'en')

        res = web_service.read_basic_services(company, group.group_extid, lang)
        if 'errors' in res:
            errors = '\n'.join(res['errors'])
            error_message = (_('Could not retrieve Postlogistics base '
                               'services:\n%s') % errors)
            raise exceptions.Warning(error_message)

        additional_services = {}
        delivery_instructions = {}
        # Create or update basic service
        for service in res['value'].BasicService:
            service_code = ','.join(service.PRZL)
            options = carrier_option_obj.search([
                ('code', '=', service_code),
                ('postlogistics_service_group_id', '=', group.id),
                ('postlogistics_type', '=', 'basic')
            ])
            data = {'name': service.Description}
            if options:
                options.write(data)
                option = options[0]
            else:
                data.update(code=service_code,
                            postlogistics_service_group_id=group.id,
                            partner_id=postlogistics_partner.id,
                            postlogistics_type='basic')
                option = carrier_option_obj.create(data)

            # Get related services
            allowed_services = self._get_additional_services(
                web_service, company, service_code)
            for key, value in additional_services.iteritems():
                if key in allowed_services:
                    field = 'postlogistics_basic_service_ids'
                    additional_services[key][field][0][2].append(option.id)
                    del allowed_services[key]
            for key, value in allowed_services.iteritems():
                field = 'postlogistics_basic_service_ids'
                value[field] = [(6, 0, [option.id])]
                additional_services[key] = value

            allowed_services = self._get_delivery_instructions(
                web_service, company, service_code)
            for key, value in delivery_instructions.iteritems():
                if key in allowed_services:
                    field = 'postlogistics_basic_service_ids'
                    delivery_instructions[key][field][0][2].append(option.id)
                    del allowed_services[key]
            for key, value in allowed_services.iteritems():
                field = 'postlogistics_basic_service_ids'
                value[field] = [(6, 0, [option.id])]
                delivery_instructions[key] = value

        _logger.info("Updated '%s' basic service [%s].", group.name, lang)
        return {
            'additional_services': additional_services,
            'delivery_instructions': delivery_instructions
        }

    @api.model
    def _update_service_groups(self, web_service, company):
        """ Also updates additional services and delivery instructions
        as they are shared between groups

        """
        service_group_obj = self.env['postlogistics.service.group']

        lang = self.env.context.get('lang', 'en')

        res = web_service.read_service_groups(company, lang)
        if 'errors' in res:
            errors = '\n'.join(res['errors'])
            error_message = (_('Could not retrieve Postlogistics group '
                               'services:\n%s') % errors)
            raise exceptions.Warning(error_message)

        additional_services = {}
        delivery_instructions = {}

        # Create or update groups
        for group in res['value'].ServiceGroup:
            group_extid = group.ServiceGroupID
            groups = service_group_obj.search(
                [('group_extid', '=', group_extid)], )
            data = {'name': group.Description}
            if groups:
                groups.write(data)
                group = groups[0]
            else:
                data['group_extid'] = group_extid
                group = service_group_obj.create(data)

            # Get related services for all basic services of this group
            res = self._update_basic_services(web_service, company, group)

            allowed_services = res.get('additional_services', {})
            for key, value in additional_services.iteritems():
                if key in allowed_services:
                    field = 'postlogistics_basic_service_ids'
                    option_ids = allowed_services[key][field][0][2]
                    additional_services[key][field][0][2].extend(option_ids)
                    del allowed_services[key]
            additional_services.update(allowed_services)

            allowed_services = res.get('delivery_instructions', {})
            for key, value in delivery_instructions.iteritems():
                if key in allowed_services:
                    field = 'postlogistics_basic_service_ids'
                    option_ids = allowed_services[key][field][0][2]
                    delivery_instructions[key][field][0][2].extend(option_ids)
                    del allowed_services[key]
            delivery_instructions.update(allowed_services)

        # Update related services
        self._update_additional_services(web_service, additional_services)
        self._update_delivery_instructions(
            web_service,
            delivery_instructions,
        )

    @api.multi
    def update_postlogistics_options(self):
        """ This action will update all postlogistics option by
        importing services from PostLogistics WebService API

        The object we create are 'delivey.carrier.template.option'

        """
        for config in self:
            company = config.company_id
            web_service = PostlogisticsWebService(company)

            # make sure we create source text in en_US
            ctx = self.env.context.copy()
            ctx['lang'] = 'en_US'
            self._update_service_groups(web_service, company)

            language_obj = self.env['res.lang']
            languages = language_obj.search([])

            # handle translations
            # we call the same method with a different language context
            for lang in languages:
                lang_code = lang.code
                postlogistics_lang = web_service._get_language(lang_code)
                # add translations only for languages that exists on
                # postlogistics, english source will be kept for other
                # languages
                if postlogistics_lang == 'en':
                    continue
                self.with_context(lang=lang_code)._update_service_groups(
                    web_service, company)
        return True

    @api.model
    def _get_allowed_service_group_codes(self, web_service, company,
                                         cp_license):
        """ Get a list of allowed service group codes"""
        lang = self.env.context.get('lang', 'en')
        res = web_service.read_allowed_services_by_franking_license(
            cp_license.number, company, lang)
        if 'errors' in res:
            errors = '\n'.join(res['errors'])
            error_message = (_('Could not retrieve allowed Postlogistics '
                               'service groups for the %s licence:\n%s') %
                             (cp_license.name, errors))
            raise exceptions.Warning(error_message)

        if not res['value']:
            return []

        if hasattr(res['value'], 'Errors') and res['value'].Errors:
            for error in res['value'].Errors.Error:
                message = '[%s] %s' % (error.Code, error.Message)
            raise exceptions.Warning(message)

        service_group_codes = []
        for group in res['value'].ServiceGroups:
            service_group_codes.append(group.ServiceGroup.ServiceGroupID)

        return service_group_codes

    @api.multi
    def assign_licenses_to_service_groups(self):
        """ Check all licenses to assign it to PostLogistics service groups """
        service_group_obj = self.env['postlogistics.service.group']
        license_obj = self.env['postlogistics.license']
        for config in self:
            company = config.company_id
            web_service = PostlogisticsWebService(company)

            relations = {}
            for cp_license in company.postlogistics_license_ids:
                service_groups = self._get_allowed_service_group_codes(
                    web_service, company, cp_license)
                groups = service_group_obj.search(
                    [('group_extid', 'in', service_groups)], )
                for group in groups:
                    relations.setdefault(group, license_obj.browse())
                    relations[group] |= cp_license
            for group, licenses in relations.iteritems():
                vals = {'postlogistics_license_ids': [(6, 0, licenses.ids)]}
                group.write(vals)
        return True
Esempio n. 11
0
class SriTaxForm(models.Model):
    _name = 'l10n_ec_sri.tax.form'
    _order = 'formulario'

    state = fields.Selection([
        ('draft', 'Borrador'),
        ('done', 'Presentado'),
        ('replaced', 'Sustituido'),
    ],
        string='Estado',
        default='draft', )

    formulario = fields.Selection([
        ('101', '101'),
        ('103', '103'),
        ('104', '104'),
        ('ats', 'Anexo Transaccional'),
    ])
    sri_tax_form_set_id = fields.Many2one(
        'l10n_ec_sri.tax.form.set', ondelete='cascade',
        string="Tax Form Set", )
    date_from = fields.Date(
        'Desde', related='sri_tax_form_set_id.date_from', )
    date_to = fields.Date(
        'Hasta', related='sri_tax_form_set_id.date_to', )

    sri_tax_form_line_ids = fields.One2many(
        'l10n_ec_sri.tax.form.line',
        inverse_name='sri_tax_form_id',
        string='Tax declarations', )

    payment_ids = fields.Many2many(
        'account.payment', 'payment_tax_form_rel', 'payment_ids',
        'tax_form_ids', string="Payments", )

    move_ids = fields.Many2many(
        'account.move', 'move_tax_form_rel', 'move_ids',
        'tax_form_ids', string="Move", )

    xml_file = fields.Binary('Archivo XML', attachment=True, readonly=True, )
    xml_filename = fields.Char(string="Archivo XML")

    declarar_facturas_electronicas = fields.Boolean(
        string='Declarar facturas electronicas', default=False, )

    @api.multi
    def prepare_ats(self):
        """
        Método para ser heredado.
        :return: dict con valores del ATS
        """
        for f in self:
            inv = self.env['account.invoice']
            form_set = f.sri_tax_form_set_id

            # Para generar los datos de ventas
            ventas = form_set.out_invoice_ids

            tipoem = ['F']
            if f.declarar_facturas_electronicas:
                tipoem = list(set(ventas.mapped('tipoem')))
                if 'F' in tipoem:
                    f.declarar_facturas_electronicas = False
                    raise UserError(_(
                        "No puede declarar las facturas electrónicas si" \
                        "tiene comprobantes de venta físicos emitidos."
                    ))
            elif not f.declarar_facturas_electronicas:
                ventas = ventas.filtered(lambda x: x.tipoem == 'F')

            devoluciones = form_set.out_refund_ids
            if devoluciones and f.declarar_facturas_electronicas:
                tipoem = list(set(devoluciones.mapped('tipoem')))
                if 'F' in tipoem:
                    f.declarar_facturas_electronicas = False
                    raise UserError(_(
                        "No puede declarar las notas de crédito electrónicas" \
                        "si tiene notas de crédito físicas emitidas."
                    ))
            elif not f.declarar_facturas_electronicas:
                devoluciones = devoluciones.filtered(lambda x: x.tipoem == 'F')
            tipoem = tipoem[0]

            detalleVentas = []
            establecimientos = set(
                (ventas).mapped('establecimiento'))
            establecimientos = establecimientos - set(['999', False])
            ventaEst = []
            for e in establecimientos:
                if tipoem == 'E':
                    e_ventas = 0.00
                else:
                    e_ventas = sum(ventas.filtered(
                        lambda r: r.establecimiento == e).mapped('subtotal'))

                ventaEst.append(OrderedDict([
                    ('codEstab', e),
                    ('ventasEstab', '{:.2f}'.format(e_ventas)),
                    ('ivaComp', '{:.2f}'.format(0)),
                ]))

            totalVentas = sum(float(v['ventasEstab']) for v in ventaEst)
            numEstabRuc = str(len(ventaEst)).zfill(3)

            partners = (ventas + devoluciones).mapped('partner_id')

            # Necesitamos una segunda lista de partners para comparar los ya procesados.
            pending_partners = self.env['res.partner']
            pending_partners += partners

            for p in partners:

                # Continuamos si el partner ya ha sido procesado.
                if p not in pending_partners:
                    continue

                # Filtramos los partners por cédula y RUC
                vat = p.vat
                if vat and len(vat) == 13:
                    id_fiscal = [vat, vat[:9]]
                elif vat and len(vat) == 10:
                    id_fiscal = [vat, vat + '001']
                else:
                    id_fiscal = [vat]

                contribuyentes = self.env['res.partner']
                contribuyentes = partners.filtered(lambda r: r.vat in id_fiscal)
                # Restamos los partners para evitar duplicar el cálculo.
                pending_partners -= contribuyentes


                fiscal = p.property_account_position_id
                identificacion = fiscal.identificacion_id

                tpidcliente = identificacion.tpidcliente
                vals = OrderedDict([
                    ('tpIdCliente', tpidcliente),
                    ('idCliente', p.vat),
                    ('parteRelVtas', p.parterel and 'SI' or 'NO')
                ])

                if tpidcliente == '06':
                    vals.update(OrderedDict([
                        ('tipoCliente', fiscal.persona_id.tpidprov),
                        # Al declarar el ATS sale un error que indica que se debe
                        # declarar DenoCli cuando el tipo es 06.
                        # ('DenoCli', inv.normalize_text(p.name))
                    ]))

                # VENTAS
                p_ventas = ventas.filtered(lambda r: r.partner_id in contribuyentes)

                if p_ventas:
                    t_ventas = p_ventas.mapped('sri_ats_line_ids')
                    ventas -= p_ventas
                    tipoEmision = tipoem

                    fp_inv = p_ventas.filtered(lambda inv: inv.subtotal >= 1000)
                    formaPago = []
                    if fp_inv:
                        formaPago = list(
                            set(fp_inv.mapped('payment_ids').mapped('formapago_id.code')))
                    if not formaPago:
                        formaPago.append(p.formapago_id.code or '01')

                    basenograiva = sum(t_ventas.mapped('basenograiva'))
                    baseimponible = sum(t_ventas.mapped('baseimponible'))
                    baseimpgrav = sum(t_ventas.mapped('baseimpgrav'))
                    montoiva = sum(t_ventas.mapped('montoiva'))
                    montoice = sum(t_ventas.mapped('montoice'))
                    valorretiva = sum(t_ventas.mapped('valorretiva'))
                    valorretrenta = sum(t_ventas.mapped('valorretrenta'))

                    ventas_dict = OrderedDict()
                    ventas_dict.update(vals)
                    ventas_dict.update(OrderedDict([
                        ('tipoComprobante', '18'),
                        ('tipoEmision', tipoEmision),
                        ('numeroComprobantes', len(p_ventas)),
                        ('baseNoGraIva', '{:.2f}'.format(abs(basenograiva))),
                        ('baseImponible', '{:.2f}'.format(abs(baseimponible))),
                        ('baseImpGrav', '{:.2f}'.format(abs(baseimpgrav))),
                        ('montoIva', '{:.2f}'.format(abs(montoiva))),
                        # TODO: Tipo y monto de compensaciones, por desarrollar.
                        # ('tipoCompe', ''),
                        # ('monto', '{:.2f}'.format(0)),
                        ('montoIce', '{:.2f}'.format(abs(montoice))),
                        ('valorRetIva', '{:.2f}'.format(abs(valorretiva))),
                        ('valorRetRenta', '{:.2f}'.format(abs(valorretrenta))),
                    ]))

                    # Solo se declaran formasDePago en comprobantes de venta '18'
                    if formaPago:
                        ventas_dict.update([
                            ('formasDePago', {'formaPago': formaPago})
                        ])

                    detalleVentas.append(ventas_dict)

                # DEVOLUCIONES

                p_devoluciones = devoluciones.filtered(
                    lambda r: r.partner_id in contribuyentes)

                if not p_devoluciones:
                    continue

                t_devoluciones = p_devoluciones.mapped('sri_ats_line_ids')
                devoluciones -= p_devoluciones
                tipoEmision = tipoem
                basenograiva = sum(t_devoluciones.mapped('basenograiva'))
                baseimponible = sum(t_devoluciones.mapped('baseimponible'))
                baseimpgrav = sum(t_devoluciones.mapped('baseimpgrav'))
                montoiva = sum(t_devoluciones.mapped('montoiva'))
                montoice = sum(t_devoluciones.mapped('montoice'))
                valorretiva = sum(t_devoluciones.mapped('valorretiva'))
                valorretrenta = sum(t_devoluciones.mapped('valorretrenta'))

                devoluciones_dict = OrderedDict()
                devoluciones_dict.update(vals)

                devoluciones_dict.update(OrderedDict([
                    ('tipoComprobante', '04'),
                    ('tipoEmision', tipoEmision),
                    ('numeroComprobantes', len(p_devoluciones)),
                    ('baseNoGraIva', '{:.2f}'.format(abs(basenograiva))),
                    ('baseImponible', '{:.2f}'.format(abs(baseimponible))),
                    ('baseImpGrav', '{:.2f}'.format(abs(baseimpgrav))),
                    ('montoIva', '{:.2f}'.format(abs(montoiva))),
                    ('montoIce', '{:.2f}'.format(abs(montoice))),
                    ('valorRetIva', '{:.2f}'.format(abs(valorretiva))),
                    ('valorRetRenta', '{:.2f}'.format(abs(valorretrenta))),
                ]))

                detalleVentas.append(devoluciones_dict)

            ventas = OrderedDict([
                ('detalleVentas', detalleVentas),
            ])

            ventasEstablecimiento = OrderedDict([
                ('ventaEst', ventaEst),
            ])

            # Para la información general del informante
            date = f.sri_tax_form_set_id.date_to
            company = self.env.user.company_id
            informante = company.partner_id
            fiscal = informante.property_account_position_id
            iva = OrderedDict([
                ('TipoIDInformante', fiscal.identificacion_id.code),
                ('IdInformante', informante.vat),
                ('razonSocial', inv.normalize_text(informante.name)),
                ('Anio', datetime.strptime(date, '%Y-%m-%d').strftime('%Y')),
                ('Mes', datetime.strptime(date, '%Y-%m-%d').strftime('%m'))
            ])

            if numEstabRuc != '000':
                iva.update(OrderedDict([
                    ('numEstabRuc', numEstabRuc)
                ]))

            iva.update(OrderedDict([
                ('totalVentas', '{:.2f}'.format(totalVentas))
                ]))

            iva.update(OrderedDict([
                ('codigoOperativo', 'IVA')
            ]))

            # Diccionario de compras
            compras = form_set.in_invoice_ids + form_set.in_refund_ids

            detalleCompras = OrderedDict([('detalleCompras', [])])

            for c in compras:
                detalleCompra = c.prepare_detallecompras_dict()
                for dc in detalleCompra:
                    detalleCompras['detalleCompras'].append(dc)

            res = {
                'iva': iva,
                'ventas': ventas,
                'ventasEstablecimiento': ventasEstablecimiento,
                'compras': detalleCompras
            }
            return res

    @api.multi
    def get_ats_xml(self):
        decl = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>"""
        for f in self:
            vals = f.prepare_ats()
            data = OrderedDict([
                ('iva', vals['iva']),
            ])

            data['iva'].update([
                ('compras', vals['compras'])
            ])

            if vals['ventas']['detalleVentas']:
                data['iva'].update([
                    ('ventas', vals['ventas'])
                ])

            if vals['ventasEstablecimiento']['ventaEst']:
                data['iva'].update([
                    ('ventasEstablecimiento', vals['ventasEstablecimiento'])
                ])

            xml_data = decl + \
                xmltodict.unparse(data, pretty=True, full_document=False)
            f.write({'xml_filename': 'ATS.xml',
                     'xml_file': base64.encodestring(xml_data)})

    @api.multi
    def get_tax_form_lines(self):
        for f in self:
            # Limpiamos las líneas de impuestos previamente creadas.
            f.sri_tax_form_line_ids.unlink()

            tax_form_lines = []

            # Calculamos los impuestos en ventas.
            in_ref = f.sri_tax_form_set_id.mapped('in_refund_ids')
            in_inv = f.sri_tax_form_set_id.mapped('in_invoice_ids')
            purchases = in_inv + in_ref

            taxes = purchases.mapped('sri_tax_line_ids').filtered(
                lambda r: r.formulario == f.formulario)

            for t in set(taxes.mapped('campo')):
                facturas = in_inv.mapped('sri_tax_line_ids').filtered(
                    lambda r: r.campo == t)
                devoluciones = in_ref.mapped(
                    'sri_tax_line_ids').filtered(lambda r: r.campo == t)

                bruto = sum(facturas.mapped('base'))
                neto = bruto - sum(devoluciones.mapped('base'))
                impuesto = sum(facturas.mapped('amount')) - \
                    sum(devoluciones.mapped('amount'))

                tax_form_lines.append({
                    'sri_tax_form_id': f.id,
                    'campo': t,
                    'bruto': bruto,
                    'neto': neto,
                    'impuesto': impuesto,
                })

            # Calculamos los impuestos en compras.
            out_inv = f.sri_tax_form_set_id.mapped('out_invoice_ids')
            out_ref = f.sri_tax_form_set_id.mapped('out_refund_ids')
            sale_inv = out_inv + out_ref

            taxes = sale_inv.mapped('sri_tax_line_ids').filtered(
                lambda r: r.formulario == f.formulario)

            for t in set(taxes.mapped('campo')):
                facturas = out_inv.mapped('sri_tax_line_ids').filtered(
                    lambda r: r.campo == t)
                devoluciones = out_ref.mapped(
                    'sri_tax_line_ids').filtered(lambda r: r.campo == t)

                bruto = sum(facturas.mapped('base'))
                neto = bruto - sum(devoluciones.mapped('base'))
                impuesto = sum(facturas.mapped('amount')) - \
                    sum(devoluciones.mapped('amount'))

                tax_form_lines.append({
                    'sri_tax_form_id': f.id,
                    'campo': t,
                    'bruto': bruto,
                    'neto': neto,
                    'impuesto': impuesto,
                })

            for line in tax_form_lines:
                self.env['l10n_ec_sri.tax.form.line'].create(line)
Esempio n. 12
0
class rbs_documento_mercantil_vehiculo(models.Model):
    _name = "rbs.documento.mercantil.vehiculo"
    _description = "Documento Mercantil Vehiculo"
    #name= field.Char('Nombre')
    anio_id = fields.Many2one('rbs.archivo.anio', string='Año', required=True)
    libro_id = fields.Many2one('rbs.archivo.libro',
                               string='Libro',
                               required=True)
    tomo_id = fields.Many2one("rbs.archivo.tomo", string='Tomo', required=True)

    persona_id = fields.Many2one('rbs.persona', string='Compareciente(n)')
    persona_nombres = fields.Char(string='Nombres del Compareciente')
    persona_apellidos = fields.Char(string='Apellidos del Compareciente')
    persona_cedula = fields.Char(string='Cedula del Compareciente')
    persona_representante = fields.Char(
        string='Representante del Compareciente')
    persona_razonSocial = fields.Char(string='Razon Social del Compareciente')

    foleo_desde = fields.Char(string='Desde', required=True)
    foleo_hasta = fields.Char(string='Hasta', required=True)

    tipo_compareciente_id = fields.Many2one('rbs.tipo.compareciente.v',
                                            string='Tipo de Compareciente')
    tipo_contrato_id = fields.Many2one('rbs.tipo.contrato',
                                       string='Tipo de Contrato',
                                       required=True)

    fecha_inscripcion = fields.Datetime(string='Fecha de Inscripcion',
                                        required=True)
    numero_inscripcion = fields.Char(string='Numero de Inscripcion',
                                     required=True)
    fecha_cancelacion = fields.Datetime(string='Fecha de Cancelacion')
    tipo_bien_id = fields.Many2one('rbs.tipo.bien',
                                   string='Tipo de Bien',
                                   required=True)
    chasis = fields.Char(string='Chasis')
    motor = fields.Char(string='Motor')
    marca = fields.Char(string='Marca')
    modelo = fields.Char(string='Modelo')
    anio_fabricacion = fields.Char(string='Año de Fabricacion')
    placa = fields.Char(string='Placa')
    ultima_modificacion = fields.Char(string='Ultima Modificacion')
    nombre_institucion = fields.Char(string='Nombre de la Institucion',
                                     required=True)
    canton_notaria = fields.Char(string='Canton de Notaria', required=True)
    fecha_escritura_contrato = fields.Datetime(string='Fecha de Escritura',
                                               required=True)

    estado = fields.Selection([
        ('VIGENTE', 'VIGENTE'),
        ('NOVIGENTE', 'NO VIGENTE'),
    ],
                              string='Estado',
                              required=True)
    #filedata = fields.Binary('Archivo',filters='*.pdf')
    #filename = fields.Char('Nombre de archivo', default="Archivo.pdf")
    filedata_id = fields.Many2one('rbs.archivo.pdf')
    filedata = fields.Binary(related='filedata_id.filedata', filters='*.pdf')
    esPesado = fields.Boolean(related='filedata_id.esPesado',
                              string='¿Es Pesado?')
    rutaFTP = fields.Char(related='filedata_id.rutaFTP',
                          string='Escriba la ruta del Archivo')

    identificacion_unica = fields.Char(
        string='Identificador Unico Sistema Remoto',
        compute='_compute_upper',
        store=True)
    ubicacion_dato_id = fields.Many2one('rbs.ubicacion.dato',
                                        string='Ubicacion del Dato',
                                        required=True)

    factura_ids = fields.One2many('account.invoice',
                                  'vehiculo_id',
                                  string='Factura')

    def _getUltimoAnio(self, cr, uid, context=None):
        acta_id = self.pool.get("rbs.documento.mercantil.vehiculo").search(
            cr, uid, [], limit=1, order='id desc')
        anio = self.pool.get("rbs.documento.mercantil.vehiculo").browse(
            cr, uid, acta_id, context=None).anio_id.id
        return anio

    def _getUltimoLibro(self, cr, uid, context=None):
        acta_id = self.pool.get("rbs.documento.mercantil.vehiculo").search(
            cr, uid, [], limit=1, order='id desc')
        libro = self.pool.get("rbs.documento.mercantil.vehiculo").browse(
            cr, uid, acta_id, context=None).libro_id.id
        return libro

    def _getUltimoTomo(self, cr, uid, context=None):
        acta_id = self.pool.get("rbs.documento.mercantil.vehiculo").search(
            cr, uid, [], limit=1, order='id desc')
        tomo = self.pool.get("rbs.documento.mercantil.vehiculo").browse(
            cr, uid, acta_id, context=None).tomo_id.id
        return tomo

    def _create_pdf(self, cr, uid, context=None):
        return self.pool.get("rbs.archivo.pdf").create(cr,
                                                       uid, {},
                                                       context=None)

    _defaults = {
        'anio_id': _getUltimoAnio,
        'libro_id': _getUltimoLibro,
        'tomo_id': _getUltimoTomo,
        'filedata_id': _create_pdf,
    }

    def open_ui(self, cr, uid, ids, context=None):
        data = self.browse(cr, uid, ids[0], context=context)
        context = dict(context or {})
        #context['active_id'] = data.ids[0]
        return {
            'type': 'ir.actions.act_url',
            'url': '/registro_mercantil/web/?binary=' + str(ids[0]) +
            '&tipo=vehiculo',
            'target': 'current',
        }

    _rec_name = 'numero_inscripcion'

    @api.depends('ubicacion_dato_id', 'persona_cedula', 'numero_inscripcion')
    def _compute_upper(self):
        for rec in self:
            try:
                rec.identificacion_unica = '03' + rec.ubicacion_dato_id.name + rec.persona_cedula + rec.numero_inscripcion
            except:
                try:
                    rec.identificacion_unica = '03' + rec.ubicacion_dato_id.name + rec.numero_inscripcion + rec.numero_inscripcion
                except:
                    pass

    def on_change_anio_id(self, cr, uid, ids, anio_id, context=None):
        result = {}
        if (self._getUltimoAnio(cr, uid, context=None) != anio_id):
            result['libro_id'] = 0
        return {
            'value': result,
        }

    def on_change_libro_id(self, cr, uid, ids, libro_id, context=None):
        result = {}
        if (self._getUltimoLibro(cr, uid, context=None) != libro_id):
            result['tomo_id'] = 0
        return {
            'value': result,
        }

    def codigoascii(self, text):
        return unicode(text).encode('utf-8')

    def onchange_persona_id(self, cr, uid, ids, persona_id, context=None):
        persona_id = self.pool.get('rbs.persona').search(
            cr, uid, [
                ('id', '=', persona_id),
            ])
        persona = self.pool.get('rbs.persona').browse(cr,
                                                      uid,
                                                      persona_id,
                                                      context=None)
        result = {}

        try:

            if persona:
                #raise osv.except_osv('Esto es un Mesaje!',establecimiento)
                try:
                    if persona.persona_nombres:
                        result['persona_nombres'] = self.codigoascii(
                            persona.persona_nombres)
                except:
                    pass

                try:
                    if persona.persona_apellidos:
                        result['persona_apellidos'] = self.codigoascii(
                            persona.persona_apellidos)
                except:
                    pass
                try:
                    if persona.name:
                        result['persona_cedula'] = str(persona.name)
                except:
                    pass
                try:
                    if persona.persona_representante:
                        result['persona_representante'] = self.codigoascii(
                            persona.persona_representante)
                except:
                    pass
                try:
                    if persona.persona_razonSocial:
                        result['persona_razonSocial'] = self.codigoascii(
                            persona.persona_razonSocial)
                except:
                    pass
        except:
            pass

        return {
            'value': result,
        }

    def onchange_inscripcion(self,
                             cr,
                             uid,
                             ids,
                             inscripcion_num,
                             libro_id,
                             context=None):
        vehiculo_id = self.pool.get('rbs.documento.mercantil.vehiculo').search(
            cr, uid, [('numero_inscripcion', '=', inscripcion_num),
                      ('libro_id', '=', libro_id)])
        vehiculo = self.pool.get('rbs.documento.mercantil.vehiculo').browse(
            cr, uid, vehiculo_id, context=None)
        result = {}

        try:

            if vehiculo:
                vehiculo = vehiculo[0]
                #raise osv.except_osv('Esto es un Mesaje!',establecimiento)
                try:
                    if vehiculo.fecha_inscripcion:
                        result['fecha_inscripcion'] = str(
                            vehiculo.fecha_inscripcion)

                except:
                    pass
                try:
                    if vehiculo.anio_id:
                        result['anio_id'] = vehiculo.anio_id.id

                except:
                    pass
                try:
                    if vehiculo.libro_id:
                        result['libro_id'] = vehiculo.libro_id.id

                except:
                    pass
                try:
                    if vehiculo.tomo_id:
                        result['tomo_id'] = vehiculo.tomo_id.id

                except:
                    pass
                try:
                    if vehiculo.tipo_contrato_id:
                        result[
                            'tipo_contrato_id'] = vehiculo.tipo_contrato_id.id

                except:
                    pass

                try:
                    if vehiculo.fecha_cancelacion:
                        result['fecha_cancelacion'] = str(
                            vehiculo.fecha_cancelacion)

                except:
                    pass
                try:
                    if vehiculo.tipo_bien_id:
                        result['tipo_bien_id'] = vehiculo.tipo_bien_id

                except:
                    pass

                try:
                    if vehiculo.chasis:
                        result['chasis'] = self.codigoascii(vehiculo.chasis)

                except:
                    pass

                try:
                    if vehiculo.motor:
                        result['motor'] = self.codigoascii(vehiculo.motor)

                except:
                    pass

                try:
                    if vehiculo.marca:
                        result['marca'] = self.codigoascii(vehiculo.marca)

                except:
                    pass

                try:
                    if vehiculo.modelo:
                        result['modelo'] = self.codigoascii(vehiculo.modelo)

                except:
                    pass

                try:
                    if vehiculo.anio_fabricacion:
                        result['anio_fabricacion'] = str(
                            vehiculo.anio_fabricacion)

                except:
                    pass

                try:
                    if vehiculo.placa:
                        result['placa'] = self.codigoascii(vehiculo.placa)

                except:
                    pass

                try:
                    if vehiculo.ultima_modificacion:
                        result['ultima_modificacion'] = str(
                            vehiculo.ultima_modificacion)

                except:
                    pass
                try:
                    if vehiculo.nombre_institucion:
                        result['nombre_institucion'] = self.codigoascii(
                            vehiculo.nombre_institucion)

                except:
                    pass
                try:
                    if vehiculo.canton_notaria:
                        result['canton_notaria'] = self.codigoascii(
                            vehiculo.canton_notaria)

                except:
                    pass
                try:
                    if vehiculo.fecha_escritura_contrato:
                        result['fecha_escritura_contrato'] = str(
                            vehiculo.fecha_escritura_contrato)

                except:
                    pass

                try:
                    if vehiculo.estado:
                        result['estado'] = vehiculo.estado

                except:
                    pass

                try:
                    if vehiculo.filedata_id:
                        result['filedata_id'] = vehiculo.filedata_id.id

                except:
                    pass

                try:
                    if vehiculo.ubicacion_dato_id:
                        result[
                            'ubicacion_dato_id'] = vehiculo.ubicacion_dato_id.id

                except:
                    pass

            if not vehiculo:
                result['filedata_id'] = self._create_pdf(cr, uid, context=None)
        except:
            pass

        return {
            'value': result,
        }
Esempio n. 13
0
class DermanordImport(models.TransientModel):
    _name = 'sale.dermanord.import.wizard'

    order_file = fields.Binary(string='Order file')
    order_url = fields.Char(string='Url')
    mime = fields.Selection([
        ('url', 'url'), ('text', 'text/plain'), ('pdf', 'application/pdf'),
        ('xlsx',
         'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'),
        ('xls', 'application/vnd.ms-excel'),
        ('xlm', 'application/vnd.ms-office')
    ])
    import_type = fields.Selection([('bangerhead', 'Bangerhead AB'),
                                    ('tailwide', 'Tailwide AB'),
                                    ('birka', u'BIRKA CRUISES AB'),
                                    ('nordicfeel', 'Nordic Web Trading AB'),
                                    ('isaksen', 'Isaksen & CO AS'),
                                    ('lyko', 'Lyko Online AB'),
                                    ('finamig', 'Fina mig i Hedemora AB'),
                                    ('skincity', 'Skincity Sweden'),
                                    ('skincity_xl', 'Skincity Sweden')])
    info = fields.Text(string='Info')
    tmp_file = fields.Char(string='Tmp File')
    file_name = fields.Char(string='File Name')

    @api.one
    @api.onchange('order_file')
    def check_file(self):
        self.mime = None
        self.import_type = None
        self.info = None
        self.tmp_file = None

        if self.order_file:
            fd, self.tmp_file = tempfile.mkstemp()
            os.write(fd, base64.b64decode(self.order_file))
            os.close(fd)

            try:
                pop = Popen(['file', '-b', '--mime', self.tmp_file],
                            shell=False,
                            stdout=PIPE)
                (result, _) = pop.communicate()
                read_mime = result.split(';')[0]
            except OSError, e:
                _logger.warning(
                    "Failed attempt to execute file. This program is necessary to check MIME type of %s",
                    fname)
                _logger.debug("Trace of the failed MIME file attempt.",
                              exc_info=True)
                raise Warning(e)

            self.mime = self.get_selection_text('mime', read_mime)

            if self.mime == 'pdf':
                try:
                    pop = Popen([
                        'pdftotext', '-enc', 'UTF-8', '-nopgbrk',
                        self.tmp_file, '-'
                    ],
                                shell=False,
                                stdout=PIPE)
                    (content, _) = pop.communicate()
                except OSError, e:
                    _logger.warning(
                        "Failed attempt to execute pdftotext. This program is necessary to index the file %s of MIME type %s. Detailed error available at DEBUG level.",
                        self.tmp_file, self.mime)
                    _logger.debug("Trace of the failed file indexing attempt.",
                                  exc_info=True)
                    raise Warning(e)
                lines = content.splitlines()
                if len(lines) >= 19 and lines[19] == 'Fina mig i Hedemora AB':
                    self.import_type = 'finamig'
                elif 'SKINCITY SWEDEN AB' in content:
                    self.import_type = 'skincity'
            elif self.mime in ['xlsx', 'xls', 'xlm']:
                try:
                    wb = open_workbook(file_contents=base64.b64decode(
                        self.order_file)).sheet_by_index(0)
                except XLRDError, e:
                    raise Warning(e)
Esempio n. 14
0
class Importimage(models.Model):
    _name = 'image_recognizer.images'
    name = fields.Char(string="Title", required=True)
    imager = fields.Binary()
    datas = fields.Char()
    description = fields.Char()
    image_filename = fields.Char("DONDOLO")
    probability = fields.Float(string="Probability", compute='_probability')
    proba = fields.Float()

    @api.depends('probability')
    def _probability(self):
        for r in self:
            if not r.probability:
                r.probability = 0.0
            else:
                r.proba = 100.0 * r.probability

    @api.onchange('imager')
    def _onchange_imager(self):
        datas = self.imager

        if datas:
            script_dir = os.path.dirname(
                __file__)  # <-- absolute dir the script is in
            rel_path = "files/imagetorecognize.jpg"
            abs_file_path = os.path.join(script_dir, rel_path)
            imagesa = open(abs_file_path, "r+")
            imagesa.write(base64.b64decode(datas))
            imagesa.close()

        class NodeLookup(object):
            def __init__(self, label_lookup_path=None, uid_lookup_path=None):
                if not label_lookup_path:
                    label_lookup_path = os.path.join(
                        FLAGS.model_dir,
                        'imagenet_2012_challenge_label_map_proto.pbtxt')
                if not uid_lookup_path:
                    uid_lookup_path = os.path.join(
                        FLAGS.model_dir,
                        'imagenet_synset_to_human_label_map.txt')
                self.node_lookup = self.load(label_lookup_path,
                                             uid_lookup_path)

            def load(self, label_lookup_path, uid_lookup_path):
                """Loads a human readable English name for each softmax node.

                Args:
                  label_lookup_path: string UID to integer node ID.
                  uid_lookup_path: string UID to human-readable string.

                Returns:
                  dict from integer node ID to human-readable string.
                """
                if not tf.gfile.Exists(uid_lookup_path):
                    tf.logging.fatal('File does not exist %s', uid_lookup_path)
                if not tf.gfile.Exists(label_lookup_path):
                    tf.logging.fatal('File does not exist %s',
                                     label_lookup_path)

                # Loads mapping from string UID to human-readable string
                proto_as_ascii_lines = tf.gfile.GFile(
                    uid_lookup_path).readlines()
                uid_to_human = {}
                p = re.compile(r'[n\d]*[ \S,]*')
                for line in proto_as_ascii_lines:
                    parsed_items = p.findall(line)
                    uid = parsed_items[0]
                    human_string = parsed_items[2]
                    uid_to_human[uid] = human_string

                # Loads mapping from string UID to integer node ID.
                node_id_to_uid = {}
                proto_as_ascii = tf.gfile.GFile(label_lookup_path).readlines()
                for line in proto_as_ascii:
                    if line.startswith('  target_class:'):
                        target_class = int(line.split(': ')[1])
                    if line.startswith('  target_class_string:'):
                        target_class_string = line.split(': ')[1]
                        node_id_to_uid[target_class] = target_class_string[
                            1:-2]

                # Loads the final mapping of integer node ID to human-readable string
                node_id_to_name = {}
                for key, val in node_id_to_uid.items():
                    if val not in uid_to_human:
                        tf.logging.fatal('Failed to locate: %s', val)
                    name = uid_to_human[val]
                    node_id_to_name[key] = name

                return node_id_to_name

            def id_to_string(self, node_id):
                if node_id not in self.node_lookup:
                    return ''
                return self.node_lookup[node_id]

        def create_graph():
            """Creates a graph from saved GraphDef file and returns a saver."""
            # Creates graph from saved graph_def.pb.
            with tf.gfile.FastGFile(
                    os.path.join(FLAGS.model_dir,
                                 'tensorflow_inception_graph.pb'), 'rb') as f:
                graph_def = tf.GraphDef()
                graph_def.ParseFromString(f.read())
                _ = tf.import_graph_def(graph_def, name='')

        def run_inference_on_image(image):
            """Runs inference on an image.

            Args:
              image: Image file name.

            Returns:
              Nothing
            """
            if not tf.gfile.Exists(image):
                tf.logging.fatal('File does not exist %s', image)
            image_data = tf.gfile.FastGFile(image, 'rb').read()

            # Creates graph from saved GraphDef.
            create_graph()

            with tf.Session() as sess:
                # Some useful tensors:
                # 'softmax:0': A tensor containing the normalized prediction across
                #   1000 labels.
                # 'pool_3:0': A tensor containing the next-to-last layer containing 2048
                #   float description of the image.
                # 'DecodeJpeg/contents:0': A tensor containing a string providing JPEG
                #   encoding of the image.
                # Runs the softmax tensor by feeding the image_data as input to the graph.
                softmax_tensor = sess.graph.get_tensor_by_name('softmax:0')
                predictions = sess.run(softmax_tensor,
                                       {'DecodeJpeg/contents:0': image_data})
                predictions = np.squeeze(predictions)

                # Creates node ID --> English string lookup.
                node_lookup = NodeLookup()

                top_k = predictions.argsort(
                )[-FLAGS.num_top_predictions:][::-1]
                for node_id in top_k:
                    human_string = node_lookup.id_to_string(node_id)
                    score = predictions[node_id] * 100
                    descript = human_string

            return descript, score

        parser = argparse.ArgumentParser()
        # classify_image_graph_def.pb:
        #   Binary representation of the GraphDef protocol buffer.
        # imagenet_synset_to_human_label_map.txt:
        #   Map from synset ID to a human readable string.
        # imagenet_2012_challenge_label_map_proto.pbtxt:
        #   Text representation of a protocol buffer mapping a label to synset ID.
        parser.add_argument('--model_dir',
                            type=str,
                            default=os.path.join(os.path.dirname(__file__),
                                                 'files'),
                            help="""\
          Path to classify_image_graph_def.pb,
          imagenet_synset_to_human_label_map.txt, and
          imagenet_2012_challenge_label_map_proto.pbtxt.\
          """)
        parser.add_argument('--image_file',
                            type=str,
                            default='',
                            help='Absolute path to image file.')
        parser.add_argument('--num_top_predictions',
                            type=int,
                            default=1,
                            help='Display this many predictions.')
        FLAGS, unparsed = parser.parse_known_args()
        image = (FLAGS.image_file if FLAGS.image_file else os.path.join(
            FLAGS.model_dir, "imagetorecognize.jpg"))

        if datas:
            self.name, self.probability = run_inference_on_image(image)
class PrintInvoiceSummary(models.TransientModel):
    _name = "print.invoice.summary"

    @api.model
    def _get_from_date(self):
        company = self.env.user.company_id
        current_date = datetime.date.today()
        from_date = company.compute_fiscalyear_dates(current_date)['date_from']
        return from_date

    from_date = fields.Date(string='From Date', default=_get_from_date)
    to_date = fields.Date(string='To Date', default=datetime.date.today())
    invoice_summary_file = fields.Binary('Invoice Summary Report')
    file_name = fields.Char('File Name')
    invoice_report_printed = fields.Boolean('Invoice Report Printed')
    invoice_status = fields.Selection([('all', 'All'), ('paid', 'Paid'),
                                       ('un_paid', 'Unpaid')],
                                      string='Invoice Status')

    @api.multi
    def action_print_invoice_summary(self):
        workbook = xlwt.Workbook()
        amount_tot = 0
        column_heading_style = easyxf('font:height 200;font:bold True;')
        worksheet = workbook.add_sheet('Invoice Summary')
        worksheet.write(
            2, 3, self.env.user.company_id.name,
            easyxf('font:height 200;font:bold True;align: horiz center;'))
        worksheet.write(
            4, 2, self.from_date,
            easyxf('font:height 200;font:bold True;align: horiz center;'))
        worksheet.write(
            4, 3, 'To',
            easyxf('font:height 200;font:bold True;align: horiz center;'))
        worksheet.write(
            4, 4, self.to_date,
            easyxf('font:height 200;font:bold True;align: horiz center;'))
        worksheet.write(6, 0, _('Invoice Number'), column_heading_style)
        worksheet.write(6, 1, _('Customer'), column_heading_style)
        worksheet.write(6, 2, _('Invoice Date'), column_heading_style)
        worksheet.write(6, 3, _('Invoice Amount'), column_heading_style)
        worksheet.write(6, 4, _('Invoice Currency'), column_heading_style)
        worksheet.write(
            6, 5,
            _('Amount in Company Currency (' +
              str(self.env.user.company_id.currency_id.name) + ')'),
            column_heading_style)

        worksheet.col(0).width = 5000
        worksheet.col(1).width = 5000
        worksheet.col(2).width = 5000
        worksheet.col(3).width = 5000
        worksheet.col(4).width = 5000
        worksheet.col(5).width = 8000

        worksheet2 = workbook.add_sheet('Customer wise Invoice Summary')
        worksheet2.write(1, 0, _('Customer'), column_heading_style)
        worksheet2.write(1, 1, _('Paid Amount'), column_heading_style)
        worksheet2.write(
            1, 2, _('Invoice Currency'),
            easyxf('font:height 200;font:bold True;align: horiz left;'))
        worksheet2.write(
            1, 3,
            _('Amount in Company Currency (' +
              str(self.env.user.company_id.currency_id.name) + ')'),
            easyxf('font:height 200;font:bold True;align: horiz left;'))
        worksheet2.col(0).width = 5000
        worksheet2.col(1).width = 5000
        worksheet2.col(2).width = 4000
        worksheet2.col(3).width = 8000

        row = 7
        customer_row = 2
        for wizard in self:
            customer_payment_data = {}
            heading = 'Invoice Summary Report'
            worksheet.write_merge(
                0, 0, 0, 5, heading,
                easyxf(
                    'font:height 210; align: horiz center;pattern: pattern solid, fore_color black; font: color white; font:bold True;'
                    "borders: top thin,bottom thin"))
            heading = 'Customer wise Invoice Summary'
            worksheet2.write_merge(
                0, 0, 0, 3, heading,
                easyxf(
                    'font:height 200; align: horiz center;pattern: pattern solid, fore_color black; font: color white; font:bold True;'
                    "borders: top thin,bottom thin"))
            if wizard.invoice_status == 'all':
                invoice_objs = self.env['account.invoice'].search([
                    ('date_invoice', '>=', wizard.from_date),
                    ('date_invoice', '<=', wizard.to_date),
                    ('type', '=', 'out_invoice'),
                    ('state', 'not in', ['draft', 'cancel'])
                ])
            elif wizard.invoice_status == 'paid':
                invoice_objs = self.env['account.invoice'].search([
                    ('date_invoice', '>=', wizard.from_date),
                    ('date_invoice', '<=', wizard.to_date),
                    ('state', '=', 'paid'), ('type', '=', 'out_invoice')
                ])
            else:
                invoice_objs = self.env['account.invoice'].search([
                    ('date_invoice', '>=', wizard.from_date),
                    ('date_invoice', '<=', wizard.to_date),
                    ('state', '=', 'open'), ('type', '=', 'out_invoice')
                ])
            for invoice in invoice_objs:
                amount = 0
                for journal_item in invoice.move_id.line_id:
                    amount += journal_item.debit
                worksheet.write(row, 0, invoice.number)
                worksheet.write(row, 1, invoice.partner_id.name)
                worksheet.write(row, 2, invoice.date_invoice)
                worksheet.write(row, 3, invoice.amount_total)
                worksheet.write(row, 4, invoice.currency_id.symbol)
                worksheet.write(row, 5, amount)
                amount_tot += amount
                row += 1
                key = str(invoice.partner_id.name) + '_' + str(
                    invoice.currency_id.name)
                if key not in customer_payment_data:
                    customer_payment_data.update({
                        key: {
                            'amount_total': invoice.amount_total,
                            'amount_company_currency': amount
                        }
                    })
                else:
                    paid_amount_data = customer_payment_data[key][
                        'amount_total'] + invoice.amount_total
                    amount_currency = customer_payment_data[key][
                        'amount_company_currency'] + amount
                    customer_payment_data.update({
                        key: {
                            'amount_total': paid_amount_data,
                            'amount_company_currency': amount_currency
                        }
                    })
            worksheet.write(row + 2, 5, amount_tot, column_heading_style)

            for customer in customer_payment_data:
                worksheet2.write(customer_row, 0, customer.split('_')[0])
                worksheet2.write(
                    customer_row, 1,
                    customer_payment_data[customer]['amount_total'])
                worksheet2.write(customer_row, 2, customer.split('_')[1])
                worksheet2.write(
                    customer_row, 3,
                    customer_payment_data[customer]['amount_company_currency'])
                customer_row += 1

            fp = StringIO()
            workbook.save(fp)
            excel_file = base64.encodestring(fp.getvalue())
            wizard.invoice_summary_file = excel_file
            wizard.file_name = 'Invoice Summary Report.xls'
            wizard.invoice_report_printed = True
            fp.close()
            return {
                'view_mode': 'form',
                'res_id': wizard.id,
                'res_model': 'print.invoice.summary',
                'view_type': 'form',
                'type': 'ir.actions.act_window',
                'context': self.env.context,
                'target': 'new',
            }
Esempio n. 16
0
class SaasPortalPlan(models.Model):
    _name = 'saas_portal.plan'

    name = fields.Char('Plan', required=True)
    summary = fields.Char('Summary')
    template_id = fields.Many2one('saas_portal.database', 'Template')
    demo = fields.Boolean('Install Demo Data')

    def _get_default_lang(self):
        return self.env.lang

    def _default_tz(self):
        return self.env.user.tz

    lang = fields.Selection(scan_languages(),
                            'Language',
                            default=_get_default_lang)
    tz = fields.Selection(_tz_get, 'TimeZone', default=_default_tz)
    sequence = fields.Integer('Sequence')
    state = fields.Selection([('draft', 'Draft'), ('confirmed', 'Confirmed')],
                             'State',
                             compute='_get_state',
                             store=True)
    expiration = fields.Integer('Expiration (hours)',
                                help='time to delete database. Use for demo')
    _order = 'sequence'

    dbname_template = fields.Char(
        'DB Names',
        help=
        'Template for db name. Use %i for numbering. Ignore if you use manually created db names',
        placeholder='crm-%i.odoo.com')
    server_id = fields.Many2one('saas_portal.server',
                                string='SaaS Server',
                                help='User this saas server or choose random')

    website_description = fields.Text('Website description')
    logo = fields.Binary('Logo')

    @api.one
    @api.depends('template_id.state')
    def _get_state(self):
        if self.template_id.state == 'template':
            self.state = 'confirmed'
        else:
            self.state = 'draft'

    @api.one
    def _new_database_vals(self, vals):
        if self.expiration:
            now = datetime.now()
            delta = timedelta(hours=self.expiration)
            vals['expiration_datetime'] = (
                now + delta).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
        return vals

    @api.multi
    def create_new_database(self,
                            dbname=None,
                            client_id=None,
                            partner_id=None,
                            user_id=None):
        self.ensure_one()
        server = self.server_id
        if not server:
            server = self.env['saas_portal.server'].get_saas_server()

        server.action_sync_server()

        vals = {
            'name': dbname or self.generate_dbname()[0],
            'server_id': server.id,
            'plan_id': self.id,
            'partner_id': partner_id,
        }
        client = None
        if client_id:
            vals['client_id'] = client_id
            client = self.env['saas_portal.client'].search([('client_id', '=',
                                                             client_id)])

        vals = self._new_database_vals(vals)[0]

        if client:
            client.write(vals)
        else:
            client = self.env['saas_portal.client'].create(vals)
        client_id = client.client_id

        scheme = server.request_scheme
        port = server.request_port
        if user_id:
            owner_user = self.env['res.users'].browse(user_id)
        else:
            owner_user = self.env.user
        owner_user_data = {
            'user_id': owner_user.id,
            'login': owner_user.login,
            'name': owner_user.name,
            'email': owner_user.email,
        }
        state = {
            'd': client.name,
            'e': client.expiration_datetime,
            'r': '%s://%s:%s/web' % (scheme, client.name, port),
            'owner_user': owner_user_data,
        }
        if self.template_id:
            state.update({'db_template': self.template_id.name})
        scope = ['userinfo', 'force_login', 'trial', 'skiptheuse']
        url = server._request_server(
            path='/saas_server/new_database',
            scheme=scheme,
            port=port,
            state=state,
            client_id=client_id,
            scope=scope,
        )[0]
        res = requests.get(url,
                           verify=(self.server_id.request_scheme == 'https'
                                   and self.server_id.verify_ssl))
        if res.status_code != 200:
            # TODO /saas_server/new_database show more details here
            raise exceptions.Warning('Error %s' % res.status_code)
        data = simplejson.loads(res.text)
        params = {
            'state':
            data.get('state'),
            'access_token':
            client.oauth_application_id._get_access_token(user_id,
                                                          create=True),
        }
        url = '{url}?{params}'.format(url=data.get('url'),
                                      params=werkzeug.url_encode(params))

        return {'url': url, 'id': client.id, 'client_id': client_id}

    @api.one
    def generate_dbname(self, raise_error=True):
        if not self.dbname_template:
            if raise_error:
                raise exceptions.Warning(
                    _('Template for db name is not configured'))
            return ''
        sequence = self.env['ir.sequence'].get('saas_portal.plan')
        return self.dbname_template.replace('%i', sequence)

    @api.multi
    def create_template(self):
        assert len(self) == 1, 'This method is applied only for single record'
        # TODO use create_new_database function
        plan = self[0]
        state = {
            'd': plan.template_id.name,
            'demo': plan.demo and 1 or 0,
            'addons': [],
            'lang': plan.lang,
            'tz': plan.tz,
            'is_template_db': 1,
        }
        client_id = plan.template_id.client_id
        plan.template_id.server_id = plan.server_id
        params = plan.server_id._request_params(
            path='/saas_server/new_database', state=state,
            client_id=client_id)[0]

        access_token = plan.template_id.oauth_application_id._get_access_token(
            create=True)
        params.update({
            'token_type': 'Bearer',
            'access_token': access_token,
            'expires_in': 3600,
        })
        url = '{scheme}://{saas_server}:{port}{path}?{params}'.format(
            scheme=plan.server_id.request_scheme,
            saas_server=plan.server_id.name,
            port=plan.server_id.request_port,
            path='/saas_server/new_database',
            params=werkzeug.url_encode(params))
        res = requests.get(url,
                           verify=(plan.server_id.request_scheme == 'https'
                                   and plan.server_id.verify_ssl))
        if res.ok != True:
            msg = """Status Code - %s
Reason - %s
URL - %s
            """ % (res.status_code, res.reason, res.url)
            raise Warning(msg)
        return self.action_sync_server()

    @api.one
    def action_sync_server(self):
        self.server_id.action_sync_server()

    @api.multi
    def edit_template(self):
        return self[0].template_id.edit_database()

    @api.multi
    def upgrade_template(self):
        return self[0].template_id.upgrade_database()

    @api.multi
    def delete_template(self):
        res = self[0].template_id.delete_database()
        return res
Esempio n. 17
0
class event_track(models.Model):
    _name = "event.track"
    _description = 'Event Track'
    _order = 'priority, date'
    _inherit = [
        'mail.thread', 'ir.needaction_mixin', 'website.seo.metadata',
        'website.published.mixin'
    ]

    name = fields.Char('Title', required=True, translate=True)
    user_id = fields.Many2one('res.users',
                              'Responsible',
                              track_visibility='onchange',
                              default=lambda self: self.env.user)
    partner_id = fields.Many2one('res.partner', 'Proposed by')
    partner_name = fields.Char('Partner Name')
    partner_email = fields.Char('Partner Email')
    partner_phone = fields.Char('Partner Phone')
    partner_biography = fields.Html('Partner Biography')
    speaker_ids = fields.Many2many('res.partner', string='Speakers')
    tag_ids = fields.Many2many('event.track.tag', string='Tags')
    state = fields.Selection([('draft', 'Proposal'),
                              ('confirmed', 'Confirmed'),
                              ('announced', 'Announced'),
                              ('published', 'Published'),
                              ('refused', 'Refused'), ('cancel', 'Cancelled')],
                             'Status',
                             default='draft',
                             required=True,
                             copy=False,
                             track_visibility='onchange')
    description = fields.Html('Track Description', translate=True)
    date = fields.Datetime('Track Date')
    duration = fields.Float('Duration', digits=(16, 2), default=1.5)
    location_id = fields.Many2one('event.track.location', 'Room')
    event_id = fields.Many2one('event.event', 'Event', required=True)
    color = fields.Integer('Color Index')
    priority = fields.Selection([('0', 'Low'), ('1', 'Medium'), ('2', 'High'),
                                 ('3', 'Highest')],
                                'Priority',
                                required=True,
                                default='1')
    image = fields.Binary('Image',
                          compute='_compute_image',
                          store=True,
                          attachment=True)

    @api.one
    @api.depends('speaker_ids.image')
    def _compute_image(self):
        if self.speaker_ids:
            self.image = self.speaker_ids[0].image
        else:
            self.image = False

    @api.model
    def create(self, vals):
        res = super(event_track, self).create(vals)
        res.message_subscribe(res.speaker_ids.ids)
        res.event_id.message_post(body="""<h3>%(header)s</h3>
<ul>
    <li>%(proposed_by)s</li>
    <li>%(mail)s</li>
    <li>%(phone)s</li>
    <li>%(title)s</li>
    <li>%(speakers)s</li>
    <li>%(introduction)s</li>
</ul>""" % {
            'header':
            _('New Track Proposal'),
            'proposed_by':
            '<b>%s</b>: %s' %
            (_('Proposed By'),
             (res.partner_id.name or res.partner_name or res.partner_email)),
            'mail':
            '<b>%s</b>: %s' % (_('Mail'), '<a href="mailto:%s">%s</a>' %
                               (res.partner_email, res.partner_email)),
            'phone':
            '<b>%s</b>: %s' % (_('Phone'), res.partner_phone),
            'title':
            '<b>%s</b>: %s' % (_('Title'), res.name),
            'speakers':
            '<b>%s</b>: %s' % (_('Speakers Biography'), res.partner_biography),
            'introduction':
            '<b>%s</b>: %s' % (_('Talk Introduction'), res.description),
        },
                                  subtype='event.mt_event_track')
        return res

    @api.multi
    def write(self, vals):
        if vals.get('state') == 'published':
            vals.update({'website_published': True})
        res = super(event_track, self).write(vals)
        if vals.get('speaker_ids'):
            self.message_subscribe([
                speaker['id'] for speaker in self.resolve_2many_commands(
                    'speaker_ids', vals['speaker_ids'], ['id'])
            ])
        return res

    @api.multi
    @api.depends('name')
    def _website_url(self, field_name, arg):
        res = super(event_track, self)._website_url(field_name, arg)
        res.update({
            (track.id,
             '/event/%s/track/%s' % (slug(track.event_id), slug(track)))
            for track in self
        })
        return res

    def read_group(self,
                   cr,
                   uid,
                   domain,
                   fields,
                   groupby,
                   offset=0,
                   limit=None,
                   context=None,
                   orderby=False,
                   lazy=True):
        """ Override read_group to always display all states. """
        if groupby and groupby[0] == "state":
            # Default result structure
            # states = self._get_state_list(cr, uid, context=context)
            states = [('draft', 'Proposal'), ('confirmed', 'Confirmed'),
                      ('announced', 'Announced'), ('published', 'Published'),
                      ('cancel', 'Cancelled')]
            read_group_all_states = [{
                '__context': {
                    'group_by': groupby[1:]
                },
                '__domain':
                domain + [('state', '=', state_value)],
                'state':
                state_value,
                'state_count':
                0,
            } for state_value, state_name in states]
            # Get standard results
            read_group_res = super(event_track,
                                   self).read_group(cr,
                                                    uid,
                                                    domain,
                                                    fields,
                                                    groupby,
                                                    offset=offset,
                                                    limit=limit,
                                                    context=context,
                                                    orderby=orderby)
            # Update standard results with default results
            result = []
            for state_value, state_name in states:
                res = filter(lambda x: x['state'] == state_value,
                             read_group_res)
                if not res:
                    res = filter(lambda x: x['state'] == state_value,
                                 read_group_all_states)
                if state_value == 'cancel':
                    res[0]['__fold'] = True
                res[0]['state'] = [state_value, state_name]
                result.append(res[0])
            return result
        else:
            return super(event_track, self).read_group(cr,
                                                       uid,
                                                       domain,
                                                       fields,
                                                       groupby,
                                                       offset=offset,
                                                       limit=limit,
                                                       context=context,
                                                       orderby=orderby)

    def open_track_speakers_list(self, cr, uid, track_id, context=None):
        track_id = self.browse(cr, uid, track_id, context=context)
        return {
            'name':
            _('Speakers'),
            'domain':
            [('id', 'in', [partner.id for partner in track_id.speaker_ids])],
            'view_type':
            'form',
            'view_mode':
            'kanban,form',
            'res_model':
            'res.partner',
            'view_id':
            False,
            'type':
            'ir.actions.act_window',
        }
class ImportReview(models.TransientModel):
    """
    Browse through the import lines and allow the user to review and correct
    the results easily.
    """

    _name = 'import.letters.review'

    ##########################################################################
    #                                 FIELDS                                 #
    ##########################################################################
    progress = fields.Float(compute='_get_current_line', store=True)
    current_line_index = fields.Integer(default=0)
    count = fields.Integer(compute='_get_current_line', store=True)
    nb_lines = fields.Integer(compute='_get_current_line', store=True)
    current_line_id = fields.Many2one(
        'import.letter.line', 'Letter', compute='_get_current_line',
        store=True, readonly=True)
    postpone_import_id = fields.Many2one('import.letters.history')

    # Import line related fields
    state = fields.Selection(related='current_line_id.status', readonly=True)
    letter_image = fields.Binary(compute='_get_current_line')
    letter_file = fields.Binary(
        'Letter file', readonly=True, compute='_get_current_line')
    fname = fields.Char(related='current_line_id.letter_image.name')
    partner_id = fields.Many2one(related='current_line_id.partner_id')
    sponsorship_id = fields.Many2one('recurring.contract', 'Sponsorship')
    child_id = fields.Many2one(related='current_line_id.child_id')
    template_id = fields.Many2one(related='current_line_id.template_id')
    language_id = fields.Many2one(
        related='current_line_id.letter_language_id',
        order='translatable desc, id asc')
    is_encourager = fields.Boolean(related='current_line_id.is_encourager')
    mandatory_review = fields.Boolean(
        related='current_line_id.mandatory_review')
    physical_attachments = fields.Selection(
        related='current_line_id.physical_attachments')
    attachments_description = fields.Char(
        related='current_line_id.attachments_description')
    edit = fields.Boolean('Edit mode')

    ##########################################################################
    #                             FIELDS METHODS                             #
    ##########################################################################
    @api.one
    @api.depends('current_line_index')
    def _get_current_line(self):
        line_ids = self.env.context.get('line_ids')
        if line_ids:
            self.current_line_id = line_ids[self.current_line_index]
            self.nb_lines = len(line_ids)
            self.count = self.current_line_index + 1
            self.progress = (float(self.count) / self.nb_lines) * 100
            self.letter_image = self.with_context(
                bin_size=False).current_line_id.letter_image_preview
            self.letter_file = self.with_context(
                bin_size=False).current_line_id.letter_image.datas

    @api.onchange('sponsorship_id')
    def _get_partner_child(self):
        for wizard in self:
            child = wizard.sponsorship_id.child_id
            if child:
                wizard.child_id = child

    @api.onchange('partner_id')
    def _get_default_sponsorship(self):
        self.ensure_one()
        if self.partner_id:
            sponsorships = self.env['recurring.contract'].search([
                ('correspondant_id', '=', self.partner_id.id)
            ])
            if len(sponsorships) == 1:
                self.sponsorship_id = sponsorships

    ##########################################################################
    #                             VIEW CALLBACKS                             #
    ##########################################################################
    @api.multi
    def next(self):
        """ Load the next import line in the view. """
        self.ensure_one()
        if self.current_line_id.status not in ('ok', 'no_template'):
            raise Warning(
                _("Import is not valid"),
                _("Please review this import before going to the next."))
        self.write({
            'current_line_index': self.current_line_index + 1,
            'sponsorship_id': False,
        })
        self.current_line_id.reviewed = True

    @api.multi
    def finish(self):
        """ Return to import view. """
        self.ensure_one()
        import_history = self.current_line_id.import_id
        import_history.import_line_ids.check_status()
        return {
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form,tree',
            'res_model': import_history._name,
            'res_id': import_history.id,
            'context': self.env.context,
            'target': 'current',
        }

    @api.multi
    def postpone(self):
        """ Move the line in another import. """
        self.ensure_one()
        postpone_import = self.postpone_import_id
        current_import = self.current_line_id.import_id
        if not postpone_import:
            import_vals = current_import.get_correspondence_metadata()
            import_vals['import_completed'] = True
            postpone_import = self.env['import.letters.history'].create(
                import_vals)
            self.postpone_import_id = postpone_import
        self.current_line_id.import_id = postpone_import
        self.current_line_index += 1
class ImportLetterLine(models.Model):
    """
    This class is used for the validation of an export.
    """

    _name = 'import.letter.line'
    _inherit = 'import.letter.config'
    _order = 'reviewed,status'

    ##########################################################################
    #                                 FIELDS                                 #
    ##########################################################################

    sponsorship_id = fields.Many2one('recurring.contract',
                                     'Sponsorship',
                                     compute='_set_sponsorship_id')
    partner_id = fields.Many2one('res.partner', 'Partner')
    name = fields.Char(compute='_set_name')
    child_id = fields.Many2one('compassion.child', 'Child')
    letter_language_id = fields.Many2one('res.lang.compassion', 'Language')
    letter_image = fields.Many2one('ir.attachment')
    letter_image_preview = fields.Binary()
    import_id = fields.Many2one('import.letters.history')
    reviewed = fields.Boolean()
    status = fields.Selection(
        [("no_lang", _("Language not Detected")),
         ("no_sponsorship", _("Sponsorship not Found")),
         ("no_child_partner", _("Partner or Child not Found")),
         ("no_template", _("Template not Detected")), ("ok", _("OK"))],
        compute="check_status",
        store=True,
        readonly=True)
    original_text = fields.Text()

    ##########################################################################
    #                              ORM METHODS                               #
    ##########################################################################
    @api.model
    def create(self, vals):
        # Fetch default values in import configuration.
        create_vals = dict()
        if vals.get('import_id'):
            config = self.env['import.letters.history'].browse(
                vals['import_id'])
            create_vals = config.get_correspondence_metadata()
        create_vals.update(vals)
        return super(ImportLetterLine, self).create(create_vals)

    ##########################################################################
    #                             FIELDS METHODS                             #
    ##########################################################################

    @api.multi
    @api.depends('partner_id', 'child_id', 'sponsorship_id',
                 'letter_language_id', 'import_id.template_id')
    def check_status(self):
        """ At each change, check if all the fields are OK
        """
        default_template = self.env.ref('sbc_compassion.default_template')
        for line in self:
            valid_template = (line.template_id
                              and not (line.template_id == default_template !=
                                       line.import_id.template_id))
            if not line.sponsorship_id:
                if not (line.child_id and line.partner_id):
                    line.status = "no_child_partner"
                else:
                    line.status = "no_sponsorship"
            elif not valid_template:
                line.status = "no_template"
            elif len(line.letter_language_id) != 1:
                line.status = "no_lang"
            else:
                line.status = "ok"

    @api.multi
    @api.depends('partner_id', 'child_id')
    def _set_sponsorship_id(self):
        """ From the partner codega and the child code, find the record
        linking them together.
        At the same time, check if the child, the partner and the sponsorship
        are found.
        """
        for line in self:
            if line.partner_id and line.child_id:
                line.sponsorship_id = line.env['recurring.contract'].search(
                    [('child_id', '=', line.child_id.id),
                     ('correspondant_id', '=', line.partner_id.id)],
                    order='is_active desc, end_date desc',
                    limit=1)

    @api.multi
    @api.depends('partner_id', 'child_id')
    def _set_name(self):
        for line in self:
            if line.sponsorship_id:
                line.name = str(
                    line.sponsorship_id.partner_codega) + " - " + str(
                        line.child_id.local_id)

    @api.multi
    def get_letter_data(self):
        """ Create a list of dictionaries in order to create some lines inside
        import_letters_history.

        :returns: list to use in a write
        :rtype: list[dict{}]

        """
        letter_data = []
        for line in self:
            vals = line.get_correspondence_metadata()
            vals.update({
                'sponsorship_id': line.sponsorship_id.id,
                'letter_image': line.letter_image.datas,
                'original_language_id': line.letter_language_id.id,
                'direction': 'Supporter To Beneficiary',
                'original_text': line.original_text,
                'source': line.source,
            })
            if line.is_encourager:
                vals['relationship'] = 'Encourager'
            del vals['is_encourager']
            letter_data.append((0, 0, vals))
        return letter_data
class AccountPaymentBatchFile(models.TransientModel):
    _name = "account.payment.batch.file"

    partner_id = fields.Many2one('res.partner', string=_('Partner'))
    payment_method_id = fields.Many2one('account.payment.method',
                                        string='Payment Type')
    csv_file = fields.Binary(_('CSV File'))
    delimiter = fields.Char(_('Delimiter'), default=',')
    csv_name = fields.Char(_('CSV File name'))
    payment_slip_number = fields.Char(_('Payment Slip Number'))
    error = fields.Text(_('Error'))
    state = fields.Selection([('new', _('New')), ('error', _('Error'))],
                             string='State',
                             default='new')

    @api.multi
    def check_invoices(self):
        res = {}
        inv_obj = self.env['account.invoice']
        for row in self:
            ctx = {}
            file_ext = row.csv_name.split('.')
            if len(file_ext) > 1 and file_ext[1] not in [u'csv', u'CSV']:
                raise UserError(_('The file to import is not CSV'))
            elif len(file_ext) == 1:
                raise UserError(
                    _('The file to import does not have a valid extention'))
            data = base64.b64decode(row.csv_file)
            file_input = cStringIO.StringIO(data)
            file_input.seek(0)
            reader_info = []
            if row.delimiter:
                delimiter = str(row.delimiter)
            else:
                delimiter = ','
            reader = csv.reader(file_input,
                                delimiter=delimiter,
                                lineterminator='\r\n')
            try:
                reader_info.extend(reader)
            except Exception:
                raise Warning(_("Not a valid file!"))
            keys = reader_info[0]
            # check if keys exist
            not_found = [x for x in ['reference', 'amount'] if x not in keys]
            if not_found:
                raise Warning(
                    _('The file to be imported does not present the following columns: {}'
                      .format(', '.join(map(str, not_found)))))
            del reader_info[0]
            active_ids = []
            invoices = {}
            no_doc = ''
            for i in reader_info:
                try:
                    number = str(int(i[0].split('-')[2]))
                except ValueError:
                    number = str(i[0].split('-')[2])
                if not number.isdigit():
                    number = str(int(re.findall('\d+', number)[0]))
                inv_id = inv_obj.search([('secuencial', 'like', number),
                                         ('state', '=', 'open'),
                                         ('partner_id', '=', row.partner_id.id)
                                         ])
                if inv_id:
                    active_ids.append(inv_id.id)
                    invoices.update({inv_id.id: abs(float(i[1]))})
                else:
                    no_doc += _(
                        'The invoice with the number: {} is not in the system or is in a different state open\n'
                        .format(i[0]))
            ctx.update({
                'active_ids': active_ids,
                'active_model': 'account.invoice',
                'payment_slip_number': row.payment_slip_number,
                'payment_method_id': row.payment_method_id.id,
                'batch': True,
                'invoices': invoices,
                'errors': no_doc
            })
            vals_ok = {
                'name': _('Batch Payments from File'),
                'context': ctx,
                'view_type': 'form',
                'view_mode': 'form',
                'res_model': 'account.register.payments',
                'view_id': False,
                'res_id': False,
                'target': 'new',
                'type': 'ir.actions.act_window',
            }
            vals_err = {
                'name': _('Batch Payments from File'),
                'context': self.env.context,
                'view_type': 'form',
                'view_mode': 'form',
                'res_model': 'account.payment.batch.file',
                'view_id': False,
                'res_id': row.id,
                'target': 'new',
                'type': 'ir.actions.act_window',
            }
        if no_doc:
            row.error = no_doc
            row.state = 'error'
            res = vals_err
        else:
            res = vals_ok
        return res
Esempio n. 21
0
class HrOrientationChecklistConfig(models.Model):
    _name = 'hr.orientation.checklist.config'

    name = fields.Char(string='Name', required=True)

    web_url = fields.Char(string='Web URL', required=True)

    responsible_user_id = fields.Many2one(
        'res.users',
        string='Responsible User',
        required=False,
    )
    survey_id = fields.Many2one(
        'survey.survey',
        string='Mini Test',
        required=False,
        store=True,
    )
    note = fields.Text(
        string='Notes',
        store=True,
    )
    attachment_ids1 = fields.Binary(
        string='First Attachment',
        store=True,
    )
    attachment_ids2 = fields.Binary(
        string='Second Attachment',
        store=True,
    )
    attachment_ids3 = fields.Binary(
        string='Third Attachment',
        store=True,
    )

    @api.multi
    def action_start_survey(self):
        self.ensure_one()
        # create a response and link it to this applicant
        if not self.response_id:
            response = self.env['survey.user_input'].create({
                'survey_id':
                self.survey_id.id,
                'partner_id':
                self.partner_id.id
            })
            self.response_id = response.id
        else:
            response = self.response_id
        # grab the token of the response and start surveying
        return self.survey_id.with_context(
            survey_token=response.token).action_start_survey()

    @api.multi
    def action_print_survey(self):
        """ If response is available then print this response otherwise print survey form (print template of the survey) """
        self.ensure_one()
        if not self.response_id:
            return self.survey_id.action_print_survey()
        else:
            response = self.response_id
            return self.survey_id.with_context(
                survey_token=response.token).action_print_survey()
Esempio n. 22
0
class Slide(models.Model):
    """ This model represents actual presentations. Those must be one of four
    types:

     - Presentation
     - Document
     - Infographic
     - Video

    Slide has various statistics like view count, embed count, like, dislikes """

    _name = 'slide.slide'
    _inherit = ['mail.thread', 'website.seo.metadata', 'website.published.mixin']
    _description = 'Slides'

    _PROMOTIONAL_FIELDS = [
        '__last_update', 'name', 'image_thumb', 'image_medium', 'slide_type', 'total_views', 'category_id',
        'channel_id', 'description', 'tag_ids', 'write_date', 'create_date',
        'website_published', 'website_url', 'website_meta_title', 'website_meta_description', 'website_meta_keywords']

    _sql_constraints = [
        ('name_uniq', 'UNIQUE(channel_id, name)', 'The slide name must be unique within a channel')
    ]

    # description
    name = fields.Char('Title', required=True, translate=True)
    description = fields.Text('Description', translate=True)
    channel_id = fields.Many2one('slide.channel', string="Channel", required=True)
    category_id = fields.Many2one('slide.category', string="Category", domain="[('channel_id', '=', channel_id)]")
    tag_ids = fields.Many2many('slide.tag', 'rel_slide_tag', 'slide_id', 'tag_id', string='Tags')
    download_security = fields.Selection(
        [('none', 'No One'), ('user', 'Authentified Users Only'), ('public', 'Everyone')],
        string='Download Security',
        required=True, default='user')
    image = fields.Binary('Image', attachment=True)
    image_medium = fields.Binary('Medium', compute="_get_image", store=True, attachment=True)
    image_thumb = fields.Binary('Thumbnail', compute="_get_image", store=True, attachment=True)

    @api.depends('image')
    def _get_image(self):
        for record in self:
            if record.image:
                record.image_medium = image.crop_image(record.image, type='top', ratio=(4, 3), thumbnail_ratio=4)
                record.image_thumb = image.crop_image(record.image, type='top', ratio=(4, 3), thumbnail_ratio=6)
            else:
                record.image_medium = False
                record.iamge_thumb = False

    # content
    slide_type = fields.Selection([
        ('infographic', 'Infographic'),
        ('presentation', 'Presentation'),
        ('document', 'Document'),
        ('video', 'Video')],
        string='Type', required=True,
        default='document',
        help="Document type will be set automatically depending on file type, height and width.")
    index_content = fields.Text('Transcript')
    datas = fields.Binary('Content')
    url = fields.Char('Document URL', help="Youtube or Google Document URL")
    document_id = fields.Char('Document ID', help="Youtube or Google Document ID")
    mime_type = fields.Char('Mime-type')

    @api.onchange('url')
    def on_change_url(self):
        self.ensure_one()
        if self.url:
            res = self._parse_document_url(self.url)
            if res.get('error'):
                raise Warning(_('Could not fetch data from url. Document or access right not available:\n%s') % res['error'])
            values = res['values']
            if not values.get('document_id'):
                raise Warning(_('Please enter valid Youtube or Google Doc URL'))
            for key, value in values.iteritems():
                setattr(self, key, value)

    # website
    date_published = fields.Datetime('Publish Date')
    website_message_ids = fields.One2many(
        'mail.message', 'res_id',
        domain=lambda self: [('model', '=', self._name), ('message_type', '=', 'comment')],
        string='Website Messages', help="Website communication history")
    likes = fields.Integer('Likes')
    dislikes = fields.Integer('Dislikes')
    # views
    embedcount_ids = fields.One2many('slide.embed', 'slide_id', string="Embed Count")
    slide_views = fields.Integer('# of Website Views')
    embed_views = fields.Integer('# of Embedded Views')
    total_views = fields.Integer("Total # Views", default="0", compute='_compute_total', store=True)

    @api.depends('slide_views', 'embed_views')
    def _compute_total(self):
        for record in self:
            record.total_views = record.slide_views + record.embed_views

    embed_code = fields.Text('Embed Code', readonly=True, compute='_get_embed_code')

    def _get_embed_code(self):
        base_url = self.env['ir.config_parameter'].get_param('web.base.url')
        for record in self:
            if record.datas and (not record.document_id or record.slide_type in ['document', 'presentation']):
                record.embed_code = '<iframe src="%s/slides/embed/%s?page=1" allowFullScreen="true" height="%s" width="%s" frameborder="0"></iframe>' % (base_url, record.id, 315, 420)
            elif record.slide_type == 'video' and record.document_id:
                if not record.mime_type:
                    # embed youtube video
                    record.embed_code = '<iframe src="//www.youtube.com/embed/%s?theme=light" allowFullScreen="true" frameborder="0"></iframe>' % (record.document_id)
                else:
                    # embed google doc video
                    record.embed_code = '<embed src="https://video.google.com/get_player?ps=docs&partnerid=30&docid=%s" type="application/x-shockwave-flash"></embed>' % (record.document_id)
            else:
                record.embed_code = False

    @api.multi
    @api.depends('name')
    def _website_url(self, name, arg):
        res = super(Slide, self)._website_url(name, arg)
        base_url = self.env['ir.config_parameter'].get_param('web.base.url')
        #link_tracker is not in dependencies, so use it to shorten url only if installed.
        if self.env.registry.get('link.tracker'):
            LinkTracker = self.env['link.tracker']
            res.update({(slide.id, LinkTracker.sudo().create({'url': '%s/slides/slide/%s' % (base_url, slug(slide))}).short_url) for slide in self})
        else:
            res.update({(slide.id, '%s/slides/slide/%s' % (base_url, slug(slide))) for slide in self})
        return res


    @api.model
    def create(self, values):
        if not values.get('index_content'):
            values['index_content'] = values.get('description')
        if values.get('slide_type') == 'infographic' and not values.get('image'):
            values['image'] = values['datas']
        if values.get('website_published') and not values.get('date_published'):
            values['date_published'] = datetime.datetime.now()
        if values.get('url'):
            doc_data = self._parse_document_url(values['url']).get('values', dict())
            for key, value in doc_data.iteritems():
                values.setdefault(key, value)
        # Do not publish slide if user has not publisher rights
        if not self.user_has_groups('base.group_website_publisher'):
            values['website_published'] = False
        slide = super(Slide, self).create(values)
        slide.channel_id.message_subscribe_users()
        slide._post_publication()
        return slide

    @api.multi
    def write(self, values):
        if values.get('url'):
            doc_data = self._parse_document_url(values['url']).get('values', dict())
            for key, value in doc_data.iteritems():
                values.setdefault(key, value)
        res = super(Slide, self).write(values)
        if values.get('website_published'):
            self.date_published = datetime.datetime.now()
            self._post_publication()
        return res

    @api.model
    def check_field_access_rights(self, operation, fields):
        """ As per channel access configuration (visibility)
         - public  ==> no restriction on slides access
         - private ==> restrict all slides of channel based on access group defined on channel group_ids field
         - partial ==> show channel, but presentations based on groups means any user can see channel but not slide's content.
        For private: implement using record rule
        For partial: user can see channel, but channel gridview have slide detail so we have to implement
        partial field access mechanism for public user so he can have access of promotional field (name, view_count) of slides,
        but not all fields like data (actual pdf content)
        all fields should be accessible only for user group defined on channel group_ids
        """
        if self.env.uid == SUPERUSER_ID:
            return fields or list(self._fields)
        fields = super(Slide, self).check_field_access_rights(operation, fields)
        # still read not perform so we can not access self.channel_id
        if self.ids:
            self.env.cr.execute('SELECT DISTINCT channel_id FROM ' + self._table + ' WHERE id IN %s', (tuple(self.ids),))
            channel_ids = [x[0] for x in self.env.cr.fetchall()]
            channels = self.env['slide.channel'].sudo().browse(channel_ids)
            limited_access = all(channel.visibility == 'partial' and
                                 not len(channel.group_ids & self.env.user.groups_id)
                                 for channel in channels)
            if limited_access:
                fields = [field for field in fields if field in self._PROMOTIONAL_FIELDS]
        return fields

    def get_related_slides(self, limit=20):
        domain = [('website_published', '=', True), ('channel_id.visibility', '!=', 'private'), ('id', '!=', self.id)]
        if self.category_id:
            domain += [('category_id', '=', self.category_id.id)]
        for record in self.search(domain, limit=limit):
            yield record

    def get_most_viewed_slides(self, limit=20):
        for record in self.search([('website_published', '=', True), ('channel_id.visibility', '!=', 'private'), ('id', '!=', self.id)], limit=limit, order='total_views desc'):
            yield record

    def _post_publication(self):
        base_url = self.env['ir.config_parameter'].get_param('web.base.url')
        for slide in self.filtered(lambda slide: slide.website_published):
            publish_template = slide.channel_id.publish_template_id
            html_body = publish_template.with_context({'base_url': base_url}).render_template(publish_template.body_html, 'slide.slide', slide.id)
            slide.channel_id.message_post(body=html_body, subtype='website_slides.mt_channel_slide_published')
        return True

    @api.one
    def send_share_email(self, email):
        base_url = self.env['ir.config_parameter'].get_param('web.base.url')
        return self.channel_id.share_template_id.with_context({'email': email, 'base_url': base_url}).send_mail(self.id)

    # --------------------------------------------------
    # Parsing methods
    # --------------------------------------------------

    @api.model
    def _fetch_data(self, base_url, data, content_type=False):
        result = {'values': dict()}
        try:
            if data:
                base_url = base_url + '?%s' % urlencode(data)
            req = urllib2.Request(base_url)
            content = urllib2.urlopen(req).read()
            if content_type == 'json':
                result['values'] = json.loads(content)
            elif content_type in ('image', 'pdf'):
                result['values'] = content.encode('base64')
            else:
                result['values'] = content
        except urllib2.HTTPError as e:
            result['error'] = e.read()
            e.close()
        except urllib2.URLError as e:
            result['error'] = e.reason
        return result

    def _find_document_data_from_url(self, url):
        expr = re.compile(r'^.*((youtu.be/)|(v/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*')
        arg = expr.match(url)
        document_id = arg and arg.group(7) or False
        if document_id:
            return ('youtube', document_id)

        expr = re.compile(r'(^https:\/\/docs.google.com|^https:\/\/drive.google.com).*\/d\/([^\/]*)')
        arg = expr.match(url)
        document_id = arg and arg.group(2) or False
        if document_id:
            return ('google', document_id)

        return (None, False)

    def _parse_document_url(self, url, only_preview_fields=False):
        document_source, document_id = self._find_document_data_from_url(url)
        if document_source and hasattr(self, '_parse_%s_document' % document_source):
            return getattr(self, '_parse_%s_document' % document_source)(document_id, only_preview_fields)
        return {'error': _('Unknown document')}

    def _parse_youtube_document(self, document_id, only_preview_fields):
        key = self.env['ir.config_parameter'].sudo().get_param('website_slides.google_app_key')
        fetch_res = self._fetch_data('https://www.googleapis.com/youtube/v3/videos', {'id': document_id, 'key': key, 'part': 'snippet', 'fields': 'items(id,snippet)'}, 'json')
        if fetch_res.get('error'):
            return fetch_res

        values = {'slide_type': 'video', 'document_id': document_id}
        youtube_values = fetch_res['values'].get('items', list(dict()))[0]
        if youtube_values.get('snippet'):
            snippet = youtube_values['snippet']
            if only_preview_fields:
                values.update({
                    'url_src': snippet['thumbnails']['high']['url'],
                    'title': snippet['title'],
                    'description': snippet['description']
                })
                return values
            values.update({
                'name': snippet['title'],
                'image': self._fetch_data(snippet['thumbnails']['high']['url'], {}, 'image')['values'],
                'description': snippet['description'],
            })
        return {'values': values}

    @api.model
    def _parse_google_document(self, document_id, only_preview_fields):
        def get_slide_type(vals):
            # TDE FIXME: WTF ??
            image = Image.open(io.BytesIO(vals['image'].decode('base64')))
            width, height = image.size
            if height > width:
                return 'document'
            else:
                return 'presentation'
        key = self.env['ir.config_parameter'].sudo().get_param('website_slides.google_app_key')
        fetch_res = self._fetch_data('https://www.googleapis.com/drive/v2/files/%s' % document_id, {'projection': 'BASIC', 'key': key}, "json")
        if fetch_res.get('error'):
            return fetch_res

        google_values = fetch_res['values']
        if only_preview_fields:
            return {
                'url_src': google_values['thumbnailLink'],
                'title': google_values['title'],
            }

        values = {
            'name': google_values['title'],
            'image': self._fetch_data(google_values['thumbnailLink'].replace('=s220', ''), {}, 'image')['values'],
            'mime_type': google_values['mimeType'],
            'document_id': document_id,
        }
        if google_values['mimeType'].startswith('video/'):
            values['slide_type'] = 'video'
        elif google_values['mimeType'].startswith('image/'):
            values['datas'] = values['image']
            values['slide_type'] = 'infographic'
        elif google_values['mimeType'].startswith('application/vnd.google-apps'):
            values['datas'] = self._fetch_data(google_values['exportLinks']['application/pdf'], {}, 'pdf')['values']
            values['slide_type'] = get_slide_type(values)
            if google_values['exportLinks'].get('text/plain'):
                values['index_content'] = self._fetch_data(google_values['exportLinks']['text/plain'], {})['values']
            if google_values['exportLinks'].get('text/csv'):
                values['index_content'] = self._fetch_data(google_values['exportLinks']['text/csv'], {})['values']
        elif google_values['mimeType'] == 'application/pdf':
            # TODO: Google Drive PDF document doesn't provide plain text transcript
            values['datas'] = self._fetch_data(google_values['webContentLink'], {}, 'pdf')['values']
            values['slide_type'] = get_slide_type(values)

        return {'values': values}
class IrActionBackground(models.Model):

    _name = "ir.action.background"

    name = fields.Char(string="Name")
    action_file = fields.Binary(string="Action File")
    progress_current = fields.Integer(string="Progress Current", readonly=True)
    progress_max = fields.Integer(string="Progress Max", readonly=True)
    track_progress = fields.Boolean(
        string="Track Progress",
        help="Tracks how far along a action is complete(decreases speed)")
    start_time = fields.Datetime(string="Start Time", readonly=True)
    auto_commit = fields.Boolean(
        string="Auto Commit",
        help=
        "Adds the records after every line is executed without waiting until the file finishes(decreases speed)"
    )
    finish_time = fields.Datetime(string="Fnish Time", readonly=True)
    time_taken = fields.Char(string="Time Taken",
                             compute="_compute_time_taken")
    rule_char_size = fields.Selection(
        [('do_not_import_record', 'Do not import record'),
         ('truncate', 'Truncate')],
        string="Exceed Max Size",
        default="do_not_import_record")
    log = fields.Text(string="Log", readonly=True)
    state = fields.Selection([('new', 'New'), ('running', 'Running'),
                              ('finished', 'Finished')],
                             default="new",
                             string="State",
                             readonly=True)

    @api.depends('start_time', 'finish_time')
    def _compute_time_taken(self):
        if self.start_time and self.finish_time:
            start_time = datetime.strptime(self.start_time,
                                           DEFAULT_SERVER_DATETIME_FORMAT)
            finish_time = datetime.strptime(self.finish_time,
                                            DEFAULT_SERVER_DATETIME_FORMAT)
            time_taken = finish_time - start_time

            m, s = divmod(time_taken.seconds, 60)
            h, m = divmod(m, 60)

            self.time_taken = str(h) + " hours, " + str(
                m) + " minutes, " + str(s) + " seconds"

    @api.one
    def reset_state(self):
        self.state = "new"

    @api.one
    def run_now(self):
        self.env['ir.action.background'].process_background_actions()

    @api.model
    def process_background_actions(self):

        for background_action in self.env['ir.action.background'].search([
            ('state', '=', 'new')
        ]):
            background_action.state = "running"

            model = "res.partner"
            my_model = self.env['ir.model'].search([('model', '=', model)])[0]

            log_string = ""
            background_action.start_time = datetime.utcnow()
            rownum = 0
            csv_data = base64.decodestring(background_action.action_file)
            progress_max = sum(1 for row in StringIO.StringIO(csv_data)) - 1
            background_action.progress_max = progress_max

            reader = csv.reader(StringIO.StringIO(csv_data), delimiter=',')
            track = background_action.track_progress
            auto_commit = background_action.auto_commit
            cancel_import = False
            create_commit_data = []

            header = []
            header_field = {}
            for row in reader:
                row_dict = {}
                # Save header row.
                if rownum == 0:
                    header = row
                    colnum = 0
                    for col in row:

                        map_column = self.env['ir.model.fields'].search([
                            ('model_id', '=', my_model.id), ('name', '=', col)
                        ])
                        if len(map_column) == 1:
                            header_field[colnum] = map_column[0]
                            colnum += 1
                        elif len(map_column) > 1:
                            log_string += "Column " + col + " maps to more then 1 field, import failed\n"
                            cancel_import = True
                        else:
                            log_string += "Column " + col + " could not be found\n"
                            cancel_import = True

                    if cancel_import:
                        break
                else:
                    colnum = 0

                    for col in row:
                        row_dict[header[colnum]] = col
                        ttype = header_field[colnum].ttype
                        size = header_field[colnum].size

                        #Char size validation
                        if ttype == "char" and size != 0:
                            #Exceeds max size
                            if len(col) > size:
                                if background_action.rule_char_size == "do_not_import_record":
                                    log_string += "Row " + str(
                                        rownum
                                    ) + " was skipped because field " + str(
                                        header[colnum]
                                    ) + " exceeded the character limit\n"
                                    break
                                elif background_action.rule_char_size == "truncate":
                                    #Truncates by  default
                                    log_string += "Row " + str(
                                        rownum) + " field " + str(
                                            header[colnum]
                                        ) + " was truncated\n"

                        colnum += 1

                    self.env[model].create(row_dict)

                    if track:
                        _logger.error(str(rownum) + "/" + str(progress_max))
                        background_action.progress_current = rownum

                    if auto_commit:
                        self._cr.commit()

                rownum += 1

            background_action.state = "finished"
            background_action.finish_time = datetime.utcnow()
            background_action.log = log_string
            background_action.state = "finished"
Esempio n. 24
0
class dev_product_movement_excel(models.TransientModel):
    _name= "dev.product.movement.excel"

    excel_file = fields.Binary('Excel Report')
    file_name = fields.Char('Excel File')
class rbs_documento_mercantil_acta(models.Model):
    _name = "rbs.documento.mercantil.acta"
    _description = "Documento Mercantil de Acta"
    #name= field.Char('Nombre')

    anio_id = fields.Many2one('rbs.archivo.anio', string='Año', required=True)
    libro_id = fields.Many2one('rbs.archivo.libro',
                               string='Libro',
                               required=True)
    tomo_id = fields.Many2one("rbs.archivo.tomo", string='Tomo', required=True)

    compania_id = fields.Many2one('rbs.compania', string='Compania')
    compania_nombres = fields.Char(string='Nombres de la Compañia')
    compania_identificacion = fields.Char(
        string='Indentificacion de la Compañia')
    compania_especie_id = fields.Many2one('rbs.compania.especie',
                                          string='Especie de Compañia')
    fecha_inscripcion = fields.Datetime(string='Fecha de Inscripcion',
                                        required=True)

    persona_id = fields.Many2one('rbs.persona', string='Compareciente(n)')
    persona_nombres = fields.Char(string='Nombres del Compareciente')
    persona_apellidos = fields.Char(string='Apellidos del Compareciente')
    persona_cedula = fields.Char(string='Cedula del Compareciente')

    cargo_id = fields.Many2one('rbs.cargo', string='Cargo')
    tipo_compareciente_id = fields.Many2one('rbs.tipo.compareciente.a',
                                            string='Tipo de Compareciente')
    numero_inscripcion = fields.Char(string='Numero de Inscripcion',
                                     required=True)
    autoridad_emisora = fields.Char(string='Autoridad que emitio el Acta')

    foleo_desde = fields.Char(string='Desde', required=True)
    foleo_hasta = fields.Char(string='Hasta', required=True)

    disposicion = fields.Char(string='Disposicion')
    fecha_disposicion = fields.Datetime(string='Fecha de Disposicion')
    numero_Disposicion = fields.Char(string='Numero de Disposicion')
    fecha_ecritura = fields.Datetime(string='Fecha de Escritura',
                                     required=True)
    nombre_instancia_publica = fields.Char(
        string='Nombre de Instancia Publica')

    canton_id = fields.Many2one('rbs.canton',
                                string='Canton de Notaria',
                                required=True)

    tipo_tramite_id = fields.Many2one('rbs.tipo.tramite',
                                      string='Tipo de Tramite',
                                      required=True)

    ubicacion_dato_id = fields.Many2one('rbs.ubicacion.dato',
                                        string='Ubicacion del Dato',
                                        required=True)

    fecha_ultima_modificacion = fields.Datetime(
        string='Ultima Modificacion de la Fuente')

    estado_inscripcion_id = fields.Many2one('rbs.estado.inscripcion',
                                            string='Estado de la Inscripcion',
                                            required=True)
    #filedata = fields.Binary('Archivo',filters='*.pdf')
    #filename = fields.Char( compute='_get_value', string = 'Nombre de archivo', default="Archivo.pdf")

    filedata_id = fields.Many2one('rbs.archivo.pdf')
    filedata = fields.Binary(related='filedata_id.filedata', filters='*.pdf')
    esPesado = fields.Boolean(related='filedata_id.esPesado',
                              string='¿Es Pesado?')
    rutaFTP = fields.Char(related='filedata_id.rutaFTP',
                          string='Escriba la ruta del Archivo')

    #libro_tipo = fields.Selection(string='Tipo de Libro', related='libro_id.libro_tipo',store = True)

    identificacion_unica = fields.Char(
        string='Identificador Unico Sistema Remoto',
        compute='_compute_upper',
        store=True)

    factura_ids = fields.One2many('account.invoice',
                                  'acta_id',
                                  string='Factura')

    contenedor_id = fields.Many2one("rbs.contenedor", string="Contenedor")

    _defaults = {}

    def open_ui(self, cr, uid, ids, context=None):
        data = self.browse(cr, uid, ids[0], context=context)
        context = dict(context or {})
        #context['active_id'] = data.ids[0]
        return {
            'type': 'ir.actions.act_url',
            'url':
            '/registro_mercantil/web/?binary=' + str(ids[0]) + '&tipo=acta',
            'target': 'current',
        }

    def _getUltimoAnio(self, cr, uid, context=None):
        acta_id = self.pool.get("rbs.documento.mercantil.acta").search(
            cr, uid, [], limit=1, order='id desc')
        anio = self.pool.get("rbs.documento.mercantil.acta").browse(
            cr, uid, acta_id, context=None).anio_id.id
        return anio

    def _getUltimoLibro(self, cr, uid, context=None):
        acta_id = self.pool.get("rbs.documento.mercantil.acta").search(
            cr, uid, [], limit=1, order='id desc')
        libro = self.pool.get("rbs.documento.mercantil.acta").browse(
            cr, uid, acta_id, context=None).libro_id.id
        return libro

    def _getUltimoTomo(self, cr, uid, context=None):
        acta_id = self.pool.get("rbs.documento.mercantil.acta").search(
            cr, uid, [], limit=1, order='id desc')
        tomo = self.pool.get("rbs.documento.mercantil.acta").browse(
            cr, uid, acta_id, context=None).tomo_id.id
        return tomo

    def _getUltimoTomo(self, cr, uid, context=None):
        acta_id = self.pool.get("rbs.documento.mercantil.acta").search(
            cr, uid, [], limit=1, order='id desc')
        tomo = self.pool.get("rbs.documento.mercantil.acta").browse(
            cr, uid, acta_id, context=None).tomo_id.id
        return tomo

    def _create_pdf(self, cr, uid, context=None):
        return self.pool.get("rbs.archivo.pdf").create(cr,
                                                       uid, {},
                                                       context=None)

    _defaults = {
        'anio_id': _getUltimoAnio,
        'libro_id': _getUltimoLibro,
        'tomo_id': _getUltimoTomo,
        'filedata_id': _create_pdf,
    }
    _rec_name = 'numero_inscripcion'

    @api.onchange('filedata')
    def on_change_filedata(self):
        a = self.env['rbs.contenedor'].create({'name': 'A'})

        im = Image.open(BytesIO(base64.b64decode(self.filedata)))
        #raise osv.except_osv('Esto es un Mesaje!',repr(im.info))
        n = 0
        self.contenedor_id = a.id
        while True:
            try:
                n = n + 1
                im.seek(n)
                #im.save('Block_%s.tif'%(n,))

                jpeg_image_buffer = cStringIO.StringIO()
                im.save(jpeg_image_buffer, format="PNG")
                imgStr = base64.b64encode(jpeg_image_buffer.getvalue())
                a.imagenes_ids |= self.env['rbs.imagenes'].create({
                    'imagen':
                    imgStr,
                    'contenedor_id':
                    a.id
                })
                #raise osv.except_osv('Esto es un Mesaje!',imgStr)
            except EOFError:
                print "Se Cargo la imagen tiff", n
                break

    @api.depends('ubicacion_dato_id', 'persona_cedula', 'numero_inscripcion')
    def _compute_upper(self):
        for rec in self:
            try:
                rec.identificacion_unica = '01' + rec.ubicacion_dato_id.name + rec.persona_cedula + rec.numero_inscripcion
            except:
                pass

    def on_change_anio_id(self, cr, uid, ids, anio_id, context=None):
        result = {}
        if (self._getUltimoAnio(cr, uid, context=None) != anio_id):
            result['libro_id'] = 0
        return {
            'value': result,
        }

    def on_change_libro_id(self, cr, uid, ids, libro_id, context=None):
        result = {}
        if (self._getUltimoLibro(cr, uid, context=None) != libro_id):
            result['tomo_id'] = 0
        return {
            'value': result,
        }

    def codigoascii(self, text):
        return unicode(text).encode('utf-8')

    def onchange_persona_id(self, cr, uid, ids, persona_id, context=None):
        persona_id = self.pool.get('rbs.persona').search(
            cr, uid, [
                ('id', '=', persona_id),
            ])
        persona = self.pool.get('rbs.persona').browse(cr,
                                                      uid,
                                                      persona_id,
                                                      context=None)
        result = {}
        try:
            if persona:
                try:
                    if persona.persona_nombres:
                        result['persona_nombres'] = self.codigoascii(
                            persona.persona_nombres)
                except:
                    pass
                try:
                    if persona.persona_apellidos:
                        result['persona_apellidos'] = self.codigoascii(
                            persona.persona_apellidos)

                except:
                    pass
                try:
                    if persona.name:
                        result['persona_cedula'] = str(persona.name)
                except:
                    pass

        except:
            pass

        return {
            'value': result,
        }

    def onchange_compania_id(self, cr, uid, ids, companiaid, context=None):
        compania_id = self.pool.get('rbs.compania').search(
            cr, uid, [
                ('id', '=', companiaid),
            ])
        compania = self.pool.get('rbs.compania').browse(cr,
                                                        uid,
                                                        compania_id,
                                                        context=None)
        result = {}
        try:
            if compania:
                try:
                    if compania.compania_nombres:
                        result['compania_nombres'] = self.codigoascii(
                            compania.compania_nombres)
                except:
                    pass
                try:
                    if compania.name:
                        result['compania_identificacion'] = str(compania.name)
                except:
                    pass
                try:
                    if compania.compania_especie_id.id:
                        result[
                            'compania_especie_id'] = compania.compania_especie_id.id
                except:
                    pass

        except:
            pass

        return {
            'value': result,
        }

    def onchange_inscripcion(self,
                             cr,
                             uid,
                             ids,
                             inscripcion_num,
                             libro_id,
                             context=None):
        acta_id = self.pool.get('rbs.documento.mercantil.acta').search(
            cr, uid, [('numero_inscripcion', '=', inscripcion_num),
                      ('libro_id', '=', libro_id)])
        acta = self.pool.get('rbs.documento.mercantil.acta').browse(
            cr, uid, acta_id, context=None)
        result = {}

        try:

            if acta:
                acta = acta[0]
                #raise osv.except_osv('Esto es un Mesaje!',establecimiento)
                try:
                    if acta.fecha_inscripcion:
                        result['fecha_inscripcion'] = str(
                            acta.fecha_inscripcion)

                except:
                    pass

                try:
                    if acta.tomo_id:
                        result['tomo_id'] = acta.tomo_id.id
                except:
                    pass

                try:
                    if acta.anio_id:
                        result['anio_id'] = acta.anio_id.id
                except:
                    pass

                try:
                    if acta.libro_id:
                        result['libro_id'] = acta.libro_id.id
                except:
                    pass

                try:
                    if acta.numero_inscripcion:
                        result[
                            'numero_inscripcion'] = acta.numero_inscripcion.id
                except:
                    pass

                try:
                    if acta.autoridad_emisora:
                        result['autoridad_emisora'] = self.codigoascii(
                            acta.autoridad_emisora)
                except:
                    pass

                try:
                    if acta.disposicion:
                        result['disposicion'] = self.codigoascii(
                            acta.disposicion)
                except:
                    pass
                try:
                    if acta.fecha_disposicion:
                        result['fecha_disposicion'] = str(
                            acta.fecha_disposicion)
                except:
                    pass

                try:
                    if acta.numero_Disposicion:
                        result['numero_Disposicion'] = str(
                            acta.numero_Disposicion)
                except:
                    pass

                try:
                    if acta.fecha_ecritura:
                        result['fecha_ecritura'] = str(acta.fecha_ecritura)
                except:
                    pass

                try:
                    if acta.nombre_instancia_publica:
                        result['nombre_instancia_publica'] = self.codigoascii(
                            acta.nombre_instancia_publica)
                except:
                    pass

                try:
                    if acta.canton_id:
                        result['canton_id'] = acta.canton_id.id

                except:
                    pass

                try:
                    if acta.tipo_tramite_id:
                        result['tipo_tramite_id'] = acta.tipo_tramite_id.id

                except:
                    pass

                try:
                    if acta.fecha_ultima_modificacion:
                        result['fecha_ultima_modificacion'] = str(
                            acta.fecha_ultima_modificacion)
                except:
                    pass

                try:
                    if acta.estado_inscripcion_id:
                        result[
                            'estado_inscripcion_id'] = acta.estado_inscripcion_id.id

                except:
                    pass

                try:
                    if acta.ubicacion_dato_id:
                        result['ubicacion_dato_id'] = acta.ubicacion_dato_id.id

                except:
                    pass

                try:
                    if acta.canton_id:
                        result['canton_id'] = acta.canton_id.id

                except:
                    pass

                try:
                    if acta.filedata_id:
                        result['filedata_id'] = acta.filedata_id.id

                except:
                    pass

            if not acta:
                result['filedata_id'] = self._create_pdf(cr, uid, context=None)

        except:
            pass

        return {
            'value': result,
        }
Esempio n. 26
0
class ImLivechatChannel(models.Model):
    """ Livechat Channel
        Define a communication channel, which can be accessed with 'script_external' (script tag to put on
        external website), 'script_internal' (code to be integrated with odoo website) or via 'web_page' link.
        It provides rating tools, and access rules for anonymous people.
    """

    _name = 'im_livechat.channel'
    _description = 'Livechat Channel'

    def _default_image(self):
        image_path = openerp.modules.get_module_resource('im_livechat', 'static/src/img', 'default.png')
        return tools.image_resize_image_big(open(image_path, 'rb').read().encode('base64'))

    def _default_user_ids(self):
        return [(6, 0, [self._uid])]

    # attribute fields
    name = fields.Char('Name', required=True, help="The name of the channel")
    button_text = fields.Char('Text of the Button', default='Have a Question? Chat with us.',
        help="Default text displayed on the Livechat Support Button")
    default_message = fields.Char('Welcome Message', default='How may I help you?',
        help="This is an automated 'welcome' message that your visitor will see when they initiate a new conversation.")
    input_placeholder = fields.Char('Chat Input Placeholder')

    # computed fields
    web_page = fields.Char('Web Page', compute='_compute_web_page_link', store=False, readonly=True,
        help="URL to a static page where you client can discuss with the operator of the channel.")
    are_you_inside = fields.Boolean(string='Are you inside the matrix?',
        compute='_are_you_inside', store=False, readonly=True)
    script_external = fields.Text('Script (external)', compute='_compute_script_external', store=False, readonly=True)
    nbr_channel = fields.Integer('Number of conversation', compute='_compute_nbr_channel', store=False, readonly=True)
    rating_percentage_satisfaction = fields.Integer(
        '% Happy', compute='_compute_percentage_satisfaction', store=False, default=-1,
        help="Percentage of happy ratings over the past 7 days")

    # images fields
    image = fields.Binary('Image', default=_default_image, attachment=True,
        help="This field holds the image used as photo for the group, limited to 1024x1024px.")
    image_medium = fields.Binary('Medium', attachment=True,
        help="Medium-sized photo of the group. It is automatically "\
             "resized as a 128x128px image, with aspect ratio preserved. "\
             "Use this field in form views or some kanban views.")
    image_small = fields.Binary('Thumbnail', attachment=True,
        help="Small-sized photo of the group. It is automatically "\
             "resized as a 64x64px image, with aspect ratio preserved. "\
             "Use this field anywhere a small image is required.")

    # relationnal fields
    user_ids = fields.Many2many('res.users', 'im_livechat_channel_im_user', 'channel_id', 'user_id', string='Operators', default=_default_user_ids)
    channel_ids = fields.One2many('mail.channel', 'livechat_channel_id', 'Sessions')
    rule_ids = fields.One2many('im_livechat.channel.rule', 'channel_id', 'Rules')


    @api.one
    def _are_you_inside(self):
        self.are_you_inside = bool(self.env.uid in [u.id for u in self.user_ids])

    @api.multi
    def _compute_script_external(self):
        view = self.env['ir.model.data'].get_object('im_livechat', 'external_loader')
        values = {
            "url": self.env['ir.config_parameter'].sudo().get_param('web.base.url'),
            "dbname": self._cr.dbname,
        }
        for record in self:
            values["channel_id"] = record.id
            record.script_external = view.render(values)

    @api.multi
    def _compute_web_page_link(self):
        base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
        for record in self:
            record.web_page = "%s/im_livechat/support/%i" % (base_url, record.id)

    @api.multi
    @api.depends('channel_ids')
    def _compute_nbr_channel(self):
        for record in self:
            record.nbr_channel = len(record.channel_ids)

    @api.multi
    @api.depends('channel_ids.rating_ids')
    def _compute_percentage_satisfaction(self):
        for record in self:
            dt = fields.Datetime.to_string(datetime.utcnow() - timedelta(days=7))
            repartition = record.channel_ids.rating_get_grades([('create_date', '>=', dt)])
            total = sum(repartition.values())
            if total > 0:
                happy = repartition['great']
                record.rating_percentage_satisfaction = ((happy*100) / total) if happy > 0 else 0
            else:
                record.rating_percentage_satisfaction = -1

    @api.model
    def create(self, vals):
        tools.image_resize_images(vals)
        return super(ImLivechatChannel, self).create(vals)

    @api.multi
    def write(self, vals):
        tools.image_resize_images(vals)
        return super(ImLivechatChannel, self).write(vals)

    # --------------------------
    # Action Methods
    # --------------------------
    @api.multi
    def action_join(self):
        self.ensure_one()
        return self.write({'user_ids': [(4, self._uid)]})

    @api.multi
    def action_quit(self):
        self.ensure_one()
        return self.write({'user_ids': [(3, self._uid)]})

    @api.multi
    def action_view_rating(self):
        """ Action to display the rating relative to the channel, so all rating of the
            sessions of the current channel
            :returns : the ir.action 'action_view_rating' with the correct domain
        """
        self.ensure_one()
        action = self.env['ir.actions.act_window'].for_xml_id('rating', 'action_view_rating')
        action['domain'] = [('res_id', 'in', [s.id for s in self.channel_ids]), ('res_model', '=', 'mail.channel')]
        return action

    # --------------------------
    # Channel Methods
    # --------------------------
    @api.multi
    def get_available_users(self):
        """ get available user of a given channel
            :retuns : return the res.users having their im_status online
        """
        self.ensure_one()
        return self.sudo().user_ids.filtered(lambda user: user.im_status == 'online')

    @api.model
    def get_mail_channel(self, livechat_channel_id, anonymous_name):
        """ Return a mail.channel given a livechat channel. It creates one with a connected operator, or return false otherwise
            :param livechat_channel_id : the identifier if the im_livechat.channel
            :param anonymous_name : the name of the anonymous person of the channel
            :type livechat_channel_id : int
            :type anonymous_name : str
            :return : channel header
            :rtype : dict
        """
        # get the avalable user of the channel
        users = self.sudo().browse(livechat_channel_id).get_available_users()
        if len(users) == 0:
            return False
        # choose the res.users operator and get its partner id
        user = random.choice(users)
        operator_partner_id = user.partner_id.id
        # partner to add to the mail.channel
        channel_partner_to_add = [(4, operator_partner_id)]
        if self.env.uid:  # if the user if logged (portal user), he can be identify
            channel_partner_to_add.append((4, self.env.user.partner_id.id))
        # create the session, and add the link with the given channel
        mail_channel = self.env["mail.channel"].with_context(mail_create_nosubscribe=False).sudo().create({
            'channel_partner_ids': channel_partner_to_add,
            'livechat_channel_id': livechat_channel_id,
            'anonymous_name': anonymous_name,
            'channel_type': 'livechat',
            'name': ', '.join([anonymous_name, user.name]),
            'public': 'private',
            'email_send': False,
        })
        return mail_channel.sudo().with_context(im_livechat_operator_partner_id=operator_partner_id).channel_info()[0]

    @api.model
    def get_channel_infos(self, channel_id):
        channel = self.browse(channel_id)
        return {
            'button_text': channel.button_text,
            'input_placeholder': channel.input_placeholder,
            'default_message': channel.default_message,
            "channel_name": channel.name,
            "channel_id": channel.id,
        }

    @api.model
    def get_livechat_info(self, channel_id, username='******'):
        info = {}
        info['available'] = len(self.browse(channel_id).get_available_users()) > 0
        info['server_url'] = self.env['ir.config_parameter'].get_param('web.base.url')
        if info['available']:
            info['options'] = self.sudo().get_channel_infos(channel_id)
            info['options']["default_username"] = username
        return info
Esempio n. 27
0
class TestModel(models.Model):
    _name = 'test.model'

    _inherit = ['mail.thread']

    _columns = {}  # deprecated columns
    _defaults = {}  # deprecated defaults
    length = fields.Integer()  # Deprecated length by js errors

    name = fields.Char(
        _(u"Näme"),  # Don't need translate
        help=u"My hëlp",
        required=False,
        compute='_compute_name',  # good compute method name
        search='_search_name',  # good search method name
        inverse='_inverse_name',  # good inverse method name
    )

    # Imported openerp.fields use Char (Upper case)
    other_field = fields.char(
        name=_("Other field"),
        copy=True,
        compute='my_method_compute',  # bad compute method name
        search='my_method_search',  # bad search method name
        inverse='my_method_inverse',  # bad inverse method name
    )
    compute_none = fields.Char(compute=None)

    other_field2 = fields.char(
        'Other Field2',
        copy=True,
    )

    # This is a inherit overwrite field then don't should show errors related
    # with creation of fields.
    def method_date(self):
        date = fields.Date.to_string(
            fields.Datetime.context_timestamp(self,
                                              timestamp=fields.Datetime.now()))
        return date

    my_ok_field = fields.Float(
        "My correctly named field",
        digits=(6, 6),  # OK: Valid field parameter
        index=True,  # OK: Valid field parameter
        help="My ok field",
    )

    my_ko_field = fields.Float(
        digits_compute=lambda cr: (6, 6),  # Deprecated field parameter
        select=True,  # Deprecated field parameter
        help="My ko field",
        string="My Ko Field",  # String parameter equal to name of variable
    )
    """The name of the variable is equal to the string parameter
    Tested all fields.*"""

    boolean_variable_1 = fields.Boolean(string='Boolean Variable 1',
                                        help="Help")
    boolean_variable_2 = fields.Boolean("Boolean Variable 2", help="Help")

    char_variable_1 = fields.Char(string='Char Variable 1', help="Help")
    char_variable_2 = fields.Char("Char Variable 2", help="Help")

    text_variable_1 = fields.Text(string='Text Variable 1', help="Help")
    text_variable_2 = fields.Text("Text Variable 2", help="Help")

    html_variable_1 = fields.Html(string='Html Variable 1', help="Help")
    html_variable_2 = fields.Html("Html Variable 2", help="Help")

    integer_variable_1 = fields.Integer(string='Integer Variable 1',
                                        help="Help")
    integer_variable_2 = fields.Integer("Integer Variable 2", help="Help")

    float_variable_1 = fields.Float(string='Float Variable 1', help="Help")
    float_variable_2 = fields.Float("Float Variable 2", help="Help")

    date_variable_1 = fields.Date(string='Date Variable 1', help="Help")
    date_variable_2 = fields.Date("Date Variable 2", help="Help")

    date_time_variable_1 = fields.DateTime(string='Date Time Variable 1',
                                           help="Help")
    date_time_variable_2 = fields.DateTime("Date Time Variable 2", help="Help")

    binary_variable_1 = fields.Binary(string='Binary Variable 1', help="Help")
    binary_variable_2 = fields.Binary("Binary Variable 2", help="Help")

    selection_variable_1 = fields.Selection(selection=[('a', 'A')],
                                            string='Selection Variable 1',
                                            help="Help")
    selection_variable_2 = fields.Selection([('a', 'A')],
                                            "Selection Variable 2",
                                            help="Help")

    reference_variable_1 = fields.Reference(selection=[('res.user', 'User')],
                                            string="Reference Variable 1",
                                            help="Help")
    reference_variable_2 = fields.Reference([('res.user', 'User')],
                                            "Reference Variable 2",
                                            help="Help")

    many_2_one_variable_1 = fields.Many2one(comodel_name='res.users',
                                            string='Many 2 One Variable 1',
                                            help="Help")
    many_2_one_variable_2 = fields.Many2one('res.users',
                                            "Many 2 One Variable 2",
                                            help="Help")

    one_2_many_variable_1 = fields.One2many(comodel_name='res.users',
                                            inverse_name='rel_id',
                                            string='One 2 Many Variable 1',
                                            help="Help")
    one_2_many_variable_2 = fields.One2many('res.users',
                                            'rel_id',
                                            "One 2 Many Variable 2",
                                            help="Help")

    many_2_many_variable_1 = fields.Many2many(comodel_name='res.users',
                                              relation='table_name',
                                              column1='col_name',
                                              column2='other_col_name',
                                              string='Many 2 Many Variable 1',
                                              help="Help")
    many_2_many_variable_2 = fields.Many2many('res.users',
                                              'table_name',
                                              'col_name',
                                              'other_col_name',
                                              "Many 2 Many Variable 2",
                                              help="Help")

    field_case_sensitive = fields.Char('Field Case SENSITIVE',
                                       help="Field case sensitive")

    name_equal_to_string = fields.Float("Name equal to string",
                                        help="Name Equal To String")

    many_2_one = fields.Many2one('res.users', "Many 2 One", help="Many 2 one")

    many_2_many = fields.Many2many('res.users',
                                   'relation',
                                   'fk_column_from',
                                   'fk_column_to',
                                   "Many 2 many",
                                   help="Many 2 Many")

    def my_method1(self, variable1):
        #  Shouldn't show error of field-argument-translate
        self.my_method2(_('hello world'))

        # Message post without translation function
        self.message_post(subject='Subject not translatable',
                          body='Body not translatable %s' % variable1)
        self.message_post(subject='Subject not translatable %(variable)s' %
                          {'variable': variable1},
                          body='Body not translatable {}'.format(variable1),
                          message_type='notification')
        self.message_post('Body not translatable',
                          'Subject not translatable {a}'.format(a=variable1))
        self.message_post(
            'Body not translatable %s' % variable1,
            'Subject not translatable %(variable)s' % {'variable': variable1})
        self.message_post('Body not translatable',
                          subject='Subject not translatable')
        self.message_post(
            body='<h1>%s</h1><p>%s</p>' %
            (_('Paragraph translatable'), 'Paragraph not translatable'))

        # Message post with translation function
        self.message_post(subject=_('Subject translatable'),
                          body=_('Body translatable'))
        self.message_post(_('Body translatable'), _('Subject translatable'))
        self.message_post(_('Body translatable'),
                          subject=_('Subject translatable'))
        self.message_post(_('A CDR has been recovered for %s') % (variable1, ))
        self.message_post(_('A CDR has been recovered for %s') % variable1)
        self.message_post(_('Var {a}').format(a=variable1))
        self.message_post(_('Var %(variable)s') % {'variable': variable1})
        self.message_post(subject=_('Subject translatable'),
                          body=_('Body translatable %s') % variable1)
        self.message_post(subject=_('Subject translatable %(variable)s') %
                          {'variable': variable1},
                          message_type='notification')
        self.message_post(_('Body translatable'),
                          _('Subject translatable {a}').format(a=variable1))
        self.message_post(
            _('Body translatable %s') % variable1,
            _('Subject translatable %(variable)s') % {'variable': variable1})
        self.message_post('<p>%s</p>' % _('Body translatable'))
        self.message_post(body='<p>%s</p>' % _('Body translatable'))

        # There is no way to know if the variable is translated, then ignoring
        self.message_post(variable1)
        self.message_post(body=variable1 + variable1)
        self.message_post(body=(variable1 + variable1))
        self.message_post(body=variable1 % variable1)
        self.message_post(body=(variable1 % variable1))

        # translation function with variables in the term
        variable2 = variable1
        self.message_post(_('Variable not translatable: %s' % variable1))
        self.message_post(
            _('Variables not translatable: %s, %s' % (variable1, variable2)))
        self.message_post(body=_('Variable not translatable: %s' % variable1))
        self.message_post(body=_('Variables not translatable: %s %s' %
                                 (variable1, variable2)))
        error_msg = _('Variable not translatable: %s' % variable1)
        error_msg = _('Variables not translatable: %s, %s' %
                      (variable1, variable2))
        error_msg = _('Variable not translatable: {}'.format(variable1))
        error_msg = _('Variables not translatable: {}, {variable2}'.format(
            variable1, variable2=variable2))
        return error_msg

    def my_method2(self, variable2):
        return variable2

    def my_method3(self, cr):
        cr.commit()  # Dangerous use of commit old api
        self.env.cr.commit()  # Dangerous use of commit
        self._cr.commit()  # Dangerous use of commit
        self.cr.commit()  # Dangerous use of commit
        return cr

    def my_method4(self, variable2):
        self.env.cr2.commit()  # This should not be detected
        return variable2

    def my_method5(self, variable2):
        self.env.cr.commit2()  # This should not be detected
        return variable2

    def my_method6(self):
        user_id = 1
        if user_id != 99:
            # Method without translation
            raise UserError('String without translation')

    def my_method7(self):
        user_id = 1
        if user_id != 99:
            # Method with translation
            raise UserError(_('String with translation'))

    def my_method8(self):
        user_id = 1
        if user_id != 99:
            str_error = 'String with translation 2'  # Don't check
            raise UserError(str_error)

    def my_method9(self):
        user_id = 1
        if user_id != 99:
            # Method without translation
            raise UserError("String without translation 2")

    def my_method10(self):
        # A example of built-in raise without parameters
        # Shouldn't show error from lint
        raise ZeroDivisionError
        raise ZeroDivisionError()

    def my_method11(self):
        # A example of built-in raise with parameters
        # Shouldn't show error from lint
        raise ZeroDivisionError("String without translation")
        # raise without class-exception to increase coverage
        raise
        raise "obsolete case"

    def my_method12(self):
        # Should show error
        raise exceptions.Warning(
            'String with params format {p1}'.format(p1='v1'))
        raise exceptions.Warning('qp2w String with params format %(p1)s' %
                                 {'p1': 'v1'})

    def my_method13(self):
        # Shouldn't show error
        raise exceptions.Warning(
            _('String with params format {p1}').format(p1='v1'))
        raise exceptions.Warning(
            _('String with params format {p1}'.format(p1='v1')))
        raise exceptions.Warning(
            _('String with params format %(p1)s') % {'p1': 'v1'})
        raise exceptions.Warning(
            _('String with params format %(p1)s' % {'p1': 'v1'}))

    def old_api_method_alias(self, cursor, user, ids, context=None):  # old api
        pass

    def sql_method(self, ids, cr):
        # Use of query parameters: nothing wrong here
        self._cr.execute('SELECT name FROM account WHERE id IN %s',
                         (tuple(ids), ))
        self.env.cr.execute('SELECT name FROM account WHERE id IN %s',
                            (tuple(ids), ))
        cr.execute('SELECT name FROM account WHERE id IN %s', (tuple(ids), ))
        self.cr.execute('SELECT name FROM account WHERE id IN %s',
                        (tuple(ids), ))

    def sql_injection_ignored_cases(self, ids, cr2):
        # This cr.execute2 or cr2.execute should not be detected
        self._cr.execute2('SELECT name FROM account WHERE id IN %s' %
                          (tuple(ids), ))
        cr2.execute('SELECT name FROM account WHERE id IN %s' % (tuple(ids), ))

        # Ignore when the query is built using private attributes
        self._cr.execute('DELETE FROM %s WHERE id IN %%s' % self._table,
                         (tuple(ids), ))

        # Ignore string parsed with "".format() if args are psycopg2.sql.* calls
        query = "SELECT * FROM table"
        # imported from pyscopg2 import sql
        self._cr.execute(
            sql.SQL("""CREATE or REPLACE VIEW {} as ({})""").format(
                sql.Identifier(self._table), sql.SQL(query)))
        self._cr.execute(
            sql.SQL("""CREATE or REPLACE VIEW {table} as ({query})""").format(
                table=sql.Identifier(self._table),
                query=sql.SQL(query),
            ))
        # imported from pyscopg2.sql import SQL, Identifier
        self._cr.execute(
            SQL("""CREATE or REPLACE VIEW {} as ({})""").format(
                Identifier(self._table),
                SQL(query),
            ))
        self._cr.execute(
            SQL("""CREATE or REPLACE VIEW {table} as ({query})""").format(
                table=Identifier(self._table),
                query=SQL(query),
            ))
        # imported from pyscopg2 direclty
        self._cr.execute(
            psycopg2.SQL("""CREATE or REPLACE VIEW {} as ({})""").format(
                psycopg2.sql.Identifier(self._table),
                psycopg2.sql.SQL(query),
            ))
        self._cr.execute(
            psycopg2.sql.SQL(
                """CREATE or REPLACE VIEW {table} as ({query})""").format(
                    table=Identifier(self._table),
                    query=SQL(query),
                ))
        # Variables build using pyscopg2.sql.* callers
        table = Identifier('table_name')
        sql_query = SQL(query)
        # format params
        self._cr.execute(
            SQL("""CREATE or REPLACE VIEW {} as ({})""").format(
                table,
                sql_query,
            ))
        # format dict
        self._cr.execute(
            SQL("""CREATE or REPLACE VIEW {table} as ({query})""").format(
                table=table,
                query=sql_query,
            ))

    # old api
    def sql_injection_modulo_operator(self, cr, uid, ids, context=None):
        # Use of % operator: risky
        self._cr.execute('SELECT name FROM account WHERE id IN %s' %
                         (tuple(ids), ))
        self.env.cr.execute('SELECT name FROM account WHERE id IN %s' %
                            (tuple(ids), ))
        cr.execute('SELECT name FROM account WHERE id IN %s' % (tuple(ids), ))
        self.cr.execute('SELECT name FROM account WHERE id IN %s' %
                        (tuple(ids), ))

        operator = 'WHERE'
        self._cr.execute('SELECT name FROM account %s id IN %%s' % operator,
                         ids)

        var = 'SELECT name FROM account WHERE id IN %s'
        values = ([
            1,
            2,
            3,
        ], )
        self._cr.execute(var % values)

    def sql_injection_executemany(self, ids, cr, v1, v2):
        # Check executemany() as well
        self.cr.executemany('INSERT INTO account VALUES (%s, %s)' % (v1, v2))

    def sql_injection_format(self, ids, cr):
        # Use of .format(): risky
        self.cr.execute('SELECT name FROM account WHERE id IN {}'.format(ids))

    def sql_injection_plus_operator(self, ids, cr):
        # Use of +: risky
        self.cr.execute('SELECT name FROM account WHERE id IN ' +
                        str(tuple(ids)))

        operator = 'WHERE'
        self._cr.execute('SELECT name FROM account ' + operator + ' id IN %s',
                         ids)
        self.cr.execute(
            ('SELECT name FROM account ' + operator + ' id IN (1)'))
        self.cr.execute('SELECT name FROM account ' + operator + ' id IN %s' %
                        (tuple(ids), ))
        self.cr.execute(
            ('SELECT name FROM account ' + operator + ' id IN %s') %
            (tuple(ids), ))

    def sql_injection_before(self, ids):
        # query built before execute: risky as well

        var = 'SELECT name FROM account WHERE id IN %s' % tuple(ids)
        self._cr.execute(var)

        var[1] = 'SELECT name FROM account WHERE id IN %s' % tuple(ids)
        self._cr.execute(var[1])

    def sql_no_injection_private_attributes(self, _variable, variable):
        # Skip sql-injection using private attributes
        self._cr.execute("CREATE VIEW %s AS (SELECT * FROM res_partner)" %
                         self._table)
        # Real sql-injection cases
        self._cr.execute("CREATE VIEW %s AS (SELECT * FROM res_partner)" %
                         self.table)
        self._cr.execute("CREATE VIEW %s AS (SELECT * FROM res_partner)" %
                         _variable)
        self._cr.execute("CREATE VIEW %s AS (SELECT * FROM res_partner)" %
                         variable)
class SmsTemplate(models.Model):

    _name = "sms.template"

    name = fields.Char(required=True, string='Template Name', translate=True)
    model_id = fields.Many2one(
        'ir.model',
        string='Applies to',
        help="The kind of document with with this template can be used")
    model = fields.Char(related="model_id.model",
                        string='Related Document Model',
                        store=True,
                        readonly=True)
    template_body = fields.Text(
        'Body',
        translate=True,
        help="Plain text version of the message (placeholders may be used here)"
    )
    sms_from = fields.Char(
        string='From (Mobile)',
        help=
        "Sender mobile number (placeholders may be used here). If not set, the default value will be the author's mobile number."
    )
    sms_to = fields.Char(
        string='To (Mobile)',
        help="To mobile number (placeholders may be used here)")
    account_gateway_id = fields.Many2one('sms.account', string="Account")
    model_object_field_id = fields.Many2one(
        'ir.model.fields',
        string="Field",
        help=
        "Select target field from the related document model.\nIf it is a relationship field you will be able to select a target field at the destination of the relationship."
    )
    sub_object_id = fields.Many2one(
        'ir.model',
        string='Sub-model',
        readonly=True,
        help=
        "When a relationship field is selected as first field, this field shows the document model the relationship goes to."
    )
    sub_model_object_field_id = fields.Many2one(
        'ir.model.fields',
        string='Sub-field',
        help=
        "When a relationship field is selected as first field, this field lets you select the target field within the destination document model (sub-model)."
    )
    null_value = fields.Char(
        string='Default Value',
        help="Optional value to use if the target field is empty")
    copyvalue = fields.Char(
        string='Placeholder Expression',
        help=
        "Final placeholder expression, to be copy-pasted in the desired template field."
    )
    lang = fields.Char(
        string='Language',
        help=
        "Optional translation language (ISO code) to select when sending out an email. If not set, the english version will be used. This should usually be a placeholder expression that provides the appropriate language, e.g. ${object.partner_id.lang}.",
        placeholder="${object.partner_id.lang}")
    from_mobile_verified_id = fields.Many2one('sms.number',
                                              string="From Mobile (stored)")
    from_mobile = fields.Char(string="From Mobile",
                              help="Placeholders are allowed here")
    media_id = fields.Binary(string="Media(MMS)")
    media_filename = fields.Char(string="Media Filename")
    media_ids = fields.Many2many('ir.attachment',
                                 string="Media(MMS)[Automated Actions Only]")

    @api.onchange('model_object_field_id')
    def _onchange_model_object_field_id(self):
        if self.model_object_field_id.relation:
            self.sub_object_id = self.env['ir.model'].search([
                ('model', '=', self.model_object_field_id.relation)
            ])[0].id
        else:
            self.sub_object_id = False

        if self.model_object_field_id:
            self.copyvalue = self.build_expression(
                self.model_object_field_id.name,
                self.sub_model_object_field_id.name, self.null_value)

    @api.onchange('sub_model_object_field_id')
    def _onchange_sub_model_object_field_id(self):
        if self.sub_model_object_field_id:
            self.copyvalue = self.build_expression(
                self.model_object_field_id.name,
                self.sub_model_object_field_id.name, self.null_value)

    @api.onchange('from_mobile_verified_id')
    def _onchange_from_mobile_verified_id(self):
        if self.from_mobile_verified_id:
            self.from_mobile = self.from_mobile_verified_id.mobile_number

    @api.model
    def send_sms(self, template_id, record_id):
        """Send the sms using all the details in this sms template, using the specified record ID"""
        sms_template = self.env['sms.template'].browse(int(template_id))

        rendered_sms_template_body = self.env['sms.template'].render_template(
            sms_template.template_body, sms_template.model_id.model, record_id)

        rendered_sms_to = self.env['sms.template'].render_template(
            sms_template.sms_to, sms_template.model_id.model, record_id)

        gateway_model = sms_template.from_mobile_verified_id.account_id.account_gateway_id.gateway_model_name

        #Queue the SMS message since we can't directly send MMS
        queued_sms = self.env['sms.message'].create({
            'record_id':
            record_id,
            'model_id':
            sms_template.model_id.id,
            'account_id':
            sms_template.from_mobile_verified_id.account_id.id,
            'from_mobile':
            sms_template.from_mobile,
            'to_mobile':
            rendered_sms_to,
            'sms_content':
            rendered_sms_template_body,
            'direction':
            'O',
            'message_date':
            datetime.utcnow(),
            'status_code':
            'queued'
        })

        #Also create the MMS attachment
        if sms_template.media_id:
            self.env['ir.attachment'].sudo().create({
                'name':
                'mms ' + str(queued_sms.id),
                'type':
                'binary',
                'datas':
                sms_template.media_id,
                'public':
                True,
                'res_model':
                'sms.message',
                'res_id':
                queued_sms.id
            })

        #Turn the queue manager on
        self.env['ir.model.data'].get_object('sms_frame',
                                             'sms_queue_check').active = True

    def render_template(self, template, model, res_id):
        """Render the given template text, replace mako expressions ``${expr}``
           with the result of evaluating these expressions with
           an evaluation context containing:

                * ``user``: browse_record of the current user
                * ``object``: browse_record of the document record this mail is
                              related to
                * ``context``: the context passed to the mail composition wizard

           :param str template: the template text to render
           :param str model: model name of the document record this mail is related to.
           :param int res_id: id of document records those mails are related to.
        """

        # try to load the template
        #try:
        template = mako_template_env.from_string(tools.ustr(template))
        #except Exception:
        #    _logger.error("Failed to load template %r", template)
        #    return False

        # prepare template variables
        user = self.env.user
        record = self.env[model].browse(res_id)

        variables = {'user': user}

        variables['object'] = record
        try:
            render_result = template.render(variables)
        except Exception:
            _logger.error("Failed to render template %r using values %r" %
                          (template, variables))
            render_result = u""
        if render_result == u"False":
            render_result = u""

        return render_result

    @api.model
    def build_expression(self, field_name, sub_field_name, null_value):
        """Returns a placeholder expression for use in a template field,
           based on the values provided in the placeholder assistant.

          :param field_name: main field name
          :param sub_field_name: sub field name (M2O)
          :param null_value: default value if the target value is empty
          :return: final placeholder expression
        """
        expression = ''
        if field_name:
            expression = "${object." + field_name
            if sub_field_name:
                expression += "." + sub_field_name
            if null_value:
                expression += " or '''%s'''" % null_value
            expression += "}"
        return expression
class website_menu(models.Model):
    _inherit = 'website.menu'

    page_title = fields.Char(default='Page Title')
    image = fields.Binary()
class msl_report(models.TransientModel):
    _name = 'msl.report'
    _description = "MSL Report"

    name = fields.Char(string="MSLReport", compute="_get_name")
    date_from = fields.Date(string="Date From",
                            default=lambda self: fields.datetime.now())
    date_to = fields.Date(string="Date To",
                          default=lambda self: fields.datetime.now())
    attachment_id = fields.Many2one('ir.attachment',
                                    string="Attachment",
                                    ondelete='cascade')
    datas = fields.Binary(string="XLS Report", related="attachment_id.datas")

    @api.constrains('date_from', 'date_to')
    @api.depends('date_from', 'date_to')
    def date_range_check(self):
        if self.date_from and self.date_to and self.date_from > self.date_to:
            raise ValidationError(
                _("Start Date should be before or be the same as End Date."))
        return True

    @api.depends('date_from', 'date_to')
    @api.multi
    def _get_name(self):
        rep_name = "MSL_Report"
        if self.date_from and self.date_to:
            date_from = datetime.datetime.strptime(
                self.date_from,
                tools.DEFAULT_SERVER_DATE_FORMAT).strftime('%d-%b-%Y')
            date_to = datetime.datetime.strptime(
                self.date_to,
                tools.DEFAULT_SERVER_DATE_FORMAT).strftime('%d-%b-%Y')
            if self.date_from == self.date_to:
                rep_name = "MSL Report(%s)" % (date_from, )
            else:
                rep_name = "MSL Report(%s|%s)" % (date_from, date_to)
        self.name = rep_name

    @api.multi
    def print_report(self):
        if self.date_from and self.date_to:
            if not self.attachment_id:
                quant_list = []
                file_name = self.name
                # Created Excel Workbook and Sheet
                workbook = xlwt.Workbook()
                worksheet = workbook.add_sheet('Sheet 1')

                main_style = xlwt.easyxf(
                    'font: bold on, height 400; align: wrap 1, vert centre, horiz center; borders: bottom thick, top thick, left thick, right thick'
                )
                sp_style = xlwt.easyxf('font: bold on, height 350;')
                header_style = xlwt.easyxf(
                    'font: bold on, height 220; align: wrap 1,  horiz center; borders: bottom thin, top thin, left thin, right thin'
                )
                base_style = xlwt.easyxf(
                    'align: wrap 1; borders: bottom thin, top thin, left thin, right thin'
                )

                worksheet.write_merge(0, 1, 0, 4, file_name, main_style)
                row_index = 2

                worksheet.col(0).width = 4000
                worksheet.col(1).width = 4000
                worksheet.col(2).width = 10000
                worksheet.col(3).width = 4000
                worksheet.col(4).width = 4000
                worksheet.col(5).width = 4000

                # Headers
                header_fields = [
                    'Code', 'HSN', 'Description', 'MSL', 'Closing Bal',
                    'Supplier'
                ]
                row_index += 1

                for index, value in enumerate(header_fields):
                    worksheet.write(row_index, index, value, header_style)
                row_index += 1

                product_ids = self.env['product.product'].search([])

                quant_ids = self.env['stock.quant'].sudo().search([])
                for quant_id in quant_ids:
                    in_date = datetime.datetime.strptime(
                        quant_id.in_date,
                        tools.DEFAULT_SERVER_DATETIME_FORMAT).date().strftime(
                            tools.DEFAULT_SERVER_DATE_FORMAT)
                    if in_date >= self.date_from and in_date <= self.date_to:
                        quant_list.append(quant_id)

                if (not quant_list):  # not quant_ids
                    raise Warning(_('Record Not Found'))

                if quant_list:
                    for rec in quant_list:
                        worksheet.write(row_index, 0,
                                        rec.product_id.default_code or '',
                                        base_style)
                        worksheet.write(row_index, 1, rec.product_id.hsn_code
                                        or '', base_style)
                        worksheet.write(row_index, 2, rec.product_id.name,
                                        base_style)
                        worksheet.write(row_index, 3, '', base_style)
                        worksheet.write(row_index, 4, '', base_style)
                        worksheet.write(row_index, 5, '', base_style)
                        row_index += 1

                fp = StringIO()
                workbook.save(fp)
                fp.seek(0)
                data = fp.read()
                fp.close()
                encoded_data = base64.encodestring(data)
                local_tz = pytz.timezone(self._context.get('tz') or 'UTC')
                attach_vals = {
                    'name': '%s' % (file_name),
                    'datas': encoded_data,
                    'datas_fname': '%s.xls' % (file_name),
                    'res_model': 'msl.report',
                }
                doc_id = self.env['ir.attachment'].create(attach_vals)
                self.attachment_id = doc_id.id
            return {
                'type':
                'ir.actions.act_url',
                'url':
                '/web/binary/download_document?model=%s&field=%s&id=%s&filename=%s.xls'
                % (self.attachment_id.res_model, 'datas', self.id,
                   self.attachment_id.name),
                'target':
                'self',
            }