Ejemplo n.º 1
0
class sprint_kanban(osv.Model):
    def set_done(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'state': 'done'}, context=context)
        return True

    def set_cancel(self, cr, uid, ids, context=None):

        self.write(cr, uid, ids, {'state': 'cancelled'}, context=context)
        return True

    def set_pending(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'state': 'pending'}, context=context)
        return True

    def set_open(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'state': 'open'}, context=context)
        return True

    _name = 'sprint.kanban'
    _inherit = ['mail.thread', 'ir.needaction_mixin']

    _columns = {
        'use_phases':
        fields.boolean('Phases',
                       help="""Check this field if you plan
                                             to use phase-based scheduling"""),
        'name':
        fields.char('Name Sprint', 264, required=True),
        'project_id':
        fields.many2one('project.project', 'Project', ondelete="cascade"),
        'description':
        fields.text('Description'),
        'datestart':
        fields.date('Start Date'),
        'dateend':
        fields.date('End Date'),
        'color':
        fields.integer('Color Index'),
        'members':
        fields.many2many('res.users',
                         'project_user_rel',
                         'project_id',
                         'uid',
                         'Project Members',
                         states={
                             'close': [('readonly', True)],
                             'cancelled': [('readonly', True)],
                         }),
        'priority':
        fields.selection([('4', 'Very Low'), ('3', 'Low'), ('2', 'Medium'),
                          ('1', 'Important'), ('0', 'Very important')],
                         'Priority',
                         select=True),
        'state':
        fields.selection(
            [('draft', 'New'), ('open', 'In Progress'),
             ('cancelled', 'Cancelled'), ('pending', 'Pending'),
             ('done', 'Done')],
            'Status',
            required=True,
        ),
        'user_id':
        fields.many2one('res.users', 'Assigned to'),
        'kanban_state':
        fields.selection([('normal', 'Normal'), ('blocked', 'Blocked'),
                          ('done', 'Ready To Pull')],
                         'Kanban State',
                         help="""A task's kanban state indicate
                                                 special situations
                                                 affecting it:\n
                                               * Normal is the default
                                                 situation\n"
                                               * Blocked indicates something
                                                 is preventing the progress
                                                 of this task\n
                                               * Ready To Pull indicates the
                                                 task is ready to be pulled
                                                 to the next stage""",
                         readonly=True,
                         required=False),
    }

    def set_kanban_state_blocked(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'kanban_state': 'blocked'}, context=context)
        return False

    def set_kanban_state_normal(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'kanban_state': 'normal'}, context=context)
        return False

    def set_kanban_state_done(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'kanban_state': 'done'}, context=context)
        return False

    def set_priority(self, cr, uid, ids, priority, *args):
        return self.write(cr, uid, ids, {'priority': priority})

    def set_high_priority(self, cr, uid, ids, *args):
        return self.set_priority(cr, uid, ids, '1')

    def set_normal_priority(self, cr, uid, ids, *args):
        return self.set_priority(cr, uid, ids, '2')

    _defaults = {
        'state': 'draft',
        'priority': '1',
    }
Ejemplo n.º 2
0
class event_track(osv.osv):
    _name = "event.track"
    _description = 'Event Tracks'
    _order = 'priority, date'
    _inherit = ['mail.thread', 'ir.needaction_mixin', 'website.seo.metadata']

    def _website_url(self, cr, uid, ids, field_name, arg, context=None):
        res = dict.fromkeys(ids, '')
        for track in self.browse(cr, uid, ids, context=context):
            res[track.id] = "/event/%s/track/%s" % (slug(
                track.event_id), slug(track))
        return res

    _columns = {
        'name':
        fields.char('Track Title', required=True, translate=True),
        'user_id':
        fields.many2one('res.users', 'Responsible'),
        'speaker_ids':
        fields.many2many('res.partner', string='Speakers'),
        'tag_ids':
        fields.many2many('event.track.tag', string='Tags'),
        'stage_id':
        fields.many2one('event.track.stage', 'Stage'),
        'description':
        fields.html('Track Description', translate=True),
        'date':
        fields.datetime('Track Date'),
        'duration':
        fields.float('Duration', digits=(16, 2)),
        'location_id':
        fields.many2one('event.track.location', 'Location'),
        'event_id':
        fields.many2one('event.event', 'Event', required=True),
        'color':
        fields.integer('Color Index'),
        'priority':
        fields.selection([('3', 'Low'), ('2', 'Medium (*)'),
                          ('1', 'High (**)'), ('0', 'Highest (***)')],
                         'Priority',
                         required=True),
        'website_published':
        fields.boolean('Available in the website'),
        'website_url':
        fields.function(_website_url, string="Website url", type="char"),
        'image':
        fields.related('speaker_ids', 'image', type='binary', readonly=True)
    }

    def set_priority(self, cr, uid, ids, priority, context={}):
        return self.write(cr, uid, ids, {'priority': priority})

    def _default_stage_id(self, cr, uid, context={}):
        stage_obj = self.pool.get('event.track.stage')
        ids = stage_obj.search(cr, uid, [], context=context)
        return ids and ids[0] or False

    _defaults = {
        'user_id': lambda self, cr, uid, ctx: uid,
        'website_published': lambda self, cr, uid, ctx: False,
        'duration': lambda *args: 1.5,
        'stage_id': _default_stage_id,
        'priority': '2'
    }

    def _read_group_stage_ids(self,
                              cr,
                              uid,
                              ids,
                              domain,
                              read_group_order=None,
                              access_rights_uid=None,
                              context=None):
        stage_obj = self.pool.get('event.track.stage')
        result = stage_obj.name_search(cr, uid, '', context=context)
        return result, {}

    _group_by_full = {
        'stage_id': _read_group_stage_ids,
    }
Ejemplo n.º 3
0
class django_panel_settings(osv.osv_memory):
    _name = 'django.panel.settings'
    _inherit = 'res.config.settings'
    
    def set_default_aws_access_id(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        myself = self.browse(cr,uid,ids[0],context=context)
        params.set_param(cr, uid, 'aws_access_id', (myself.aws_access_id or '').strip(), groups=['base.group_system'], context=None)

    def get_default_aws_access_id(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        aws_access_id = params.get_param(cr, uid, 'aws_access_id',default='',context=context)        
        return dict(aws_access_id=aws_access_id)

    def set_default_website_url(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        myself = self.browse(cr,uid,ids[0],context=context)
        params.set_param(cr, uid, 'website_url', (myself.website_url or '').strip(), groups=['base.group_system'], context=None)

    def get_default_website_url(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        website_url = params.get_param(cr, uid, 'website_url',default='',context=context)
        return dict(website_url=website_url)

    def set_default_website_username(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        myself = self.browse(cr,uid,ids[0],context=context)
        params.set_param(cr, uid, 'website_username', (myself.website_username or '').strip(), groups=['base.group_system'], context=None)

    def get_default_website_username(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        website_username = params.get_param(cr, uid, 'website_username',default='',context=context)
        return dict(website_username=website_username)

    def set_default_website_pwd(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        myself = self.browse(cr,uid,ids[0],context=context)
        params.set_param(cr, uid, 'website_pwd', (myself.website_pwd or '').strip(), groups=['base.group_system'], context=None)

    def get_default_website_pwd(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        website_pwd = params.get_param(cr, uid, 'website_pwd',default='',context=context)
        return dict(website_pwd=website_pwd)

    def set_default_aws_secret_key(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        myself = self.browse(cr,uid,ids[0],context=context)
        params.set_param(cr, uid, 'aws_secret_key', (myself.aws_secret_key or '').strip(), groups=['base.group_system'], context=None)

    def get_default_aws_secret_key(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        aws_secret_key = params.get_param(cr, uid, 'aws_secret_key',default='',context=context)        
        return dict(aws_secret_key=aws_secret_key) 
    
#     def set_default_website_banner_key(self,cr,uid,ids,context=None):
#         params = self.pool.get('ir.config_parameter')
#         myself = self.browse(cr,uid,ids[0],context=context)
#         params.set_param(cr, uid, 'website_banner_key', (myself.website_banner_key or '').strip(), groups=['base.group_system'], context=None)
# 
#     def get_default_website_banner_key(self,cr,uid,ids,context=None):
#         params = self.pool.get('ir.config_parameter')
#         website_banner_key = params.get_param(cr, uid, 'website_banner_key',default='',context=context)        
#         return dict(website_banner_key=website_banner_key)                                                                                                   

    def set_default_root_bucket(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        myself = self.browse(cr,uid,ids[0],context=context)
        params.set_param(cr, uid, 'root_bucket', (myself.root_bucket or '').strip(), groups=['base.group_system'], context=None)
 
    def get_default_root_bucket(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        root_bucket = params.get_param(cr, uid, 'root_bucket',default='',context=context)        
        return dict(root_bucket=root_bucket)                                                                                                   

    def set_default_aws_base_url(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        myself = self.browse(cr,uid,ids[0],context=context)
        params.set_param(cr, uid, 'aws_base_url', (myself.aws_base_url or '').strip(), groups=['base.group_system'], context=None)
 
    def get_default_aws_base_url(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        aws_base_url = params.get_param(cr, uid, 'aws_base_url',default='',context=context)        
        return dict(aws_base_url=aws_base_url)                                                                                                   

#     def set_default_website_policy_key(self,cr,uid,ids,context=None):
#         params = self.pool.get('ir.config_parameter')
#         myself = self.browse(cr,uid,ids[0],context=context)
#         params.set_param(cr, uid, 'website_policy_key', (myself.website_policy_key or '').strip(), groups=['base.group_system'], context=None)
# 
#     def get_default_website_policy_key(self,cr,uid,ids,context=None):
#         params = self.pool.get('ir.config_parameter')
#         website_policy_key = params.get_param(cr, uid, 'website_policy_key',default='',context=context)        
#         return dict(website_policy_key=website_policy_key)

    def set_default_meta_keywords(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        myself = self.browse(cr,uid,ids[0],context=context)
        params.set_param(cr, uid, 'meta_keywords', (myself.meta_keywords or '').strip(), groups=['base.group_system'], context=None)

    def get_default_meta_keywords(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        meta_keywords = params.get_param(cr, uid, 'meta_keywords',default='',context=context)        
        return dict(meta_keywords=meta_keywords)                                                                                                       

    def set_default_meta_description(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        myself = self.browse(cr,uid,ids[0],context=context)
        params.set_param(cr, uid, 'meta_description', (myself.meta_description or '').strip(), groups=['base.group_system'], context=None)

    def get_default_meta_description(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        meta_description = params.get_param(cr, uid, 'meta_description',default='',context=context)        
        return dict(meta_description=meta_description)

    def set_default_site_name(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        myself = self.browse(cr,uid,ids[0],context=context)
        params.set_param(cr, uid, 'site_name', (myself.site_name or '').strip(), groups=['base.group_system'], context=None)

    def get_default_site_name(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        site_name = params.get_param(cr, uid, 'site_name',default='',context=context)        
        return dict(site_name=site_name)                                                                                                                
                                                                                                              
    def set_default_attribute_value_ids(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        params = self.pool.get('ir.config_parameter')
        attribute_value_ids = map(lambda x:x.id,myself.attribute_value_ids)
        params.set_param(cr, uid, 'attribute_value_ids', (attribute_value_ids), groups=['base.group_system'], context=None)                                                                                      
    
    def get_default_attribute_value_ids(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        try:
            attribute_value_ids = params.get_param(cr, uid, 'attribute_value_ids',default='[]',context=context)
            return dict(attribute_value_ids=[(6,0,eval(attribute_value_ids))])
        except Exception as e:
            raise osv.except_osv('Error','Please check the value of Volumes not available for Retailers. It is invalid!')        
    
    def set_default_mailing_list_id(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        params = self.pool.get('ir.config_parameter')
        params.set_param(cr, uid, 'mailing_list_id', (myself.mailing_list_id.id), groups=['base.group_system'], context=None)                                                                                      
    
    def get_default_mailing_list_id(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        mailing_list_id = params.get_param(cr, uid, 'mailing_list_id',default=[],context=context)
        try:
            return dict(mailing_list_id=eval(mailing_list_id))
        except Exception as e:
            return []
     
    def _get_domain_volume(self,context=None):
        # We have access to self.env in this context.
        ids = self.env.ref('jjuice.attribute_vol').id
        return [('attribute_id','=', ids)]

    def set_default_attributes_available_ids(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        params = self.pool.get('ir.config_parameter')
        attributes_available_ids = map(lambda x:x.id,myself.attributes_available_ids)
        params.set_param(cr, uid, 'attributes_available_ids', (attributes_available_ids), groups=['base.group_system'], context=None)                                                                                      
    
    def get_default_attributes_available_ids(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        try:
            attributes_available_ids = params.get_param(cr, uid, 'attributes_available_ids',default='[]',context=context)
            return dict(attributes_available_ids=[(6,0,eval(attributes_available_ids))])
        except Exception as e:
            raise osv.except_osv('Error','Please check the value of Volumes available for website display . It is invalid!')        

    def set_default_aboutus_banner(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        s3_object = self.pool.get('s3.object')
        existing_banner_ids = s3_object.search(cr,uid,[('aboutus_banner','=',True),('id','!=',myself.aboutus_banner.id)])
        if existing_banner_ids:
            for i in existing_banner_ids:
                s3_object.unlink(cr,uid,i)
        s3_object.write(cr,uid,myself.aboutus_banner.id,{'aboutus_banner':True})
    
    def get_default_aboutus_banner(self,cr,uid,ids,context=None):
        s3_object_ids = self.pool.get('s3.object').search(cr,uid,[('aboutus_banner','=',True)],limit=1)
        if s3_object_ids:
            return dict(aboutus_banner=s3_object_ids[0])
        else:
            return dict(aboutus_banner=False)

    def set_default_checkout_banner(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        s3_object = self.pool.get('s3.object')
        existing_banner_ids = s3_object.search(cr,uid,[('checkout_banner','=',True),('id','!=',myself.checkout_banner.id)])
        if existing_banner_ids:
            for i in existing_banner_ids:
                s3_object.unlink(cr,uid,i)
        s3_object.write(cr,uid,myself.checkout_banner.id,{'checkout_banner':True})
    
    def get_default_checkout_banner(self,cr,uid,ids,context=None):
        s3_object_ids = self.pool.get('s3.object').search(cr,uid,[('checkout_banner','=',True)],limit=1)
        if s3_object_ids:
            return dict(checkout_banner=s3_object_ids[0])
        else:
            return dict(checkout_banner=False)        

    def set_default_contactus_banner(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        s3_object = self.pool.get('s3.object')
        existing_banner_ids = s3_object.search(cr,uid,[('contactus_banner','=',True),('id','!=',myself.contactus_banner.id)])
        if existing_banner_ids:
            for i in existing_banner_ids:
                s3_object.unlink(cr,uid,i)
        s3_object.write(cr,uid,myself.contactus_banner.id,{'contactus_banner':True})
    
    def get_default_contactus_banner(self,cr,uid,ids,context=None):
        s3_object_ids = self.pool.get('s3.object').search(cr,uid,[('contactus_banner','=',True)],limit=1)
        if s3_object_ids:
            return dict(contactus_banner=s3_object_ids[0])
        else:
            return dict(contactus_banner=False)        

    def set_default_customerreview_banner(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        s3_object = self.pool.get('s3.object')
        existing_banner_ids = s3_object.search(cr,uid,[('customerreview_banner','=',True),('id','!=',myself.customerreview_banner.id)])
        if existing_banner_ids:
            for i in existing_banner_ids:
                s3_object.unlink(cr,uid,i)
        s3_object.write(cr,uid,myself.customerreview_banner.id,{'customerreview_banner':True})
    
    def get_default_customerreview_banner(self,cr,uid,ids,context=None):
        s3_object_ids = self.pool.get('s3.object').search(cr,uid,[('customerreview_banner','=',True)],limit=1)
        if s3_object_ids:
            return dict(customerreview_banner=s3_object_ids[0])
        else:
            return dict(customerreview_banner=False)                

    def set_default_promo_business_ids(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        params = self.pool.get('ir.config_parameter')
        promo_business_ids = map(lambda x:x.id,myself.promo_business_ids)
        params.set_param(cr, uid, 'promo_business_ids', (promo_business_ids), groups=['base.group_system'], context=None)                                                                                      
    
    def get_default_promo_business_ids(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        try:
            promo_business_ids = params.get_param(cr, uid, 'promo_business_ids',default='[]',context=context)
            return dict(promo_business_ids=[(6,0,eval(promo_business_ids))])
        except Exception as e:
            raise osv.except_osv('Error','Please check the value of business promotions. It is invalid!')                    
    
    def set_default_promo_non_business_ids(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        params = self.pool.get('ir.config_parameter')
        promo_non_business_ids = map(lambda x:x.id,myself.promo_non_business_ids)
        params.set_param(cr, uid, 'promo_non_business_ids', (promo_non_business_ids), groups=['base.group_system'], context=None)                                                                                      
    
    def get_default_promo_non_business_ids(self,cr,uid,ids,context=None):
        params = self.pool.get('ir.config_parameter')
        try:
            promo_non_business_ids = params.get_param(cr, uid, 'promo_non_business_ids',default='[]',context=context)
            return dict(promo_non_business_ids=[(6,0,eval(promo_non_business_ids))])
        except Exception as e:
            raise osv.except_osv('Error','Please check the value of Volumes not available for Retailers. It is invalid!')                            

    def set_default_privacy_policy_banner(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        s3_object = self.pool.get('s3.object')
        existing_banner_ids = s3_object.search(cr,uid,[('privacy_policy_banner','=',True),('id','!=',myself.privacy_policy_banner.id)])
        if existing_banner_ids:
            for i in existing_banner_ids:
                s3_object.unlink(cr,uid,i)
        s3_object.write(cr,uid,myself.privacy_policy_banner.id,{'privacy_policy_banner':True})
    
    def get_default_privacy_policy_banner(self,cr,uid,ids,context=None):
        s3_object_ids = self.pool.get('s3.object').search(cr,uid,[('privacy_policy_banner','=',True)],limit=1)
        if s3_object_ids:
            return dict(privacy_policy_banner=s3_object_ids[0])
        else:
            return dict(privacy_policy_banner=False)        
    
    def set_default_terms_conditions_banner(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        s3_object = self.pool.get('s3.object')
        existing_banner_ids = s3_object.search(cr,uid,[('terms_conditions_banner','=',True),('id','!=',myself.terms_conditions_banner.id)])
        if existing_banner_ids:
            for i in existing_banner_ids:
                s3_object.unlink(cr,uid,i)
        s3_object.write(cr,uid,myself.terms_conditions_banner.id,{'terms_conditions_banner':True})
    
    def get_default_terms_conditions_banner(self,cr,uid,ids,context=None):
        s3_object_ids = self.pool.get('s3.object').search(cr,uid,[('terms_conditions_banner','=',True)],limit=1)
        if s3_object_ids:
            return dict(terms_conditions_banner=s3_object_ids[0])
        else:
            return dict(terms_conditions_banner=False)                

    def set_default_search_banner(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        s3_object = self.pool.get('s3.object')
        existing_banner_ids = s3_object.search(cr,uid,[('search_banner','=',True),('id','!=',myself.search_banner.id)])
        if existing_banner_ids:
            for i in existing_banner_ids:
                s3_object.unlink(cr,uid,i)
        s3_object.write(cr,uid,myself.search_banner.id,{'search_banner':True})
    
    def get_default_search_banner(self,cr,uid,ids,context=None):
        s3_object_ids = self.pool.get('s3.object').search(cr,uid,[('search_banner','=',True)],limit=1)
        if s3_object_ids:
            return dict(search_banner=s3_object_ids[0])
        else:
            return dict(search_banner=False)

    def set_default_shipping_returns_policy_banner(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        s3_object = self.pool.get('s3.object')
        existing_banner_ids = s3_object.search(cr,uid,[('shipping_returns_policy_banner','=',True),('id','!=',myself.shipping_returns_policy_banner.id)])
        if existing_banner_ids:
            for i in existing_banner_ids:
                s3_object.unlink(cr,uid,i)
        s3_object.write(cr,uid,myself.shipping_returns_policy_banner.id,{'shipping_returns_policy_banner':True})
    
    def get_default_shipping_returns_policy_banner(self,cr,uid,ids,context=None):
        s3_object_ids = self.pool.get('s3.object').search(cr,uid,[('shipping_returns_policy_banner','=',True)],limit=1)
        if s3_object_ids:
            return dict(shipping_returns_policy_banner=s3_object_ids[0])
        else:
            return dict(shipping_returns_policy_banner=False)

    def set_default_contactus_banner_500340(self, cr, uid, ids, context=None):
        myself = self.browse(cr, uid, ids[0], context=context)
        s3_object = self.pool.get('s3.object')
        existing_banner_ids = s3_object.search(cr, uid, [("contactus_banner_500340", '=', True),
                                                         ('id', '!=', myself.contactus_banner_500340.id)])
        if existing_banner_ids:
            for i in existing_banner_ids:
                s3_object.unlink(cr, uid, i)
        s3_object.write(cr, uid, myself.contactus_banner_500340.id, {'contactus_banner_500340': True})

    def get_default_contactus_banner_500340(self, cr, uid, ids, context=None):
        s3_object_ids = self.pool.get('s3.object').search(cr, uid, [('contactus_banner_500340', '=', True)],
                                                          limit=1)
        if s3_object_ids:
            return dict(contactus_banner_500340=s3_object_ids[0])
        else:
            return dict(contactus_banner_500340=False)

    def get_default_company_logo(self,cr,uid,ids,context=None):
        s3_object_ids = self.pool.get('s3.object').search(cr,uid,[('company_logo','=',True)],limit=1)
        if s3_object_ids:
            return dict(company_logo=s3_object_ids[0])
        else:
            return dict(company_logo=False)

    def set_default_company_logo(self,cr,uid,ids,context=None):
        myself = self.browse(cr,uid,ids[0],context=context)
        s3_object = self.pool.get('s3.object')
        existing_banner_ids = s3_object.search(cr,uid,[('company_logo','=',True),('id','!=',myself.company_logo.id)])
        if existing_banner_ids:
            for i in existing_banner_ids:
                s3_object.unlink(cr,uid,i)
        s3_object.write(cr,uid,myself.checkout_banner.id,{'company_logo':True})        

    _columns = {
            'site_name':fields.char("Site Name"),
            'aws_access_id' : fields.char("AWS Access ID"),
            'aws_secret_key' : fields.char('AWS Secret Key'),
            'root_bucket':fields.char("Root Bucket"),
#             'website_banner_key' : fields.char("Website Banner Bucket Key"),
#             'website_policy_key' : fields.char("Website Policy Bucket Key"),
#             'volume_key':fields.char("Volumes Bucket Key"),
            'aws_base_url':fields.char("S3 Base URL",help="This is required so that when determining the url we do not have to send extra request to determine the location of the bucket"),
            'meta_keywords':fields.text("Meta Keywords"),
            'meta_description':fields.text('Meta Description'),
            'attribute_value_ids':fields.many2many('product.attribute.value','django_panel_settings_attribute_value',column1='django_panel_settings_id',column2='attribute_value_id',
                                                   string = "Volumes available to Normal Website Visitors",domain=_get_domain_volume,
                                                   ),
            'mailing_list_id':fields.many2one('mail.mass_mailing.list','News Letter Mailing List'),
            'attributes_available_ids':fields.many2many('product.attribute.value','django_panel_settings_attribute_value_available',column1='django_panel_settings_id',column2='attribute_value_id',
                                                   string = "Volumes available to Businesses",domain=_get_domain_volume,
                                                   ),
            'shipping_returns_policy_banner':fields.many2one('s3.object',string="Shipping & Returns Policy Banner"),
            'aboutus_banner':fields.many2one('s3.object',string="About Us Banner"),
            'checkout_banner':fields.many2one('s3.object',string="Checkout Banner"),
            'terms_conditions_banner':fields.many2one('s3.object',string="Terms & Conditions Banner"),
            'privacy_policy_banner':fields.many2one('s3.object',string="Privacy Policy Banner"),
            'search_banner':fields.many2one('s3.object',string = "Search Banner"),
            'contactus_banner':fields.many2one('s3.object',string="Contact Us Banner"),
            'company_logo':fields.many2one('s3.object',string="Company Logo"),
            'contactus_banner_500340': fields.many2one('s3.object', string="Contact Us Banner (500x340)"),
            'customerreview_banner':fields.many2one('s3.object',string="Customer Review Banner"),
            'promo_business_ids':fields.many2many('website.policy','django_panel_settings_website_policy',column1='django_panel_settings_id',column2='policy_id',
                                                   string = "Business Promotions"),
            'promo_non_business_ids':fields.many2many('website.policy','django_panel_settings_non_business_website_policy',column1='django_panel_settings_id',column2='policy_id',
                                                   string = "Non Business Promotions"),
            'website_url':fields.char('Website URL'),
            'website_username':fields.char('Website Username'),
            'website_pwd': fields.char('Website Password'),
        }
Ejemplo n.º 4
0
class project_issue(osv.Model):
    _name = "project.issue"
    _description = "Project Issue"
    _order = "priority desc, create_date desc"
    _inherit = ['mail.thread', 'ir.needaction_mixin']
    _mail_post_access = 'read'

    def _get_default_partner(self, cr, uid, context=None):
        if context is None:
            context = {}
        if 'default_project_id' in context:
            project = self.pool.get('project.project').browse(
                cr, uid, context['default_project_id'], context=context)
            if project and project.partner_id:
                return project.partner_id.id
        return False

    def _get_default_stage_id(self, cr, uid, context=None):
        """ Gives default stage_id """
        if context is None:
            context = {}
        return self.stage_find(cr,
                               uid, [],
                               context.get('default_project_id'),
                               [('fold', '=', False)],
                               context=context)

    def _read_group_stage_ids(self,
                              cr,
                              uid,
                              ids,
                              domain,
                              read_group_order=None,
                              access_rights_uid=None,
                              context=None):
        if context is None:
            context = {}
        access_rights_uid = access_rights_uid or uid
        stage_obj = self.pool.get('project.task.type')
        order = stage_obj._order
        # lame hack to allow reverting search, should just work in the trivial case
        if read_group_order == 'stage_id desc':
            order = "%s desc" % order
        # retrieve team_id from the context, add them to already fetched columns (ids)
        if 'default_project_id' in context:
            search_domain = [
                '|', ('project_ids', '=', context['default_project_id']),
                ('id', 'in', ids)
            ]
        else:
            search_domain = [('id', 'in', ids)]
        # perform search
        stage_ids = stage_obj._search(cr,
                                      uid,
                                      search_domain,
                                      order=order,
                                      access_rights_uid=access_rights_uid,
                                      context=context)
        result = stage_obj.name_get(cr,
                                    access_rights_uid,
                                    stage_ids,
                                    context=context)
        # restore order of the search
        result.sort(
            lambda x, y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0])))

        fold = {}
        for stage in stage_obj.browse(cr,
                                      access_rights_uid,
                                      stage_ids,
                                      context=context):
            fold[stage.id] = stage.fold or False
        return result, fold

    def _compute_day(self, cr, uid, ids, fields, args, context=None):
        """
        @param cr: the current row, from the database cursor,
        @param uid: the current user’s ID for security checks,
        @param ids: List of Openday’s IDs
        @return: difference between current date and log date
        @param context: A standard dictionary for contextual values
        """
        Calendar = self.pool['resource.calendar']

        res = dict((res_id, {}) for res_id in ids)
        for issue in self.browse(cr, uid, ids, context=context):
            values = {
                'day_open': 0.0,
                'day_close': 0.0,
                'working_hours_open': 0.0,
                'working_hours_close': 0.0,
                'days_since_creation': 0.0,
                'inactivity_days': 0.0,
            }
            # if the working hours on the project are not defined, use default ones (8 -> 12 and 13 -> 17 * 5), represented by None
            calendar_id = None
            if issue.project_id and issue.project_id.resource_calendar_id:
                calendar_id = issue.project_id.resource_calendar_id.id

            dt_create_date = datetime.strptime(issue.create_date,
                                               DEFAULT_SERVER_DATETIME_FORMAT)

            if issue.date_open:
                dt_date_open = datetime.strptime(
                    issue.date_open, DEFAULT_SERVER_DATETIME_FORMAT)
                values['day_open'] = (dt_date_open - dt_create_date
                                      ).total_seconds() / (24.0 * 3600)
                values['working_hours_open'] = Calendar._interval_hours_get(
                    cr,
                    uid,
                    calendar_id,
                    dt_create_date,
                    dt_date_open,
                    timezone_from_uid=issue.user_id.id or uid,
                    exclude_leaves=False,
                    context=context)

            if issue.date_closed:
                dt_date_closed = datetime.strptime(
                    issue.date_closed, DEFAULT_SERVER_DATETIME_FORMAT)
                values['day_close'] = (dt_date_closed - dt_create_date
                                       ).total_seconds() / (24.0 * 3600)
                values['working_hours_close'] = Calendar._interval_hours_get(
                    cr,
                    uid,
                    calendar_id,
                    dt_create_date,
                    dt_date_closed,
                    timezone_from_uid=issue.user_id.id or uid,
                    exclude_leaves=False,
                    context=context)

            days_since_creation = datetime.today() - dt_create_date
            values['days_since_creation'] = days_since_creation.days
            if issue.date_action_last:
                inactive_days = datetime.today() - datetime.strptime(
                    issue.date_action_last, DEFAULT_SERVER_DATETIME_FORMAT)
            elif issue.date_last_stage_update:
                inactive_days = datetime.today() - datetime.strptime(
                    issue.date_last_stage_update,
                    DEFAULT_SERVER_DATETIME_FORMAT)
            else:
                inactive_days = datetime.today() - datetime.strptime(
                    issue.create_date, DEFAULT_SERVER_DATETIME_FORMAT)
            values['inactivity_days'] = inactive_days.days

            # filter only required values
            for field in fields:
                res[issue.id][field] = values[field]

        return res

    def on_change_project(self, cr, uid, ids, project_id, context=None):
        if project_id:
            project = self.pool.get('project.project').browse(cr,
                                                              uid,
                                                              project_id,
                                                              context=context)
            if project and project.partner_id:
                return {'value': {'partner_id': project.partner_id.id}}
        return {}

    _columns = {
        'id': fields.integer('ID', readonly=True),
        'name': fields.char('Issue', required=True),
        'active': fields.boolean('Active', required=False),
        'create_date': fields.datetime('Creation Date', readonly=True, select=True),
        'write_date': fields.datetime('Update Date', readonly=True),
        'days_since_creation': fields.function(_compute_day, string='Days since creation date', \
                                               multi='compute_day', type="integer", help="Difference in days between creation date and current date",
                                               groups='base.group_user'),
        'date_deadline': fields.date('Deadline'),
        'team_id': fields.many2one('crm.team', 'Sales Team', oldname='section_id',\
                        select=True, help='Sales team to which Case belongs to.\
                             Define Responsible user and Email account for mail gateway.'                                                                                         ),
        'partner_id': fields.many2one('res.partner', 'Contact', select=1),
        'company_id': fields.many2one('res.company', 'Company'),
        'description': fields.text('Private Note'),
        'kanban_state': fields.selection([('normal', 'Normal'),('blocked', 'Blocked'),('done', 'Ready for next stage')], 'Kanban State',
                                         track_visibility='onchange',
                                         help="A Issue's kanban state indicates special situations affecting it:\n"
                                              " * Normal is the default situation\n"
                                              " * Blocked indicates something is preventing the progress of this issue\n"
                                              " * Ready for next stage indicates the issue is ready to be pulled to the next stage",
                                         required=True),
        'email_from': fields.char('Email', size=128, help="These people will receive email.", select=1),
        'email_cc': fields.char('Watchers Emails', size=256, help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
        'date_open': fields.datetime('Assigned', readonly=True, select=True),
        # Project Issue fields
        'date_closed': fields.datetime('Closed', readonly=True, select=True),
        'date': fields.datetime('Date'),
        'date_last_stage_update': fields.datetime('Last Stage Update', select=True),
        'channel': fields.char('Channel', help="Communication channel."),
        'tag_ids': fields.many2many('project.tags', string='Tags'),
        'priority': fields.selection([('0','Low'), ('1','Normal'), ('2','High')], 'Priority', select=True),
        'stage_id': fields.many2one ('project.task.type', 'Stage',
                        track_visibility='onchange', select=True,
                        domain="[('project_ids', '=', project_id)]", copy=False),
        'project_id': fields.many2one('project.project', 'Project', track_visibility='onchange', select=True),
        'duration': fields.float('Duration'),
        'task_id': fields.many2one('project.task', 'Task', domain="[('project_id','=',project_id)]",
            help="You can link this issue to an existing task or directly create a new one from here"),
        'day_open': fields.function(_compute_day, string='Days to Assign',
                                    multi='compute_day', type="float",
                                    store={'project.issue': (lambda self, cr, uid, ids, c={}: ids, ['date_open'], 10)},
                                    groups='base.group_user'),
        'day_close': fields.function(_compute_day, string='Days to Close',
                                     multi='compute_day', type="float",
                                     store={'project.issue': (lambda self, cr, uid, ids, c={}: ids, ['date_closed'], 10)},
                                     groups='base.group_user'),
        'user_id': fields.many2one('res.users', 'Assigned to', required=False, select=1, track_visibility='onchange'),
        'working_hours_open': fields.function(_compute_day, string='Working Hours to assign the Issue',
                                              multi='compute_day', type="float",
                                              store={'project.issue': (lambda self, cr, uid, ids, c={}: ids, ['date_open'], 10)},
                                              groups='base.group_user'),
        'working_hours_close': fields.function(_compute_day, string='Working Hours to close the Issue',
                                               multi='compute_day', type="float",
                                               store={'project.issue': (lambda self, cr, uid, ids, c={}: ids, ['date_closed'], 10)},
                                               groups='base.group_user'),
        'inactivity_days': fields.function(_compute_day, string='Days since last action',
                                           multi='compute_day', type="integer", help="Difference in days between last action and current date",
                                           groups='base.group_user'),
        'color': fields.integer('Color Index'),
        'user_email': fields.related('user_id', 'email', type='char', string='User Email', readonly=True),
        'date_action_last': fields.datetime('Last Action', readonly=1),
        'date_action_next': fields.datetime('Next Action', readonly=1),
        'legend_blocked': fields.related("stage_id", "legend_blocked", type="char", string='Kanban Blocked Explanation'),
        'legend_done': fields.related("stage_id", "legend_done", type="char", string='Kanban Valid Explanation'),
        'legend_normal': fields.related("stage_id", "legend_normal", type="char", string='Kanban Ongoing Explanation'),
    }

    _defaults = {
        'active':
        1,
        'team_id':
        lambda s, cr, uid, c: s.pool['crm.team']._get_default_team_id(
            cr, uid, context=c),
        'stage_id':
        lambda s, cr, uid, c: s._get_default_stage_id(cr, uid, c),
        'company_id':
        lambda s, cr, uid, c: s.pool['res.users']._get_company(
            cr, uid, context=c),
        'priority':
        '0',
        'kanban_state':
        'normal',
        'date_last_stage_update':
        fields.datetime.now,
        'user_id':
        lambda obj, cr, uid, context: uid,
    }

    _group_by_full = {'stage_id': _read_group_stage_ids}

    def copy(self, cr, uid, id, default=None, context=None):
        issue = self.read(cr, uid, [id], ['name'], context=context)[0]
        if not default:
            default = {}
        default = default.copy()
        default.update(name=_('%s (copy)') % (issue['name']))
        return super(project_issue, self).copy(cr,
                                               uid,
                                               id,
                                               default=default,
                                               context=context)

    def create(self, cr, uid, vals, context=None):
        context = dict(context or {})
        if vals.get('project_id') and not context.get('default_project_id'):
            context['default_project_id'] = vals.get('project_id')
        if vals.get('user_id') and not vals.get('date_open'):
            vals['date_open'] = fields.datetime.now()
        if 'stage_id' in vals:
            vals.update(
                self.onchange_stage_id(cr,
                                       uid,
                                       None,
                                       vals.get('stage_id'),
                                       context=context)['value'])

        # context: no_log, because subtype already handle this
        create_context = dict(context, mail_create_nolog=True)
        return super(project_issue, self).create(cr,
                                                 uid,
                                                 vals,
                                                 context=create_context)

    def write(self, cr, uid, ids, vals, context=None):
        # stage change: update date_last_stage_update
        if 'stage_id' in vals:
            vals.update(
                self.onchange_stage_id(cr,
                                       uid,
                                       ids,
                                       vals.get('stage_id'),
                                       context=context)['value'])
            vals['date_last_stage_update'] = fields.datetime.now()
            if 'kanban_state' not in vals:
                vals['kanban_state'] = 'normal'
        # user_id change: update date_open
        if vals.get('user_id') and 'date_open' not in vals:
            vals['date_open'] = fields.datetime.now()

        return super(project_issue, self).write(cr, uid, ids, vals, context)

    def onchange_task_id(self, cr, uid, ids, task_id, context=None):
        if not task_id:
            return {'value': {}}
        task = self.pool.get('project.task').browse(cr,
                                                    uid,
                                                    task_id,
                                                    context=context)
        return {
            'value': {
                'user_id': task.user_id.id,
            }
        }

    def onchange_partner_id(self, cr, uid, ids, partner_id, context=None):
        """ This function returns value of partner email address based on partner
            :param part: Partner's id
        """
        if partner_id:
            partner = self.pool['res.partner'].browse(cr, uid, partner_id,
                                                      context)
            return {'value': {'email_from': partner.email}}
        return {'value': {'email_from': False}}

    def get_empty_list_help(self, cr, uid, help, context=None):
        context = dict(context or {})
        context['empty_list_help_model'] = 'project.project'
        context['empty_list_help_id'] = context.get('default_project_id')
        context['empty_list_help_document_name'] = _("issues")
        return super(project_issue, self).get_empty_list_help(cr,
                                                              uid,
                                                              help,
                                                              context=context)

    # -------------------------------------------------------
    # Stage management
    # -------------------------------------------------------

    def onchange_stage_id(self, cr, uid, ids, stage_id, context=None):
        if not stage_id:
            return {'value': {}}
        stage = self.pool['project.task.type'].browse(cr,
                                                      uid,
                                                      stage_id,
                                                      context=context)
        if stage.fold:
            return {'value': {'date_closed': fields.datetime.now()}}
        return {'value': {'date_closed': False}}

    def stage_find(self,
                   cr,
                   uid,
                   cases,
                   team_id,
                   domain=[],
                   order='sequence',
                   context=None):
        """ Override of the base.stage method
            Parameter of the stage search taken from the issue:
            - type: stage type must be the same or 'both'
            - team_id: if set, stages must belong to this team or
              be a default case
        """
        if isinstance(cases, (int, long)):
            cases = self.browse(cr, uid, cases, context=context)
        # collect all team_ids
        team_ids = []
        if team_id:
            team_ids.append(team_id)
        for task in cases:
            if task.project_id:
                team_ids.append(task.project_id.id)
        # OR all team_ids and OR with case_default
        search_domain = []
        if team_ids:
            search_domain += [('|')] * (len(team_ids) - 1)
            for team_id in team_ids:
                search_domain.append(('project_ids', '=', team_id))
        search_domain += list(domain)
        # perform search, return the first found
        stage_ids = self.pool.get('project.task.type').search(cr,
                                                              uid,
                                                              search_domain,
                                                              order=order,
                                                              context=context)
        if stage_ids:
            return stage_ids[0]
        return False

    # -------------------------------------------------------
    # Mail gateway
    # -------------------------------------------------------

    def _track_subtype(self, cr, uid, ids, init_values, context=None):
        record = self.browse(cr, uid, ids[0], context=context)
        if 'kanban_state' in init_values and record.kanban_state == 'blocked':
            return 'project_issue.mt_issue_blocked'
        elif 'kanban_state' in init_values and record.kanban_state == 'done':
            return 'project_issue.mt_issue_ready'
        elif 'user_id' in init_values and record.user_id:  # assigned -> new
            return 'project_issue.mt_issue_new'
        elif 'stage_id' in init_values and record.stage_id and record.stage_id.sequence <= 1:  # start stage -> new
            return 'project_issue.mt_issue_new'
        elif 'stage_id' in init_values:
            return 'project_issue.mt_issue_stage'
        return super(project_issue, self)._track_subtype(cr,
                                                         uid,
                                                         ids,
                                                         init_values,
                                                         context=context)

    def _notification_group_recipients(self,
                                       cr,
                                       uid,
                                       ids,
                                       message,
                                       recipients,
                                       done_ids,
                                       group_data,
                                       context=None):
        """ Override the mail.thread method to handle project users and officers
        recipients. Indeed those will have specific action in their notification
        emails: creating tasks, assigning it. """
        group_project_user = self.pool['ir.model.data'].xmlid_to_res_id(
            cr, uid, 'project.group_project_user')
        group_user = self.pool['ir.model.data'].xmlid_to_res_id(
            cr, uid, 'base.group_user')
        for recipient in recipients:
            if recipient.id in done_ids:
                continue
            if recipient.user_ids and group_project_user in recipient.user_ids[
                    0].groups_id.ids:
                group_data['group_project_user'] |= recipient
            elif not recipient.user_ids:
                group_data['partner'] |= recipient
            else:
                group_data['user'] |= recipient
            done_ids.add(recipient.id)
        return super(project_issue,
                     self)._notification_group_recipients(cr,
                                                          uid,
                                                          ids,
                                                          message,
                                                          recipients,
                                                          done_ids,
                                                          group_data,
                                                          context=context)

    def _notification_get_recipient_groups(self,
                                           cr,
                                           uid,
                                           ids,
                                           message,
                                           recipients,
                                           context=None):
        res = super(project_issue,
                    self)._notification_get_recipient_groups(cr,
                                                             uid,
                                                             ids,
                                                             message,
                                                             recipients,
                                                             context=context)

        new_action_id = self.pool['ir.model.data'].xmlid_to_res_id(
            cr, uid, 'project_issue.project_issue_categ_act0')
        take_action = self._notification_link_helper(cr,
                                                     uid,
                                                     ids,
                                                     'assign',
                                                     context=context)
        new_action = self._notification_link_helper(cr,
                                                    uid,
                                                    ids,
                                                    'new',
                                                    context=context,
                                                    action_id=new_action_id)

        task_record = self.browse(cr, uid, ids[0], context=context)
        actions = []
        if not task_record.user_id:
            actions.append({'url': take_action, 'title': _('I take it')})
        else:
            actions.append({'url': new_action, 'title': _('New Issue')})

        res['group_project_user'] = {'actions': actions}
        return res

    @api.cr_uid_context
    def message_get_reply_to(self, cr, uid, ids, default=None, context=None):
        """ Override to get the reply_to of the parent project. """
        issues = self.browse(cr, SUPERUSER_ID, ids, context=context)
        project_ids = set(
            [issue.project_id.id for issue in issues if issue.project_id])
        aliases = self.pool['project.project'].message_get_reply_to(
            cr, uid, list(project_ids), default=default, context=context)
        return dict(
            (issue.id,
             aliases.get(issue.project_id and issue.project_id.id or 0, False))
            for issue in issues)

    def message_get_suggested_recipients(self, cr, uid, ids, context=None):
        recipients = super(project_issue,
                           self).message_get_suggested_recipients(
                               cr, uid, ids, context=context)
        try:
            for issue in self.browse(cr, uid, ids, context=context):
                if issue.partner_id:
                    issue._message_add_suggested_recipient(
                        recipients,
                        partner=issue.partner_id,
                        reason=_('Customer'))
                elif issue.email_from:
                    issue._message_add_suggested_recipient(
                        recipients,
                        email=issue.email_from,
                        reason=_('Customer Email'))
        except AccessError:  # no read access rights -> just ignore suggested recipients because this imply modifying followers
            pass
        return recipients

    def email_split(self, cr, uid, ids, msg, context=None):
        email_list = tools.email_split((msg.get('to') or '') + ',' +
                                       (msg.get('cc') or ''))
        # check left-part is not already an alias
        issue_ids = self.browse(cr, uid, ids, context=context)
        aliases = [
            issue.project_id.alias_name for issue in issue_ids
            if issue.project_id
        ]
        return filter(lambda x: x.split('@')[0] not in aliases, email_list)

    def message_new(self, cr, uid, msg, custom_values=None, context=None):
        """ Overrides mail_thread message_new that is called by the mailgateway
            through message_process.
            This override updates the document according to the email.
        """
        if custom_values is None:
            custom_values = {}
        context = dict(context or {}, state_to='draft')
        defaults = {
            'name': msg.get('subject') or _("No Subject"),
            'email_from': msg.get('from'),
            'email_cc': msg.get('cc'),
            'partner_id': msg.get('author_id', False),
            'user_id': False,
        }
        defaults.update(custom_values)

        res_id = super(project_issue, self).message_new(cr,
                                                        uid,
                                                        msg,
                                                        custom_values=defaults,
                                                        context=context)
        email_list = self.email_split(cr, uid, [res_id], msg, context=context)
        partner_ids = filter(
            None,
            self._find_partner_from_emails(cr,
                                           uid, [res_id],
                                           email_list,
                                           force_create=False,
                                           context=context))
        self.message_subscribe(cr, uid, [res_id], partner_ids, context=context)
        return res_id

    def message_update(self,
                       cr,
                       uid,
                       ids,
                       msg,
                       update_vals=None,
                       context=None):
        """ Override to update the issue according to the email. """

        email_list = self.email_split(cr, uid, ids, msg, context=context)
        partner_ids = filter(
            None,
            self._find_partner_from_emails(cr,
                                           uid,
                                           ids,
                                           email_list,
                                           force_create=False,
                                           context=context))
        self.message_subscribe(cr, uid, ids, partner_ids, context=context)
        return super(project_issue,
                     self).message_update(cr,
                                          uid,
                                          ids,
                                          msg,
                                          update_vals=update_vals,
                                          context=context)

    @api.cr_uid_ids_context
    @api.returns('mail.message', lambda value: value.id)
    def message_post(self,
                     cr,
                     uid,
                     thread_id,
                     subtype=None,
                     context=None,
                     **kwargs):
        """ Overrides mail_thread message_post so that we can set the date of last action field when
            a new message is posted on the issue.
        """
        if context is None:
            context = {}
        res = super(project_issue, self).message_post(cr,
                                                      uid,
                                                      thread_id,
                                                      subtype=subtype,
                                                      context=context,
                                                      **kwargs)
        if thread_id and subtype:
            self.write(cr,
                       SUPERUSER_ID,
                       thread_id, {'date_action_last': fields.datetime.now()},
                       context=context)
        return res
Ejemplo n.º 5
0
class pos_most_sold_product_wzd(osv.osv_memory):
    _name = 'pos.most.sold.product.wzd'
    _description = 'Most Sold Products'

    _columns = {
        'nbr_product':
        fields.integer('Nr. Products', help="Number of most sold products"),
        'nbr_records':
        fields.integer('Nr. Records', help="Number of records"),
        'date_start':
        fields.date('Date Start', required=True),
        'date_end':
        fields.date('Date End', required=True),
        'partner_ids':
        fields.many2many('res.partner', 'pos_most_sold_product_partner_rel',
                         'partner_id', 'wizard_id', 'Customers'),
    }

    _defaults = {
        'nbr_product': 1,
        'nbr_records': 40,
        'date_start': lambda *a: time.strftime('%Y-%m-01'),
        'date_end': fields.date.context_today,
    }

    def execute_query(self, cr, uid, ids, create_parent=False, context=None):

        obj = self.browse(cr, uid, ids[0])
        query = """
            select * from (
            SELECT *, ROW_NUMBER() OVER () as fila
            FROM
                (
                    SELECT      
                        s.partner_id AS partner_id,
                        l.product_id AS product_id,
                        SUM (l.qty * u.factor) AS product_qty,
                        MIN (l.price_unit) AS product_unit_price,
                        SUM (l.qty * l.price_unit) AS price_total,
                        to_char(date_trunc('day',s.date_order),'YYYY-MM-DD')::text as date_order,                  
                        ROW_NUMBER() OVER (PARTITION BY s.partner_id ORDER BY SUM (l.qty * u.factor) DESC ) row_num,
                        cl.name as client_name
                    FROM
                        pos_order_line AS l
                        LEFT JOIN pos_order s ON (s. ID = l.order_id) 
                        LEFT JOIN res_partner cl ON (s.partner_id = cl.ID)                           
                        LEFT JOIN product_product P ON (P . ID = l.product_id)
                        LEFT JOIN product_template pt ON (pt. ID = P .product_tmpl_id)
                        LEFT JOIN product_uom u ON (u. ID = pt.uom_id) 
                    %s 
                    GROUP BY
                        s.partner_id,
                        cl.name,
                        l.product_id,
                        to_char(date_trunc('day',s.date_order),'YYYY-MM-DD')::text
                    ORDER BY
                        cl.name, 
                        l.product_id,
                        to_char(date_trunc('day',s.date_order),'YYYY-MM-DD')::text DESC,
                        SUM (l.qty * u.factor) DESC
                ) A
                WHERE A.row_num <= %s
            ) B WHERE B.fila <= %s
        """

        partner_ids = []
        with_customers = False
        if obj.partner_ids:
            with_customers = True
            for p in obj.partner_ids:
                if p.id not in partner_ids:
                    partner_ids.append(p.id)

        whereCondition = ' '
        if with_customers:
            filter_values = (obj.date_start, obj.date_end, tuple(partner_ids))
            whereCondition = " where cast(s.date_order as date) BETWEEN '%s' and '%s' and s.partner_id in %s " % filter_values
        else:
            filter_values = (obj.date_start, obj.date_end)
            whereCondition = " where cast(s.date_order as date) BETWEEN '%s' and '%s'" % filter_values

        str_query = query % (whereCondition, obj.nbr_product, obj.nbr_records)
        cr.execute(str_query)

        lines = cr.fetchall()
        line_ids = self.pool.get('pos.most.sold.product.line').search(
            cr, uid, [])
        self.pool.get('pos.most.sold.product.line').unlink(cr, uid, line_ids)

        rpt_lines = []
        for line in lines:
            if line[0]:
                vals = {
                    'partner_id': line[0],
                    'product_id': line[1],
                    'product_qty': line[2],
                    'product_unit_price': line[3],
                    'price_total': line[4],
                    'date_order': line[5]
                }
                if not create_parent:
                    rpt_lines.append(
                        self.pool.get('pos.most.sold.product.line').create(
                            cr, uid, vals))
                else:
                    rpt_lines.append((0, 0, vals))
        if create_parent:
            line_ids = self.pool.get('pos.most.sold.product').search(
                cr, uid, [])
            self.pool.get('pos.most.sold.product').unlink(cr, uid, line_ids)

            dict_parent = {
                'nbr_product': obj.nbr_product,
                'date_start': obj.date_start,
                'date_end': obj.date_end,
                'user_id': uid,
                'line_ids': rpt_lines
            }
            return [
                self.pool.get('pos.most.sold.product').create(
                    cr, uid, dict_parent)
            ]
        else:
            return rpt_lines

    def show_sale_analysis_view(self, cr, uid, ids, context=None):

        rpt_lines = self.execute_query(cr, uid, ids, False, context)
        if rpt_lines:
            mod_obj = self.pool.get('ir.model.data')
            res = mod_obj.get_object_reference(
                cr, uid, 'my_point_of_sale',
                'view_report_pos_most_sold_product_graph')
            res_id = res and res[1] or False
            return {
                'name': 'Products Sale Analysis',
                'view_type': 'form',
                'view_mode': 'graph',
                'view_id': [res_id],
                'res_model': 'pos.most.sold.product.line',
                'type': 'ir.actions.act_window',
                'target': 'current',
            }

    def print_report_pdf(self, cr, uid, ids, context=None):

        if context is None:
            context = {}
        rpt_lines = self.execute_query(cr, uid, ids, True, context)
        datas = {'ids': rpt_lines}
        return {
            'type': 'ir.actions.report.xml',
            'report_name': 'pos_most_sold_product_report',
            'datas': datas,
        }
Ejemplo n.º 6
0
class stock_landed_cost(osv.osv):
    _name = 'stock.landed.cost'
    _description = 'Stock Landed Cost'
    _inherit = 'mail.thread'

    def _total_amount(self, cr, uid, ids, name, args, context=None):
        result = {}
        for cost in self.browse(cr, uid, ids, context=context):
            total = 0.0
            for line in cost.cost_lines:
                total += line.price_unit
            result[cost.id] = total
        return result

    def _get_cost_line(self, cr, uid, ids, context=None):
        cost_to_recompute = []
        for line in self.pool.get('stock.landed.cost.lines').browse(
                cr, uid, ids, context=context):
            cost_to_recompute.append(line.cost_id.id)
        return cost_to_recompute

    def get_valuation_lines(self,
                            cr,
                            uid,
                            ids,
                            picking_ids=None,
                            context=None):
        picking_obj = self.pool.get('stock.picking')
        lines = []
        if not picking_ids:
            return lines

        for picking in picking_obj.browse(cr, uid, picking_ids):
            for move in picking.move_lines:
                #it doesn't make sense to make a landed cost for a product that isn't set as being valuated in real time at real cost
                if move.product_id.valuation != 'real_time' or move.product_id.cost_method != 'real':
                    continue
                total_cost = 0.0
                total_qty = move.product_qty
                weight = move.product_id and move.product_id.weight * move.product_qty
                volume = move.product_id and move.product_id.volume * move.product_qty
                for quant in move.quant_ids:
                    total_cost += quant.cost
                vals = dict(product_id=move.product_id.id,
                            move_id=move.id,
                            quantity=move.product_uom_qty,
                            former_cost=total_cost * total_qty,
                            weight=weight,
                            volume=volume)
                lines.append(vals)
        if not lines:
            raise UserError(
                _('The selected picking does not contain any move that would be impacted by landed costs. Landed costs are only possible for products configured in real time valuation with real price costing method. Please make sure it is the case, or you selected the correct picking'
                  ))
        return lines

    _columns = {
        'name':
        fields.char('Name',
                    track_visibility='always',
                    readonly=True,
                    copy=False),
        'date':
        fields.date('Date',
                    required=True,
                    states={'done': [('readonly', True)]},
                    track_visibility='onchange',
                    copy=False),
        'picking_ids':
        fields.many2many('stock.picking',
                         string='Pickings',
                         states={'done': [('readonly', True)]},
                         copy=False),
        'cost_lines':
        fields.one2many('stock.landed.cost.lines',
                        'cost_id',
                        'Cost Lines',
                        states={'done': [('readonly', True)]},
                        copy=True),
        'valuation_adjustment_lines':
        fields.one2many('stock.valuation.adjustment.lines',
                        'cost_id',
                        'Valuation Adjustments',
                        states={'done': [('readonly', True)]}),
        'description':
        fields.text('Item Description', states={'done': [('readonly', True)]}),
        'amount_total':
        fields.function(_total_amount,
                        type='float',
                        string='Total',
                        digits=0,
                        store={
                            'stock.landed.cost':
                            (lambda self, cr, uid, ids, c={}: ids,
                             ['cost_lines'], 20),
                            'stock.landed.cost.lines':
                            (_get_cost_line,
                             ['price_unit', 'quantity', 'cost_id'], 20),
                        },
                        track_visibility='always'),
        'state':
        fields.selection([('draft', 'Draft'), ('done', 'Posted'),
                          ('cancel', 'Cancelled')],
                         'State',
                         readonly=True,
                         track_visibility='onchange',
                         copy=False),
        'account_move_id':
        fields.many2one('account.move',
                        'Journal Entry',
                        readonly=True,
                        copy=False),
        'account_journal_id':
        fields.many2one('account.journal',
                        'Account Journal',
                        required=True,
                        states={'done': [('readonly', True)]}),
    }

    _defaults = {
        'name':
        lambda obj, cr, uid, context: obj.pool.get('ir.sequence').next_by_code(
            cr, uid, 'stock.landed.cost'),
        'state':
        'draft',
        'date':
        fields.date.context_today,
    }

    def _create_accounting_entries(self,
                                   cr,
                                   uid,
                                   line,
                                   move_id,
                                   qty_out,
                                   context=None):
        product_obj = self.pool.get('product.template')
        cost_product = line.cost_line_id and line.cost_line_id.product_id
        if not cost_product:
            return False
        accounts = product_obj.browse(cr,
                                      uid,
                                      line.product_id.product_tmpl_id.id,
                                      context=context).get_product_accounts()
        debit_account_id = accounts.get(
            'stock_valuation',
            False) and accounts['stock_valuation'].id or False
        already_out_account_id = accounts['stock_output'].id
        credit_account_id = line.cost_line_id.account_id.id or cost_product.property_account_expense_id.id or cost_product.categ_id.property_account_expense_categ_id.id

        if not credit_account_id:
            raise UserError(
                _('Please configure Stock Expense Account for product: %s.') %
                (cost_product.name))

        return self._create_account_move_line(cr,
                                              uid,
                                              line,
                                              move_id,
                                              credit_account_id,
                                              debit_account_id,
                                              qty_out,
                                              already_out_account_id,
                                              context=context)

    def _create_account_move_line(self,
                                  cr,
                                  uid,
                                  line,
                                  move_id,
                                  credit_account_id,
                                  debit_account_id,
                                  qty_out,
                                  already_out_account_id,
                                  context=None):
        """
        Generate the account.move.line values to track the landed cost.
        Afterwards, for the goods that are already out of stock, we should create the out moves
        """
        aml_obj = self.pool.get('account.move.line')
        if context is None:
            context = {}
        ctx = context.copy()
        ctx['check_move_validity'] = False
        base_line = {
            'name': line.name,
            'move_id': move_id,
            'product_id': line.product_id.id,
            'quantity': line.quantity,
        }
        debit_line = dict(base_line, account_id=debit_account_id)
        credit_line = dict(base_line, account_id=credit_account_id)
        diff = line.additional_landed_cost
        if diff > 0:
            debit_line['debit'] = diff
            credit_line['credit'] = diff
        else:
            # negative cost, reverse the entry
            debit_line['credit'] = -diff
            credit_line['debit'] = -diff
        aml_obj.create(cr, uid, debit_line, context=ctx)
        aml_obj.create(cr, uid, credit_line, context=ctx)

        #Create account move lines for quants already out of stock
        if qty_out > 0:
            debit_line = dict(debit_line,
                              name=(line.name + ": " + str(qty_out) +
                                    _(' already out')),
                              quantity=qty_out,
                              account_id=already_out_account_id)
            credit_line = dict(credit_line,
                               name=(line.name + ": " + str(qty_out) +
                                     _(' already out')),
                               quantity=qty_out,
                               account_id=debit_account_id)
            diff = diff * qty_out / line.quantity
            if diff > 0:
                debit_line['debit'] = diff
                credit_line['credit'] = diff
            else:
                # negative cost, reverse the entry
                debit_line['credit'] = -diff
                credit_line['debit'] = -diff
            aml_obj.create(cr, uid, debit_line, context=ctx)
            aml_obj.create(cr, uid, credit_line, context=ctx)
        self.pool.get('account.move').assert_balanced(cr,
                                                      uid, [move_id],
                                                      context=context)
        return True

    def _create_account_move(self, cr, uid, cost, context=None):
        vals = {
            'journal_id': cost.account_journal_id.id,
            'date': cost.date,
            'ref': cost.name
        }
        return self.pool.get('account.move').create(cr,
                                                    uid,
                                                    vals,
                                                    context=context)

    def _check_sum(self, cr, uid, landed_cost, context=None):
        """
        Will check if each cost line its valuation lines sum to the correct amount
        and if the overall total amount is correct also
        """
        costcor = {}
        tot = 0
        for valuation_line in landed_cost.valuation_adjustment_lines:
            if costcor.get(valuation_line.cost_line_id):
                costcor[valuation_line.
                        cost_line_id] += valuation_line.additional_landed_cost
            else:
                costcor[valuation_line.
                        cost_line_id] = valuation_line.additional_landed_cost
            tot += valuation_line.additional_landed_cost

        prec = self.pool['decimal.precision'].precision_get(cr, uid, 'Account')
        # float_compare returns 0 for equal amounts
        res = not bool(
            float_compare(tot, landed_cost.amount_total,
                          precision_digits=prec))
        for costl in costcor.keys():
            if float_compare(costcor[costl],
                             costl.price_unit,
                             precision_digits=prec):
                res = False
        return res

    def button_validate(self, cr, uid, ids, context=None):
        quant_obj = self.pool.get('stock.quant')

        for cost in self.browse(cr, uid, ids, context=context):
            if cost.state != 'draft':
                raise UserError(_('Only draft landed costs can be validated'))
            if not cost.valuation_adjustment_lines or not self._check_sum(
                    cr, uid, cost, context=context):
                raise UserError(
                    _('You cannot validate a landed cost which has no valid valuation adjustments lines. Did you click on Compute?'
                      ))
            move_id = self._create_account_move(cr, uid, cost, context=context)
            quant_dict = {}
            for line in cost.valuation_adjustment_lines:
                if not line.move_id:
                    continue
                per_unit = line.final_cost / line.quantity
                diff = per_unit - line.former_cost_per_unit
                quants = [quant for quant in line.move_id.quant_ids]
                for quant in quants:
                    if quant.id not in quant_dict:
                        quant_dict[quant.id] = quant.cost + diff
                    else:
                        quant_dict[quant.id] += diff
                for key, value in quant_dict.items():
                    print value
                    quant_obj.write(cr,
                                    uid,
                                    key, {'cost': value},
                                    context=context)
                qty_out = 0
                for quant in line.move_id.quant_ids:
                    if quant.location_id.usage != 'internal':
                        qty_out += quant.qty
                self._create_accounting_entries(cr,
                                                uid,
                                                line,
                                                move_id,
                                                qty_out,
                                                context=context)
            self.write(cr,
                       uid,
                       cost.id, {
                           'state': 'done',
                           'account_move_id': move_id
                       },
                       context=context)
            self.pool.get('account.move').post(cr,
                                               uid, [move_id],
                                               context=context)
        return True

    def button_cancel(self, cr, uid, ids, context=None):
        cost = self.browse(cr, uid, ids, context=context)
        if cost.state == 'done':
            raise UserError(
                _('Validated landed costs cannot be cancelled, '
                  'but you could create negative landed costs to reverse them')
            )
        return cost.write({'state': 'cancel'})

    def unlink(self, cr, uid, ids, context=None):
        # cancel or raise first
        self.button_cancel(cr, uid, ids, context)
        return super(stock_landed_cost, self).unlink(cr,
                                                     uid,
                                                     ids,
                                                     context=context)

    def compute_landed_cost(self, cr, uid, ids, context=None):
        line_obj = self.pool.get('stock.valuation.adjustment.lines')
        unlink_ids = line_obj.search(cr,
                                     uid, [('cost_id', 'in', ids)],
                                     context=context)
        line_obj.unlink(cr, uid, unlink_ids, context=context)
        digits = dp.get_precision('Product Price')(cr)
        towrite_dict = {}
        for cost in self.browse(cr, uid, ids, context=None):
            if not cost.picking_ids:
                continue
            picking_ids = [p.id for p in cost.picking_ids]
            total_qty = 0.0
            total_cost = 0.0
            total_weight = 0.0
            total_volume = 0.0
            total_line = 0.0
            vals = self.get_valuation_lines(cr,
                                            uid, [cost.id],
                                            picking_ids=picking_ids,
                                            context=context)
            for v in vals:
                for line in cost.cost_lines:
                    v.update({'cost_id': cost.id, 'cost_line_id': line.id})
                    self.pool.get('stock.valuation.adjustment.lines').create(
                        cr, uid, v, context=context)
                total_qty += v.get('quantity', 0.0)
                total_cost += v.get('former_cost', 0.0)
                total_weight += v.get('weight', 0.0)
                total_volume += v.get('volume', 0.0)
                total_line += 1

            for line in cost.cost_lines:
                value_split = 0.0
                for valuation in cost.valuation_adjustment_lines:
                    value = 0.0
                    if valuation.cost_line_id and valuation.cost_line_id.id == line.id:
                        if line.split_method == 'by_quantity' and total_qty:
                            per_unit = (line.price_unit / total_qty)
                            value = valuation.quantity * per_unit
                        elif line.split_method == 'by_weight' and total_weight:
                            per_unit = (line.price_unit / total_weight)
                            value = valuation.weight * per_unit
                        elif line.split_method == 'by_volume' and total_volume:
                            per_unit = (line.price_unit / total_volume)
                            value = valuation.volume * per_unit
                        elif line.split_method == 'equal':
                            value = (line.price_unit / total_line)
                        elif line.split_method == 'by_current_cost_price' and total_cost:
                            per_unit = (line.price_unit / total_cost)
                            value = valuation.former_cost * per_unit
                        else:
                            value = (line.price_unit / total_line)

                        if digits:
                            value = float_round(value,
                                                precision_digits=digits[1],
                                                rounding_method='UP')
                            value = min(value, line.price_unit - value_split)
                            value_split += value

                        if valuation.id not in towrite_dict:
                            towrite_dict[valuation.id] = value
                        else:
                            towrite_dict[valuation.id] += value
        if towrite_dict:
            for key, value in towrite_dict.items():
                line_obj.write(cr,
                               uid,
                               key, {'additional_landed_cost': value},
                               context=context)
        return True

    def _track_subtype(self, cr, uid, ids, init_values, context=None):
        record = self.browse(cr, uid, ids[0], context=context)
        if 'state' in init_values and record.state == 'done':
            return 'stock_landed_costs.mt_stock_landed_cost_open'
        return super(stock_landed_cost, self)._track_subtype(cr,
                                                             uid,
                                                             ids,
                                                             init_values,
                                                             context=context)
Ejemplo n.º 7
0
class MassMailingCampaign(osv.Model):
    """Model of mass mailing campaigns. """
    _name = "mail.mass_mailing.campaign"
    _description = 'Mass Mailing Campaign'

    def _get_statistics(self, cr, uid, ids, name, arg, context=None):
        """ Compute statistics of the mass mailing campaign """
        results = {}
        cr.execute(
            """
            SELECT
                c.id as campaign_id,
                COUNT(s.id) AS total,
                COUNT(CASE WHEN s.sent is not null THEN 1 ELSE null END) AS sent,
                COUNT(CASE WHEN s.scheduled is not null AND s.sent is null AND s.exception is null THEN 1 ELSE null END) AS scheduled,
                COUNT(CASE WHEN s.scheduled is not null AND s.sent is null AND s.exception is not null THEN 1 ELSE null END) AS failed,
                COUNT(CASE WHEN s.id is not null AND s.bounced is null THEN 1 ELSE null END) AS delivered,
                COUNT(CASE WHEN s.opened is not null THEN 1 ELSE null END) AS opened,
                COUNT(CASE WHEN s.replied is not null THEN 1 ELSE null END) AS replied ,
                COUNT(CASE WHEN s.bounced is not null THEN 1 ELSE null END) AS bounced
            FROM
                mail_mail_statistics s
            RIGHT JOIN
                mail_mass_mailing_campaign c
                ON (c.id = s.mass_mailing_campaign_id)
            WHERE
                c.id IN %s
            GROUP BY
                c.id
        """, (tuple(ids), ))
        for row in cr.dictfetchall():
            results[row.pop('campaign_id')] = row
            total = row['total'] or 1
            row['delivered'] = row['sent'] - row['bounced']
            row['received_ratio'] = 100.0 * row['delivered'] / total
            row['opened_ratio'] = 100.0 * row['opened'] / total
            row['replied_ratio'] = 100.0 * row['replied'] / total
        return results

    _columns = {
        'name':
        fields.char('Name', required=True),
        'stage_id':
        fields.many2one('mail.mass_mailing.stage', 'Stage', required=True),
        'user_id':
        fields.many2one(
            'res.users',
            'Responsible',
            required=True,
        ),
        'category_ids':
        fields.many2many('mail.mass_mailing.category',
                         'mail_mass_mailing_category_rel',
                         'category_id',
                         'campaign_id',
                         string='Categories'),
        'mass_mailing_ids':
        fields.one2many(
            'mail.mass_mailing',
            'mass_mailing_campaign_id',
            'Mass Mailings',
        ),
        'unique_ab_testing':
        fields.boolean(
            'AB Testing',
            help=
            'If checked, recipients will be mailed only once, allowing to send'
            'various mailings in a single campaign to test the effectiveness'
            'of the mailings.'),
        'color':
        fields.integer('Color Index'),
        # stat fields
        'total':
        fields.function(_get_statistics,
                        string='Total',
                        type='integer',
                        multi='_get_statistics'),
        'scheduled':
        fields.function(_get_statistics,
                        string='Scheduled',
                        type='integer',
                        multi='_get_statistics'),
        'failed':
        fields.function(_get_statistics,
                        string='Failed',
                        type='integer',
                        multi='_get_statistics'),
        'sent':
        fields.function(_get_statistics,
                        string='Sent Emails',
                        type='integer',
                        multi='_get_statistics'),
        'delivered':
        fields.function(
            _get_statistics,
            string='Delivered',
            type='integer',
            multi='_get_statistics',
        ),
        'opened':
        fields.function(
            _get_statistics,
            string='Opened',
            type='integer',
            multi='_get_statistics',
        ),
        'replied':
        fields.function(_get_statistics,
                        string='Replied',
                        type='integer',
                        multi='_get_statistics'),
        'bounced':
        fields.function(_get_statistics,
                        string='Bounced',
                        type='integer',
                        multi='_get_statistics'),
        'received_ratio':
        fields.function(
            _get_statistics,
            string='Received Ratio',
            type='integer',
            multi='_get_statistics',
        ),
        'opened_ratio':
        fields.function(
            _get_statistics,
            string='Opened Ratio',
            type='integer',
            multi='_get_statistics',
        ),
        'replied_ratio':
        fields.function(
            _get_statistics,
            string='Replied Ratio',
            type='integer',
            multi='_get_statistics',
        ),
    }

    def _get_default_stage_id(self, cr, uid, context=None):
        stage_ids = self.pool['mail.mass_mailing.stage'].search(
            cr, uid, [], limit=1, context=context)
        return stage_ids and stage_ids[0] or False

    _defaults = {
        'user_id': lambda self, cr, uid, ctx=None: uid,
        'stage_id': lambda self, *args: self._get_default_stage_id(*args),
    }

    def get_recipients(self, cr, uid, ids, model=None, context=None):
        """Return the recipients of a mailing campaign. This is based on the statistics
        build for each mailing. """
        Statistics = self.pool['mail.mail.statistics']
        res = dict.fromkeys(ids, False)
        for cid in ids:
            domain = [('mass_mailing_campaign_id', '=', cid)]
            if model:
                domain += [('model', '=', model)]
            stat_ids = Statistics.search(cr, uid, domain, context=context)
            res[cid] = set(stat.res_id for stat in Statistics.browse(
                cr, uid, stat_ids, context=context))
        return res
Ejemplo n.º 8
0
     "rent.order",
     "Rent Reference",
     required=True,
     ondelete="cascade",
     select=True,
     readonly=True,
     states={"draft": [("readonly", False)]},
 ),
 "sequence": fields.integer("Sequence"),
 "product_id": fields.many2one(
     "product.product", "Product", domain=[("is_rent", "=", True)], change_default=True
 ),
 "invoice_lines": fields.many2many(
     "account.invoice.line",
     "rent_order_line_invoice_rel",
     "order_line_id",
     "invoice_id",
     "Invoice Lines",
     readonly=True,
 ),
 "price_unit": fields.float(
     "Unit Price",
     required=True,
     digits_compute=dp.get_precision("Product Price"),
     readonly=True,
     states={"draft": [("readonly", False)]},
 ),
 "price_subtotal": fields.function(_amount_line, string="Subtotal", digits_compute=dp.get_precision("Account")),
 "tax_id": fields.many2many(
     "account.tax",
     "rent_order_tax",
     "order_line_id",
Ejemplo n.º 9
0
class delivery_grid(osv.osv):
    _name = "delivery.grid"
    _description = "Delivery Grid"
    _columns = {
        'name':
        fields.char('Grid Name', required=True),
        'sequence':
        fields.integer(
            'Sequence',
            required=True,
            help=
            "Gives the sequence order when displaying a list of delivery grid."
        ),
        'carrier_id':
        fields.many2one('delivery.carrier',
                        'Carrier',
                        required=True,
                        ondelete='cascade'),
        'country_ids':
        fields.many2many('res.country', 'delivery_grid_country_rel', 'grid_id',
                         'country_id', 'Countries'),
        'state_ids':
        fields.many2many('res.country.state', 'delivery_grid_state_rel',
                         'grid_id', 'state_id', 'States'),
        'zip_from':
        fields.char('Start Zip', size=12),
        'zip_to':
        fields.char('To Zip', size=12),
        'line_ids':
        fields.one2many('delivery.grid.line',
                        'grid_id',
                        'Grid Line',
                        copy=True),
        'active':
        fields.boolean(
            'Active',
            help=
            "If the active field is set to False, it will allow you to hide the delivery grid without removing it."
        ),
    }
    _defaults = {
        'active': lambda *a: 1,
        'sequence': lambda *a: 1,
    }
    _order = 'sequence'

    def get_price(self, cr, uid, id, order, dt, context=None):
        total = 0
        weight = 0
        volume = 0
        quantity = 0
        product_uom_obj = self.pool.get('product.uom')
        for line in order.order_line:
            if not line.product_id or line.is_delivery:
                continue
            q = product_uom_obj._compute_qty(cr, uid, line.product_uom.id,
                                             line.product_uom_qty,
                                             line.product_id.uom_id.id)
            weight += (line.product_id.weight or 0.0) * q
            volume += (line.product_id.volume or 0.0) * q
            quantity += q
        total = order.amount_total or 0.0

        return self.get_price_from_picking(cr,
                                           uid,
                                           id,
                                           total,
                                           weight,
                                           volume,
                                           quantity,
                                           context=context)

    def get_price_from_picking(self,
                               cr,
                               uid,
                               id,
                               total,
                               weight,
                               volume,
                               quantity,
                               context=None):
        grid = self.browse(cr, uid, id, context=context)
        price = 0.0
        ok = False
        price_dict = {
            'price': total,
            'volume': volume,
            'weight': weight,
            'wv': volume * weight,
            'quantity': quantity
        }
        for line in grid.line_ids:
            test = eval(line.type + line.operator + str(line.max_value),
                        price_dict)
            if test:
                if line.price_type == 'variable':
                    price = line.list_price * price_dict[line.variable_factor]
                else:
                    price = line.list_price
                ok = True
                break
        if not ok:
            raise osv.except_osv(
                _("Unable to fetch delivery method!"),
                _("Selected product in the delivery method doesn't fulfill any of the delivery grid(s) criteria."
                  ))

        return price
class fee_defaulters(osv.osv_memory):
    """
    This wizard was initially developed for printing defaulter students list only, now we are using this for fee analysis purpose, other reports 
    are also added to this, later on its name will be change in .py and xml file
    --last updated: 31 DEC 17 by Shahid
    """
    def _get_active_session(self, cr, uid, context={}):
        ssn = self.pool.get('sms.session').search(cr, uid,
                                                  [('state', '=', 'Active')])
        if ssn:
            return ssn[0]

    _name = "fee.defaulters"
    _description = "Prints defaulter list"
    _columns = {
        "session":
        fields.many2one(
            'sms.session',
            'Session',
            help=
            "Select A session , you can also print reprts from previous session."
        ),
        "class_id":
        fields.many2many('sms.academiccalendar',
                         'sms_academiccalendar_class_fee',
                         'thisobj_id',
                         'academiccalendar_id',
                         'Class',
                         domain="[('session_id','=',session)]"),
        "fee_type_list":
        fields.many2many('smsfee.feetypes', 'fee_defaulters_feetype_rel',
                         'fee_defaulters_id', 'smsfee_feetypes_id', 'SS'),
        'report_type':
        fields.selection(
            [('summary', 'Print Summary (Donot show monthly Details'),
             ('detailed', 'Detailed Report')], 'Options'),
        'category':
        fields.selection([('Academics', 'Academics'),
                          ('Transport', 'Transport'),
                          ('All', 'All Fee Categories')], 'Fee Category'),
        'order_by':
        fields.selection(
            [('sms_student.name', 'Student Name'),
             ('sms_student.registration_no', 'Registration No'),
             ('sms_student.state', 'Admission Status'),
             ('sms_academiccalendar.name,sms_student.name', 'Class')],
            'Order By'),
        'show_phone_no':
        fields.boolean('Display Contact No'),
        'developer_mode':
        fields.boolean('For Developer'),
        'base_amount':
        fields.integer(
            'Dues Greater Than',
            help=
            'Enter an amount e.g 1000, it will search all students having dues greater or equal to 1000.'
        ),
        'student_type':
        fields.selection([('Current', 'Current'), ('Withdrawn', 'Withdrawn')],
                         'Student Type',
                         readonly=True),
    }
    _defaults = {
        'session': _get_active_session,
        'category': 'Academics',
        'base_amount': 1,
        'order_by': 'sms_student.registration_no',
        'student_type': 'Current',
    }

    def print_defaulter_summary(self, cr, uid, ids, data):
        result = []
        datas = {
            'ids': [],
            'active_ids': '',
            'model': 'smsfee.classfees.register',
            'form': self.read(cr, uid, ids)[0],
        }
        return {
            'type': 'ir.actions.report.xml',
            'report_name': 'smsfee_defaulter_studnent_list_name',
            'datas': datas,
        }

    def print_fee_analysis_ms_excel(self, cr, uid, ids, data):
        print("print_fee_analysis_ms_excel called")

        result = []
        book = xlwt.Workbook()
        header_top = xlwt.Style.easyxf(
            'font: bold 0, color white,  height 250;'
            'align: vertical center, horizontal center, wrap on;'
            'borders: left thin, right thin, bottom thick;'
            'pattern: pattern solid, fore_colour gray80;')

        header_feetypes = xlwt.Style.easyxf(
            'font: bold 0, color white, , height 250;'
            'align: vertical center, horizontal center, wrap on;'
            'borders: left thin, right thin, bottom thick;'
            'pattern: pattern solid, fore_colour  light_blue;')
        header_months = xlwt.Style.easyxf(
            'font: bold 0, color black, height 250;'
            'align: vertical center, horizontal center, wrap on;'
            'borders: left thin, right thin, bottom thick;'
            'pattern: pattern solid, fore_colour  light_green;')

        student_white_rows = xlwt.Style.easyxf(
            'font: bold 0, color black, height 250;'
            'align: vertical center, horizontal left, wrap on;'
            'borders: left thin, right thin, bottom thick;'
            'pattern: pattern solid, fore_colour  white;')
        student_grey_rows = xlwt.Style.easyxf(
            'font: bold 0, color black, height 250;'
            'align: vertical center, horizontal left, wrap on;'
            'borders: left thin, right thin, bottom thick;'
            'pattern: pattern solid, fore_colour  gray25 ;')
        paid_fee = xlwt.Style.easyxf(
            'font: bold 0, color black, height 250;'
            'align: vertical center, horizontal left, wrap on;'
            'borders: left thin, right thin, bottom thick;'
            'pattern: pattern solid, fore_colour  white;')
        unpaid_fee = xlwt.Style.easyxf(
            'font: bold 0, color black, height 250;'
            'align: vertical center, horizontal left, wrap on;'
            'borders:top_color red, bottom_color red, right_color red, left_color red,\
                              left thin, right thin, top thin, bottom thin;'
            'pattern: pattern solid, fore_colour  white;'
            'font: color red')

        selected_fee_list = []
        for f in self.browse(cr, uid, ids):
            if not f.fee_type_list:
                raise osv.except_osv(
                    ('Please Select Fee'),
                    ('Defaulter Excel Report Fees to be included'))
            for s in f.fee_type_list:
                selected_fee_list.append(s.id)
        #classes = self.pool.get('sms.academiccalendar').browse(cr,uid,41)

        #loop via classes, for each class there will be 1 sheet

        collected_classes = []
        for f in self.browse(cr, uid, ids):
            if f.class_id:
                for cls2 in f.class_id:
                    collected_classes.append(cls2.id)

#                 sql1 = """SELECT id,name from sms_academiccalendar where id in"""  +str(collected_classes +"""" ORDER BY name """
#                 cr.execute(sql1)
#                 classes = cr.fetchall()
                classes = self.pool.get('sms.academiccalendar').browse(
                    cr, uid, collected_classes)
                class_ctr = 1
                row = 0
                for this_class in classes:
                    print("this_class.name", this_class.name)

                    sheet1 = book.add_sheet(str(class_ctr) + " " +
                                            str(this_class.class_id.name),
                                            cell_overwrite_ok=True)
                    title = this_class.class_id.name
                    class_ctr = class_ctr + 1
                    _col = (sheet1.col(0)).width = 100 * 20
                    _col = (sheet1.col(1)).width = 400 * 20
                    # _col = (sheet1.row(2)).height = 300 * 15
                    # _col = (sheet1.row(2)).height = 200 * 15

                    sheet1.write(3, 0, 'Rego NO', header_top)
                    sheet1.write(3, 1, 'Name', header_top)

                    #Find all fee types of this class and arrange in one reow of excel #changes: added subtype in select query
                    sqlfees = """ SELECT smsfee_feetypes.id,smsfee_feetypes.name,  
                                CASE
                                  WHEN (subtype != 'Monthly_Fee') THEN '01'
                                  WHEN (subtype= 'Monthly_Fee') THEN '02'
                                  ELSE '00'
                                 END AS sequence_no
                                from smsfee_feetypes
                                where  smsfee_feetypes.category = '"""+str(f.category)+ """'
                                ORDER BY sequence_no,smsfee_feetypes.name """         # changes: interchanged category.name and seq no

                    cr.execute(sqlfees)
                    feerec = cr.fetchall()
                    col_fee = 2  # this is the column no in sheet for fee header
                    fee_ids_list = []
                    month_dict_ids = {}
                    adm_dict_ids = {}
                    annual_dict_ids = {}
                    feerec2 = []
                    for feere in feerec:
                        for id in selected_fee_list:
                            if id == feere[0]:
                                feerec2.append(feere)

                    for fee in feerec2:
                        fee_ids_list.append(fee[0])
                        print("this_class", this_class,
                              "this_class.session_id", this_class.session_id,
                              "/nthis_class.session_id.id",
                              this_class.session_id.id)

                        sql3 = """SELECT id,name from sms_session_months where session_id  = """ + str(
                            this_class.session_id.id
                        ) + """ order by session_year, to_date(name,'Month') """
                        cr.execute(sql3)
                        months = cr.fetchall()
                        annual_number = 4
                        #testing git branch 2
                        if fee[0] == 2:
                            if fee[0] == 2:
                                month_ids_list = []
                                for this_month in months:
                                    if f.developer_mode:
                                        ft_name = str(fee[1]) + "\n" + str(
                                            this_month[1]
                                        ) + "\nmonth_id:" + str(
                                            this_month[0]) + "\nfee_id:" + str(
                                                fee[0])
                                    else:
                                        ft_name = str(fee[1]) + "\n" + str(
                                            this_month[1])[:3].upper() + str(
                                                this_month[1])[-5:]
                                    sheet1.write_merge(r1=0, c1=0, r2=2, c2=11)
                                    _col = (
                                        sheet1.row(col_fee)).height = 100 * 10
                                    #cell width for fee type other than months
                                    _col = (
                                        sheet1.col(col_fee)).width = 200 * 20
                                    sheet1.write(0, 2, title, header_top)
                                    sheet1.write(3, col_fee, ft_name,
                                                 header_feetypes)
                                    month_ids_list.append(this_month[0])
                                    month_dict_ids[this_month[0] +
                                                   fee[0]] = col_fee
                                    col_fee = col_fee + 1

                        else:
                            annual_dict_ids[fee[0]] = col_fee
                            annual_number = annual_number + 1
                            sheet1.write_merge(r1=0, c1=0, r2=2, c2=11)
                            _col = (sheet1.row(col_fee)).height = 100 * 10
                            _col = (sheet1.col(col_fee)).width = 200 * 20
                            sheet1.write(0, 2, title, header_feetypes)
                            if f.developer_mode:
                                ft_name = str(fee[1]) + "\nfee_id:" + str(
                                    fee[0])
                            else:
                                ft_name = str(fee[1])
                            sheet1.write(3, col_fee, ft_name, header_feetypes)
                            #popluate dict1 for non mnthly fees
                            col_fee = col_fee + 1

                    #get students for selected class
                    print "total " + str(
                        fee_ids_list) + " fee ids in fee_ids_list"
                    print("this_class_id ", this_class.id)
                    sql4 = """ SELECT id,registration_no, name,state from sms_student where current_class= """ + str(
                        this_class.id) + """ 
                               order by registration_no,name """
                    cr.execute(sql4)
                    students = cr.fetchall()
                    row = 4
                    color = True
                    #set column again to start iele left most
                    for this_student in students:
                        color = not color

                        _col = (sheet1.col(1)).width = 200 * 20
                        _col = (sheet1.col(1)).height = 400 * 20
                        _col = (sheet1.row(row)).height = 200 * 10

                        if color:
                            sheet1.write(row, 0, this_student[1],
                                         student_grey_rows)
                            sheet1.write(row, 1, this_student[2],
                                         student_grey_rows)
                        else:
                            sheet1.write(row, 0, this_student[1],
                                         student_white_rows)
                            sheet1.write(row, 1, this_student[2],
                                         student_white_rows)
                    # print("student id",this_student[0],"\nmonth ids",month_ids_list ,"\nfee ids",fee_ids_list )
                    #now loop via the fees dictionaru for this student
                        col_fee = 2
                        col_month = 25
                        col_adminiistrative = 13

                        for fees2 in fee_ids_list:

                            if 2 in selected_fee_list:
                                for month2 in month_ids_list:
                                    sql5 = """select id,fee_month,fee_amount,generic_fee_type,state,receipt_no,date_fee_paid
                                                  from smsfee_studentfee where student_id =  """ + str(
                                        this_student[0]) + """
                                              and generic_fee_type= """ + str(
                                            fees2
                                        ) + """ and fee_month=""" + str(month2)

                                    cr.execute(sql5)
                                    stdfee = cr.fetchall()
                                    print("stdfee", stdfee)
                                    for found_fee in stdfee:
                                        #print( "generic fee type",fees2,"fee_month",month2,"this_student",this_student[0])
                                        if found_fee[3] == 2:
                                            if found_fee[4] == 'fee_paid':
                                                if f.developer_mode:
                                                    label = 'Paid Amount:\n' + str(
                                                        found_fee[2]
                                                    ) + "\nmonth_id:" + str(
                                                        month2
                                                    ) + "\nfee_id:" + str(
                                                        fees2
                                                    ) + "\nfee_id_genric:" + str(
                                                        found_fee[3]
                                                    ) + '\n' + 'Bill No:' + str(
                                                        found_fee[5]
                                                    ) + '\n' + 'Date On :\n' + str(
                                                        found_fee[6])
                                                    print 'labellll', label
                                                else:
                                                    label = 'Paid Amount:\n' + str(
                                                        found_fee[2]
                                                    ) + '\nBill No:' + str(
                                                        found_fee[5]
                                                    ) + '\n' + 'Date On:\n' + str(
                                                        found_fee[6])
                                                sheet1.write(
                                                    row,
                                                    month_dict_ids[month2 +
                                                                   fees2],
                                                    label, paid_fee)
                                                col_month = col_month + 1
                                                col_fee = col_fee + 1
                                            else:
                                                if f.developer_mode:
                                                    label = 'Fee Amount:\n' + str(
                                                        found_fee[2]
                                                    ) + "\nmonth_id:" + str(
                                                        month2
                                                    ) + "\nfee_id:" + str(
                                                        fees2
                                                    ) + "\nfee_id_genric:" + str(
                                                        found_fee[3])
                                                else:
                                                    label = 'Fee Amount\n' + str(
                                                        found_fee[2])
                                                sheet1.write(
                                                    row,
                                                    month_dict_ids[month2 +
                                                                   fees2],
                                                    label, unpaid_fee)
                                                col_month = col_month + 1
                                                col_fee = col_fee + 1

                                        else:
                                            if found_fee[4] == 'fee_paid':
                                                if f.developer_mode:
                                                    label = 'Paid Amount:\n' + str(
                                                        found_fee[2]
                                                    ) + "\nmonth_id:" + str(
                                                        month2
                                                    ) + "\nfee_id:" + str(
                                                        fees2
                                                    ) + "\nfee_id_genric:" + str(
                                                        found_fee[3])
                                                else:
                                                    label = 'Paid Amount:\n' + str(
                                                        found_fee[2]
                                                    ) + '\nBill No:' + str(
                                                        found_fee[5]
                                                    ) + '\n' + 'Date On:\n' + str(
                                                        found_fee[6])
                                                sheet1.write(
                                                    row,
                                                    annual_dict_ids[fees2],
                                                    label, student_white_rows)
                                            else:
                                                if f.developer_mode:
                                                    label = 'Fee Amount:\n' + str(
                                                        found_fee[2]
                                                    ) + "\nmonth_id:" + str(
                                                        month2
                                                    ) + "\nfee_id:" + str(
                                                        fees2
                                                    ) + "\nfee_id_genric:" + str(
                                                        found_fee[3])
                                                else:
                                                    label = 'Fee Amount:\n ' + str(
                                                        found_fee[2])
                                                sheet1.write(
                                                    row,
                                                    annual_dict_ids[fees2],
                                                    label, student_white_rows)

                                    # if found_fee[3] !='02':
                                    #  sheet1.write(row,annual_dict_ids[fees2[0]], label,student_rows)

                                    #    print("found fee",found_fee ,"\nsearch on ______generic id____",fees2,"\nthis_student.......",this_student[0],"\nmonth",month2)
                                    #
                                    #   label = str(found_fee[2])+"\nmonth_id:"+str(month2)+"\nfee_id:"+str(fees2)+"\nfee_id_genric:"+str(found_fee[3])
                                    #  print "label:",label
                                    # sheet1.write(row,col_fee, label,student_rows)
                                            col_fee = col_fee + 1
                            else:

                                sql6 = """select id,fee_month,fee_amount,generic_fee_type,state
                                              from smsfee_studentfee where student_id =  """ + str(
                                    this_student[0]) + """
                                          and generic_fee_type= """ + str(
                                        fees2)

                                cr.execute(sql6)
                                stdfee = cr.fetchall()
                                for found_fee in stdfee:
                                    #print( "generic fee type",fees2,"fee_month",month2,"this_student",this_student[0])
                                    if found_fee[3] == 2:
                                        if found_fee[4] == 'fee_paid':
                                            if f.developer_mode:

                                                label = 'Paid Amount\n' + str(
                                                    found_fee[2]
                                                ) + "\nfee_id:" + str(
                                                    fees2
                                                ) + "\nfee_id_genric:" + str(
                                                    found_fee[3]
                                                ) + '\n' + 'Bill No:' + str(
                                                    found_fee[5]
                                                ) + '\n' + 'Date On :\n' + str(
                                                    found_fee[6])
                                            else:
                                                label = 'Paid Amount\n: ' + str(
                                                    found_fee[2]
                                                ) + '\nBill No:' + str(
                                                    found_fee[5]
                                                ) + '\n' + 'Date On:\n' + str(
                                                    found_fee[6])
                                            sheet1.write(
                                                row, month_dict_ids[fees2],
                                                label, paid_fee)
                                            col_month = col_month + 1
                                            col_fee = col_fee + 1
                                        else:
                                            if f.developer_mode:
                                                label = 'Fee Amount:\n ' + str(
                                                    found_fee[2]
                                                ) + "\nfee_id:" + str(
                                                    fees2
                                                ) + "\nfee_id_genric:" + str(
                                                    found_fee[3])
                                            else:
                                                label = 'Fee Amount:\n ' + str(
                                                    found_fee[2])
                                            sheet1.write(
                                                row, month_dict_ids[fees2],
                                                label, unpaid_fee)
                                            col_month = col_month + 1
                                            col_fee = col_fee + 1

                                    else:
                                        if found_fee[4] == 'fee_paid':
                                            if f.developer_mode:
                                                label = 'Paid Amount:\n' + str(
                                                    found_fee[2]
                                                ) + "\nmonth_id:" + "\nfee_id:" + str(
                                                    fees2
                                                ) + "\nfee_id_genric:" + str(
                                                    found_fee[3]
                                                ) + '\nBill No:' + str(
                                                    found_fee[5]
                                                ) + '\n' + 'Date On:\n' + str(
                                                    found_fee[6])
                                            else:
                                                label = 'Paid Amount:\n ' + str(
                                                    found_fee[2]
                                                ) + '\nBill No:' + str(
                                                    found_fee[5]
                                                ) + '\n' + 'Date On :' + str(
                                                    found_fee[6])
                                            sheet1.write(
                                                row, annual_dict_ids[fees2],
                                                label, student_white_rows)
                                        else:
                                            if f.developer_mode:
                                                label = 'Fee Amount:\n ' + str(
                                                    found_fee[2]
                                                ) + "\nmonth_id:" + "\nfee_id:" + str(
                                                    fees2
                                                ) + "\nfee_id_genric:" + str(
                                                    found_fee[3]
                                                ) + '\nBill No:' + str(
                                                    found_fee[5]
                                                ) + '\n' + 'Date On:\n' + str(
                                                    found_fee[6])
                                            else:
                                                label = 'Fee Amount:\n ' + str(
                                                    found_fee[2])
                                            sheet1.write(
                                                row, annual_dict_ids[fees2],
                                                label, student_white_rows)

                                # if found_fee[3] !='02':
                                #  sheet1.write(row,annual_dict_ids[fees2[0]], label,student_rows)

                                #    print("found fee",found_fee ,"\nsearch on ______generic id____",fees2,"\nthis_student.......",this_student[0],"\nmonth",month2)
                                #
                                #   label = str(found_fee[2])+"\nmonth_id:"+str(month2)+"\nfee_id:"+str(fees2)+"\nfee_id_genric:"+str(found_fee[3])
                                #  print "label:",label
                                # sheet1.write(row,col_fee, label,student_rows)
                                        col_fee = col_fee + 1

                        row = row + 1

        print "generating exel"

        path = os.path.join(os.path.expanduser('~'), 'file.xls')
        book.save(path)

    def print_defaulter_detailed(self, cr, uid, ids, data):
        result = []
        datas = {
            'ids': [],
            'active_ids': '',
            'model': 'smsfee.classfees.register',
            'form': self.read(cr, uid, ids)[0],
        }
        return {
            'type': 'ir.actions.report.xml',
            'report_name': 'smsfee_annaul_defaulter_list_name',
            'datas': datas,
        }
Ejemplo n.º 11
0
class Post(osv.Model):
    _name = 'forum.post'
    _description = 'Forum Post'
    _inherit = ['mail.thread', 'website.seo.metadata']
    _order = "is_correct DESC, vote_count DESC"

    def _get_user_vote(self, cr, uid, ids, field_name, arg, context):
        res = dict.fromkeys(ids, 0)
        vote_ids = self.pool['forum.post.vote'].search(cr,
                                                       uid,
                                                       [('post_id', 'in', ids),
                                                        ('user_id', '=', uid)],
                                                       context=context)
        for vote in self.pool['forum.post.vote'].browse(cr,
                                                        uid,
                                                        vote_ids,
                                                        context=context):
            res[vote.post_id.id] = vote.vote
        return res

    def _get_vote_count(self, cr, uid, ids, field_name, arg, context):
        res = dict.fromkeys(ids, 0)
        for post in self.browse(cr, uid, ids, context=context):
            for vote in post.vote_ids:
                res[post.id] += int(vote.vote)
        return res

    def _get_post_from_vote(self, cr, uid, ids, context=None):
        result = {}
        for vote in self.pool['forum.post.vote'].browse(cr,
                                                        uid,
                                                        ids,
                                                        context=context):
            result[vote.post_id.id] = True
        return result.keys()

    def _get_user_favourite(self, cr, uid, ids, field_name, arg, context):
        res = dict.fromkeys(ids, False)
        for post in self.browse(cr, uid, ids, context=context):
            if uid in [f.id for f in post.favourite_ids]:
                res[post.id] = True
        return res

    def _get_favorite_count(self, cr, uid, ids, field_name, arg, context):
        res = dict.fromkeys(ids, 0)
        for post in self.browse(cr, uid, ids, context=context):
            res[post.id] += len(post.favourite_ids)
        return res

    def _get_post_from_hierarchy(self, cr, uid, ids, context=None):
        post_ids = set(ids)
        for post in self.browse(cr, SUPERUSER_ID, ids, context=context):
            if post.parent_id:
                post_ids.add(post.parent_id.id)
        return list(post_ids)

    def _get_child_count(self,
                         cr,
                         uid,
                         ids,
                         field_name=False,
                         arg={},
                         context=None):
        res = dict.fromkeys(ids, 0)
        for post in self.browse(cr, uid, ids, context=context):
            if post.parent_id:
                res[post.parent_id.id] = len(post.parent_id.child_ids)
            else:
                res[post.id] = len(post.child_ids)
        return res

    def _get_uid_answered(self, cr, uid, ids, field_name, arg, context=None):
        res = dict.fromkeys(ids, False)
        for post in self.browse(cr, uid, ids, context=context):
            res[post.id] = any(answer.create_uid.id == uid
                               for answer in post.child_ids)
        return res

    def _get_has_validated_answer(self,
                                  cr,
                                  uid,
                                  ids,
                                  field_name,
                                  arg,
                                  context=None):
        res = dict.fromkeys(ids, False)
        ans_ids = self.search(cr,
                              uid, [('parent_id', 'in', ids),
                                    ('is_correct', '=', True)],
                              context=context)
        for answer in self.browse(cr, uid, ans_ids, context=context):
            res[answer.parent_id.id] = True
        return res

    def _is_self_reply(self, cr, uid, ids, field_name, arg, context=None):
        res = dict.fromkeys(ids, False)
        for post in self.browse(cr, uid, ids, context=context):
            res[post.
                id] = post.parent_id and post.parent_id.create_uid == post.create_uid or False
        return res

    _columns = {
        'name':
        fields.char('Title', size=128),
        'forum_id':
        fields.many2one('forum.forum', 'Forum', required=True),
        'content':
        fields.html('Content'),
        'tag_ids':
        fields.many2many('forum.tag', 'forum_tag_rel', 'forum_id',
                         'forum_tag_id', 'Tags'),
        'state':
        fields.selection([('active', 'Active'), ('close', 'Close'),
                          ('offensive', 'Offensive')], 'Status'),
        'views':
        fields.integer('Number of Views'),
        'active':
        fields.boolean('Active'),
        'is_correct':
        fields.boolean(
            'Valid Answer',
            help='Correct Answer or Answer on this question accepted.'),
        'website_message_ids':
        fields.one2many(
            'mail.message',
            'res_id',
            domain=lambda self:
            ['&', ('model', '=', self._name), ('type', '=', 'comment')],
            string='Post Messages',
            help="Comments on forum post",
        ),
        # history
        'create_date':
        fields.datetime('Asked on', select=True, readonly=True),
        'create_uid':
        fields.many2one('res.users', 'Created by', select=True, readonly=True),
        'write_date':
        fields.datetime('Update on', select=True, readonly=True),
        'write_uid':
        fields.many2one('res.users', 'Updated by', select=True, readonly=True),
        # vote fields
        'vote_ids':
        fields.one2many('forum.post.vote', 'post_id', 'Votes'),
        'user_vote':
        fields.function(_get_user_vote, string='My Vote', type='integer'),
        'vote_count':
        fields.function(_get_vote_count,
                        string="Votes",
                        type='integer',
                        store={
                            'forum.post':
                            (lambda self, cr, uid, ids, c={}: ids,
                             ['vote_ids'], 10),
                            'forum.post.vote': (_get_post_from_vote, [], 10),
                        }),
        # favorite fields
        'favourite_ids':
        fields.many2many('res.users', string='Favourite'),
        'user_favourite':
        fields.function(_get_user_favourite,
                        string="My Favourite",
                        type='boolean'),
        'favourite_count':
        fields.function(_get_favorite_count,
                        string='Favorite Count',
                        type='integer',
                        store={
                            'forum.post':
                            (lambda self, cr, uid, ids, c={}: ids,
                             ['favourite_ids'], 10),
                        }),
        # hierarchy
        'parent_id':
        fields.many2one('forum.post', 'Question', ondelete='cascade'),
        'self_reply':
        fields.function(_is_self_reply,
                        'Reply to own question',
                        type='boolean',
                        store={
                            'forum.post':
                            (lambda self, cr, uid, ids, c={}: ids,
                             ['parent_id', 'create_uid'], 10),
                        }),
        'child_ids':
        fields.one2many('forum.post', 'parent_id', 'Answers'),
        'child_count':
        fields.function(_get_child_count,
                        string="Answers",
                        type='integer',
                        store={
                            'forum.post': (_get_post_from_hierarchy,
                                           ['parent_id', 'child_ids'], 10),
                        }),
        'uid_has_answered':
        fields.function(
            _get_uid_answered,
            string='Has Answered',
            type='boolean',
        ),
        'has_validated_answer':
        fields.function(_get_has_validated_answer,
                        string='Has a Validated Answered',
                        type='boolean',
                        store={
                            'forum.post':
                            (_get_post_from_hierarchy,
                             ['parent_id', 'child_ids', 'is_correct'], 10),
                        }),
        # closing
        'closed_reason_id':
        fields.many2one('forum.post.reason', 'Reason'),
        'closed_uid':
        fields.many2one('res.users', 'Closed by', select=1),
        'closed_date':
        fields.datetime('Closed on', readonly=True),
    }

    _defaults = {
        'state': 'active',
        'views': 0,
        'active': True,
        'vote_ids': list(),
        'favourite_ids': list(),
        'child_ids': list(),
    }

    def create(self, cr, uid, vals, context=None):
        if context is None:
            context = {}
        create_context = dict(context, mail_create_nolog=True)
        post_id = super(Post, self).create(cr,
                                           uid,
                                           vals,
                                           context=create_context)
        # post message + subtype depending on parent_id
        if vals.get("parent_id"):
            parent = self.browse(cr,
                                 SUPERUSER_ID,
                                 vals['parent_id'],
                                 context=context)
            body = _(
                '<p><a href="forum/%s/question/%s">New Answer Posted</a></p>' %
                (slug(parent.forum_id), slug(parent)))
            self.message_post(cr,
                              uid,
                              parent.id,
                              subject=_('Re: %s') % parent.name,
                              body=body,
                              subtype='website_forum.mt_answer_new',
                              context=context)
        else:
            self.message_post(cr,
                              uid,
                              post_id,
                              subject=vals.get('name', ''),
                              body=_('New Question Created'),
                              subtype='website_forum.mt_question_new',
                              context=context)
            self.pool['res.users'].add_karma(
                cr,
                SUPERUSER_ID, [uid],
                self.pool['forum.forum']._karma_gen_quest_new,
                context=context)
        return post_id

    def write(self, cr, uid, ids, vals, context=None):
        Forum = self.pool['forum.forum']
        # update karma when accepting/rejecting answers
        if 'is_correct' in vals:
            mult = 1 if vals['is_correct'] else -1
            for post in self.browse(cr, uid, ids, context=context):
                if vals['is_correct'] != post.is_correct:
                    self.pool['res.users'].add_karma(
                        cr,
                        SUPERUSER_ID, [post.create_uid.id],
                        Forum._karma_gen_ans_accepted * mult,
                        context=context)
                    self.pool['res.users'].add_karma(
                        cr,
                        SUPERUSER_ID, [uid],
                        Forum._karma_gen_ans_accept * mult,
                        context=context)
        res = super(Post, self).write(cr, uid, ids, vals, context=context)
        # if post content modify, notify followers
        if 'content' in vals or 'name' in vals:
            for post in self.browse(cr, uid, ids, context=context):
                if post.parent_id:
                    body, subtype = _(
                        'Answer Edited'), 'website_forum.mt_answer_edit'
                    obj_id = post.parent_id.id
                else:
                    body, subtype = _(
                        'Question Edited'), 'website_forum.mt_question_edit'
                    obj_id = post.id
                self.message_post(cr,
                                  uid,
                                  obj_id,
                                  body=_(body),
                                  subtype=subtype,
                                  context=context)
        return res

    def vote(self, cr, uid, ids, upvote=True, context=None):
        Vote = self.pool['forum.post.vote']
        vote_ids = Vote.search(cr,
                               uid, [('post_id', 'in', ids),
                                     ('user_id', '=', uid)],
                               context=context)
        if vote_ids:
            for vote in Vote.browse(cr, uid, vote_ids, context=context):
                if upvote:
                    new_vote = '0' if vote.vote == '-1' else '1'
                else:
                    new_vote = '0' if vote.vote == '1' else '-1'
                Vote.write(cr,
                           uid,
                           vote_ids, {'vote': new_vote},
                           context=context)
        else:
            for post_id in ids:
                new_vote = '1' if upvote else '-1'
                Vote.create(cr,
                            uid, {
                                'post_id': post_id,
                                'vote': new_vote
                            },
                            context=context)
        return {
            'vote_count':
            self._get_vote_count(cr, uid, ids, None, None,
                                 context=context)[ids[0]]
        }

    def set_viewed(self, cr, uid, ids, context=None):
        cr.execute("""UPDATE forum_post SET views = views+1 WHERE id IN %s""",
                   (tuple(ids), ))
        return True

    def _get_access_link(self, cr, uid, mail, partner, context=None):
        post = self.pool['forum.post'].browse(cr,
                                              uid,
                                              mail.res_id,
                                              context=context)
        res_id = post.parent_id and "%s#answer-%s" % (post.parent_id.id,
                                                      post.id) or post.id
        return "/forum/%s/question/%s" % (post.forum_id.id, res_id)
Ejemplo n.º 12
0
class asset_custody_management(osv.osv_memory):
    _name = "asset.custody.management"
    _description = "management custodies"
    USERS_SELECTION = [
        ('admin', 'Supply Department'),
        ('tech', 'Techncial Services Department'),
        ('arms', 'Arms Department'),
    ]
    _columns = {
        'type':
        fields.selection([('product', 'product'), ('category', 'category'),
                          ('employee', 'employee'),
                          ('department', 'department')], "Type"),
        #'office_id': fields.many2one('office.office','office', ),
        'department_id':
        fields.many2one(
            'hr.department',
            'Department',
        ),
        'cat_id':
        fields.many2one(
            'product.category',
            'Category',
        ),
        'product_id':
        fields.many2one(
            'product.product',
            'Product',
        ),
        'office_ids':
        fields.many2many('office.office',
                         'office_management_wizard_rel',
                         'management',
                         'office_id',
                         string='office'),
        'executing_agency':
        fields.selection(USERS_SELECTION,
                         'Executing Agency',
                         select=True,
                         help='Department Which this request will executed it',
                         required="1"),
    }

    def print_report(self, cr, uid, ids, context=None):
        data = self.read(cr, uid, ids, [], context=context)[0]

        context = {
            'department_id': data['department_id'],
            'executing_agency': data['executing_agency'],
            'office_id': data['office_ids'],
            'product_id': data['product_id'],
            'cat_id': data['cat_id'],
        }

        datas = {
            'ids': [],
            'model': 'asset.custody',
            'form': data,
            'context': context
        }
        return {
            'type': 'ir.actions.report.xml',
            'report_name': 'asset.custody.management',
            'datas': datas,
        }
class kg_pattern_request(osv.osv):

    _name = "kg.pattern.request"
    _description = "Pattern Request"
    _order = "entry_date desc"

    _columns = {

        ### Header Details ####
        'name':
        fields.char('Request No.', size=128, select=True),
        'entry_date':
        fields.date('Request Date', required=True),
        'note':
        fields.text('Notes'),
        'remarks':
        fields.text('Remarks'),
        'cancel_remark':
        fields.text('Cancel Remarks'),
        'active':
        fields.boolean('Active'),
        'state':
        fields.selection([('draft', 'Draft'), ('confirmed', 'Confirmed'),
                          ('cancel', 'Cancelled')],
                         'Status',
                         readonly=True),
        'production_line_ids':
        fields.many2many('kg.production',
                         'm2m_pattern_request_details',
                         'request_id',
                         'production_id',
                         'Production Lines',
                         domain="[('state','=','draft')]"),
        'line_ids':
        fields.one2many('ch.pattern.request.line', 'header_id',
                        "Request Line Details"),
        'flag_reqline':
        fields.boolean('Request Line Created'),

        ### Entry Info ####
        'company_id':
        fields.many2one('res.company', 'Company Name', readonly=True),
        'crt_date':
        fields.datetime('Creation Date', readonly=True),
        'user_id':
        fields.many2one('res.users', 'Created By', readonly=True),
        'confirm_date':
        fields.datetime('Confirmed Date', readonly=True),
        'confirm_user_id':
        fields.many2one('res.users', 'Confirmed By', readonly=True),
        'cancel_date':
        fields.datetime('Cancelled Date', readonly=True),
        'cancel_user_id':
        fields.many2one('res.users', 'Cancelled By', readonly=True),
        'update_date':
        fields.datetime('Last Updated Date', readonly=True),
        'update_user_id':
        fields.many2one('res.users', 'Last Updated By', readonly=True),
    }

    _defaults = {
        'company_id':
        lambda self, cr, uid, c: self.pool.get('res.company').
        _company_default_get(cr, uid, 'kg_pattern_request', context=c),
        'entry_date':
        lambda *a: time.strftime('%Y-%m-%d'),
        'user_id':
        lambda obj, cr, uid, context: uid,
        'crt_date':
        lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
        'active':
        True,
        'state':
        'draft'
    }

    def onchange_production_ids(self, cr, uid, ids, production_line_ids):
        new_ids = production_line_ids[0][2]
        if ids:
            if new_ids != []:
                cr.execute(
                    ''' 
						select request_id,request_line_id,production_id from tmp_pattern_request_details 
						where production_id not in %s and request_id = %s

						''', [tuple(new_ids), ids[0]])
                deleted_ids = cr.dictfetchall()
                if deleted_ids:
                    for item in deleted_ids:

                        cr.execute(
                            ''' 
							select count(request_line_id) from tmp_pattern_request_details where 
							request_line_id = %s and request_id = %s

						''', [item['request_line_id'], ids[0]])
                        req_line_count = cr.fetchone()

                        if req_line_count[0] == 1:

                            del_sql = """ delete from ch_pattern_request_line where header_id=%s and id = %s """ % (
                                ids[0], item['request_line_id'])
                            cr.execute(del_sql)

                        del_sql = """ delete from tmp_pattern_request_details where request_id=%s and production_id = %s and request_line_id = %s """ % (
                            ids[0], item['production_id'],
                            item['request_line_id'])
                        cr.execute(del_sql)

            if new_ids == []:
                del_sql = """ delete from ch_pattern_request_line where header_id=%s """ % (
                    ids[0])
                cr.execute(del_sql)

                del_sql = """ delete from tmp_pattern_request_details where request_id=%s """ % (
                    ids[0])
                cr.execute(del_sql)

        return True

    def update_line_items(self, cr, uid, ids, context=None):
        entry = self.browse(cr, uid, ids[0])

        production_obj = self.pool.get('kg.production')
        request_line_obj = self.pool.get('ch.pattern.request.line')

        del_sql = """ delete from ch_pattern_request_line where header_id=%s """ % (
            ids[0])
        cr.execute(del_sql)

        #del_sql = """ delete from tmp_pattern_request_details where request_id=%s """ %(ids[0])
        #cr.execute(del_sql)

        if entry.production_line_ids:
            """
		
			produc_line_ids = map(lambda x:x.id,entry.production_line_ids)
			produc_line_browse = production_obj.browse(cr,uid,produc_line_ids)
			produc_line_browse = sorted(produc_line_browse, key=lambda k: k.pattern_id.id)
			groups = []
			
			for key, group in groupby(produc_line_browse, lambda x: x.pattern_id.id):
				groups.append(map(lambda r:r,group))
			for key,group in enumerate(groups):
			
			"""

            for line_item in entry.production_line_ids:

                vals = {
                    'header_id': entry.id,
                    'pattern_id': line_item.pattern_id.id,
                    'pattern_name': line_item.pattern_id.pattern_name,
                    'production_id': line_item.id,
                    'order_ref_no': line_item.order_ref_no,
                    'pump_model_id': line_item.pump_model_id.id,
                    'moc_id': line_item.moc_id.id,
                }

                request_line_id = request_line_obj.create(cr, uid, vals)
            """	cr.execute(''' insert into tmp_pattern_request_details(request_id,request_line_id,production_id,creation_date)
					values(%s,%s,%s,now())
					''',[entry.id,request_line_id,line_item.id]) """

            self.write(cr, uid, ids, {'flag_reqline': True})

        return True

    def entry_confirm(self, cr, uid, ids, context=None):
        entry = self.browse(cr, uid, ids[0])
        issue_obj = self.pool.get('kg.pattern.issue')
        if not entry.line_ids:
            raise osv.except_osv(
                _('Warning!'),
                _('System not allow to confirm without Request Items !!'))

        ### Issue Creation against Pattern Request ###

        for req_item in entry.line_ids:

            vals = {
                'name':
                self.pool.get('ir.sequence').get(cr, uid, 'kg.pattern.issue'),
                'request_id':
                entry.id,
                'request_date':
                entry.entry_date,
                'request_line_id':
                req_item.id,
                'pattern_id':
                req_item.pattern_id.id,
                'pattern_name':
                req_item.pattern_id.pattern_name,
                'order_ref_no':
                req_item.order_ref_no,
                'pump_model_id':
                req_item.pump_model_id.id,
                'moc_id':
                req_item.moc_id.id,
                'requested_qty':
                req_item.qty,
                'state':
                'open',
            }

            issue_id = issue_obj.create(cr, uid, vals)

        self.write(
            cr, uid, ids, {
                'name':
                self.pool.get('ir.sequence').get(cr, uid,
                                                 'kg.pattern.request'),
                'state':
                'confirmed',
                'confirm_user_id':
                uid,
                'confirm_date':
                time.strftime('%Y-%m-%d %H:%M:%S')
            })
        cr.execute(
            ''' update ch_pattern_request_line set state = 'confirmed' where header_id = %s ''',
            [ids[0]])
        return True

    def entry_cancel(self, cr, uid, ids, context=None):
        entry = self.browse(cr, uid, ids[0])
        if entry.cancel_remark == False:
            raise osv.except_osv(_('Warning!'),
                                 _('Cancellation Remarks is must !!'))
        self.write(
            cr, uid, ids, {
                'state': 'cancel',
                'cancel_user_id': uid,
                'cancel_date': time.strftime('%Y-%m-%d %H:%M:%S'),
                'transac_state': 'cancel'
            })
        cr.execute(
            ''' update ch_pattern_request_line set state = 'cancel' where header_id = %s ''',
            [ids[0]])
        return True

    def unlink(self, cr, uid, ids, context=None):
        unlink_ids = []
        for rec in self.browse(cr, uid, ids):
            if rec.state == 'confirmed':
                raise osv.except_osv(_('Warning!'),
                                     _('You can not delete this entry !!'))
        return osv.osv.unlink(self, cr, uid, ids, context=context)

    def write(self, cr, uid, ids, vals, context=None):
        vals.update({
            'update_date': time.strftime('%Y-%m-%d %H:%M:%S'),
            'update_user_id': uid
        })
        return super(kg_pattern_request, self).write(cr, uid, ids, vals,
                                                     context)

    def _future_entry_date_check(self, cr, uid, ids, context=None):
        rec = self.browse(cr, uid, ids[0])
        today = date.today()
        today = str(today)
        today = datetime.strptime(today, '%Y-%m-%d')
        entry_date = rec.entry_date
        entry_date = str(entry_date)
        entry_date = datetime.strptime(entry_date, '%Y-%m-%d')
        if entry_date > today:
            return False
        return True

    _constraints = [
        (_future_entry_date_check,
         'System not allow to save with future date. !!', ['']),
    ]
Ejemplo n.º 14
0
		'qty' : fields.function(_qty_all_1,type="float",string='Bonus Qty',digits_compute=dp.get_precision('Product Unit of Measure')),
		'uom_id' : fields.many2one('product.uom','UoM',required=True),
		'uom_id2' : fields.many2one('product.uom','UoM',required=True),
		'value' : fields.float('Price Value',domain=[('is_percent','=',False)]),
		'per_product' : fields.boolean('Per Product'),
		'persentase' : fields.float('Percent Value', digits_compute= dp.get_precision('Discount'),domain=[('is_percent','=',True)]),
		'multi' : fields.boolean('Multiples'),
		'is_active' : fields.boolean('Active?'),
		'date_from' : fields.date('Start Date', required=True),
		'date_to' : fields.date('End Date', required=True),
		'condition_ids' : fields.one2many('master.condition','discount_id','Value Condition'),
		'condition2_ids' : fields.one2many('master.condition2','discount_id','Product Condition'),
		'condition3_ids' : fields.one2many('master.condition3','discount_id','Product Condition 2'),
		'condition4_ids' : fields.one2many('master.condition4','discount_id','Product Condition 3'),
		'condition5_ids' : fields.one2many('master.condition5','discount_id','Product Condition 4'),
		'group_price_ids' : fields.many2many('res.partner.category', id1='discount_id', id2='category_id', string='Group Price Category'),
		'is_percent' : fields.boolean('Is Percent'),
		'is_flat' : fields.boolean('Flat'),
		'type' :fields.selection([('regular','Regular Discount'),('promo','Promo Discount'),('extra','Extra Discount'),('cash','Cash Discount'),('mix','Mix Discount')],string='Type Discount',required=True),
		'min_qty_product' : fields.float('Min. Product Item',digits_compute=dp.get_precision('Product Unit of Measure')),
		'multi2' : fields.boolean('Value Condition'),
		'multi3' : fields.boolean('Multiples for New Product'),
		# 'multi_sel' : fields.selection([('general','General Multiples'),('specific','Specific Multiples for New Product')],string="Multiples"),
		'product_id2' : fields.many2one('product.product','Bonus New Product'),
		'qty2_2' : fields.float('Bonus Qty', digits_compute=dp.get_precision('Product Unit of Measure')),
		'qty2' : fields.function(_qty_all_2,type="float",string='Bonus Qty',digits_compute=dp.get_precision('Product Unit of Measure')),
		'is_category': fields.boolean('Category Condition'),
		'location_ids' : fields.many2many('sale.shop',id1='discount_id',id2='location_id',string='Location'),
		
		} 
Ejemplo n.º 15
0
class MassMailing(osv.Model):
    """ MassMailing models a wave of emails for a mass mailign campaign.
    A mass mailing is an occurence of sending emails. """

    _name = 'mail.mass_mailing'
    _description = 'Mass Mailing'
    # number of periods for tracking mail_mail statistics
    _period_number = 6
    _order = 'sent_date DESC'

    def __get_bar_values(self,
                         cr,
                         uid,
                         obj,
                         domain,
                         read_fields,
                         value_field,
                         groupby_field,
                         date_begin,
                         context=None):
        """ Generic method to generate data for bar chart values using SparklineBarWidget.
            This method performs obj.read_group(cr, uid, domain, read_fields, groupby_field).

            :param obj: the target model (i.e. crm_lead)
            :param domain: the domain applied to the read_group
            :param list read_fields: the list of fields to read in the read_group
            :param str value_field: the field used to compute the value of the bar slice
            :param str groupby_field: the fields used to group

            :return list section_result: a list of dicts: [
                                                {   'value': (int) bar_column_value,
                                                    'tootip': (str) bar_column_tooltip,
                                                }
                                            ]
        """
        date_begin = date_begin.date()
        section_result = [{
            'value':
            0,
            'tooltip':
            ustr((date_begin +
                  relativedelta.relativedelta(days=i)).strftime('%d %B %Y')),
        } for i in range(0, self._period_number)]
        group_obj = obj.read_group(cr,
                                   uid,
                                   domain,
                                   read_fields,
                                   groupby_field,
                                   context=context)
        field = obj._fields.get(groupby_field.split(':')[0])
        pattern = tools.DEFAULT_SERVER_DATE_FORMAT if field.type == 'date' else tools.DEFAULT_SERVER_DATETIME_FORMAT
        for group in group_obj:
            group_begin_date = datetime.strptime(group['__domain'][0][2],
                                                 pattern).date()
            timedelta = relativedelta.relativedelta(group_begin_date,
                                                    date_begin)
            section_result[timedelta.days] = {
                'value': group.get(value_field, 0),
                'tooltip': group.get(groupby_field)
            }
        return section_result

    def _get_daily_statistics(self,
                              cr,
                              uid,
                              ids,
                              field_name,
                              arg,
                              context=None):
        """ Get the daily statistics of the mass mailing. This is done by a grouping
        on opened and replied fields. Using custom format in context, we obtain
        results for the next 6 days following the mass mailing date. """
        obj = self.pool['mail.mail.statistics']
        res = {}
        for mailing in self.browse(cr, uid, ids, context=context):
            res[mailing.id] = {}
            date = mailing.sent_date if mailing.sent_date else mailing.create_date
            date_begin = datetime.strptime(
                date, tools.DEFAULT_SERVER_DATETIME_FORMAT)
            date_end = date_begin + relativedelta.relativedelta(
                days=self._period_number - 1)
            date_begin_str = date_begin.strftime(
                tools.DEFAULT_SERVER_DATETIME_FORMAT)
            date_end_str = date_end.strftime(
                tools.DEFAULT_SERVER_DATETIME_FORMAT)
            domain = [('mass_mailing_id', '=', mailing.id),
                      ('opened', '>=', date_begin_str),
                      ('opened', '<=', date_end_str)]
            res[mailing.id]['opened_daily'] = json.dumps(
                self.__get_bar_values(cr,
                                      uid,
                                      obj,
                                      domain, ['opened'],
                                      'opened_count',
                                      'opened:day',
                                      date_begin,
                                      context=context))
            domain = [('mass_mailing_id', '=', mailing.id),
                      ('replied', '>=', date_begin_str),
                      ('replied', '<=', date_end_str)]
            res[mailing.id]['replied_daily'] = json.dumps(
                self.__get_bar_values(cr,
                                      uid,
                                      obj,
                                      domain, ['replied'],
                                      'replied_count',
                                      'replied:day',
                                      date_begin,
                                      context=context))
        return res

    def _get_statistics(self, cr, uid, ids, name, arg, context=None):
        """ Compute statistics of the mass mailing """
        results = {}
        cr.execute(
            """
            SELECT
                m.id as mailing_id,
                COUNT(s.id) AS total,
                COUNT(CASE WHEN s.sent is not null THEN 1 ELSE null END) AS sent,
                COUNT(CASE WHEN s.scheduled is not null AND s.sent is null AND s.exception is null THEN 1 ELSE null END) AS scheduled,
                COUNT(CASE WHEN s.scheduled is not null AND s.sent is null AND s.exception is not null THEN 1 ELSE null END) AS failed,
                COUNT(CASE WHEN s.sent is not null AND s.bounced is null THEN 1 ELSE null END) AS delivered,
                COUNT(CASE WHEN s.opened is not null THEN 1 ELSE null END) AS opened,
                COUNT(CASE WHEN s.replied is not null THEN 1 ELSE null END) AS replied,
                COUNT(CASE WHEN s.bounced is not null THEN 1 ELSE null END) AS bounced
            FROM
                mail_mail_statistics s
            RIGHT JOIN
                mail_mass_mailing m
                ON (m.id = s.mass_mailing_id)
            WHERE
                m.id IN %s
            GROUP BY
                m.id
        """, (tuple(ids), ))
        for row in cr.dictfetchall():
            results[row.pop('mailing_id')] = row
            total = row['total'] or 1
            row['received_ratio'] = 100.0 * row['delivered'] / total
            row['opened_ratio'] = 100.0 * row['opened'] / total
            row['replied_ratio'] = 100.0 * row['replied'] / total
        return results

    def _get_mailing_model(self, cr, uid, context=None):
        res = []
        for model_name in self.pool:
            model = self.pool[model_name]
            if hasattr(model, '_mail_mass_mailing') and getattr(
                    model, '_mail_mass_mailing'):
                res.append((model._name, getattr(model, '_mail_mass_mailing')))
        res.append(('mail.mass_mailing.contact', _('Mailing List')))
        return res

    # indirections for inheritance
    _mailing_model = lambda self, *args, **kwargs: self._get_mailing_model(
        *args, **kwargs)

    _columns = {
        'name':
        fields.char('Subject', required=True),
        'email_from':
        fields.char('From', required=True),
        'create_date':
        fields.datetime('Creation Date'),
        'sent_date':
        fields.datetime('Sent Date', oldname='date', copy=False),
        'body_html':
        fields.html('Body'),
        'attachment_ids':
        fields.many2many('ir.attachment', 'mass_mailing_ir_attachments_rel',
                         'mass_mailing_id', 'attachment_id', 'Attachments'),
        'mass_mailing_campaign_id':
        fields.many2one(
            'mail.mass_mailing.campaign',
            'Mass Mailing Campaign',
            ondelete='set null',
        ),
        'state':
        fields.selection(
            [('draft', 'Draft'), ('test', 'Tested'), ('done', 'Sent')],
            string='Status',
            required=True,
            copy=False,
        ),
        'color':
        fields.related(
            'mass_mailing_campaign_id',
            'color',
            type='integer',
            string='Color Index',
        ),
        # mailing options
        'reply_to_mode':
        fields.selection(
            [('thread', 'In Document'), ('email', 'Specified Email Address')],
            string='Reply-To Mode',
            required=True,
        ),
        'reply_to':
        fields.char('Reply To', help='Preferred Reply-To Address'),
        # recipients
        'mailing_model':
        fields.selection(_mailing_model,
                         string='Recipients Model',
                         required=True),
        'mailing_domain':
        fields.char('Domain', oldname='domain'),
        'contact_list_ids':
        fields.many2many(
            'mail.mass_mailing.list',
            'mail_mass_mailing_list_rel',
            string='Mailing Lists',
        ),
        'contact_ab_pc':
        fields.integer(
            'AB Testing percentage',
            help=
            'Percentage of the contacts that will be mailed. Recipients will be taken randomly.'
        ),
        # statistics data
        'statistics_ids':
        fields.one2many(
            'mail.mail.statistics',
            'mass_mailing_id',
            'Emails Statistics',
        ),
        'total':
        fields.function(
            _get_statistics,
            string='Total',
            type='integer',
            multi='_get_statistics',
        ),
        'scheduled':
        fields.function(
            _get_statistics,
            string='Scheduled',
            type='integer',
            multi='_get_statistics',
        ),
        'failed':
        fields.function(
            _get_statistics,
            string='Failed',
            type='integer',
            multi='_get_statistics',
        ),
        'sent':
        fields.function(
            _get_statistics,
            string='Sent',
            type='integer',
            multi='_get_statistics',
        ),
        'delivered':
        fields.function(
            _get_statistics,
            string='Delivered',
            type='integer',
            multi='_get_statistics',
        ),
        'opened':
        fields.function(
            _get_statistics,
            string='Opened',
            type='integer',
            multi='_get_statistics',
        ),
        'replied':
        fields.function(
            _get_statistics,
            string='Replied',
            type='integer',
            multi='_get_statistics',
        ),
        'bounced':
        fields.function(
            _get_statistics,
            string='Bounced',
            type='integer',
            multi='_get_statistics',
        ),
        'received_ratio':
        fields.function(
            _get_statistics,
            string='Received Ratio',
            type='integer',
            multi='_get_statistics',
        ),
        'opened_ratio':
        fields.function(
            _get_statistics,
            string='Opened Ratio',
            type='integer',
            multi='_get_statistics',
        ),
        'replied_ratio':
        fields.function(
            _get_statistics,
            string='Replied Ratio',
            type='integer',
            multi='_get_statistics',
        ),
        # daily ratio
        'opened_daily':
        fields.function(
            _get_daily_statistics,
            string='Opened',
            type='char',
            multi='_get_daily_statistics',
        ),
        'replied_daily':
        fields.function(
            _get_daily_statistics,
            string='Replied',
            type='char',
            multi='_get_daily_statistics',
        )
    }

    def default_get(self, cr, uid, fields, context=None):
        res = super(MassMailing, self).default_get(cr,
                                                   uid,
                                                   fields,
                                                   context=context)
        if 'reply_to_mode' in fields and not 'reply_to_mode' in res and res.get(
                'mailing_model'):
            if res['mailing_model'] in [
                    'res.partner', 'mail.mass_mailing.contact'
            ]:
                res['reply_to_mode'] = 'email'
            else:
                res['reply_to_mode'] = 'thread'
        return res

    _defaults = {
        'state':
        'draft',
        'email_from':
        lambda self, cr, uid, ctx=None: self.pool[
            'mail.message']._get_default_from(cr, uid, context=ctx),
        'reply_to':
        lambda self, cr, uid, ctx=None: self.pool['mail.message'].
        _get_default_from(cr, uid, context=ctx),
        'mailing_model':
        'mail.mass_mailing.contact',
        'contact_ab_pc':
        100,
    }

    #------------------------------------------------------
    # Technical stuff
    #------------------------------------------------------

    def copy_data(self, cr, uid, id, default=None, context=None):
        mailing = self.browse(cr, uid, id, context=context)
        default = dict(default or {}, name=_('%s (copy)') % mailing.name)
        return super(MassMailing, self).copy_data(cr,
                                                  uid,
                                                  id,
                                                  default,
                                                  context=context)

    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', 'Draft'), ('test', 'Tested'), ('done', 'Sent')]
            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(MassMailing,
                                   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)
                res[0]['state'] = [state_value, state_name]
                result.append(res[0])
            return result
        else:
            return super(MassMailing, self).read_group(cr,
                                                       uid,
                                                       domain,
                                                       fields,
                                                       groupby,
                                                       offset=offset,
                                                       limit=limit,
                                                       context=context,
                                                       orderby=orderby)

    #------------------------------------------------------
    # Views & Actions
    #------------------------------------------------------

    def on_change_model_and_list(self,
                                 cr,
                                 uid,
                                 ids,
                                 mailing_model,
                                 list_ids,
                                 context=None):
        value = {}
        if mailing_model == 'mail.mass_mailing.contact':
            mailing_list_ids = set()
            for item in list_ids:
                if isinstance(item, (int, long)):
                    mailing_list_ids.add(item)
                elif len(item) == 3:
                    mailing_list_ids |= set(item[2])
            if mailing_list_ids:
                value['mailing_domain'] = "[('list_id', 'in', %s)]" % list(
                    mailing_list_ids)
            else:
                value['mailing_domain'] = "[('list_id', '=', False)]"
        else:
            value['mailing_domain'] = False
        return {'value': value}

    def action_duplicate(self, cr, uid, ids, context=None):
        copy_id = None
        for mid in ids:
            copy_id = self.copy(cr, uid, mid, context=context)
        if copy_id:
            return {
                'type': 'ir.actions.act_window',
                'view_type': 'form',
                'view_mode': 'form',
                'res_model': 'mail.mass_mailing',
                'res_id': copy_id,
                'context': context,
            }
        return False

    def action_test_mailing(self, cr, uid, ids, context=None):
        ctx = dict(context, default_mass_mailing_id=ids[0])
        return {
            'name': _('Test Mailing'),
            'type': 'ir.actions.act_window',
            'view_mode': 'form',
            'res_model': 'mail.mass_mailing.test',
            'target': 'new',
            'context': ctx,
        }

    def action_edit_html(self, cr, uid, ids, context=None):
        if not len(ids) == 1:
            raise ValueError('One and only one ID allowed for this action')
        mail = self.browse(cr, uid, ids[0], context=context)
        url = '/website_mail/email_designer?model=mail.mass_mailing&res_id=%d&template_model=%s&enable_editor=1' % (
            ids[0], mail.mailing_model)
        return {
            'name': _('Open with Visual Editor'),
            'type': 'ir.actions.act_url',
            'url': url,
            'target': 'self',
        }

    #------------------------------------------------------
    # Email Sending
    #------------------------------------------------------

    def get_recipients(self, cr, uid, mailing, context=None):
        if mailing.mailing_domain:
            domain = eval(mailing.mailing_domain)
            res_ids = self.pool[mailing.mailing_model].search(cr,
                                                              uid,
                                                              domain,
                                                              context=context)
        else:
            res_ids = []
            domain = [('id', 'in', res_ids)]

        # randomly choose a fragment
        if mailing.contact_ab_pc < 100:
            contact_nbr = self.pool[mailing.mailing_model].search(
                cr, uid, domain, count=True, context=context)
            topick = int(contact_nbr / 100.0 * mailing.contact_ab_pc)
            if mailing.mass_mailing_campaign_id and mailing.mass_mailing_campaign_id.unique_ab_testing:
                already_mailed = self.pool[
                    'mail.mass_mailing.campaign'].get_recipients(
                        cr,
                        uid, [mailing.mass_mailing_campaign_id.id],
                        context=context)[mailing.mass_mailing_campaign_id.id]
            else:
                already_mailed = set([])
            remaining = set(res_ids).difference(already_mailed)
            if topick > len(remaining):
                topick = len(remaining)
            res_ids = random.sample(remaining, topick)
        return res_ids

    def send_mail(self, cr, uid, ids, context=None):
        author_id = self.pool['res.users'].browse(
            cr, uid, uid, context=context).partner_id.id
        for mailing in self.browse(cr, uid, ids, context=context):
            # instantiate an email composer + send emails
            res_ids = self.get_recipients(cr, uid, mailing, context=context)
            if not res_ids:
                raise Warning('Please select recipients.')
            comp_ctx = dict(context, active_ids=res_ids)
            composer_values = {
                'author_id':
                author_id,
                'attachment_ids':
                [(4, attachment.id) for attachment in mailing.attachment_ids],
                'body':
                mailing.body_html,
                'subject':
                mailing.name,
                'model':
                mailing.mailing_model,
                'email_from':
                mailing.email_from,
                'record_name':
                False,
                'composition_mode':
                'mass_mail',
                'mass_mailing_id':
                mailing.id,
                'mailing_list_ids':
                [(4, l.id) for l in mailing.contact_list_ids],
                'no_auto_thread':
                mailing.reply_to_mode != 'thread',
            }
            if mailing.reply_to_mode == 'email':
                composer_values['reply_to'] = mailing.reply_to
            composer_id = self.pool['mail.compose.message'].create(
                cr, uid, composer_values, context=comp_ctx)
            self.pool['mail.compose.message'].send_mail(cr,
                                                        uid, [composer_id],
                                                        context=comp_ctx)
            self.write(cr,
                       uid, [mailing.id], {
                           'sent_date': fields.datetime.now(),
                           'state': 'done'
                       },
                       context=context)
        return True
Ejemplo n.º 16
0
     'department_id':fields.related('employee_id','department_id', type='many2one', relation='hr.department', string='Department', store=True),
     'job_id':fields.related('employee_id','job_id', type='many2one', relation='hr.job', string='Title', store=True),
     'emp_code':fields.related('employee_id','emp_code', type='char', string='Employee Code', store=True),
     'mobile_phone':fields.related('employee_id','mobile_phone', type='char', string='Work Mobile', store=True),
     'borrow_money_residual':fields.related('employee_id','money_residual', type='float', string='Borrowed residual', readonly=True),
     
     'dimmission_reason':fields.text('Dimission Reason', required=True),
     'advice_to_company':fields.text('Advice to company'),
     'employment_start':fields.date('Employment Started'),
     'date_request':fields.date('Request Date', required=True),
     'date_done':fields.date('Done Date', required=False, readonly=True),
     
     'approve_ids': fields.one2many('hr.dimission.item', 'dimission_id', 'Approvals', domain=[('type','=','approve')]),
     'transfer_ids': fields.one2many('hr.dimission.item', 'dimission_id', 'Transfers', domain=[('type','=','transfer')]),
     
     'payslip_id': fields.many2many('hr.emppay', string='Payslip'),
     'attrpt_ids': fields.many2many('hr.rpt.attend.month', string='Attendance Reports'),
     'hr_clock_ids': fields.function(_emp_clocks, string='HR Clocks', type='many2many', relation='hr.clock', readonly=True),
     'attachment_lines': fields.one2many('ir.attachment', 'hr_admission_id','Attachment'),    
     'company_id':fields.many2one('res.company', 'Company', required=True),   
                                                  
     'state': fields.selection([
         ('draft', 'Draft'),
         ('in_progress', 'In Progress'),
         ('done', 'Done'),
         ('cancel', 'Cancel'),
     ], 'Status', select=True, readonly=True),
 }
 
 _defaults = {
     'state': 'draft',
Ejemplo n.º 17
0
class website(osv.osv):
    def _get_menu(self, cr, uid, ids, name, arg, context=None):
        res = {}
        menu_obj = self.pool.get('website.menu')
        for id in ids:
            menu_ids = menu_obj.search(cr, uid, [('parent_id', '=', False), ('website_id', '=', id)], order='id', context=context)
            res[id] = menu_ids and menu_ids[0] or False
        return res

    _name = "website" # Avoid website.website convention for conciseness (for new api). Got a special authorization from xmo and rco
    _description = "Website"
    _columns = {
        'name': fields.char('Website Name'),
        'domain': fields.char('Website Domain'),
        'company_id': fields.many2one('res.company', string="Company"),
        'language_ids': fields.many2many('res.lang', 'website_lang_rel', 'website_id', 'lang_id', 'Languages'),
        'default_lang_id': fields.many2one('res.lang', string="Default language"),
        'default_lang_code': fields.related('default_lang_id', 'code', type="char", string="Default language code", store=True),
        'social_twitter': fields.char('Twitter Account'),
        'social_facebook': fields.char('Facebook Account'),
        'social_github': fields.char('GitHub Account'),
        'social_linkedin': fields.char('LinkedIn Account'),
        'social_youtube': fields.char('Youtube Account'),
        'social_googleplus': fields.char('Google+ Account'),
        'google_analytics_key': fields.char('Google Analytics Key'),
        'user_id': fields.many2one('res.users', string='Public User'),
        'compress_html': fields.boolean('Compress HTML'),
        'cdn_activated': fields.boolean('Activate CDN for assets'),
        'cdn_url': fields.char('CDN Base URL'),
        'cdn_filters': fields.text('CDN Filters', help="URL matching those filters will be rewritten using the CDN Base URL"),
        'partner_id': fields.related('user_id','partner_id', type='many2one', relation='res.partner', string='Public Partner'),
        'menu_id': fields.function(_get_menu, relation='website.menu', type='many2one', string='Main Menu')
    }
    _defaults = {
        'user_id': lambda self,cr,uid,c: self.pool['ir.model.data'].xmlid_to_res_id(cr, openerp.SUPERUSER_ID, 'base.public_user'),
        'company_id': lambda self,cr,uid,c: self.pool['ir.model.data'].xmlid_to_res_id(cr, openerp.SUPERUSER_ID,'base.main_company'),
        'compress_html': False,
        'cdn_activated': False,
        'cdn_url': '//localhost:8069/',
        'cdn_filters': '\n'.join(DEFAULT_CDN_FILTERS),
    }

    # cf. Wizard hack in website_views.xml
    def noop(self, *args, **kwargs):
        pass

    def write(self, cr, uid, ids, vals, context=None):
        self._get_languages.clear_cache(self)
        return super(website, self).write(cr, uid, ids, vals, context)

    def new_page(self, cr, uid, name, template='website.default_page', ispage=True, context=None):
        context = context or {}
        imd = self.pool.get('ir.model.data')
        view = self.pool.get('ir.ui.view')
        template_module, template_name = template.split('.')

        # completely arbitrary max_length
        page_name = slugify(name, max_length=50)
        page_xmlid = "%s.%s" % (template_module, page_name)

        try:
            # existing page
            imd.get_object_reference(cr, uid, template_module, page_name)
        except ValueError:
            # new page
            _, template_id = imd.get_object_reference(cr, uid, template_module, template_name)
            website_id = context.get('website_id')
            key = template_module+'.'+page_name
            page_id = view.copy(cr, uid, template_id, {'website_id': website_id, 'key': key}, context=context)
            page = view.browse(cr, uid, page_id, context=context)
            page.write({
                'arch': page.arch.replace(template, page_xmlid),
                'name': page_name,
                'page': ispage,
            })
        return page_xmlid

    def page_for_name(self, cr, uid, ids, name, module='website', context=None):
        # whatever
        return '%s.%s' % (module, slugify(name, max_length=50))

    def page_exists(self, cr, uid, ids, name, module='website', context=None):
        try:
            name = (name or "").replace("/page/website.", "").replace("/page/", "")
            if not name:
                return False
            return self.pool["ir.model.data"].get_object_reference(cr, uid, module, name)
        except:
            return False

    @openerp.tools.ormcache(skiparg=3)
    def _get_languages(self, cr, uid, id, context=None):
        website = self.browse(cr, uid, id)
        return [(lg.code, lg.name) for lg in website.language_ids]

    def get_cdn_url(self, cr, uid, uri, context=None):
        # Currently only usable in a website_enable request context
        if request and request.website and not request.debug:
            cdn_url = request.website.cdn_url
            cdn_filters = (request.website.cdn_filters or '').splitlines()
            for flt in cdn_filters:
                if flt and re.match(flt, uri):
                    return urlparse.urljoin(cdn_url, uri)
        return uri

    def get_languages(self, cr, uid, ids, context=None):
        return self._get_languages(cr, uid, ids[0], context=context)

    def get_alternate_languages(self, cr, uid, ids, req=None, context=None):
        langs = []
        if req is None:
            req = request.httprequest
        default = self.get_current_website(cr, uid, context=context).default_lang_code
        uri = req.path
        if req.query_string:
            uri += '?' + req.query_string
        shorts = []
        for code, name in self.get_languages(cr, uid, ids, context=context):
            lg_path = ('/' + code) if code != default else ''
            lg = code.split('_')
            shorts.append(lg[0])
            lang = {
                'hreflang': ('-'.join(lg)).lower(),
                'short': lg[0],
                'href': req.url_root[0:-1] + lg_path + uri,
            }
            langs.append(lang)
        for lang in langs:
            if shorts.count(lang['short']) == 1:
                lang['hreflang'] = lang['short']
        return langs

    @openerp.tools.ormcache(skiparg=4)
    def _get_current_website_id(self, cr, uid, domain_name, context=None):
        website_id = 1
        if request:
            ids = self.search(cr, uid, [('domain', '=', domain_name)], context=context)
            if ids:
                website_id = ids[0]
        return website_id

    def get_current_website(self, cr, uid, context=None):
        domain_name = request.httprequest.environ.get('HTTP_HOST', '').split(':')[0]
        website_id = self._get_current_website_id(cr, uid, domain_name, context=context)
        return self.browse(cr, uid, website_id, context=context)

    def is_publisher(self, cr, uid, ids, context=None):
        Access = self.pool['ir.model.access']
        is_website_publisher = Access.check(cr, uid, 'ir.ui.view', 'write', False, context=context)
        return is_website_publisher

    def is_user(self, cr, uid, ids, context=None):
        Access = self.pool['ir.model.access']
        return Access.check(cr, uid, 'ir.ui.menu', 'read', False, context=context)

    def get_template(self, cr, uid, ids, template, context=None):
        if not isinstance(template, (int, long)) and '.' not in template:
            template = 'website.%s' % template
        View = self.pool['ir.ui.view']
        view_id = View.get_view_id(cr, uid, template, context=context)
        if not view_id:
            raise NotFound
        return View.browse(cr, uid, view_id, context=context)

    def _render(self, cr, uid, ids, template, values=None, context=None):
        # TODO: remove this. (just kept for backward api compatibility for saas-3)
        return self.pool['ir.ui.view'].render(cr, uid, template, values=values, context=context)

    def render(self, cr, uid, ids, template, values=None, status_code=None, context=None):
        # TODO: remove this. (just kept for backward api compatibility for saas-3)
        return request.render(template, values, uid=uid)

    def pager(self, cr, uid, ids, url, total, page=1, step=30, scope=5, url_args=None, context=None):
        # Compute Pager
        page_count = int(math.ceil(float(total) / step))

        page = max(1, min(int(page if str(page).isdigit() else 1), page_count))
        scope -= 1

        pmin = max(page - int(math.floor(scope/2)), 1)
        pmax = min(pmin + scope, page_count)

        if pmax - pmin < scope:
            pmin = pmax - scope if pmax - scope > 0 else 1

        def get_url(page):
            _url = "%s/page/%s" % (url, page) if page > 1 else url
            if url_args:
                _url = "%s?%s" % (_url, werkzeug.url_encode(url_args))
            return _url

        return {
            "page_count": page_count,
            "offset": (page - 1) * step,
            "page": {
                'url': get_url(page),
                'num': page
            },
            "page_start": {
                'url': get_url(pmin),
                'num': pmin
            },
            "page_previous": {
                'url': get_url(max(pmin, page - 1)),
                'num': max(pmin, page - 1)
            },
            "page_next": {
                'url': get_url(min(pmax, page + 1)),
                'num': min(pmax, page + 1)
            },
            "page_end": {
                'url': get_url(pmax),
                'num': pmax
            },
            "pages": [
                {'url': get_url(page), 'num': page}
                for page in xrange(pmin, pmax+1)
            ]
        }

    def rule_is_enumerable(self, rule):
        """ Checks that it is possible to generate sensible GET queries for
        a given rule (if the endpoint matches its own requirements)

        :type rule: werkzeug.routing.Rule
        :rtype: bool
        """
        endpoint = rule.endpoint
        methods = rule.methods or ['GET']
        converters = rule._converters.values()
        if not ('GET' in methods
            and endpoint.routing['type'] == 'http'
            and endpoint.routing['auth'] in ('none', 'public')
            and endpoint.routing.get('website', False)
            and all(hasattr(converter, 'generate') for converter in converters)
            and endpoint.routing.get('website')):
            return False

        # dont't list routes without argument having no default value or converter
        spec = inspect.getargspec(endpoint.method.original_func)

        # remove self and arguments having a default value
        defaults_count = len(spec.defaults or [])
        args = spec.args[1:(-defaults_count or None)]

        # check that all args have a converter
        return all( (arg in rule._converters) for arg in args)

    def enumerate_pages(self, cr, uid, ids, query_string=None, context=None):
        """ Available pages in the website/CMS. This is mostly used for links
        generation and can be overridden by modules setting up new HTML
        controllers for dynamic pages (e.g. blog).

        By default, returns template views marked as pages.

        :param str query_string: a (user-provided) string, fetches pages
                                 matching the string
        :returns: a list of mappings with two keys: ``name`` is the displayable
                  name of the resource (page), ``url`` is the absolute URL
                  of the same.
        :rtype: list({name: str, url: str})
        """
        router = request.httprequest.app.get_db_router(request.db)
        # Force enumeration to be performed as public user
        url_list = []
        for rule in router.iter_rules():
            if not self.rule_is_enumerable(rule):
                continue

            converters = rule._converters or {}
            if query_string and not converters and (query_string not in rule.build([{}], append_unknown=False)[1]):
                continue
            values = [{}]
            convitems = converters.items()
            # converters with a domain are processed after the other ones
            gd = lambda x: hasattr(x[1], 'domain') and (x[1].domain <> '[]')
            convitems.sort(lambda x, y: cmp(gd(x), gd(y)))
            for (i,(name, converter)) in enumerate(convitems):
                newval = []
                for val in values:
                    query = i==(len(convitems)-1) and query_string
                    for v in converter.generate(request.cr, uid, query=query, args=val, context=context):
                        newval.append( val.copy() )
                        v[name] = v['loc']
                        del v['loc']
                        newval[-1].update(v)
                values = newval

            for value in values:
                domain_part, url = rule.build(value, append_unknown=False)
                page = {'loc': url}
                for key,val in value.items():
                    if key.startswith('__'):
                        page[key[2:]] = val
                if url in ('/sitemap.xml',):
                    continue
                if url in url_list:
                    continue
                url_list.append(url)

                yield page

    def search_pages(self, cr, uid, ids, needle=None, limit=None, context=None):
        name = (needle or "").replace("/page/website.", "").replace("/page/", "")
        res = []
        for page in self.enumerate_pages(cr, uid, ids, query_string=name, context=context):
            if needle in page['loc']:
                res.append(page)
                if len(res) == limit:
                    break
        return res

    def kanban(self, cr, uid, ids, model, domain, column, template, step=None, scope=None, orderby=None, context=None):
        step = step and int(step) or 10
        scope = scope and int(scope) or 5
        orderby = orderby or "name"

        get_args = dict(request.httprequest.args or {})
        model_obj = self.pool[model]
        relation = model_obj._columns.get(column)._obj
        relation_obj = self.pool[relation]

        get_args.setdefault('kanban', "")
        kanban = get_args.pop('kanban')
        kanban_url = "?%s&kanban=" % werkzeug.url_encode(get_args)

        pages = {}
        for col in kanban.split(","):
            if col:
                col = col.split("-")
                pages[int(col[0])] = int(col[1])

        objects = []
        for group in model_obj.read_group(cr, uid, domain, ["id", column], groupby=column):
            obj = {}

            # browse column
            relation_id = group[column][0]
            obj['column_id'] = relation_obj.browse(cr, uid, relation_id)

            obj['kanban_url'] = kanban_url
            for k, v in pages.items():
                if k != relation_id:
                    obj['kanban_url'] += "%s-%s" % (k, v)

            # pager
            number = model_obj.search(cr, uid, group['__domain'], count=True)
            obj['page_count'] = int(math.ceil(float(number) / step))
            obj['page'] = pages.get(relation_id) or 1
            if obj['page'] > obj['page_count']:
                obj['page'] = obj['page_count']
            offset = (obj['page']-1) * step
            obj['page_start'] = max(obj['page'] - int(math.floor((scope-1)/2)), 1)
            obj['page_end'] = min(obj['page_start'] + (scope-1), obj['page_count'])

            # view data
            obj['domain'] = group['__domain']
            obj['model'] = model
            obj['step'] = step
            obj['orderby'] = orderby

            # browse objects
            object_ids = model_obj.search(cr, uid, group['__domain'], limit=step, offset=offset, order=orderby)
            obj['object_ids'] = model_obj.browse(cr, uid, object_ids)

            objects.append(obj)

        values = {
            'objects': objects,
            'range': range,
            'template': template,
        }
        return request.website._render("website.kanban_contain", values)

    def kanban_col(self, cr, uid, ids, model, domain, page, template, step, orderby, context=None):
        html = ""
        model_obj = self.pool[model]
        domain = safe_eval(domain)
        step = int(step)
        offset = (int(page)-1) * step
        object_ids = model_obj.search(cr, uid, domain, limit=step, offset=offset, order=orderby)
        object_ids = model_obj.browse(cr, uid, object_ids)
        for object_id in object_ids:
            html += request.website._render(template, {'object_id': object_id})
        return html

    def _image_placeholder(self, response):
        # file_open may return a StringIO. StringIO can be closed but are
        # not context managers in Python 2 though that is fixed in 3
        with contextlib.closing(openerp.tools.misc.file_open(
                os.path.join('web', 'static', 'src', 'img', 'placeholder.png'),
                mode='rb')) as f:
            response.data = f.read()
            return response.make_conditional(request.httprequest)

    def _image(self, cr, uid, model, id, field, response, max_width=maxint, max_height=maxint, cache=None, context=None):
        """ Fetches the requested field and ensures it does not go above
        (max_width, max_height), resizing it if necessary.

        Resizing is bypassed if the object provides a $field_big, which will
        be interpreted as a pre-resized version of the base field.

        If the record is not found or does not have the requested field,
        returns a placeholder image via :meth:`~._image_placeholder`.

        Sets and checks conditional response parameters:
        * :mailheader:`ETag` is always set (and checked)
        * :mailheader:`Last-Modified is set iif the record has a concurrency
          field (``__last_update``)

        The requested field is assumed to be base64-encoded image data in
        all cases.
        """
        Model = self.pool[model]
        id = int(id)

        ids = Model.search(cr, uid,
                           [('id', '=', id)], context=context)
        if not ids and 'website_published' in Model._fields:
            ids = Model.search(cr, openerp.SUPERUSER_ID,
                               [('id', '=', id), ('website_published', '=', True)], context=context)
        if not ids:
            return self._image_placeholder(response)

        concurrency = '__last_update'
        [record] = Model.read(cr, openerp.SUPERUSER_ID, [id],
                              [concurrency, field],
                              context=context)

        if concurrency in record:
            server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT
            try:
                response.last_modified = datetime.datetime.strptime(
                    record[concurrency], server_format + '.%f')
            except ValueError:
                # just in case we have a timestamp without microseconds
                response.last_modified = datetime.datetime.strptime(
                    record[concurrency], server_format)

        # Field does not exist on model or field set to False
        if not record.get(field):
            # FIXME: maybe a field which does not exist should be a 404?
            return self._image_placeholder(response)

        response.set_etag(hashlib.sha1(record[field]).hexdigest())
        response.make_conditional(request.httprequest)

        if cache:
            response.cache_control.max_age = cache
            response.expires = int(time.time() + cache)

        # conditional request match
        if response.status_code == 304:
            return response

        data = record[field].decode('base64')
        image = Image.open(cStringIO.StringIO(data))
        response.mimetype = Image.MIME[image.format]

        filename = '%s_%s.%s' % (model.replace('.', '_'), id, str(image.format).lower())
        response.headers['Content-Disposition'] = 'inline; filename="%s"' % filename

        if (not max_width) and (not max_height):
            response.data = data
            return response

        w, h = image.size
        max_w = int(max_width) if max_width else maxint
        max_h = int(max_height) if max_height else maxint

        if w < max_w and h < max_h:
            response.data = data
        else:
            size = (max_w, max_h)
            img = image_resize_and_sharpen(image, size, preserve_aspect_ratio=True)
            image_save_for_web(img, response.stream, format=image.format)
            # invalidate content-length computed by make_conditional as
            # writing to response.stream does not do it (as of werkzeug 0.9.3)
            del response.headers['Content-Length']

        return response

    def image_url(self, cr, uid, record, field, size=None, context=None):
        """Returns a local url that points to the image field of a given browse record."""
        model = record._name
        id = '%s_%s' % (record.id, hashlib.sha1(record.sudo().write_date).hexdigest()[0:7])
        size = '' if size is None else '/%s' % size
        return '/website/image/%s/%s/%s%s' % (model, id, field, size)
Ejemplo n.º 18
0
    ('integer', fields.integer()),
    ('float', fields.float()),
    ('decimal', fields.float(digits=(16, 3))),
    ('string.bounded', fields.char('unknown', size=16)),
    ('string.required', fields.char('unknown', size=None, required=True)),
    ('string', fields.char('unknown', size=None)),
    ('date', fields.date()),
    ('datetime', fields.datetime()),
    ('text', fields.text()),
    ('selection', fields.selection([(1, "Foo"), (2, "Bar"), (3, "Qux"), (4, '')])),
    # here use size=-1 to store the values as integers instead of strings
    ('selection.function', fields.selection(selection_fn, size=-1)),
    # just relate to an integer
    ('many2one', fields.many2one('export.integer')),
    ('one2many', fields.one2many('export.one2many.child', 'parent_id')),
    ('many2many', fields.many2many('export.many2many.other')),
    ('function', fields.function(function_fn, fnct_inv=function_fn_write, type="integer")),
    # related: specialization of fields.function, should work the same way
    # TODO: reference
]

for name, field in models:
    class NewModel(orm.Model):
        _name = 'export.%s' % name
        _columns = {
            'const': fields.integer(),
            'value': field,
        }
        _defaults = {
            'const': 4,
        }
Ejemplo n.º 19
0
class proforma_invoice_line(osv.osv):
    def _amount_line(self, cr, uid, ids, prop, unknow_none, unknow_dict):
        res = {}
        tax_obj = self.pool.get('account.tax')
        cur_obj = self.pool.get('res.currency')
        for line in self.browse(cr, uid, ids):
            price = line.price_unit
            taxes = tax_obj.compute_all(cr,
                                        uid,
                                        line.invoice_line_tax_id,
                                        price,
                                        line.quantity,
                                        product=line.product_id,
                                        partner=line.invoice_id.partner_id)
            res[line.id] = taxes['total']
            if line.invoice_id:
                cur = line.invoice_id.currency_id
                res[line.id] = cur_obj.round(cr, uid, cur, res[line.id])
        return res

    _name = "proforma.invoice.line"
    _description = "Proforma Invoice Line"
    _order = "invoice_id,sequence,id"
    _columns = {
        'name':
        fields.text('Description', required=True),
        'origin':
        fields.char(
            'Source Document',
            size=256,
            help=
            "Reference of the document that produced this proforma invoice."),
        'sequence':
        fields.integer(
            'Sequence',
            help="Gives the sequence of this line when displaying the invoice."
        ),
        'invoice_id':
        fields.many2one('proforma.invoice',
                        'Proforma Invoice',
                        ondelete='cascade',
                        select=True),
        'uom_id':
        fields.many2one('product.uom',
                        'Unit of Measure',
                        ondelete='set null',
                        select=True),
        'product_id':
        fields.many2one('product.product',
                        'Product',
                        ondelete='set null',
                        select=True),
        'price_unit':
        fields.float('Unit Price',
                     required=True,
                     digits_compute=dp.get_precision('Product Price')),
        'price_subtotal':
        fields.function(_amount_line,
                        string='Amount',
                        type="float",
                        digits_compute=dp.get_precision('Account')),
        'invoice_line_tax_id':
        fields.many2many('account.tax',
                         'proforma_invoice_line_tax',
                         'proforma_invoice_line_id',
                         'tax_id',
                         'Taxes',
                         domain=[('parent_id', '=', False)]),
        'quantity':
        fields.float(
            'Quantity',
            digits_compute=dp.get_precision('Product Unit of Measure'),
            required=True),
        'company_id':
        fields.related('invoice_id',
                       'company_id',
                       type='many2one',
                       relation='res.company',
                       string='Company',
                       store=True,
                       readonly=True),
        'partner_id':
        fields.related('invoice_id',
                       'partner_id',
                       type='many2one',
                       relation='res.partner',
                       string='Partner',
                       store=True)
    }

    _defaults = {
        'quantity': 1,
        'price_unit': 0.0,
        'sequence': 10,
    }
class cashback_lines_wizard(osv.osv_memory):
    _name = "cashback.lines.wizard"

    _columns = {
        "customer_ids":
        fields.many2many(
            'res.partner',
            'cashback_lines_wizard_partner_rel',
            'wiz_id',
            'partner_id',
            'Customers',
        ),
        "cashback_id":
        fields.many2one('account.cashback', "Cashback"),
        "current_customer_ids":
        fields.many2many(
            'res.partner',
            'cashback_lines_current_partner_rel',
            'wiz_id',
            'partner_id',
            'Existing Customers',
        ),
        "start_date":
        fields.date("Start Date", required=True),
        "end_date":
        fields.date("End Date", required=True),
    }

    def default_get(self, cr, uid, fields, context=None):
        res = super(cashback_lines_wizard, self).default_get(cr,
                                                             uid,
                                                             fields,
                                                             context=context)
        if context.get('active_id', False):
            cashback = self.pool.get('account.cashback').browse(
                cr, uid, context.get('active_id'))
            current_customer_ids = [
                x.name and x.name.id for x in cashback.line_ids
            ]
        res.update({
            'cashback_id': context.get('active_id', False),
            'current_customer_ids': current_customer_ids,
            'start_date': cashback.start_date,
            'end_date': cashback.end_date,
        })
        return res

    def generate(self, cr, uid, ids, context=None):
        if not context: context = {}
        wiz = self.browse(cr, uid, ids[0], context=context)
        for partner in wiz.customer_ids:
            value = {
                "name": partner and partner.id,
                "start_date": wiz.start_date,
                "end_date": wiz.end_date,
                "current_disc": partner.current_discount or 0.0,
                "cashback_id": wiz.cashback_id and wiz.cashback_id.id or False,
                "omzet_before_disc": 0.0,
                "omzet_after_disc": 0.0,
                "omzet_paid": 0.0,
                "deposit": 0.0,
                "proposed_disc": 0.0,
                "cash_back_amt": 0.0,
            }
            print "xxxxxxxxxxxxxxxxx", value
            self.pool.get('account.cashback.line').create(cr, uid, value)
        return True
Ejemplo n.º 21
0
class account_sat_related_wizard(osv.osv_memory):
    """ Relacion plan de cuentas SAT con el plan de cuentas """
    _name = 'account.sat.related.wizard'
    _description = 'Relacionar cuentas SAT'

    _columns = {
        'id':
        fields.integer('ID'),
        'name':
        fields.char('Nombre'),
        'account_sat_id':
        fields.many2one('account.account.sat',
                        'Cuenta SAT',
                        domain=[('type', '!=', 'view')],
                        select="1"),
        #'account_apply_ids': fields.one2many('account.sat.related.apply.wizard', 'wizard_id', 'Cuentas aplicadas'),
        'account_apply_ids':
        fields.many2many('account.account',
                         'account_sat_related_apply_wizard_rel',
                         'wizard_id',
                         'account_id',
                         'Cuentas aplicadas',
                         domain=[('type', '!=', 'view')]),
        'account_ids':
        fields.one2many('account.sat.related.account.wizard', 'wizard_id',
                        'Plan contable'),
        'filter':
        fields.char('Filtrar cuenta', size=164),
    }

    _defaults = {'name': 'Relacion Cuentas SAT'}

    def onchange_account_sat_id(self,
                                cr,
                                uid,
                                ids,
                                account_sat_id,
                                filter,
                                context=None):
        """
            Actualiza la informacion de los movimientos pendientes de relacionar
        """
        acc_obj = self.pool.get('account.account')
        acc_line_rel = []
        acc_line_ids = []

        if account_sat_id:
            # Genera filtros para obtener las cuentas
            filter_search = [('account_sat_id', '=', False),
                             ('type', '!=', 'view')]
            if filter:
                filter_search.append('|')
                filter_search.append(('name', 'ilike', '%' + filter + '%'))
                filter_search.append(('code', 'ilike', '%' + filter + '%'))

            # Busca las cuentas pendientes de conciliar
            account_ids = acc_obj.search(cr, uid, filter_search)
            if account_ids:
                # Recorre los movimientos y los agrega en la vista de banco
                for account_id in account_ids:
                    val = {
                        'account_id': account_id,
                    }
                    acc_line_ids.append(val)

            # Busca las cuentas conciliadas con la cuenta
            acc_line_rel = acc_obj.search(
                cr, uid, [('account_sat_id', '=', account_sat_id),
                          ('type', '!=', 'view')])

        # Actualiza los valores de retorno
        return {
            'value': {
                'account_ids': acc_line_ids,
                'account_apply_ids': acc_line_rel
            }
        }

    def onchange_filter(self,
                        cr,
                        uid,
                        ids,
                        filter,
                        account_sat_id,
                        account_apply_ids,
                        context=None):
        """
            Filtra la lista de cuentas que estan pendientes de aplicar
        """
        acc_obj = self.pool.get('account.account')
        acc_line_ids = []
        apply_ids = []

        # Valida que ya este seleccionada una cuenta sat y este guardado
        if account_sat_id:
            # Descarta las cuentas que estan ya sobre la lista
            for acc in account_apply_ids:
                print "************* acc ******* ", acc
                if acc[0] == 6:
                    apply_ids = acc[2]

            # Genera filtros para obtener las cuentas
            filter_search = [
                '|', ('account_sat_id', '=', account_sat_id),
                ('account_sat_id', '=', False), ('type', '!=', 'view'),
                ('id', 'not in', apply_ids)
            ]
            if filter:
                filter_search.append('|')
                filter_search.append(('name', 'ilike', '%' + filter + '%'))
                filter_search.append(('code', 'ilike', '%' + filter + '%'))

            # Busca las cuentas pendientes de conciliar
            acc_ids = acc_obj.search(cr, uid, filter_search, context=context)
            for account_id in acc_ids:
                val = {'account_id': account_id}
                acc_line_ids.append(val)

        # Actualiza los valores de retorno
        return {'value': {'account_ids': acc_line_ids}}

    def action_related_auto(self, cr, uid, ids, context=None):
        act_obj = self.pool.get('account.account')
        acc_obj = self.pool.get('account.account.sat')

        accounts = [
            (1111001000, 101.01),
            (1111002000, 101.01),
            (1111003000, 101.01),
            (111301, 102.01),
            (11130201000, 102.01),
            (11130202000, 102.02),
            (11130203000, 103.01),
            (1114001000, 103.01),
            (1115001000, 103.01),
            (1115002000, 103.03),
            (1115003000, 105.01),
            (1115004000, 105.01),
            (1121001000, 105.01),
            (1122001000, 105.01),  #107.05
            (1123001000, 105.02),
            (1122004000, 107.01),
            (1122005000, 107.01),
            (1124001000, 107.02),
            (1125001000, 107.05),  #107.05
            (1125002000, 107.05),  #107.05
            (1125003000, 107.05),  #107.05
            (1125004000, 107.02),
            (1125008000, 120.01),
            (1125009000, 115.01),
            (1128001000, 115.01),
            (1129001000, 115.01),
            (1131001000, 115.01),
            (1131002000, 115.01),
            (1131003000, 174.01),
            (1131009000, 109.01),
            (1134001000, 184.02),
            (1151006000, 118.02),
            (1151007000, 119.01),
            (1151004000, 118.01),
            (1211001000, 151.01),
            (1211005000, 152.01),
            (1211007000, 153.01),
            (1211009000, 154.01),
            (1211011000, 155.01),
            (1212001000, 156.01),
            (1212007000, 171.01),
            (1212009000, 171.02),
            (1212011000, 171.03),
            (1212015000, 171.04),
            (2111001000, 171.05),
            (2122001000, 179.01),
            (2124001000, 177.01),
            (2151001000, 202.01),
            (2161005000, 201.01),
            (2161006000, 203.18),
            (2161007000, 210.04),
            (2171001000, 210.07),
            (2173001000, 211.01),
            (2173002000, 203.18),
            (2173003000, 203.18),
            (2175004000, 203.18),
            (2175005000, 213.04),
            (2175006000, 210.01),
            (2175014000, 215.01),
            (2175017000, 213.03),
            (2175021000, 213.03),
            (2191001000, 213.03),
            (2191002000, 216.1),
            (2201111000, 216.01),
            (2201112000, 216.02),
            (2201113000, 216.04),
            (2201114000, 216.03),
            (2201115000, 216.1),
            (2201116000, 216.1),
            (2201117000, 213.01),
            (2201118000, 252.01),
            (2202111000, 252.05),
            (2511001000, 252.17),
            (2581001000, 301.01),
            (2591001000, 301.04),
            (3111001000, 304.01),
            (3131001000, 305.01),
            (3211001000, 303.01),
            (3211002000, 301.03),
            (3311001000, 306.01),
            (3311002000, 306.01),
            (4511002000, 401.01),
            (4511003000, 401.01),
            (5111001000, 401.13),
            (5111002000, 401.16),
            (5111003000, 402.01),
            (5112001000, 601.72),
            (5114001000, 601.61),
            (6111001000, 601.84),
            (7111001000, 601.84),
            (7111002000, 601.84),
            (7111003000, 601.61),
            (7111004000, 601.61),
            (7111005000, 601.84),
            (7111006000, 601.84),
            (7111007000, 601.72),
            (7111008000, 601.76),
            (7111009000, 601.01),
            (7111010000, 601.01),
            (7111011000, 601.03),
            (7131001000, 601.05),
            (7131002000, 601.1),
            (7131003000, 601.16),
            (7131004000, 601.15),
            (7131005000, 601.25),
            (7131006000, 601.25),
            (7131007000, 601.17),
            (7131008000, 601.25),
            (7131009000, 601.25),
            (7131010000, 601.25),
            (7131011000, 601.27),
            (7131012000, 601.25),
            (7131013000, 601.06),
            (7131016000, 601.07),
            (7131017000, 601.29),
            (7131019000, 601.25),
            (7131020000, 601.49),
            (7131021000, 601.31),
            (7131025000, 601.25),
            (7131030000, 601.25),
            (7131031000, 601.25),
            (7131033000, 601.56),
            (7131035000, 601.56),
            (7131036000, 601.56),
            (7151001000, 601.56),
            (7151002000, 601.56),
            (7151003000, 601.53),
            (7151004000, 601.38),
            (7151005000, 601.79),
            (7151006000, 601.52),
            (7151007000, 601.5),
            (7151009000, 601.51),
            (7151010000, 601.54),
            (7151012000, 601.55),
            (7151013000, 601.54),
            (7151014000, 601.49),
            (7151015000, 601.83),
            (7151016000, 601.49),
            (7151017000, 601.84),
            (7151018000, 601.64),
            (7151019000, 601.84),
            (7151021000, 601.61),
            (7151022000, 601.84),
            (7151023000, 601.46),
            (7151024000, 601.45),
            (7151025000, 601.84),
            (7151026000, 601.84),
            (7151027000, 601.84),
            (7151028000, 601.84),
            (7151029000, 601.72),
            (7151030000, 601.84),
            (7151031000, 601.38),
            (7151032000, 601.64),
            (7151033000, 601.49),
            (7151035000, 601.48),
            (7151036000, 601.84),
            (7151039000, 601.57),
            (7151040000, 601.83),
            (7151041000, 601.32),
            (7151043000, 601.84),
            (7151044000, 601.61),
            (7151045000, 613.01),
            (7151046000, 613.02),
            (7151047000, 613.03),
            (7151048000, 613.04),
            (7131037000, 613.05),
            (7161002000, 614.01),
            (7161003000, 701.04),
            (7161004000, 701.1),
            (7161005000, 701.1),
            (7161006000, 701.04),
            (7162001000, 601.59),
            (9111001000, 703.21),
            (9111002000, 701.01),
            (9111003000, 703.21),
            (9111004000, 701.01),
            (9113099000, 702.04),
            (9113002000, 702.05),
            (9113006000, 702.1),
            (9113010000, 704.23),
            (9113012000, 704.19),
            (9211001000, 702.01),
            (9211002000, 702.1),
            (9211003000, 704.23),
            (9212001000, 114.01),
            (9212002000, 113.08),
            (9212003000, 119.01),
            (9212004000, 110.01),
            (1152001000, 207.01),
            (1151005000, 704.23),
            (1152005000, 703.21),
            (1152, 113.04),
            (2202119000, 113.07),
            (9212006000, 113.01),
            (11130204000, 113.02),
            (2124002000, 113.03),
            (2511002000, 183.01),
            (2511002001, 216.11),
            (2511002002, 211.02),
            (2511003000, 211.03),
            (2511004000, 217.01),
            (3912, 208.01),
            (3911000001, 601.26),
            (3911000002, 601.28),
            (3911000003, 614.02),
            (3911000004, 614.1),
            (3911000005, 113.08),
            (3912000001, 613.05),
            (3912000002, 703.21),
            (3912000003, 703.21),
            (3911000006, 118.01),
            (1212013000, 206.01),
            (1152002000, 501.01),
            (1152003000, 174.01),
            (3912000004, 304.02),
            (7171002000, 304.01),
            (7171003000, 216.03),
            (7171004000, 216.1),
            (7171, 216.04),
            (717, 216.1),
            (13, 105.02),
            (1371001000, 704.23),
            (1371, 704.23),
            (137, 601.58),
            (7161008000, 213.02),
            (4511001000, 601.31),
            (1151008000, 210.06),
            (1152007000, 601.62),
            (1153001000, 205.02),
            (1153002000, 601.6),
            (1153003000, 601.46),
            (1221001000, 113.08),
            (1221003000, 182.01),
            (1251, 184.03),
            (1251001000, 184.03),
            (127, 184.02),
            (1271, 216.1),
            (1272, 611.01),
            (1272001, 607.01),
            (1272001001, 703.09),
            (1272001002, 601.21),
            (1272001003, 601.34),
            (1272001004, 601.84)
        ]

        for account in accounts:
            act_ids = act_obj.search(cr, uid, [('code', '=', str(account[0]))])
            acc_ids = acc_obj.search(cr, uid, [('code', '=', str(account[1]))])

            for act_act in act_obj.browse(cr, uid, act_ids):
                act = act_act.id
            for acc_sat in acc_obj.browse(cr, uid, acc_ids):
                acc = acc_sat.id

            cr.execute(
                """update account_account set account_sat_id = %s where id = %s"""
                % (acc, act))
            cr.commit()

    def action_related_account(self, cr, uid, ids, context=None):
        """
            Hace la aplicacion sobre las cuentas relacionadas
        """
        # Recorre los registros a validar
        for wizard in self.browse(cr, uid, ids, context=context):
            acc_ids = []

            # Si no hay una cuenta sat no aplica la relacion
            if not wizard.account_sat_id:
                continue

            # Obtiene el total a cargar en las transacciones
            for account in wizard.account_apply_ids:
                # Actualiza la lista de cuentas a relacionar
                acc_ids.append(account.id)

            # Actualiza la informacion de las cuentas sobre la cuenta SAT
            self.pool.get('account.account.sat').write(
                cr,
                uid, [wizard.account_sat_id.id],
                {'account_ids': [[6, False, acc_ids]]},
                context=context)

        # Elimina registros anteriores
        reg_ids = self.search(cr, uid, [], context=context)
        self.unlink(cr, uid, reg_ids, context=context)

        # Actualiza variable de retorno
        context.update({'default_account_sat_id': False})

        dummy, view_id = self.pool.get('ir.model.data').get_object_reference(
            cr, uid, 'account_sat', 'account_sat_related_wizard_form_view')
        return {
            'name': _("Relacionar Cuentas SAT"),
            'view_mode': 'form',
            'view_id': view_id,
            'view_type': 'form',
            'res_model': 'account.sat.related.wizard',
            'type': 'ir.actions.act_window',
            'nodestroy': True,
            'target': 'inline',
            'domain': '[]',
            'context': context,
            #'res_id' : res_id, # id of the object to which to redirected
        }

    def action_related_cancel(self, cr, uid, ids, context=None):
        """
            Hace la cancelacion de la relacion de cuentas
        """

        # Elimina registros anteriores
        reg_ids = self.search(cr, uid, [], context=context)
        self.unlink(cr, uid, reg_ids, context=context)

        # Actualiza variable de retorno
        context.update({'default_account_sat_id': False})

        dummy, view_id = self.pool.get('ir.model.data').get_object_reference(
            cr, uid, 'account_sat', 'account_sat_related_wizard_form_view')
        return {
            'name': _("Relacionar Cuentas SAT"),
            'view_mode': 'form',
            'view_id': view_id,
            'view_type': 'form',
            'res_model': 'account.sat.related.wizard',
            'type': 'ir.actions.act_window',
            'nodestroy': True,
            'target': 'inline',
            'domain': '[]',
            'context': context,
            #'res_id' : res_id, # id of the object to which to redirected
        }

    def action_remove(self, cr, uid, ids, context=None):
        """
            Quita la relacion de las cuentas relacionadas a la cuenta sat
        """
        if context is None:
            context = {}

        self.write(cr,
                   uid,
                   ids, {'account_apply_ids': [[6, False, []]]},
                   context=context)
        return True

    def action_apply(self, cr, uid, ids, context=None):
        """
            Actualiza el valor del monto aplicado sobre las lineas seleccionadas
        """
        if context is None:
            context = {}
        line_ids = []

        # Recorre las lineas de las cuentas a aplicar
        for wizard in self.browse(cr, uid, ids, context=context):
            # Agrega al arreglo los ids a aplicar a la cuenta sat
            for line in wizard.account_ids:
                if line.account_id:
                    line_ids.append(line.account_id.id)
            # Agrega al arrelog los ids ya aplycados
            for line in wizard.account_apply_ids:
                line_ids.append(line.id)

        print "************ line_ids ******* ", line_ids

        self.write(cr,
                   uid,
                   ids, {
                       'account_apply_ids': [[6, False, line_ids]],
                       'account_ids': [[6, False, []]]
                   },
                   context=context)
        return False

    def button_dummy(self, cr, uid, ids, context=None):
        """
            Actualiza el valor del monto aplicado sobre las lineas seleccionadas
        """
        if context is None:
            context = {}
        acc_obj = self.pool.get('account.account')
        line_obj = self.pool.get('account.sat.related.account.wizard')
        line_rel_obj = self.pool.get('account.sat.related.apply.wizard')
        acc_line_rel = []
        acc_line_ids = []

        # Obtiene la cuenta sat
        wizard = self.browse(cr, uid, ids[0], context=context)
        account_sat_id = wizard.account_sat_id.id or False
        wizard_id = wizard.id

        # Elimina las lineas relacionadas
        line_ids = line_obj.search(cr, uid, [('wizard_id', '=', wizard_id)])
        line_obj.unlink(cr, uid, line_ids, context=context)
        line_rel_ids = line_obj.search(cr, uid,
                                       [('wizard_id', '=', wizard_id)])
        line_rel_obj.unlink(cr, uid, line_rel_ids, context=context)

        # Busca las cuentas pendientes de conciliar
        acc_ids = acc_obj.search(cr, uid, [('account_sat_id', '=', False),
                                           ('type', '!=', 'view')])
        for account_id in acc_ids:
            val = {'wizard_id': wizard_id, 'account_id': account_id}
            line_obj.create(cr, uid, val, context=context)
            #acc_line_ids.append(val)

        if account_sat_id:
            # Busca las cuentas conciliadas con la cuenta
            account_ids = acc_obj.search(
                cr, uid, [('account_sat_id', '=', account_sat_id),
                          ('type', '!=', 'view')])
            if account_ids:
                # Recorre los movimientos y los agrega en la vista de banco
                for account_id in account_ids:
                    val = {
                        'wizard_id': wizard_id,
                        'account_id': account_id,
                    }
                    line_rel_obj.create(cr, uid, val, context=context)
                    #acc_line_rel.append(val)

        self.write(cr, uid, ids, {}, context=context)
        return True
Ejemplo n.º 22
0
class partner_vat_intra(osv.osv_memory):
    """
    Partner Vat Intra
    """
    _name = "partner.vat.intra"
    _description = 'Partner VAT Intra'

    def _get_xml_data(self, cr, uid, context=None):
        if context.get('file_save', False):
            return base64.encodestring(context['file_save'].encode('utf8'))
        return ''

    def _get_europe_country(self, cursor, user, context=None):
        return self.pool.get('res.country').search(cursor, user, [
            ('code', 'in', [
                'AT', 'BG', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR',
                'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT',
                'RO', 'SK', 'SI', 'ES', 'SE', 'GB'
            ])
        ])

    _columns = {
        'name':
        fields.char('File Name'),
        'period_code':
        fields.char(
            'Period Code',
            size=6,
            required=True,
            help=
            '''This is where you have to set the period code for the intracom declaration using the format: ppyyyy
      PP can stand for a month: from '01' to '12'.
      PP can stand for a trimester: '31','32','33','34'
          The first figure means that it is a trimester,
          The second figure identify the trimester.
      PP can stand for a complete fiscal year: '00'.
      YYYY stands for the year (4 positions).
    '''),
        'period_ids':
        fields.many2many(
            'account.period',
            'account_period_rel',
            'acc_id',
            'period_id',
            'Period (s)',
            help=
            'Select here the period(s) you want to include in your intracom declaration'
        ),
        'tax_code_id':
        fields.many2one('account.tax.code',
                        'Company',
                        domain=[('parent_id', '=', False)],
                        help="Keep empty to use the user's company",
                        required=True),
        'test_xml':
        fields.boolean('Test XML file',
                       help="Sets the XML output as test file"),
        'mand_id':
        fields.char(
            'Reference',
            help="Reference given by the Representative of the sending company."
        ),
        'msg':
        fields.text('File created', readonly=True),
        'no_vat':
        fields.text(
            'Partner With No VAT',
            readonly=True,
            help=
            "The Partner whose VAT number is not defined and they are not included in XML File."
        ),
        'file_save':
        fields.binary('Save File', readonly=True),
        'country_ids':
        fields.many2many('res.country', 'vat_country_rel', 'vat_id',
                         'country_id', 'European Countries'),
        'comments':
        fields.text('Comments'),
    }

    def _get_tax_code(self, cr, uid, context=None):
        obj_tax_code = self.pool.get('account.tax.code')
        obj_user = self.pool.get('res.users')
        company_id = obj_user.browse(cr, uid, uid,
                                     context=context).company_id.id
        tax_code_ids = obj_tax_code.search(cr,
                                           uid,
                                           [('company_id', '=', company_id),
                                            ('parent_id', '=', False)],
                                           context=context)
        return tax_code_ids and tax_code_ids[0] or False

    _defaults = {
        'country_ids': _get_europe_country,
        'file_save': _get_xml_data,
        'name': 'vat_intra.xml',
        'tax_code_id': _get_tax_code,
    }

    def _get_datas(self, cr, uid, ids, context=None):
        """Collects require data for vat intra xml
        :param ids: id of wizard.
        :return: dict of all data to be used to generate xml for Partner VAT Intra.
        :rtype: dict
        """
        if context is None:
            context = {}

        obj_user = self.pool.get('res.users')
        obj_sequence = self.pool.get('ir.sequence')
        obj_partner = self.pool.get('res.partner')

        xmldict = {}
        post_code = street = city = country = data_clientinfo = ''
        seq = amount_sum = 0

        wiz_data = self.browse(cr, uid, ids[0], context=context)
        comments = wiz_data.comments

        if wiz_data.tax_code_id:
            data_company = wiz_data.tax_code_id.company_id
        else:
            data_company = obj_user.browse(cr, uid, uid,
                                           context=context).company_id

        # Get Company vat
        company_vat = data_company.partner_id.vat
        if not company_vat:
            raise osv.except_osv(
                _('Insufficient Data!'),
                _('No VAT number associated with your company.'))
        company_vat = company_vat.replace(' ', '').upper()
        issued_by = company_vat[:2]

        if len(wiz_data.period_code) != 6:
            raise osv.except_osv(_('Error!'), _('Period code is not valid.'))

        if not wiz_data.period_ids:
            raise osv.except_osv(_('Insufficient Data!'),
                                 _('Please select at least one Period.'))

        p_id_list = obj_partner.search(cr,
                                       uid, [('vat', '!=', False)],
                                       context=context)
        if not p_id_list:
            raise osv.except_osv(
                _('Insufficient Data!'),
                _('No partner has a VAT number associated with him.'))

        seq_declarantnum = obj_sequence.next_by_code(cr, uid, 'declarantnum')
        dnum = company_vat[2:] + seq_declarantnum[-4:]

        addr = obj_partner.address_get(cr, uid, [data_company.partner_id.id],
                                       ['invoice'])
        email = data_company.partner_id.email or ''
        phone = data_company.partner_id.phone or ''

        if addr.get('invoice', False):
            ads = obj_partner.browse(cr, uid, [addr['invoice']])[0]
            city = (ads.city or '')
            post_code = (ads.zip or '')
            if ads.street:
                street = ads.street
            if ads.street2:
                street += ' '
                street += ads.street2
            if ads.country_id:
                country = ads.country_id.code

        if not country:
            country = company_vat[:2]
        if not email:
            raise osv.except_osv(
                _('Insufficient Data!'),
                _('No email address associated with the company.'))
        if not phone:
            raise osv.except_osv(_('Insufficient Data!'),
                                 _('No phone associated with the company.'))
        xmldict.update({
            'company_name':
            data_company.name,
            'company_vat':
            company_vat,
            'vatnum':
            company_vat[2:],
            'mand_id':
            wiz_data.mand_id,
            'sender_date':
            str(time.strftime('%Y-%m-%d')),
            'street':
            street,
            'city':
            city,
            'post_code':
            post_code,
            'country':
            country,
            'email':
            email,
            'phone':
            phone.replace('/', '').replace('.', '').replace('(', '').replace(
                ')', '').replace(' ', ''),
            'period':
            wiz_data.period_code,
            'clientlist': [],
            'comments':
            comments,
            'issued_by':
            issued_by,
        })
        #tax code 44: services
        #tax code 46L: normal good deliveries
        #tax code 46T: ABC good deliveries
        #tax code 48xxx: credite note on tax code xxx
        codes = ('44', '46L', '46T', '48s44', '48s46L', '48s46T')
        cr.execute(
            '''SELECT p.name As partner_name, l.partner_id AS partner_id, p.vat AS vat,
                      (CASE WHEN t.code = '48s44' THEN '44'
                            WHEN t.code = '48s46L' THEN '46L'
                            WHEN t.code = '48s46T' THEN '46T'
                       ELSE t.code END) AS intra_code,
                      SUM(CASE WHEN t.code in ('48s44','48s46L','48s46T') THEN -l.tax_amount ELSE l.tax_amount END) AS amount
                      FROM account_move_line l
                      LEFT JOIN account_tax_code t ON (l.tax_code_id = t.id)
                      LEFT JOIN res_partner p ON (l.partner_id = p.id)
                      WHERE t.code IN %s
                       AND l.period_id IN %s
                       AND t.company_id = %s
                      GROUP BY p.name, l.partner_id, p.vat, intra_code''',
            (codes, tuple([p.id
                           for p in wiz_data.period_ids]), data_company.id))

        p_count = 0

        for row in cr.dictfetchall():
            if not row['vat']:
                row['vat'] = ''
                p_count += 1

            seq += 1
            amt = row['amount'] or 0.0
            amount_sum += amt

            intra_code = row['intra_code'] == '44' and 'S' or (
                row['intra_code'] == '46L' and 'L' or
                (row['intra_code'] == '46T' and 'T' or ''))

            xmldict['clientlist'].append({
                'partner_name':
                row['partner_name'],
                'seq':
                seq,
                'vatnum':
                row['vat'][2:].replace(' ', '').upper(),
                'vat':
                row['vat'],
                'country':
                row['vat'][:2],
                'amount':
                round(amt, 2),
                'intra_code':
                row['intra_code'],
                'code':
                intra_code
            })

        xmldict.update({
            'dnum': dnum,
            'clientnbr': str(seq),
            'amountsum': round(amount_sum, 2),
            'partner_wo_vat': p_count
        })
        return xmldict

    def create_xml(self, cursor, user, ids, context=None):
        """Creates xml that is to be exported and sent to estate for partner vat intra.
        :return: Value for next action.
        :rtype: dict
        """
        mod_obj = self.pool.get('ir.model.data')
        xml_data = self._get_datas(cursor, user, ids, context=context)
        month_quarter = xml_data['period'][:2]
        year = xml_data['period'][2:]
        data_file = ''

        # Can't we do this by etree?
        data_head = """<?xml version="1.0" encoding="ISO-8859-1"?>
<ns2:IntraConsignment xmlns="http://www.minfin.fgov.be/InputCommon" xmlns:ns2="http://www.minfin.fgov.be/IntraConsignment" IntraListingsNbr="1">
    <ns2:Representative>
        <RepresentativeID identificationType="NVAT" issuedBy="%(issued_by)s">%(vatnum)s</RepresentativeID>
        <Name>%(company_name)s</Name>
        <Street>%(street)s</Street>
        <PostCode>%(post_code)s</PostCode>
        <City>%(city)s</City>
        <CountryCode>%(country)s</CountryCode>
        <EmailAddress>%(email)s</EmailAddress>
        <Phone>%(phone)s</Phone>
    </ns2:Representative>""" % (xml_data)
        if xml_data['mand_id']:
            data_head += '\n\t\t<ns2:RepresentativeReference>%(mand_id)s</ns2:RepresentativeReference>' % (
                xml_data)
        data_comp_period = '\n\t\t<ns2:Declarant>\n\t\t\t<VATNumber>%(vatnum)s</VATNumber>\n\t\t\t<Name>%(company_name)s</Name>\n\t\t\t<Street>%(street)s</Street>\n\t\t\t<PostCode>%(post_code)s</PostCode>\n\t\t\t<City>%(city)s</City>\n\t\t\t<CountryCode>%(country)s</CountryCode>\n\t\t\t<EmailAddress>%(email)s</EmailAddress>\n\t\t\t<Phone>%(phone)s</Phone>\n\t\t</ns2:Declarant>' % (
            xml_data)
        if month_quarter.startswith('3'):
            data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Quarter>' + month_quarter[
                1] + '</ns2:Quarter> \n\t\t\t<ns2:Year>' + year + '</ns2:Year>\n\t\t</ns2:Period>'
        elif month_quarter.startswith('0') and month_quarter.endswith('0'):
            data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Year>' + year + '</ns2:Year>\n\t\t</ns2:Period>'
        else:
            data_comp_period += '\n\t\t<ns2:Period>\n\t\t\t<ns2:Month>' + month_quarter + '</ns2:Month> \n\t\t\t<ns2:Year>' + year + '</ns2:Year>\n\t\t</ns2:Period>'

        data_clientinfo = ''
        for client in xml_data['clientlist']:
            if not client['vatnum']:
                raise osv.except_osv(
                    _('Insufficient Data!'),
                    _('No vat number defined for %s.') %
                    client['partner_name'])
            data_clientinfo += '\n\t\t<ns2:IntraClient SequenceNumber="%(seq)s">\n\t\t\t<ns2:CompanyVATNumber issuedBy="%(country)s">%(vatnum)s</ns2:CompanyVATNumber>\n\t\t\t<ns2:Code>%(code)s</ns2:Code>\n\t\t\t<ns2:Amount>%(amount).2f</ns2:Amount>\n\t\t</ns2:IntraClient>' % (
                client)

        data_decl = '\n\t<ns2:IntraListing SequenceNumber="1" ClientsNbr="%(clientnbr)s" DeclarantReference="%(dnum)s" AmountSum="%(amountsum).2f">' % (
            xml_data)

        data_file += data_head + data_decl + data_comp_period + data_clientinfo + '\n\t\t<ns2:Comment>%(comments)s</ns2:Comment>\n\t</ns2:IntraListing>\n</ns2:IntraConsignment>' % (
            xml_data)
        context = dict(context or {})
        context['file_save'] = data_file

        model_data_ids = mod_obj.search(cursor,
                                        user,
                                        [('model', '=', 'ir.ui.view'),
                                         ('name', '=', 'view_vat_intra_save')],
                                        context=context)
        resource_id = mod_obj.read(cursor,
                                   user,
                                   model_data_ids,
                                   fields=['res_id'],
                                   context=context)[0]['res_id']

        return {
            'name': _('Save'),
            'context': context,
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'partner.vat.intra',
            'views': [(resource_id, 'form')],
            'view_id': 'view_vat_intra_save',
            'type': 'ir.actions.act_window',
            'target': 'new',
        }

    def preview(self, cr, uid, ids, context=None):
        xml_data = self._get_datas(cr, uid, ids, context=context)
        datas = {'ids': [], 'model': 'partner.vat.intra', 'form': xml_data}
        return self.pool['report'].get_action(
            cr,
            uid, [],
            'l10n_be.report_l10nvatintraprint',
            data=datas,
            context=context)
Ejemplo n.º 23
0
class website(osv.osv):
    def _get_menu_website(self, cr, uid, ids, context=None):
        # IF a menu is changed, update all websites
        return self.search(cr, uid, [], context=context)

    def _get_menu(self, cr, uid, ids, name, arg, context=None):
        root_domain = [('parent_id', '=', False)]
        menus = self.pool.get('website.menu').search(cr,
                                                     uid,
                                                     root_domain,
                                                     order='id',
                                                     context=context)
        menu = menus and menus[0] or False
        return dict(map(lambda x: (x, menu), ids))

    def _get_public_user(self,
                         cr,
                         uid,
                         ids,
                         name='public_user',
                         arg=(),
                         context=None):
        ref = self.get_public_user(cr, uid, context=context)
        return dict(map(lambda x: (x, ref), ids))

    _name = "website"  # Avoid website.website convention for conciseness (for new api). Got a special authorization from xmo and rco
    _description = "Website"
    _columns = {
        'name':
        fields.char('Domain'),
        'company_id':
        fields.many2one('res.company', string="Company"),
        'language_ids':
        fields.many2many('res.lang', 'website_lang_rel', 'website_id',
                         'lang_id', 'Languages'),
        'default_lang_id':
        fields.many2one('res.lang', string="Default language"),
        'default_lang_code':
        fields.related('default_lang_id',
                       'code',
                       type="char",
                       string="Default language code",
                       store=True),
        'social_twitter':
        fields.char('Twitter Account'),
        'social_facebook':
        fields.char('Facebook Account'),
        'social_github':
        fields.char('GitHub Account'),
        'social_linkedin':
        fields.char('LinkedIn Account'),
        'social_youtube':
        fields.char('Youtube Account'),
        'social_googleplus':
        fields.char('Google+ Account'),
        'google_analytics_key':
        fields.char('Google Analytics Key'),
        'user_id':
        fields.many2one('res.users', string='Public User'),
        'public_user':
        fields.function(_get_public_user,
                        relation='res.users',
                        type='many2one',
                        string='Public User'),
        'menu_id':
        fields.function(_get_menu,
                        relation='website.menu',
                        type='many2one',
                        string='Main Menu',
                        store={
                            'website.menu':
                            (_get_menu_website,
                             ['sequence', 'parent_id', 'website_id'], 10)
                        })
    }

    # cf. Wizard hack in website_views.xml
    def noop(self, *args, **kwargs):
        pass

    def write(self, cr, uid, ids, vals, context=None):
        self._get_languages.clear_cache(self)
        return super(website, self).write(cr, uid, ids, vals, context)

    def new_page(self,
                 cr,
                 uid,
                 name,
                 template='website.default_page',
                 ispage=True,
                 context=None):
        context = context or {}
        imd = self.pool.get('ir.model.data')
        view = self.pool.get('ir.ui.view')
        template_module, template_name = template.split('.')

        # completely arbitrary max_length
        page_name = slugify(name, max_length=50)
        page_xmlid = "%s.%s" % (template_module, page_name)

        try:
            # existing page
            imd.get_object_reference(cr, uid, template_module, page_name)
        except ValueError:
            # new page
            _, template_id = imd.get_object_reference(cr, uid, template_module,
                                                      template_name)
            page_id = view.copy(cr, uid, template_id, context=context)
            page = view.browse(cr, uid, page_id, context=context)
            page.write({
                'arch': page.arch.replace(template, page_xmlid),
                'name': page_name,
                'page': ispage,
            })
            imd.create(cr,
                       uid, {
                           'name': page_name,
                           'module': template_module,
                           'model': 'ir.ui.view',
                           'res_id': page_id,
                           'noupdate': True
                       },
                       context=context)
        return page_xmlid

    def page_for_name(self,
                      cr,
                      uid,
                      ids,
                      name,
                      module='website',
                      context=None):
        # whatever
        return '%s.%s' % (module, slugify(name, max_length=50))

    def page_exists(self, cr, uid, ids, name, module='website', context=None):
        page = self.page_for_name(cr,
                                  uid,
                                  ids,
                                  name,
                                  module=module,
                                  context=context)

        try:
            self.pool["ir.model.data"].get_object_reference(
                cr, uid, module, name)
        except:
            return False

    def get_public_user(self, cr, uid, context=None):
        uid = openerp.SUPERUSER_ID
        res = self.pool['ir.model.data'].get_object_reference(
            cr, uid, 'base', 'public_user')
        return res and res[1] or False

    @openerp.tools.ormcache(skiparg=3)
    def _get_languages(self, cr, uid, id, context=None):
        website = self.browse(cr, uid, id)
        return [(lg.code, lg.name) for lg in website.language_ids]

    def get_languages(self, cr, uid, ids, context=None):
        return self._get_languages(cr, uid, ids[0])

    def get_current_website(self, cr, uid, context=None):
        # TODO: Select website, currently hard coded
        return self.pool['website'].browse(cr, uid, 1, context=context)

    def preprocess_request(self, cr, uid, ids, request, context=None):
        # TODO FP: is_website_publisher and editable in context should be removed
        # for performance reasons (1 query per image to load) but also to be cleaner
        # I propose to replace this by a group 'base.group_website_publisher' on the
        # view that requires it.
        Access = request.registry['ir.model.access']
        is_website_publisher = Access.check(cr, uid, 'ir.ui.view', 'write',
                                            False, context)

        lang = request.context['lang']
        is_master_lang = lang == request.website.default_lang_code

        request.redirect = lambda url: werkzeug.utils.redirect(url_for(url))
        request.context.update(
            is_master_lang=is_master_lang,
            editable=is_website_publisher,
            translatable=not is_master_lang,
        )

    def get_template(self, cr, uid, ids, template, context=None):
        if '.' not in template:
            template = 'website.%s' % template
        module, xmlid = template.split('.', 1)
        model, view_id = request.registry[
            "ir.model.data"].get_object_reference(cr, uid, module, xmlid)
        return self.pool["ir.ui.view"].browse(cr,
                                              uid,
                                              view_id,
                                              context=context)

    def _render(self, cr, uid, ids, template, values=None, context=None):
        user = self.pool.get("res.users")
        if not context:
            context = {}

        # Take a context
        qweb_values = context.copy()
        # add some values
        if values:
            qweb_values.update(values)
        # fill some defaults
        qweb_values.update(
            request=request,
            json=simplejson,
            website=request.website,
            url_for=url_for,
            keep_query=keep_query,
            slug=slug,
            res_company=request.website.company_id,
            user_id=user.browse(cr, uid, uid),
            quote_plus=werkzeug.url_quote_plus,
        )
        qweb_values.setdefault('editable', False)

        # in edit mode ir.ui.view will tag nodes
        context['inherit_branding'] = qweb_values['editable']

        view = self.get_template(cr, uid, ids, template)

        if 'main_object' not in qweb_values:
            qweb_values['main_object'] = view
        return view.render(qweb_values, engine='website.qweb', context=context)

    def render(self,
               cr,
               uid,
               ids,
               template,
               values=None,
               status_code=None,
               context=None):
        def callback(template, values, context):
            return self._render(cr, uid, ids, template, values, context)

        if values is None:
            values = {}
        return LazyResponse(callback,
                            status_code=status_code,
                            template=template,
                            values=values,
                            context=context)

    def pager(self,
              cr,
              uid,
              ids,
              url,
              total,
              page=1,
              step=30,
              scope=5,
              url_args=None,
              context=None):
        # Compute Pager
        page_count = int(math.ceil(float(total) / step))

        page = max(1, min(int(page), page_count))
        scope -= 1

        pmin = max(page - int(math.floor(scope / 2)), 1)
        pmax = min(pmin + scope, page_count)

        if pmax - pmin < scope:
            pmin = pmax - scope if pmax - scope > 0 else 1

        def get_url(page):
            _url = "%spage/%s/" % (url, page)
            if url_args:
                _url = "%s?%s" % (_url, werkzeug.url_encode(url_args))
            return _url

        return {
            "page_count":
            page_count,
            "offset": (page - 1) * step,
            "page": {
                'url': get_url(page),
                'num': page
            },
            "page_start": {
                'url': get_url(pmin),
                'num': pmin
            },
            "page_previous": {
                'url': get_url(max(pmin, page - 1)),
                'num': max(pmin, page - 1)
            },
            "page_next": {
                'url': get_url(min(pmax, page + 1)),
                'num': min(pmax, page + 1)
            },
            "page_end": {
                'url': get_url(pmax),
                'num': pmax
            },
            "pages": [{
                'url': get_url(page),
                'num': page
            } for page in xrange(pmin, pmax + 1)]
        }

    def rule_is_enumerable(self, rule):
        """ Checks that it is possible to generate sensible GET queries for
        a given rule (if the endpoint matches its own requirements)

        :type rule: werkzeug.routing.Rule
        :rtype: bool
        """
        endpoint = rule.endpoint
        methods = rule.methods or ['GET']
        converters = rule._converters.values()

        return (
            'GET' in methods and endpoint.routing['type'] == 'http'
            and endpoint.routing['auth'] in ('none', 'public')
            and endpoint.routing.get('website', False)
            # preclude combinatorial explosion by only allowing a single converter
            and len(converters) <= 1
            # ensure all converters on the rule are able to generate values for
            # themselves
            and all(
                hasattr(converter, 'generate') for converter in converters)
        ) and self.endpoint_is_enumerable(rule)

    def endpoint_is_enumerable(self, rule):
        """ Verifies that it's possible to generate a valid url for the rule's
        endpoint

        :type rule: werkzeug.routing.Rule
        :rtype: bool
        """
        spec = inspect.getargspec(rule.endpoint.method)

        # if *args bail the f**k out, only dragons can live there
        if spec.varargs:
            return False

        # remove all arguments with a default value from the list
        defaults_count = len(spec.defaults or [])  # spec.defaults can be None
        # a[:-0] ~ a[:0] ~ [] -> replace defaults_count == 0 by None to get
        # a[:None] ~ a
        args = spec.args[:(-defaults_count or None)]

        # params with defaults were removed, leftover allowed are:
        # * self (technically should be first-parameter-of-instance-method but whatever)
        # * any parameter mapping to a converter
        return all((arg == 'self' or arg in rule._converters) for arg in args)

    def enumerate_pages(self, cr, uid, ids, query_string=None, context=None):
        """ Available pages in the website/CMS. This is mostly used for links
        generation and can be overridden by modules setting up new HTML
        controllers for dynamic pages (e.g. blog).

        By default, returns template views marked as pages.

        :param str query_string: a (user-provided) string, fetches pages
                                 matching the string
        :returns: a list of mappings with two keys: ``name`` is the displayable
                  name of the resource (page), ``url`` is the absolute URL
                  of the same.
        :rtype: list({name: str, url: str})
        """
        router = request.httprequest.app.get_db_router(request.db)
        # Force enumeration to be performed as public user
        uid = self.get_public_user(cr, uid, context=context)
        for rule in router.iter_rules():
            if not self.rule_is_enumerable(rule):
                continue

            converters = rule._converters
            filtered = bool(converters)
            if converters:
                # allow single converter as decided by fp, checked by
                # rule_is_enumerable
                [(name, converter)] = converters.items()
                converter_values = converter.generate(request.cr,
                                                      uid,
                                                      query=query_string,
                                                      context=context)
                generated = ({
                    k: v
                }
                             for k, v in itertools.izip(
                                 itertools.repeat(name), converter_values))
            else:
                # force single iteration for literal urls
                generated = [{}]

            for values in generated:
                domain_part, url = rule.build(values, append_unknown=False)
                page = {'name': url, 'url': url}

                if not filtered and query_string and not self.page_matches(
                        cr, uid, page, query_string, context=context):
                    continue
                yield page

    def search_pages(self,
                     cr,
                     uid,
                     ids,
                     needle=None,
                     limit=None,
                     context=None):
        return list(
            itertools.islice(
                self.enumerate_pages(cr,
                                     uid,
                                     ids,
                                     query_string=needle,
                                     context=context), limit))

    def page_matches(self, cr, uid, page, needle, context=None):
        """ Checks that a "page" matches a user-provide search string.

        The default implementation attempts to perform a non-contiguous
        substring match of the page's name.

        :param page: {'name': str, 'url': str}
        :param needle: str
        :rtype: bool
        """
        haystack = page['name'].lower()

        needle = iter(needle.lower())
        n = next(needle)
        end = object()

        for char in haystack:
            if char != n: continue

            n = next(needle, end)
            # found all characters of needle in haystack in order
            if n is end:
                return True

        return False

    def kanban(self,
               cr,
               uid,
               ids,
               model,
               domain,
               column,
               template,
               step=None,
               scope=None,
               orderby=None,
               context=None):
        step = step and int(step) or 10
        scope = scope and int(scope) or 5
        orderby = orderby or "name"

        get_args = dict(request.httprequest.args or {})
        model_obj = self.pool[model]
        relation = model_obj._columns.get(column)._obj
        relation_obj = self.pool[relation]

        get_args.setdefault('kanban', "")
        kanban = get_args.pop('kanban')
        kanban_url = "?%s&kanban=" % werkzeug.url_encode(get_args)

        pages = {}
        for col in kanban.split(","):
            if col:
                col = col.split("-")
                pages[int(col[0])] = int(col[1])

        objects = []
        for group in model_obj.read_group(cr,
                                          uid,
                                          domain, ["id", column],
                                          groupby=column):
            obj = {}

            # browse column
            relation_id = group[column][0]
            obj['column_id'] = relation_obj.browse(cr, uid, relation_id)

            obj['kanban_url'] = kanban_url
            for k, v in pages.items():
                if k != relation_id:
                    obj['kanban_url'] += "%s-%s" % (k, v)

            # pager
            number = model_obj.search(cr, uid, group['__domain'], count=True)
            obj['page_count'] = int(math.ceil(float(number) / step))
            obj['page'] = pages.get(relation_id) or 1
            if obj['page'] > obj['page_count']:
                obj['page'] = obj['page_count']
            offset = (obj['page'] - 1) * step
            obj['page_start'] = max(
                obj['page'] - int(math.floor((scope - 1) / 2)), 1)
            obj['page_end'] = min(obj['page_start'] + (scope - 1),
                                  obj['page_count'])

            # view data
            obj['domain'] = group['__domain']
            obj['model'] = model
            obj['step'] = step
            obj['orderby'] = orderby

            # browse objects
            object_ids = model_obj.search(cr,
                                          uid,
                                          group['__domain'],
                                          limit=step,
                                          offset=offset,
                                          order=orderby)
            obj['object_ids'] = model_obj.browse(cr, uid, object_ids)

            objects.append(obj)

        values = {
            'objects': objects,
            'range': range,
            'template': template,
        }
        return request.website._render("website.kanban_contain", values)

    def kanban_col(self,
                   cr,
                   uid,
                   ids,
                   model,
                   domain,
                   page,
                   template,
                   step,
                   orderby,
                   context=None):
        html = ""
        model_obj = self.pool[model]
        domain = safe_eval(domain)
        step = int(step)
        offset = (int(page) - 1) * step
        object_ids = model_obj.search(cr,
                                      uid,
                                      domain,
                                      limit=step,
                                      offset=offset,
                                      order=orderby)
        object_ids = model_obj.browse(cr, uid, object_ids)
        for object_id in object_ids:
            html += request.website._render(template, {'object_id': object_id})
        return html
Ejemplo n.º 24
0
class export_report(osv.osv):
    _name = 'export.report'

    def _default_uom(self, cr, uid, context=None):
        if context is None:context = {}
        res = self.pool.get('product.uom').search(cr, uid, [('name', 'ilike', 'Nos')])
        return res and res[0] or False

    def _ng_default_uom(self, cr, uid, context=None):
        if context is None:context = {}
        res = self.pool.get('product.uom').search(cr, uid, [('name', 'ilike', 'kg')])
        return res and res[0] or False

    def _total(self, cr, uid, ids, name, args, context=None):
        """
        Process
            -total of all lines(net wt and gross wt)
        """
        result = dict([(id, {'net_wt_total': 0.0,'gross_wt_total':0.0,'total_qty':0.0,'count':0}) for id in ids])
        net_wt_total,gross_wt_total,total_qty,count = 0.0,0.0,0.0,0
        for ex in self.browse(cr, uid, ids, context=context):
            for l in ex.line_ids:
                count += 1
                net_wt_total += l.net_wt
                gross_wt_total += l.gross_wt
                total_qty  += l.qty
            result[ex.id]['net_wt_total'] = net_wt_total
            result[ex.id]['gross_wt_total'] = gross_wt_total
            result[ex.id]['total_qty'] = total_qty
            result[ex.id]['count'] = count
        return result

    _columns = {
        'name': fields.char('Name', readonly=True),
        'date': fields.datetime('Creation Date', required=True),
        'exporter_id': fields.many2one('res.partner', 'Exporter', required=True),
        'buyer_id': fields.many2one('res.partner', 'Buyer(if other than consignee)', required=True, domain=[('customer', '=', True)]),
        'consignee_id': fields.many2one('res.partner', 'Consignee', required=True, domain=[('customer', '=', True)]),
        'origin_country': fields.char('Country of Origin of Goods', required=True),
        'dest_country': fields.char('Country of Final Destination', required=True),
        'pre_carriage_by': fields.char('Pre-Carriage by'),
        'place_pre_carrier': fields.char('Place of Receipt Pre-Carrier'),
        'v_f_no': fields.char('Vessal/Flight No.'),
        'landing_port': fields.char('Port of Loading'),
        'discharge_port': fields.char('Port of Discharge'),
        'final_dest': fields.char('Final Destination'),
        'no_of_packages': fields.char('No. & kind of Pkgs.'),
        'container_no': fields.char('Marks & Nos./Container No.'),
        'depends_on': fields.selection([('delivey_order', 'Delivery Order'), ('manually', 'Manually')], 'Depends', required=True),
        'delivery_ids': fields.many2many('stock.picking.out', 'delivery_export_id', 'delivery_id', 'export_id', 'Delivery Orders', domain=[('type', '=', 'out')]),
        'line_ids': fields.one2many('export.line', 'export_id', 'Lines'),
        'inv_no': fields.char('Invoice Number', required=True),
        'inv_date': fields.date('Invoice Date'),
        'buyer_ref': fields.char("Buyer's Ref No.", required=True),
        'buyer_date': fields.date("Buyer's Date."),
        'other_ref': fields.char("Other Reference(s)."),
        'notes': fields.text('Description'),
        'total_qty': fields.function(_total, multi='c', type='float', string='Total Qty',digits_compute=dp.get_precision('Product Unit of Measure')),
        'net_wt_total': fields.function(_total, multi='c', type='float', string='Net Wt. Total',digits_compute=dp.get_precision('Product Unit of Measure')),
        'gross_wt_total': fields.function(_total, multi='c', type='float', string='Gross Wt. Total',digits_compute=dp.get_precision('Product Unit of Measure')),
        'count': fields.function(_total, multi='c', type='integer', string='count',digits_compute=dp.get_precision('Product Unit of Measure')),
        'uom': fields.many2one('product.uom', 'UoM', required=True),
        'n_uom': fields.many2one('product.uom', 'Net Wt. UoM', required=True),
        'g_uom': fields.many2one('product.uom', 'Gross Wt. UoM', required=True),

    }
    _defaults = {
        'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'export.report'),
        'date': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
        'uom':_default_uom,
        'n_uom':_ng_default_uom,
        'g_uom':_ng_default_uom,
        'depends_on':'manually'
    }

    def load_items(self, cr, uid, ids , context=None):
        """
        -Process
            -Add delivery lines from delivery order
        """
        exp_obj = self.pool.get('export.line')
        data = self.browse(cr, uid, ids[0])
        added_line = []
        if data.delivery_ids:
            for do in data.delivery_ids:
                for mv in do.move_lines:
                    desc = self.pool.get('product.product').name_get(cr, uid, [mv.product_id.id], context=context)[0][1]
                    added_line.append({
                                       'product_id':mv.product_id.id,
                                       'product_desc':desc,
                                       'qty':mv.product_qty or 0.0,
                                       'export_id':ids[0],
                                       })
        cr.execute(""" DELETE FROM export_line WHERE export_id = %s""" % (ids[0]))
        if added_line:
            for c in added_line:
                exp_obj.create(cr, uid, c)
        return True

    def action_print(self,cr, uid, ids, context=None):
        """
        Process
            - Action to print export report
                Before printing , required to check all data fullfill that reports.
        """
        context = context or {}
        if not ids:
            raise osv.except_osv(
                _('Error!'),_('You cannot print report this report because some miss-match values.'))

        data = self.read(cr, uid, ids[0], [], context=context)
        if not data['line_ids']:
            raise osv.except_osv(_('Warning!'),_('No Delivery lines found'))
        return {
            'type': 'ir.actions.report.xml',
            'report_name': 'export.do.order',
            'datas': {
                     'ids': [ids[0]],
                     'model': 'export.report',
                     'form': data
                     },
        }
Ejemplo n.º 25
0
class AccountAgingWizardPartner(osv.osv_memory):
    _name = 'account.aging.wizard.partner'
    _description = 'Account Aging Wizard Partner'
    _rec_name = 'partner_id'
    _order = 'name'

    def _get_amount(self, cr, uid, ids, field_names, arg, context=None):
        context = dict(context or {})
        res = {}
        for line in self.browse(cr, uid, ids, context=context):
            direction = line.aaw_id.direction == 'past'
            spans = [
                line.aaw_id.period_length * x * (direction and 1 or -1)
                for x in range(5)
            ]
            res[line.id] = dict((fn, 0.0) for fn in field_names)
            for doc in line.document_ids:
                if 'residual' in field_names:
                    res[line.id]['residual'] += doc.residual
                if 'payment' in field_names:
                    res[line.id]['payment'] += doc.payment
                if 'total' in field_names:
                    res[line.id]['total'] += doc.total

                if 'not_due' in field_names and not direction:
                    # We will use same field not due to store all due amounts
                    if doc.due_days > 0:
                        res[line.id]['not_due'] += doc.residual
                if 'span01' in field_names and not direction:
                    if doc.due_days <= 0 and doc.due_days > spans[1]:
                        res[line.id]['span01'] += doc.residual
                if 'span02' in field_names and not direction:
                    if doc.due_days <= spans[1] and doc.due_days > spans[2]:
                        res[line.id]['span02'] += doc.residual
                if 'span03' in field_names and not direction:
                    if doc.due_days <= spans[2] and doc.due_days > spans[3]:
                        res[line.id]['span03'] += doc.residual
                if 'span04' in field_names and not direction:
                    if doc.due_days <= spans[3] and doc.due_days > spans[4]:
                        res[line.id]['span04'] += doc.residual
                if 'span05' in field_names and not direction:
                    if doc.due_days <= spans[4]:
                        res[line.id]['span05'] += doc.residual

                if 'not_due' in field_names and direction:
                    if doc.due_days <= 0:
                        res[line.id]['not_due'] += doc.residual
                if 'span01' in field_names and direction:
                    if doc.due_days > 0 and doc.due_days <= spans[1]:
                        res[line.id]['span01'] += doc.residual
                if 'span02' in field_names and direction:
                    if doc.due_days > spans[1] and doc.due_days <= spans[2]:
                        res[line.id]['span02'] += doc.residual
                if 'span03' in field_names and direction:
                    if doc.due_days > spans[2] and doc.due_days <= spans[3]:
                        res[line.id]['span03'] += doc.residual
                if 'span04' in field_names and direction:
                    if doc.due_days > spans[3] and doc.due_days <= spans[4]:
                        res[line.id]['span04'] += doc.residual
                if 'span05' in field_names and direction:
                    if doc.due_days > spans[4]:
                        res[line.id]['span05'] += doc.residual

        return res

    def _get_aawp(self, cr, uid, ids, context=None):
        context = dict(context or {})
        res = {}
        for line in self.browse(cr, uid, ids, context=context):
            res[line.aawp_id.id] = True
        return res.keys()

    _columns = {
        'partner_id':
        fields.many2one(
            'res.partner',
            'Partner',
            required=True,
        ),
        'name':
        fields.related('partner_id',
                       'name',
                       string='Name',
                       type='char',
                       store=True),
        'aaw_id':
        fields.many2one('account.aging.wizard',
                        'Account Aging Wizard',
                        help='Account Aging Wizard Holder'),
        'document_ids':
        fields.one2many('account.aging.wizard.document',
                        'aawp_id',
                        'Documents',
                        help='Balance by Currency'),
        'aml_ids':
        fields.many2many('account.move.line',
                         'aaw_id',
                         'Journal Items',
                         help='Journal Items'),
        'currency_id':
        fields.many2one(
            'res.currency',
            'Currency',
            required=True,
        ),
        'total':
        fields.function(_get_amount,
                        string='Total',
                        store={
                            _name:
                            (lambda self, cr, uid, ids, cx: ids, [], 15),
                            'account.aging.wizard.document':
                            (_get_aawp, [], 15),
                        },
                        multi='amounts',
                        type='float'),
        'payment':
        fields.function(_get_amount,
                        string='Payment',
                        store={
                            _name:
                            (lambda self, cr, uid, ids, cx: ids, [], 15),
                            'account.aging.wizard.document':
                            (_get_aawp, [], 15),
                        },
                        multi='amounts',
                        type='float'),
        'residual':
        fields.function(_get_amount,
                        string='Residual',
                        store={
                            _name:
                            (lambda self, cr, uid, ids, cx: ids, [], 15),
                            'account.aging.wizard.document':
                            (_get_aawp, [], 15),
                        },
                        multi='amounts',
                        type='float'),
        'not_due':
        fields.function(_get_amount,
                        string='Not Due',
                        store={
                            _name:
                            (lambda self, cr, uid, ids, cx: ids, [], 15),
                            'account.aging.wizard.document':
                            (_get_aawp, [], 15),
                        },
                        multi='amounts',
                        type='float'),
        'span01':
        fields.function(_get_amount,
                        string='span01',
                        store={
                            _name:
                            (lambda self, cr, uid, ids, cx: ids, [], 15),
                            'account.aging.wizard.document':
                            (_get_aawp, [], 15),
                        },
                        multi='amounts',
                        type='float'),
        'span02':
        fields.function(_get_amount,
                        string='span02',
                        store={
                            _name:
                            (lambda self, cr, uid, ids, cx: ids, [], 15),
                            'account.aging.wizard.document':
                            (_get_aawp, [], 15),
                        },
                        multi='amounts',
                        type='float'),
        'span03':
        fields.function(_get_amount,
                        string='span03',
                        store={
                            _name:
                            (lambda self, cr, uid, ids, cx: ids, [], 15),
                            'account.aging.wizard.document':
                            (_get_aawp, [], 15),
                        },
                        multi='amounts',
                        type='float'),
        'span04':
        fields.function(_get_amount,
                        string='span04',
                        store={
                            _name:
                            (lambda self, cr, uid, ids, cx: ids, [], 15),
                            'account.aging.wizard.document':
                            (_get_aawp, [], 15),
                        },
                        multi='amounts',
                        type='float'),
        'span05':
        fields.function(_get_amount,
                        string='span05',
                        store={
                            _name:
                            (lambda self, cr, uid, ids, cx: ids, [], 15),
                            'account.aging.wizard.document':
                            (_get_aawp, [], 15),
                        },
                        multi='amounts',
                        type='float'),
        'aawc_id':
        fields.many2one('account.aging.wizard.currency',
                        'Account Aging Wizard Currency',
                        help='Account Aging Wizard Currency Holder'),
    }
Ejemplo n.º 26
0
class merge_pickings(osv.osv_memory):
    _inherit = "merge.pickings"

    _columns = {
        'picking_ids':
        fields.many2many(
            'stock.picking',
            'merge_do_picking_rel',
            'merge_do_id',
            'picking_id',
            'Pickings',
            required=True,
            domain=
            "[('state', '=', 'done'), ('type', '=', type), ('partner_id', '=', partner_id),('invoice_state', '=', '2binvoiced')]"
        ),
    }

    def type_change(self, cr, uid, ids, tipe):
        domain = {'partner_id': [('customer', '=', True)]}
        if tipe == 'in':
            domain = {'partner_id': [('supplier', '=', True)]}
        return {
            'value': {
                'picking_ids': None,
                'partner_id': None
            },
            'domain': domain
        }

    def merge_orders(self, cr, uid, ids, context={}):
        pool_data = self.pool.get('ir.model.data')
        journal_obj = self.pool.get('account.journal')
        pool_invoice = self.pool.get('account.invoice')
        pool_picking = self.pool.get('stock.picking')
        pool_partner = self.pool.get('res.partner')
        pool_invoice_line = self.pool.get('account.invoice.line')

        data = self.browse(cr, uid, ids, context=context)[0]
        picking_ids = [x.id for x in data['picking_ids']]
        partner_obj = data['partner_id']
        print data, "=++++++++++++++++++++++"
        # Valisasi Invoice Picking Cek Po apakah sudah ada Invoice
        for x in picking_ids:
            pick = pool_picking.browse(cr, uid, x)
            invoice = []
            print pick.purchase_id.id, "::::::::::::::::::"
            if pick.purchase_id.id:
                print "AAAAAAAA"
                cr.execute(
                    "SELECT invoice_id FROM purchase_invoice_rel WHERE purchase_id = %s",
                    [pick.purchase_id.id])
                invoice = map(lambda x: x[0], cr.fetchall())

            if invoice:
                raise osv.except_osv(
                    _('Warning!'),
                    _('Picking ' + pick.name + ' dari PO ' +
                      pick.purchase_id.name[:6] +
                      ' Tidak Dapat Di Buat Invoice Dari Consolidate Picking'))

        alamat = pool_partner.address_get(cr, uid, [partner_obj.id],
                                          ['contact', 'invoice'])
        address_contact_id = alamat['contact']
        address_invoice_id = alamat['invoice']

        picking = pool_picking.browse(cr, uid, picking_ids[0], context=context)
        namepick = False
        origin = False
        if data.type == 'out':
            type_inv = 'out_invoice'
            account_id = partner_obj.property_account_receivable.id
            curency = picking.sale_id.pricelist_id.currency_id.id
            journal_ids = journal_obj.search(cr,
                                             uid, [('type', '=', 'sale'),
                                                   ('company_id', '=', 1)],
                                             limit=1)

            origin = ''
            namepick = ''
            for picking in pool_picking.browse(cr,
                                               uid,
                                               picking_ids,
                                               context=context):
                if picking.note_id.id:
                    origin += picking.origin + ':' + (
                        picking.note_id.name)[:7] + ', '
                else:
                    origin += picking.origin + ', '

                namepick += picking.sale_id.client_order_ref + ', '

        elif data.type == 'in':
            type_inv = 'in_invoice'
            account_id = partner_obj.property_account_payable.id
            curency = picking.purchase_id.pricelist_id.currency_id.id
            journal_ids = journal_obj.search(cr,
                                             uid, [('type', '=', 'purchase'),
                                                   ('company_id', '=', 1)],
                                             limit=1)

        if not journal_ids:
            raise osv.except_osv(
                ('Error !'),
                ('There is no sale/purchase journal defined for this company'))

        invoice_id = pool_invoice.create(
            cr,
            uid,
            {
                'name':
                namepick[:-2] if namepick else 'Merged Invoice for ' +
                partner_obj.name + ' on ' + time.strftime('%Y-%m-%d %H:%M:%S'),
                # 'name': 'Merged Invoice for '+ partner_obj.name + ' on ' + time.strftime('%Y-%m-%d %H:%M:%S'),
                'type':
                type_inv,
                'account_id':
                account_id,
                'partner_id':
                partner_obj.id,
                'journal_id':
                journal_ids[0] or False,
                'address_invoice_id':
                address_invoice_id,
                'address_contact_id':
                address_contact_id,
                'date_invoice':
                time.strftime('%Y-%m-%d'),
                'user_id':
                uid,
                'origin':
                origin[:-2] if origin else False,
                'currency_id':
                curency or False,
                'picking_ids': [(6, 0, picking_ids)]
            })

        # Daftarkan Ke Purchase Invoice Rel
        add_po_id = []
        for y in picking_ids:
            pick2 = pool_picking.browse(cr, uid, y)
            add_po_id += [pick2.purchase_id.id]

        #convert list into set
        cek_unique = set(add_po_id)

        #convert back to list
        add_po_id = list(cek_unique)

        # Filter PO ID yang sama, Handle jika Multi Picking dari PO yang sama
        unique_list = [
            e for i, e in enumerate(add_po_id) if add_po_id.index(e) == i
        ]

        if data.type == 'in':
            for a in add_po_id:
                cr.execute(
                    'insert into purchase_invoice_rel (purchase_id,invoice_id) values (%s,%s)',
                    (a, invoice_id))

        for picking in pool_picking.browse(cr,
                                           uid,
                                           picking_ids,
                                           context=context):
            pool_picking.write(cr, uid, [picking.id], {
                'invoice_state': 'invoiced',
                'invoice_id': invoice_id
            })
            for move_line in picking.move_lines:
                disc_amount = 0
                if data.type == 'out':
                    price_unit = pool_picking._get_price_unit_invoice(
                        cr, uid, move_line, 'out_invoice')
                    tax_ids = pool_picking._get_taxes_invoice(
                        cr, uid, move_line, 'out_invoice')
                    line_account_id = move_line.product_id.product_tmpl_id.property_account_income.id or move_line.product_id.categ_id.property_account_income_categ.id
                elif data.type == 'in':
                    price_unit = pool_picking._get_price_unit_invoice(
                        cr, uid, move_line, 'in_invoice')
                    tax_ids = pool_picking._get_taxes_invoice(
                        cr, uid, move_line, 'in_invoice')
                    line_account_id = move_line.product_id.product_tmpl_id.property_account_expense.id or move_line.product_id.categ_id.property_account_expense_categ.id
                    disc_amount = move_line.purchase_line_id.discount_nominal
                discount = pool_picking._get_discount_invoice(
                    cr, uid, move_line)

                origin = picking.origin + ':' + (picking.name).strip()
                #origin = (picking.delivery_note).strip() +';'+ (picking.name).strip()
                if picking.note_id:
                    # search op line id by move line ID

                    cekopline = self.pool.get('order.preparation.line').search(
                        cr, uid, [('move_id', '=', move_line.id)])

                    op_line = self.pool.get('order.preparation.line').browse(
                        cr, uid, cekopline)

                    if op_line:
                        for opl in op_line:
                            #Search DN Line ID By OP Line ID
                            cek = self.pool.get('delivery.note.line').search(
                                cr, uid, [('op_line_id', '=', opl.id)])
                            product_dn = self.pool.get(
                                'delivery.note.line').browse(cr, uid, cek)[0]

                            if cek:
                                pool_invoice_line.create(
                                    cr, uid, {
                                        'name':
                                        product_dn.name,
                                        'picking_id':
                                        picking.id,
                                        'origin':
                                        origin,
                                        'uos_id':
                                        move_line.product_uos.id
                                        or move_line.product_uom.id,
                                        'product_id':
                                        move_line.product_id.id,
                                        'price_unit':
                                        price_unit,
                                        'discount':
                                        discount,
                                        'quantity':
                                        move_line.product_qty,
                                        'invoice_id':
                                        invoice_id,
                                        'invoice_line_tax_id': [(6, 0, tax_ids)
                                                                ],
                                        'account_analytic_id':
                                        pool_picking.
                                        _get_account_analytic_invoice(
                                            cr, uid, picking, move_line),
                                        'account_id':
                                        self.pool.get(
                                            'account.fiscal.position'
                                        ).map_account(
                                            cr, uid, partner_obj.
                                            property_account_position,
                                            line_account_id),
                                        'amount_discount':
                                        disc_amount
                                    })
                            else:
                                raise osv.except_osv(
                                    ('Perhatian..!!'),
                                    ('No Delivery Note Tidak Ditemukan'))
                        # end for
                    else:
                        pool_invoice_line.create(
                            cr,
                            uid,
                            {
                                # 'name': picking.origin +':'+ (picking.name).strip(), #move_line.name,
                                'name':
                                move_line.name,
                                'picking_id':
                                picking.id,
                                'origin':
                                origin,
                                'uos_id':
                                move_line.product_uos.id
                                or move_line.product_uom.id,
                                'product_id':
                                move_line.product_id.id,
                                'price_unit':
                                price_unit,
                                'discount':
                                discount,
                                'quantity':
                                move_line.product_qty,
                                'invoice_id':
                                invoice_id,
                                'invoice_line_tax_id': [(6, 0, tax_ids)],
                                'account_analytic_id':
                                pool_picking._get_account_analytic_invoice(
                                    cr, uid, picking, move_line),
                                'account_id':
                                self.pool.get(
                                    'account.fiscal.position').map_account(
                                        cr, uid,
                                        partner_obj.property_account_position,
                                        line_account_id),
                                'amount_discount':
                                disc_amount
                            })
                else:
                    pool_invoice_line.create(
                        cr,
                        uid,
                        {
                            # 'name': picking.origin +':'+ (picking.name).strip(), #move_line.name,
                            'name':
                            move_line.name,
                            'picking_id':
                            picking.id,
                            'origin':
                            origin,
                            'uos_id':
                            move_line.product_uos.id
                            or move_line.product_uom.id,
                            'product_id':
                            move_line.product_id.id,
                            'price_unit':
                            price_unit,
                            'discount':
                            discount,
                            'quantity':
                            move_line.product_qty,
                            'invoice_id':
                            invoice_id,
                            'invoice_line_tax_id': [(6, 0, tax_ids)],
                            'account_analytic_id':
                            pool_picking._get_account_analytic_invoice(
                                cr, uid, picking, move_line),
                            'account_id':
                            self.pool.
                            get('account.fiscal.position').map_account(
                                cr, uid, partner_obj.property_account_position,
                                line_account_id),
                            'amount_discount':
                            disc_amount
                        })
        pool_invoice.button_compute(cr,
                                    uid, [invoice_id],
                                    context=context,
                                    set_total=False)
        action_model, action_id = pool_data.get_object_reference(
            cr, uid, 'account', "invoice_form")
        if data.type == 'in':
            action_model, action_id = pool_data.get_object_reference(
                cr, uid, 'account', "invoice_supplier_form")

        action_pool = self.pool.get(action_model)
        res_id = action_model and action_id or False
        action = action_pool.read(cr, uid, action_id, context=context)
        action['name'] = 'Merged Invoice'
        action['view_type'] = 'form'
        action['view_mode'] = 'form'
        action['view_id'] = [res_id]
        action['res_model'] = 'account.invoice'
        action['type'] = 'ir.actions.act_window'
        action['target'] = 'current'
        action['res_id'] = invoice_id
        return action
Ejemplo n.º 27
0
class grap_timesheet(Model):
    _description = 'Time Sheet'
    _name = 'grap.timesheet'
    _order = 'min_date, max_date, type_id'

    # Fields Function Section
    def _get_amount_activity(self, cr, uid, ids, pFields, args, context=None):
        res = {}
        for gt in self.browse(cr, uid, ids, context=context):
            fmt = '%Y-%m-%d %H:%M:%S'
            d1 = datetime.strptime(gt.min_date, fmt)
            d2 = datetime.strptime(gt.max_date, fmt)
            amount = (d2 - d1).seconds / 3600.0
            res[gt.id] = {
                'amount': amount,
                'activity_qty': len(gt.activity_ids),
                'amount_per_activity': amount / len(gt.activity_ids),
            }
        return res

    def _get_timesheet_group_id(self,
                                cr,
                                uid,
                                ids,
                                pFields,
                                args,
                                context=None):
        return dict([(x, False) for x in ids])

    def _set_timesheet_group_id(self,
                                cr,
                                uid,
                                pId,
                                field_name,
                                field_value,
                                args,
                                context=None):
        pass

    # Columns section
    _columns = {
        'name':
        fields.char('Name', size=256, required=True),
        'user_id':
        fields.many2one('res.users', 'User', required=True),
        'min_date':
        fields.datetime(string='Minimum date', required=True),
        'max_date':
        fields.datetime(string='Maximum date', required=True),
        'activity_ids':
        fields.many2many('grap.activity',
                         'grap_timesheet_activity_rel',
                         'timesheet_id',
                         'activity_id',
                         'Activities',
                         required=True),
        'type_id':
        fields.many2one('grap.timesheet.type', 'Work Type', required=True),
        'timesheet_group_id':
        fields.function(_get_timesheet_group_id,
                        type='many2one',
                        fnct_inv=_set_timesheet_group_id,
                        relation='grap.timesheet.group',
                        string='Group'),
        'amount':
        fields.function(_get_amount_activity,
                        type='float',
                        string='Hours',
                        help='Specifies the amount of worked hours.',
                        multi='activity',
                        store={
                            'grap.timesheet':
                            (lambda self, cr, uid, ids, context=None: ids, [
                                'activity_ids',
                                'min_date',
                                'max_date',
                            ], 10)
                        }),
        'activity_qty':
        fields.function(_get_amount_activity,
                        type='integer',
                        string='Activities Quantity',
                        multi='activity',
                        store={
                            'grap.timesheet':
                            (lambda self, cr, uid, ids, context=None: ids, [
                                'activity_ids',
                                'min_date',
                                'max_date',
                            ], 10)
                        }),
        'amount_per_activity':
        fields.function(_get_amount_activity,
                        type='float',
                        string='Amount Per Activity',
                        multi='activity',
                        store={
                            'grap.timesheet':
                            (lambda self, cr, uid, ids, context=None: ids, [
                                'activity_ids',
                                'min_date',
                                'max_date',
                            ], 10)
                        }),
    }

    # Default Section
    def _get_default_min_date(self, cr, uid, context=None):
        # TODO Make now without minut
        return fields.date.context_today(self, cr, uid, context=context)

    def _get_default_max_date(self, cr, uid, context=None):
        return fields.date.context_today(self, cr, uid, context=context)

    _defaults = {
        'name': '/',
        'user_id': lambda obj, cr, uid, context: uid,
        'min_date': _get_default_min_date,
        'max_date': _get_default_max_date,
    }

    # Views section
    def on_change_timesheet_group_id(self,
                                     cr,
                                     uid,
                                     ids,
                                     timesheet_group_id,
                                     context=None):
        if not timesheet_group_id:
            values = {}
        else:
            gtg_obj = self.pool['grap.timesheet.group']
            gtg = gtg_obj.browse(cr, uid, timesheet_group_id, context=context)
            values = {'activity_ids': [x.id for x in gtg.activity_ids]}
        return {'value': values}
Ejemplo n.º 28
0
class event_event(osv.osv):
    _inherit = "event.event"

    def _list_tz(self, cr, uid, context=None):
        # put POSIX 'Etc/*' entries at the end to avoid confusing users - see bug 1086728
        return [(tz, tz)
                for tz in sorted(pytz.all_timezones,
                                 key=lambda tz: tz
                                 if not tz.startswith('Etc/') else '_')]

    def _count_tracks(self, cr, uid, ids, field_name, arg, context=None):
        return {
            event.id: len(event.track_ids)
            for event in self.browse(cr, uid, ids, context=context)
        }

    def _get_tracks_tag_ids(self,
                            cr,
                            uid,
                            ids,
                            field_names,
                            arg=None,
                            context=None):
        res = dict.fromkeys(ids, [])
        for event in self.browse(cr, uid, ids, context=context):
            for track in event.track_ids:
                res[event.id] += [tag.id for tag in track.tag_ids]
            res[event.id] = list(set(res[event.id]))
        return res

    _columns = {
        'tag_ids':
        fields.many2many('event.tag', string='Tags'),
        'track_ids':
        fields.one2many('event.track', 'event_id', 'Tracks'),
        'sponsor_ids':
        fields.one2many('event.sponsor', 'event_id', 'Sponsorships'),
        'blog_id':
        fields.many2one('blog.blog', 'Event Blog'),
        'show_track_proposal':
        fields.boolean('Talks Proposals'),
        'show_tracks':
        fields.boolean('Multiple Tracks'),
        'show_blog':
        fields.boolean('News'),
        'count_tracks':
        fields.function(_count_tracks, type='integer', string='Tracks'),
        'tracks_tag_ids':
        fields.function(_get_tracks_tag_ids,
                        type='one2many',
                        relation='event.track.tag',
                        string='Tags of Tracks'),
        'allowed_track_tag_ids':
        fields.many2many('event.track.tag',
                         string='Accepted Tags',
                         help="List of available tags for track proposals."),
        'timezone_of_event':
        fields.selection(_list_tz, 'Event Timezone', size=64),
    }

    _defaults = {
        'show_track_proposal':
        False,
        'show_tracks':
        False,
        'show_blog':
        False,
        'timezone_of_event':
        lambda self, cr, uid, c: self.pool.get('res.users').browse(
            cr, uid, uid, c).tz,
    }

    def _get_new_menu_pages(self, cr, uid, event, context=None):
        context = context or {}
        result = super(event_event, self)._get_new_menu_pages(cr,
                                                              uid,
                                                              event,
                                                              context=context)
        if event.show_tracks:
            result.append((_('Talks'), '/event/%s/track' % slug(event)))
            result.append((_('Agenda'), '/event/%s/agenda' % slug(event)))
        if event.blog_id:
            result.append((_('News'), '/blogpost' + slug(event.blog_ig)))
        if event.show_track_proposal:
            result.append((_('Talk Proposals'),
                           '/event/%s/track_proposal' % slug(event)))
        return result
Ejemplo n.º 29
0
class res_partner(osv.osv):
    """ Inherits partner and adds CRM information in the partner form """
    _inherit = 'res.partner'

    def _opportunity_meeting_count(self,
                                   cr,
                                   uid,
                                   ids,
                                   field_name,
                                   arg,
                                   context=None):
        res = dict(
            map(lambda x: (x, {
                'opportunity_count': 0,
                'meeting_count': 0
            }), ids))
        # the user may not have access rights for opportunities or meetings
        try:
            for partner in self.browse(cr, uid, ids, context):
                res[partner.id] = {
                    'opportunity_count': len(partner.opportunity_ids),
                    'meeting_count': len(partner.meeting_ids),
                }
        except:
            pass
        return res

    _columns = {
        'section_id': fields.many2one('crm.case.section', 'Sales Team'),
        'opportunity_ids': fields.one2many('crm.lead', 'partner_id',\
            'Leads and Opportunities', domain=[('probability', 'not in', ['0', '100'])]),
        'meeting_ids': fields.many2many('calendar.event', 'calendar_event_partner_rel','partner_id', 'meeting_id',
            'Meetings'),
        'phonecall_ids': fields.one2many('crm.phonecall', 'partner_id',\
            'Phonecalls'),
        'opportunity_count': fields.function(_opportunity_meeting_count, string="Opportunity", type='integer', multi='opp_meet'),
        'meeting_count': fields.function(_opportunity_meeting_count, string="# Meetings", type='integer', multi='opp_meet'),
    }

    def copy(self, cr, uid, record_id, default=None, context=None):
        if default is None:
            default = {}

        default.update({
            'opportunity_ids': [],
            'meeting_ids': [],
            'phonecall_ids': []
        })

        return super(res_partner, self).copy(cr, uid, record_id, default,
                                             context)

    def redirect_partner_form(self, cr, uid, partner_id, context=None):
        search_view = self.pool.get('ir.model.data').get_object_reference(
            cr, uid, 'base', 'view_res_partner_filter')
        value = {
            'domain': "[]",
            'view_type': 'form',
            'view_mode': 'form,tree',
            'res_model': 'res.partner',
            'res_id': int(partner_id),
            'view_id': False,
            'context': context,
            'type': 'ir.actions.act_window',
            'search_view_id': search_view and search_view[1] or False
        }
        return value

    def make_opportunity(self,
                         cr,
                         uid,
                         ids,
                         opportunity_summary,
                         planned_revenue=0.0,
                         probability=0.0,
                         partner_id=None,
                         context=None):
        categ_obj = self.pool.get('crm.case.categ')
        categ_ids = categ_obj.search(cr, uid,
                                     [('object_id.model', '=', 'crm.lead')])
        lead_obj = self.pool.get('crm.lead')
        opportunity_ids = {}
        for partner in self.browse(cr, uid, ids, context=context):
            if not partner_id:
                partner_id = partner.id
            opportunity_id = lead_obj.create(
                cr,
                uid, {
                    'name': opportunity_summary,
                    'planned_revenue': planned_revenue,
                    'probability': probability,
                    'partner_id': partner_id,
                    'categ_ids': categ_ids and categ_ids[0:1] or [],
                    'type': 'opportunity'
                },
                context=context)
            opportunity_ids[partner_id] = opportunity_id
        return opportunity_ids
class unefa_generar_lista_semestre(osv.TransientModel):
    """
        Este wizard es para crear listas por semestre de todos los estudiantes.
    """
    _name = "unefa.generar_lista_semestre"
    _description = "Crear lista de estudiantes por semesre"

    _columns = {
        'carrera_id':
        fields.many2one(
            'unefa.carrera',
            'Carrera',
            required=True,
            readonly=True,
        ),
        'turno':
        fields.selection([('nocturno', 'NOCTURNO'), ('diurno', 'DIURNO')],
                         'Turno',
                         readonly=True),
        'periodo_id':
        fields.many2one('unefa.conf.periodo_academico',
                        'Período Académico',
                        required=True),
        'pensum_id':
        fields.many2one('unefa.pensum', 'Pensum', required=True),
        'semestre_ids':
        fields.many2many('unefa.semestre', 'unefa_list_semestre_rel',
                         'lista_id', 'semestre_id', 'Semestres')
    }

    def carrera_turno_default(self, cr, uid, ids, context=None):
        coordinador_obj = self.pool.get('res.users')
        coordinador_data = coordinador_obj.browse(cr, uid, uid)
        carrera_id = coordinador_data['coordinacion_id']['carrera_id']['id']
        turno = coordinador_data['coordinacion_id']['regimen']
        value = {
            'carrera_id': carrera_id,
            'turno': turno,
        }
        return {'value': value}

    def domain_semestre_ofertados(self,
                                  cr,
                                  uid,
                                  ids,
                                  carrera_id,
                                  turno,
                                  pensum_id,
                                  periodo_id,
                                  context=None):
        if pensum_id:
            list_semestres_ids = []
            oferta_obj = self.pool.get('unefa.oferta_academica')
            oferta_ids = oferta_obj.search(cr, uid, [
                ('carrera_id', '=', carrera_id),
                ('turno', '=', turno),
                ('periodo_id', '=', periodo_id),
            ])
            oferta_data = oferta_obj.browse(cr, uid, oferta_ids)
            for oferta in oferta_data:
                for pensum in oferta.pensum_ids:
                    if pensum.pensum_id.id == pensum_id:
                        for semestre in pensum.semestres_ids:
                            list_semestres_ids.append(semestre.semestre_id.id)
            domain = {
                'semestre_ids':
                [('id', '=', list([6, False, list_semestres_ids]))]
            }
            return {'domain': domain}

    def generar_listas_semestres(self, cr, uid, ids, context=None):
        url = '/descargar/listas_estudiantes_semestre/%d' % ids[0]
        return {
            'type': 'ir.actions.act_url',
            'url': url,
            'target': 'new',
        }

    def create(self, cr, uid, vals, context=None):
        vals.update({
            'carrera_id':
            self.carrera_turno_default(cr, uid, [])['value']['carrera_id'],
            'turno':
            self.carrera_turno_default(cr, uid, [])['value']['turno'],
        })
        return super(unefa_generar_lista_semestre,
                     self).create(cr, uid, vals, context=context)
Ejemplo n.º 31
0
class hr_employee_overtime_wiz(osv.TransientModel):
    _name = 'hr.employee.overtime.wiz'
    _description = 'Allocation dheures sup par employees'
    _columns = {
        'date':
        fields.date('Date', required=True),
        'hours':
        fields.float('Heures Alloué', required=True),
        'period_id':
        fields.many2one('account.period', 'Periode Salariale', required=True),
        'depts':
        fields.many2many('hr.department', 'summ_dept_rel', 'sum_id', 'dept_id',
                         'Department(s)'),
        'employee_ids':
        fields.many2many('hr.employee', 'summ_dept_emp_rel', 'sum_id',
                         'emp_id', 'Employee(s)'),
        'type':
        fields.selection([('hs', 'Heures Supplementaires'), ('ferie', 'Ferie'),
                          ('nuit', 'Nuit'), ('nuit_extra', 'Nuit Extra')],
                         'Type',
                         required=True),
    }

    def _get_depts(self, cursor, user, context={}):
        employee = self.pool.get('hr.employee').search(
            cursor, user, [('user_id', '=', user)])
        dept_id = self.pool.get('hr.employee').browse(
            cursor, user, employee, context={})[0].department_id.id
        depts = self.pool.get('hr.department').search(
            cursor, user, [('parent_id', 'in', [dept_id])])
        depts.append(dept_id)
        return depts

    def _get_employee(self, cursor, user, context={}):
        employee = self.pool.get('hr.employee').search(
            cursor, user, [('user_id', '=', user)])
        dept_id = self.pool.get('hr.employee').browse(
            cursor, user, employee, context={})[0].department_id.id
        depts = self.pool.get('hr.department').search(
            cursor, user, [('parent_id', 'in', [dept_id])])
        depts.append(dept_id)
        return self.pool.get('hr.employee').search(
            cursor, user, [('department_id', 'in', depts)])

    def _from_date(self, cursor, user, context={}):
        return datetime.date.today().strftime('%Y-%m-%d')

    _defaults = {
        'date': _from_date,
        'depts': _get_depts,
        'employee_ids': _get_employee,
        'type': 'hs',
    }

    def generate_leaves(self, cr, uid, ids, context=None):
        data = self.read(cr, uid, ids, [])[0]
        planning_obj = self.pool.get('hr.employee.overtime')
        if not data['employee_ids']:
            raise osv.except_osv(
                _('Error'),
                _('You have to select at least 1 Employee. And try again'))
        created = []
        st = datetime.datetime.strptime(data['date'], '%Y-%m-%d')
        for employee in data['employee_ids']:
            print data['period_id']
            print data['period_id'][0]
            print data['hours']
            print data['type']
            created.append(
                planning_obj.create(
                    cr, uid, {
                        'type': data['type'],
                        'name': employee,
                        'date': st,
                        'period_id': data['period_id'][0],
                        'hours': data['hours'],
                        'state': 'draft'
                    }))

        return {
            'domain': "[('id','in', [" + ','.join(map(str, created)) + "])]",
            'name': 'Planning',
            'view_type': 'form',
            'view_mode': 'tree,form',
            'res_model': 'hr.employee.overtime',
            'view_id': False,
            'type': 'ir.actions.act_window',
        }
Ejemplo n.º 32
0
        'sequence': fields.integer('Priority', help="Give to the more specialized category, a higher priority to have them in top of the list."),
    }


class product_category(osv.osv):
    _inherit = 'product.category'

    def calculate_total_routes(self, cr, uid, ids, name, args, context=None):
        res = {}
        for categ in self.browse(cr, uid, ids, context=context):
            categ2 = categ
            routes = [x.id for x in categ.route_ids]
            while categ2.parent_id:
                categ2 = categ2.parent_id
                routes += [x.id for x in categ2.route_ids]
            res[categ.id] = routes
        return res

    _columns = {
        'route_ids': fields.many2many('stock.location.route', 'stock_location_route_categ', 'categ_id', 'route_id', 'Routes', domain="[('product_categ_selectable', '=', True)]"),
        'removal_strategy_id': fields.many2one('product.removal', 'Force Removal Strategy', help="Set a specific removal strategy that will be used regardless of the source location for this product category"),
        'total_route_ids': fields.function(calculate_total_routes, relation='stock.location.route', type='many2many', string='Total routes', readonly=True),
    }


    _columns = {
        'route_ids': fields.many2many('stock.location.route', 'stock_location_route_categ', 'categ_id', 'route_id', 'Routes', domain="[('product_categ_selectable', '=', True)]"),
        'removal_strategy_id': fields.many2one('product.removal', 'Force Removal Strategy', help="Set a specific removal strategy that will be used regardless of the source location for this product category"),
        'total_route_ids': fields.function(calculate_total_routes, relation='stock.location.route', type='many2many', string='Total routes', readonly=True),
    }
Ejemplo n.º 33
0
class nucleo(osv.osv):
    _name = 'unefa.nucleo'
    _rec_name = 'nombre'

    _columns = {
        'nombre':
        fields.char('Sede',
                    size=80,
                    required=True,
                    help='Aquí se coloca el nombre de la sede'),
        'decano':
        fields.char('Decano',
                    size=80,
                    required=True,
                    help='Aquí se coloca el nombre del decano de la sede'),
        'unidad_academica':
        fields.char(
            'Jefe Unidad Académica',
            size=80,
            required=True,
            help='Aquí se coloca el nombre del jefe de la unidad académica'),
        'tipo_sede':
        fields.selection([('nucleo', 'NÚCLEO'), ('extension', 'EXTENCIÓN'),
                          ('ampliacion', 'AMPLIACIÓN')],
                         'Tipo de sede',
                         required=True,
                         help='Aquí selecciona el tipo de sede.'),
        'redi_id':
        fields.many2one(
            'unefa.redi',
            'REDI',
            required=True,
            help='Aquí se coloca la REDI donde está ubicada el sede'),
        'region_id':
        fields.many2one(
            'unefa.region_defensa_integral',
            'Región Defensa Integral',
            required=True,
            help=
            'Aquí se coloca la Región de Defensa Integral donde está ubicada el sede'
        ),
        'direccion':
        fields.text('Dirección',
                    required=True,
                    help='Aquí se coloca el dirección del núcleo'),
        'universidad_id':
        fields.many2one('res.company', 'Universidad'),
        'carrera_ids':
        fields.many2many('unefa.carrera', 'unefa_nucleo_carrera', 'nucleo_id',
                         'carrera_id', 'Carreras'),
        'telefono':
        fields.char('Teléfono',
                    size=64,
                    required=True,
                    help='Aquí se coloca el Telefono del nucleo'),
        'estado_id':
        fields.many2one('unefa.estados', 'Estado', required=True),
        'municipio_id':
        fields.many2one('unefa.municipios', 'Municipio', required=True),
        'parroquia_id':
        fields.many2one('unefa.parroquias', 'Parroquia', required=True),
        'direccion':
        fields.char('Dirección',
                    size=80,
                    required=True,
                    help='Aquí se coloca la dirección de la sede'),
        'active':
        fields.boolean(
            'Activo',
            help='Si esta activo el motor lo incluira en la vista...'),
    }

    _defaults = {
        'active': True,
    }

    _sql_constraints = [('nucleo_uniq', 'unique(nombre)',
                         'El Nucleo que ingresó ya ha sido registrado.')]

    _order = 'create_date desc, id desc'

    def cp_limpiar_campos(self, cr, uid, ids, campo, context=None):
        return {'value': {campo: ''}}

    def create(self, cr, uid, vals, context=None):
        vals.update({
            'nombre': vals['nombre'].upper(),
            'direccion': vals['direccion'].upper(),
            'decano': vals['direccion'].upper(),
            'unidad_academica': vals['direccion'].upper(),
        })
        return super(nucleo, self).create(cr, uid, vals, context=context)

    def write(self, cr, uid, ids, vals, context=None):
        if 'nombre' in vals.keys():
            vals.update({
                'nombre': vals['nombre'].upper(),
            })
        if 'direccion' in vals.keys():
            vals.update({
                'direccion': vals['direccion'].upper(),
            })
        if 'unidad_academica' in vals.keys():
            vals.update({
                'unidad_academica': vals['unidad_academica'].upper(),
            })
        if 'decano' in vals.keys():
            vals.update({
                'decano': vals['decano'].upper(),
            })
        return super(nucleo, self).write(cr, uid, ids, vals, context=context)
Ejemplo n.º 34
0
	def _order_lines_from_invoice(self, cr, uid, ids, context=None):
		# direct access to the m2m table is the less convoluted way to achieve this (and is ok ACL-wise)
		cr.execute("""SELECT DISTINCT sol.id FROM sale_order_invoice_rel rel JOIN
												  sale_order_line sol ON (sol.order_id = rel.order_id)
									WHERE rel.invoice_id = ANY(%s)""", (list(ids),))
		return [i[0] for i in cr.fetchall()]

	_name = 'sale.order.line'
	_description = 'Sales Order Line'
	_columns = {
		'order_id': fields.many2one('sale.order', 'Order Reference', required=True, ondelete='cascade', select=True, readonly=True, states={'draft':[('readonly',False)]}),
		'name': fields.text('Description', required=True, readonly=True, states={'draft': [('readonly', False)]}),
		'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of sales order lines."),
		'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], change_default=True),
		'invoice_lines': fields.many2many('account.invoice.line', 'sale_order_line_invoice_rel', 'order_line_id', 'invoice_id', 'Invoice Lines', readonly=True),
		'invoiced': fields.function(_fnct_line_invoiced, string='Invoiced', type='boolean',
			store={
				'account.invoice': (_order_lines_from_invoice, ['state'], 10),
				'sale.order.line': (lambda self,cr,uid,ids,ctx=None: ids, ['invoice_lines'], 10)}),
		'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price'), readonly=True, states={'draft': [('readonly', False)]}),
		'type': fields.selection([('make_to_stock', 'from stock'), ('make_to_order', 'on order')], 'Procurement Method', required=True, readonly=True, states={'draft': [('readonly', False)]},
		 help="From stock: When needed, the product is taken from the stock or we wait for replenishment.\nOn order: When needed, the product is purchased or produced."),
		'price_subtotal': fields.function(_amount_line, string='Subtotal', digits_compute= dp.get_precision('Account')),
		'tax_id': fields.many2many('account.tax', 'sale_order_tax', 'order_line_id', 'tax_id', 'Taxes', readonly=True, states={'draft': [('readonly', False)]}),
		'address_allotment_id': fields.many2one('res.partner', 'Allotment Partner',help="A partner to whom the particular product needs to be allotted."),
		'product_uom_qty': fields.float('Quantity', digits_compute= dp.get_precision('Product UoS'), required=True, readonly=True, states={'draft': [('readonly', False)]}),
		'product_uom': fields.many2one('product.uom', 'Unit of Measure ', required=True, readonly=True, states={'draft': [('readonly', False)]}),
		'product_uos_qty': fields.float('Quantity (UoS)' ,digits_compute= dp.get_precision('Product UoS'), readonly=True, states={'draft': [('readonly', False)]}),
		'product_uos': fields.many2one('product.uom', 'Product UoS'),
		'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Discount'), readonly=True, states={'draft': [('readonly', False)]}),
Ejemplo n.º 35
0
class sale_configuration(osv.TransientModel):
    _inherit = 'sale.config.settings'

    _columns = {
        'group_product_variant':
        fields.selection(
            [(0, "No variants on products"),
             (1,
              'Products can have several attributes, defining variants (Example: size, color,...)'
              )],
            "Product Variants",
            help=
            'Work with product variant allows you to define some variant of the same products, an ease the product management in the ecommerce for example',
            implied_group='product.group_product_variant'),
        'group_sale_pricelist':
        fields.boolean(
            "Use pricelists to adapt your price per customers",
            implied_group='product.group_sale_pricelist',
            help=
            """Allows to manage different prices based on rules per category of customers.
                    Example: 10% for retailers, promotion of 5 EUR on this product, etc."""
        ),
        'group_pricelist_item':
        fields.boolean("Show pricelists to customers",
                       implied_group='product.group_pricelist_item'),
        'group_product_pricelist':
        fields.boolean("Show pricelists On Products",
                       implied_group='product.group_product_pricelist'),
        'group_uom':
        fields.selection(
            [(0, 'Products have only one unit of measure (easier)'),
             (1,
              'Some products may be sold/purchased in different unit of measures (advanced)'
              )],
            "Unit of Measures",
            implied_group='product.group_uom',
            help=
            """Allows you to select and maintain different units of measure for products."""
        ),
        'group_discount_per_so_line':
        fields.selection(
            [(0, 'No discount on sales order lines, global discount only'),
             (1, 'Allow discounts on sales order lines')],
            "Discount",
            implied_group='sale.group_discount_per_so_line'),
        'group_display_incoterm':
        fields.selection(
            [(0, 'No incoterm on reports'),
             (1, 'Show incoterms on sale orders and invoices')],
            "Incoterms",
            implied_group='sale.group_display_incoterm',
            help=
            "The printed reports will display the incoterms for the sale orders and the related invoices"
        ),
        'module_sale_margin':
        fields.selection(
            [(0, 'Salespeople do not need to view margins when quoting'),
             (1, 'Display margins on quotations and sales orders')],
            "Margins"),
        'module_website_sale_digital':
        fields.selection(
            [(0, 'No digital products'),
             (1, 'Allows to sell downloadable content from the portal')],
            "Digital Products"),
        'module_website_quote':
        fields.selection(
            [(0, 'Print quotes or send by email'),
             (1, 'Send online quotations based on templates (advanced)')],
            "Online Quotations"),
        'group_sale_delivery_address':
        fields.selection([
            (0,
             "Invoicing and shipping addresses are always the same (Example: services companies)"
             ),
            (1,
             'Have 3 fields on sales orders: customer, invoice address, delivery address'
             )
        ],
                         "Customer Addresses",
                         implied_group='sale.group_delivery_invoice_address'),
        'sale_pricelist_setting':
        fields.selection(
            [('fixed', 'A single sale price per product'),
             ('percentage', 'Different prices per customer segment'),
             ('formula', 'Advanced pricing based on formula')],
            required=True,
            help='Fix Price: all price manage from products sale price.\n'
            'Different prices per Customer: you can assign price on buying of minimum quantity in products sale tab.\n'
            'Advanced pricing based on formula: You can have all the rights on pricelist'
        ),
        'default_invoice_policy':
        fields.selection(
            [('order', 'Invoice ordered quantities'),
             ('delivery', 'Invoice delivered quantities'),
             ('cost', 'Invoice based on costs (time and material, expenses)')],
            'Default Invoicing',
            default_model='product.template'),
        'deposit_property_account_income_id':
        fields.property(
            type="many2one",
            relation="account.account",
            string="Income Account",
            domain=[('deprecated', '=', False)],
            help=
            "This account will be used for invoices instead of the default one to value sales for the deposit."
        ),
        'deposit_taxes_ids':
        fields.many2many('account.tax',
                         'product_taxes_rel',
                         'prod_id',
                         'tax_id',
                         string='Customer Taxes',
                         domain=[('type_tax_use', '=', 'sale')]),
    }

    _defaults = {
        'sale_pricelist_setting': 'fixed',
        'default_invoice_policy': 'order',
    }

    def set_sale_defaults(self, cr, uid, ids, context=None):
        sale_price = self.browse(cr, uid, ids,
                                 context=context).sale_pricelist_setting
        res = self.pool.get('ir.values').set_default(cr, uid,
                                                     'sale.config.settings',
                                                     'sale_pricelist_setting',
                                                     sale_price)
        return res

    def onchange_sale_price(self,
                            cr,
                            uid,
                            ids,
                            sale_pricelist_setting,
                            context=None):
        if sale_pricelist_setting == 'percentage':
            return {
                'value': {
                    'group_product_pricelist': True,
                    'group_sale_pricelist': True,
                    'group_pricelist_item': False
                }
            }
        if sale_pricelist_setting == 'formula':
            return {
                'value': {
                    'group_pricelist_item': True,
                    'group_sale_pricelist': True,
                    'group_product_pricelist': False
                }
            }
        return {
            'value': {
                'group_pricelist_item': False,
                'group_sale_pricelist': False,
                'group_product_pricelist': False
            }
        }

    def get_default_deposit_values(self, cr, uid, fields, context=None):
        deposit_product_template = self.pool['ir.model.data'].xmlid_to_object(
            cr, uid, 'sale.advance_product_1', context=context)
        return {
            'deposit_property_account_income_id':
            deposit_product_template.product_variant_ids.
            property_account_income_id.id,
            'deposit_taxes_ids':
            deposit_product_template.product_variant_ids.taxes_id.ids
        }

    def set_deposit_values(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        config_value = self.browse(cr, uid, ids, context=context)
        deposit_product_template = self.pool['ir.model.data'].xmlid_to_object(
            cr, uid, 'sale.advance_product_1', context=context)
        deposit_product_template.product_variant_ids.write({
            'property_account_income_id':
            config_value.deposit_property_account_income_id.id,
            'taxes_id': [(6, 0, config_value.deposit_taxes_ids.ids)],
        })
Ejemplo n.º 36
0
                cr, uid, line.taxes_id, line.price, line.qty, line.product_id, line.back_order_id.partner_id
            )
            cur = line.back_order_id.pricelist_id.currency_id
            res[line.id] = cur_obj.round(cr, uid, cur, taxes["total"])
        return res

    def _get_uom_id(self, cr, uid, context=None):
        try:
            proxy = self.pool.get("ir.model.data")
            result = proxy.get_object_reference(cr, uid, "product", "product_uom_unit")
            return result[1]
        except Exception, ex:
            return False

    _columns = {
        #        'location_destination_id': fields.many2one('stock.location', 'Stock Destination Location'),
        #        'location_id': fields.many2one('stock.location', 'Stock Source Location'),
        "product_id": fields.many2one("product.product", "Product"),
        "back_order_id": fields.many2one("back.to.back.order", "Back Order"),
        "qty": fields.float("Quantity"),
        "price": fields.float("Unit Price"),
        "subtotal": fields.function(_amount_line, string="Subtotal", digits_compute=dp.get_precision("Account")),
        "taxes_id": fields.many2many("account.tax", "purchase_order_taxe", "ord_id", "tax_id", "Taxes"),
        "product_uom": fields.many2one("product.uom", "Product Unit of Measure", required=True),
    }

    _defaults = {"product_uom": _get_uom_id}


# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
Ejemplo n.º 37
0
class procurement_order(osv.osv):
    _inherit = 'procurement.order'
    _columns = {
        'bom_id':
        fields.many2one('mrp.bom', 'BoM', ondelete='cascade', select=True),
        'property_ids':
        fields.many2many('mrp.property', 'procurement_property_rel',
                         'procurement_id', 'property_id', 'Properties'),
        'production_id':
        fields.many2one('mrp.production', 'Manufacturing Order'),
    }

    def propagate_cancel(self, cr, uid, procurement, context=None):
        if procurement.rule_id.action == 'manufacture' and procurement.production_id:
            self.pool.get('mrp.production').action_cancel(
                cr, uid, [procurement.production_id.id], context=context)
        return super(procurement_order, self).propagate_cancel(cr,
                                                               uid,
                                                               procurement,
                                                               context=context)

    def _run(self, cr, uid, procurement, context=None):
        if procurement.rule_id and procurement.rule_id.action == 'manufacture':
            #make a manufacturing order for the procurement
            return self.make_mo(cr, uid, [procurement.id],
                                context=context)[procurement.id]
        return super(procurement_order, self)._run(cr,
                                                   uid,
                                                   procurement,
                                                   context=context)

    def _check(self, cr, uid, procurement, context=None):
        if procurement.production_id and procurement.production_id.state == 'done':  # TOCHECK: no better method?
            return True
        return super(procurement_order, self)._check(cr,
                                                     uid,
                                                     procurement,
                                                     context=context)

    def check_bom_exists(self, cr, uid, ids, context=None):
        """ Finds the bill of material for the product from procurement order.
        @return: True or False
        """
        for procurement in self.browse(cr, uid, ids, context=context):
            properties = [x.id for x in procurement.property_ids]
            bom_id = self.pool.get('mrp.bom')._bom_find(
                cr,
                uid,
                product_id=procurement.product_id.id,
                properties=properties,
                context=context)
            if not bom_id:
                return False
        return True

    def _get_date_planned(self, cr, uid, procurement, context=None):
        format_date_planned = datetime.strptime(
            procurement.date_planned, DEFAULT_SERVER_DATETIME_FORMAT)
        date_planned = format_date_planned - relativedelta(
            days=procurement.product_id.produce_delay or 0.0)
        date_planned = date_planned - relativedelta(
            days=procurement.company_id.manufacturing_lead)
        return date_planned

    def _prepare_mo_vals(self, cr, uid, procurement, context=None):
        res_id = procurement.move_dest_id and procurement.move_dest_id.id or False
        newdate = self._get_date_planned(cr, uid, procurement, context=context)
        bom_obj = self.pool.get('mrp.bom')
        if procurement.bom_id:
            bom_id = procurement.bom_id.id
            routing_id = procurement.bom_id.routing_id.id
        else:
            properties = [x.id for x in procurement.property_ids]
            bom_id = bom_obj._bom_find(
                cr,
                uid,
                product_id=procurement.product_id.id,
                properties=properties,
                context=dict(context, company_id=procurement.company_id.id))
            bom = bom_obj.browse(cr, uid, bom_id, context=context)
            routing_id = bom.routing_id.id
        return {
            'origin':
            procurement.origin,
            'product_id':
            procurement.product_id.id,
            'product_qty':
            procurement.product_qty,
            'product_uom':
            procurement.product_uom.id,
            'product_uos_qty':
            procurement.product_uos and procurement.product_uos_qty or False,
            'product_uos':
            procurement.product_uos and procurement.product_uos.id or False,
            'location_src_id':
            procurement.location_id.id,
            'location_dest_id':
            procurement.location_id.id,
            'bom_id':
            bom_id,
            'routing_id':
            routing_id,
            'date_planned':
            newdate.strftime('%Y-%m-%d %H:%M:%S'),
            'move_prod_id':
            res_id,
            'company_id':
            procurement.company_id.id,
        }

    def make_mo(self, cr, uid, ids, context=None):
        """ Make Manufacturing(production) order from procurement
        @return: New created Production Orders procurement wise
        """
        res = {}
        production_obj = self.pool.get('mrp.production')
        procurement_obj = self.pool.get('procurement.order')
        for procurement in procurement_obj.browse(cr,
                                                  uid,
                                                  ids,
                                                  context=context):
            if self.check_bom_exists(cr,
                                     uid, [procurement.id],
                                     context=context):
                #create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example)
                vals = self._prepare_mo_vals(cr,
                                             uid,
                                             procurement,
                                             context=context)
                produce_id = production_obj.create(
                    cr,
                    SUPERUSER_ID,
                    vals,
                    context=dict(context,
                                 force_company=procurement.company_id.id))
                res[procurement.id] = produce_id
                self.write(cr, uid, [procurement.id],
                           {'production_id': produce_id})
                self.production_order_create_note(cr,
                                                  uid,
                                                  procurement,
                                                  context=context)
                production_obj.action_compute(
                    cr,
                    uid, [produce_id],
                    properties=[x.id for x in procurement.property_ids])
                production_obj.signal_workflow(cr, uid, [produce_id],
                                               'button_confirm')
            else:
                res[procurement.id] = False
                self.message_post(cr,
                                  uid, [procurement.id],
                                  body=_("No BoM exists for this product!"),
                                  context=context)
        return res

    def production_order_create_note(self, cr, uid, procurement, context=None):
        body = _("Manufacturing Order <em>%s</em> created.") % (
            procurement.production_id.name, )
        self.message_post(cr,
                          uid, [procurement.id],
                          body=body,
                          context=context)
 'to_{0}_state'.format(ATTR_USE_DOM_PINVOICE[0]): fields.many2one(
     'res.country.state', 'State',
     domain="[('country_id','=',to_{0}_country)]".format(ATTR_USE_DOM_PINVOICE[0])),
 'to_{0}_country'.format(ATTR_USE_DOM_PSHIPPER[0]): fields.many2one(
     'res.country', 'Country'),
 'to_{0}_state'.format(ATTR_USE_DOM_PSHIPPER[0]): fields.many2one(
     'res.country.state', 'State',
     domain="[('country_id','=',to_{0}_country)]".format(ATTR_USE_DOM_PSHIPPER[0])),
 # These are the Fiscal Attributes which are checked at runtime on the invoice-line level. As a many2many you can
 # select a custom number out of the Fiscal Attributes Table. Typically you might want to constrain the choice to
 # an above set Fiscal Domain (optional). Typically when parametrizing you might filter by Attribute Use (eg.
 # 'partner' or 'product' cases for convenience. (planned partner specific roles: 'seller' 'invoiced partner'
 # 'shipped partner'
 'fiscal_attributes_id': fields.many2many(
     'account.fiscal.attribute', 'fiscal_attribute_rel',
     'rule_id', 'attr_id',
     'Fiscal Attributes',
     # TODO this probably might result in problems as templates do not have field company_id
     domain="[('company_id','=',company_id),('fiscal_domain_id','=',fiscal_domain_id)]"),
 'use_sale': fields.boolean('Sales Order'),
 'use_invoice': fields.boolean('Invoices'),
 'use_purchase': fields.boolean('Purchases'),
 'use_picking': fields.boolean('Picking'),
 'date_start': fields.date(
     'from', help="Starting date for this rule to be valid."),
 'date_end': fields.date(
     'until', help="Ending date for this rule to be valid."),
 'vat_rule': fields.selection(
     [('with', 'With VAT number'),
      ('both', 'With or Without VAT number'),
      ('without', 'Without VAT number')], "VAT Rule",
     help=("Choose if the customer need to have the"
Ejemplo n.º 39
0
    
    def _get_uom_id(self, cr, uid, context=None):
        try:
            proxy = self.pool.get('ir.model.data')
            result = proxy.get_object_reference(cr, uid, 'product', 'product_uom_unit')
            return result[1]
        except Exception, ex:
            return False
    
    _columns = {
        
#        'location_destination_id': fields.many2one('stock.location', 'Stock Destination Location'),
#        'location_id': fields.many2one('stock.location', 'Stock Source Location'),
        'product_id': fields.many2one('product.product', 'Product'),
        'back_order_id': fields.many2one('back.to.back.order', 'Back Order'),
        'qty': fields.float('Quantity'),
        'price': fields.float('Unit Price'),
        'subtotal': fields.function(_amount_line, string='Subtotal', digits_compute= dp.get_precision('Account')),
        'taxes_id': fields.many2many('account.tax', 'purchase_order_taxe', 'ord_id', 'tax_id', 'Taxes'),
        'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
        
           
    }
    
    
    _defaults = {
        'product_uom' : _get_uom_id,
    }

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: