Пример #1
0
    def _group(self, items, prefix):
        """Return an XML chunk which represents a group of fields."""
        names = []
        for k, v in items:
            key = '%s\\%s' % (prefix, k)
            # Mask passwords
            if 'passw' in k and not self.show_passwords:
                v = '**********'
            self._columns[key] = fields.char(k, size=1024)
            self._conf_defaults[key] = v
            names.append(key)

        return ('<group col="2" colspan="4">' +
                ''.join(['<field name="%s" readonly="1"/>' %
                         _escape(name) for name in names]) +
                '</group>')
Пример #2
0
    def __init__(self, pool, cr):
        """ Dynamically add columns."""

        super(report_prompt_class, self).__init__(pool, cr)

        for counter in range(0, MAX_PARAMS):
            field_name = PARAM_XXX_STRING_VALUE % counter
            self._columns[field_name] = fields.char('String Value', size=64)
            field_name = PARAM_XXX_BOOLEAN_VALUE % counter
            self._columns[field_name] = fields.boolean('Boolean Value')
            field_name = PARAM_XXX_INTEGER_VALUE % counter
            self._columns[field_name] = fields.integer('Integer Value')
            field_name = PARAM_XXX_NUMBER_VALUE % counter
            self._columns[field_name] = fields.float('Number Value')
            field_name = PARAM_XXX_DATE_VALUE % counter
            self._columns[field_name] = fields.date('Date Value')
            field_name = PARAM_XXX_TIME_VALUE % counter
            self._columns[field_name] = fields.datetime('Time Value')

        self.paramfile = False
Пример #3
0
    def __init__(self, pool, cr):
        """ Dynamically add columns."""

        super(report_prompt_class, self).__init__(pool, cr)

        for counter in range(0, MAX_PARAMS):
            field_name = PARAM_XXX_STRING_VALUE % counter
            self._columns[field_name] = fields.char('String Value', size=64)
            field_name = PARAM_XXX_BOOLEAN_VALUE % counter
            self._columns[field_name] = fields.boolean('Boolean Value')
            field_name = PARAM_XXX_INTEGER_VALUE % counter
            self._columns[field_name] = fields.integer('Integer Value')
            field_name = PARAM_XXX_NUMBER_VALUE % counter
            self._columns[field_name] = fields.float('Number Value')
            field_name = PARAM_XXX_DATE_VALUE % counter
            self._columns[field_name] = fields.date('Date Value')
            field_name = PARAM_XXX_TIME_VALUE % counter
            self._columns[field_name] = fields.datetime('Time Value')
            field_name = PARAM_XXX_2M_VALUE % counter
            self._columns[field_name] = fields.function(self._multi_select_values.im_func,
                                                        arg={"entry_num": counter},
                                                        fnct_inv=self._multi_select_values_store.im_func,
                                                        fnct_inv_arg={"entry_num": counter},
                                                        method=False, type='many2many', relation='ir.actions.report.multivalues.promptwizard', string='Multi-Select')
Пример #4
0
class product_tmalljd(osv.osv):
    _name = "product.tmalljd"

    def _get_ean13(self, cr, uid, ids, field_name, arg, context=None):	
        result = {}
        for line in self.pool.get('product.tmalljd').browse(cr, uid, ids, context=context):
            if line.erp_product_id : result[line.id] = line.erp_product_id.ean13 or line.erp_product_id.default_code
        return result		

    def _get_stock(self, cr, uid, ids, field_name, arg, context=None):	
        result = {}
        domain_products = [('location_id','=',38)]		
        quants = self.pool.get('stock.quant').read_group(cr, uid, domain_products, ['product_id', 'qty'], ['product_id'], context=context)	
        quants = dict(map(lambda x: (x['product_id'][0], x['qty']), quants))
		
        for line in self.pool.get('product.tmalljd').browse(cr, uid, ids, context=context):
            id = line.id
            if line.erp_product_id :
                pid = line.erp_product_id.id			
                result[id] = quants.get(pid, 0.0)
            else:
                result[id] = 0			
        return result		
		
    _columns = {
        'gift_ids': fields.one2many('product.tmalljd.gifts','tmalljd_id','Gift Products'), 
        'erp_product_set': fields.many2many('product.product', 'product_product_tmalljd_rel', 'tmalljd_id', 'product_id', u'Product Set(套装)'),
        'erp_product_id': fields.many2one('product.product','ERP Product Name'),
        'erp_ean13': fields.char('ERP_EAN13'), #fields.function(_get_ean13,type='char',string='ERP_EAN13'),
        'erp_stock': fields.float('ERPStock'),#fields.function(_get_stock,type='float',string='ERP库存'),		
        'ec_shop_id': fields.many2one('loewieec.shop', u'店铺'),		
        'ec_num_iid': fields.char(u'淘宝数字编码'),
        'ec_sku_id': fields.char(u'淘宝SKU_ID'),
        'ec_title':fields.char(u'商品标题'),
        'ec_price':fields.float(u'售价'),
        'ec_color':fields.char(u'颜色'),
        'ec_ean13': fields.char(u'条形码'),
        'ec_brand': fields.char(u'品牌'),
        'ec_qty': fields.integer(u'EC数量'),
        'ec_outer_code': fields.char(u'商家外部编码'),		
        'ec_product_name': fields.char(u'产品名称'),	
        'ec_product_id': fields.char(u'EC产品ID'),		
        'ec_num_custom':fields.char(u'海关代码'),	
    }
Пример #5
0
    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
        result = super(product_search_ept, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu)
        if context is None:
            context={}
        self._columns = {}
        self._columns['product_ids'] = fields.text('Product IDS')
        if view_type != 'form':
            return result
        _moves_arch_lst = """
            <form string="Stone Search" version="7.0">
                  <div>
        """
        #_moves_arch_lst += """<group colspan="4" col="10">"""
        _line_fields = result['fields']
        info = [
                    {'model':None,'_column_name':'product_name','label':'Stone ID','type':'char','name':'name','product_search_type':'char'},
                    {'model':None,'_column_name':'product_certificate_no','label':'Certificate No.','type':'char','name':'certificate_no','product_search_type':'char'},
                    {'model':None,'_column_name':'product_weight','label':'Weight','no':3,'type':'float','name':'weight','product_search_type':'char','range':True},
                    {'model':None,'_column_name':'product_price_caret','label':'PPC','no':1,'type':'float','name':'price_caret','product_search_type':'char','range':True},
                    {'model':None,'_column_name':'product_discount','label':'Back%','no':1,'type':'float','name':'discount','product_search_type':'char','range':True},
                    {'model':'product.shape','width':'15%','_column_name':'product_shape','label':'SHP','help':'Shape','type':'many2one','name':'shape_id','product_search_type':'boolean','on_change':'product_shape_change'}, 
                    {'model':'product.color','width':'8%','_column_name':'product_color','label':'CLR','help':'Color','type':'many2one','name':'color_id','product_search_type':'boolean','on_change':'product_color_change'},
                    {'model':'product.clarity','width':'10%','_column_name':'product_clarity','label':'CLRTY','help':'Clarity','type':'many2one','name':'clarity_id','product_search_type':'boolean','on_change':'product_clarity_change'},
                    {'model':'product.cut','width':'12%','_column_name':'product_cut','label':'CUT','help':'Cut','type':'many2one','name':'cut_id','product_search_type':'boolean','on_change':'product_cut_change'},
                    {'model':'product.polish','width':'8%','_column_name':'product_polish','label':'POL','help':'Polish','type':'many2one','name':'polish_id','product_search_type':'boolean','on_change':'product_polish_change'},
                    {'model':'product.symmetry','width':'10%','_column_name':'product_symmetry','label':'SYM','help':'Symmetry','type':'many2one','name':'symmetry_id','product_search_type':'boolean','on_change':'product_symmetry_change'},
                    {'model':'product.fluorescence.intensity','width':'13%','_column_name':'product_fluorescence_intensity','label':'FLUR','help':'Fluorescence Intensity','type':'many2one','name':'fluorescence_intensity_id','product_search_type':'boolean','on_change':'product_fluorescence_intensity_change'},
                    {'model':'product.lab','width':'8%','_column_name':'product_lab','label':'LAB','help':'Lab','type':'many2one','name':'lab_id','product_search_type':'boolean','on_change':'product_lab_change'},
                    {'model':'product.fancy.color','width':'15%','_column_name':'product_fancy_color','label':'FNC CLR','help':'Fancy Color','type':'many2one','name':'fancy_color_id','product_search_type':'boolean','on_change':'product_fancy_color_change'},
                    {'model':'product.fancy.color.intensity','width':'15%','_column_name':'product1_fancy_color_intensity','label':'FNC CLR INT','help':'Fancy Color Intensity','type':'many2one','name':'fancy_color_intensity','product_search_type':'boolean','on_change':'product1_fancy_color_intensity_change'},
                    {'model':'product.fancy.color.overtone','width':'15%','_column_name':'product2_fancy_color_overtone','label':'FNC CLR OVR','help':'Fancy Color Overtone','type':'many2one','name':'fancy_color_overtone','product_search_type':'boolean','on_change':'product2_fancy_color_overtone_change'},
                    {'model':None,'_column_name':'product_status','width':'20%','label':'Status','type':'selection','name':'product_status','product_search_type':'boolean'
                              ,'selection_val':[('available','Available'),
                                                ('hold','Hold'),
                                                ('sold','Sold'),
                                               ('on_approval','On Approval'),
                                                ('on_consignment','On Consignment'),
                                                ('offline','Offline'),
                                                ('repair','Repair'),
                                                ('web_sale','Web Sale')]},
                    {'model':'stock.location','_column_name':'stock_location','width':'15%','label':'Location','type':'many2one','name':'location_id','product_search_type':'boolean'
                                    ,'domain':[('usage','=','internal')],},
                ]

        for model_info in info :        
            if model_info['type'] == 'many2one' and model_info['product_search_type'] == 'boolean' :
                if model_info['model']:
                    ids = self.pool.get(model_info['model']).search(cr,uid,model_info.get('domain',[]))
                    if ids :
                        _moves_arch_lst += """<div style="float:left;width:%s;">"""%(model_info.get('width', '100%'))
                        ''' Header '''
                        if model_info.get('label', False)=='Location':
                            _moves_arch_lst += """<u><label style="color:rgb(124,123,173);font-weight:bold;" string="%s"/></u>"""%(model_info['label'])
                        if model_info.get('on_change', False):
                            ''' Check box for Select All '''
                            _moves_arch_lst += """<div><field name="%s"  class="oe_inline"  
                                                         nolabel="1" 
                                                         on_change="%s(%s)"/>
                                                         """%(model_info['on_change'],model_info['on_change'],model_info['on_change'])
                            ''' Label for Select All '''                  
                            _moves_arch_lst += """<u><label help='%s' style="color:rgb(124, 123, 173);" string="%s" for="%s" /></u></div>"""%(model_info['help'],model_info['label'],model_info['label']) 
                            _line_fields.update({
                             '%s'%(model_info['on_change']) : {
                                 'string': 'All ?',
                                 'type' : 'boolean',
                            },})  
                            self._columns['%s'%(model_info['on_change'])] = fields.boolean(model_info['on_change'])                
                        for obj in self.pool.get(model_info['model']).browse(cr,uid,ids,context=context):
                            name=len(obj.name) > 7 and (obj.name[:7]+'...') or obj.name[:7]
                            _line_fields.update({
                             '%s%s'%(model_info['_column_name'],obj.id) : {
                                 'string': obj.name,
                                 'type' : 'boolean',
                                 'help' : '%s'%(obj.name)
                             },})
                            self._columns['%s%s'%(model_info['_column_name'],obj.id)] = fields.boolean(obj.name)
                        
                            ''' Check box and related label '''
                            _moves_arch_lst += """
                                 <div><field name="%s%s" class="oe_inline" nolabel="1"/>
                                 <label string="%s" for="%s%s" /></div>
                                 """%(model_info['_column_name'],obj.id,name,model_info['_column_name'],obj.id)

                        _moves_arch_lst += """</div>"""           
#######################            
            if model_info['type'] == 'char' and model_info['product_search_type'] == 'char':
                _moves_arch_lst += """<div style="width:%s;float:left;">""" %('50%')
                _line_fields.update({
                             '%s'%(model_info['_column_name']) : {
                                 'string': 'Name',
                                 'type' : 'char',
                                 'help' : '%s'%(model_info['_column_name']),
                             },})
                self._columns['%s'%(model_info['_column_name'])] = fields.char(model_info['label'],size=1024)
                _moves_arch_lst += """
                                <div>
                                    <label style="color:rgb(124, 123, 173);" string="%s" for="%s" />
                                    <field name="%s" style="width: 70%%"  nolabel="1"/>
                                </div>
                                </div>
                                 """%(model_info['label'],model_info['_column_name'],model_info['_column_name'])
  
################################
            if model_info['type'] == 'selection' and model_info['product_search_type'] == 'boolean' :
                if model_info['selection_val']:
                    _moves_arch_lst += """<div style="float:left;width:%s">"""%(model_info['width'])
                    _moves_arch_lst += """<u><label style="color:rgb(124, 123, 173);font-weight:bold;" string="%s" /></u><newline/>"""%(model_info['label'])
                    for value in model_info['selection_val']:
                        _line_fields.update({
                         '%s_%s'%(model_info['_column_name'],value[0]) : {
                             'string': value[1],
                             'type' : 'boolean',
                         },})
                        self._columns['%s_%s'%(model_info['_column_name'],value[0])] = fields.boolean(value[1])
                        _moves_arch_lst += """
                             <div><field name="%s_%s" nolabel="1"/>
                             <label string="%s" for="%s_%s" /></div>
                             """%(model_info['_column_name'],value[0],value[1],model_info['_column_name'],value[0])
                    _moves_arch_lst +="""</div>"""
###########################                        
            if model_info.get('range') and model_info['range']:
                width = '50%'
                if model_info.get('no') > 1:width = '100%'
                _moves_arch_lst += """<div style="float:left;width:%s;">"""%(width)
                _moves_arch_lst += """<div style="float:left;width:%s;"><label style="color:rgb(124, 123, 173);font-weight:bold;" string="%s" /></div>"""%('15%',model_info['label'])
                if model_info.get('no'):
                    no = model_info.get('no')
                    wid = str(85/int(no)) + '%'
                    while no != 0 :
                         
                        no = no - 1
                        _line_fields.update({'%s_from_%s'%(model_info['_column_name'],no) : {'string': model_info['label'],'type':'float'}})
                        _line_fields.update({'%s_to_%s'%(model_info['_column_name'],no) : {'string': model_info['label'],'type':'float'}})
                        self._columns['%s_from_%s'%(model_info['_column_name'],no)] = fields.float(model_info['label'],digits=(16,2))
                        self._columns['%s_to_%s'%(model_info['_column_name'],no)] = fields.float(model_info['label'],digits=(16,2))
                        _moves_arch_lst += """
                                        <div style="float:left;width:%s;"> 
                                             
                                             <div style="float:left;"><field name="%s_from_%s" placeholder="From" class="oe_inline" nolabel="1"/></div>
                                             <div style="float:left;"><b><label style="color:rgb(124, 123, 173);" string="--" /></b></div>
                                             <div style="float:left;"><field name="%s_to_%s" placeholder="To" class="oe_inline" nolabel="1"/></div>
                                             
                                        </div> 
                                     """%(wid,model_info['_column_name'],no,model_info['_column_name'],no)
                _moves_arch_lst += """</div>"""         
        _moves_arch_lst += """ 
                            </div>
                          <footer>
                          <button name="get_product" string="Search" type="object" colspan="2" class="oe_highlight"/>
                             or
                         <button string="Cancel" class="oe_link" special="cancel"/>
                          </footer>
                          </form>
                 """

        result['arch'] = _moves_arch_lst
        result['arch'] = result['arch'].replace('&','&amp;')
        result['fields'] = _line_fields
        return result       
Пример #6
0
    def _save_file(self, path, b64_file):
        """Save a file encoded in base 64"""
        self._check_filestore(path)
        with open(path, 'w') as ofile:
            ofile.write(base64.b64decode(b64_file))
        return True

    def _set_image(self, cr, uid, id, name, value, arg, context=None):
        image = self.browse(cr, uid, id, context=context)
        full_path = self._image_path(cr, uid, image, context=context)
        if full_path:
            return self._save_file(full_path, value)
        return self.write(cr, uid, id, {'file_db_store' : value}, context=context)

    _columns = {
        'name':fields.char('Image Title', size=100, required=True),
        'extention': fields.char('file extention', size=6),
        'link':fields.boolean('Link?', help="Images can be linked from files on your file system or remote (Preferred)"),
        'file_db_store':fields.binary('Image stored in database'),
        'file':fields.function(_get_image, fnct_inv=_set_image, type="binary", filters='*.png,*.jpg,*.gif'),
        'url':fields.char('File Location', size=250),
        'comments':fields.text('Comments'),
        'product_id':fields.many2one('product.product', 'Product')
        }
    _defaults = {
        'link': lambda *a: False,
        }
    _sql_constraints = [('uniq_name_product_id', 'UNIQUE(product_id, name)',
                         _('A product can have only one image with the same name'))]

Пример #7
0
            _logger.debug("Creating new Odoo user \"%s\" from LDAP" % login)
            user_obj = self.pool['res.users']
            values = self.map_ldap_attributes(cr, uid, conf, login, ldap_entry)
            if conf['user']:
                values['active'] = True
                user_id = user_obj.copy(cr, SUPERUSER_ID, conf['user'],
                                        default=values)
            else:
                user_id = user_obj.create(cr, SUPERUSER_ID, values)
        return user_id

    _columns = {
        'sequence': fields.integer('Sequence'),
        'company': fields.many2one('res.company', 'Company', required=True,
            ondelete='cascade'),
        'ldap_server': fields.char('LDAP Server address', required=True),
        'ldap_server_port': fields.integer('LDAP Server port', required=True),
        'ldap_binddn': fields.char('LDAP binddn', 
            help=("The user account on the LDAP server that is used to query "
                  "the directory. Leave empty to connect anonymously.")),
        'ldap_password': fields.char('LDAP password',
            help=("The password of the user account on the LDAP server that is "
                  "used to query the directory.")),
        'ldap_filter': fields.char('LDAP filter', required=True),
        'ldap_base': fields.char('LDAP base', required=True),
        'user': fields.many2one('res.users', 'Template User',
            help="User to copy when creating new users"),
        'create_user': fields.boolean('Create user',
            help="Automatically create local user accounts for new users authenticating via LDAP"),
        'ldap_tls': fields.boolean('Use TLS',
            help="Request secure TLS/SSL encryption when connecting to the LDAP server. "
Пример #8
0
        for record in self.browse(cr, uid, ids, context=context):
            if record.res_model != 'ir.ui.view' or not record.datas: continue
            try:
                result[record.id] = openerp.tools.image_resize_image_big(record.datas)
            except Exception,ex:  # ignore any f*****g exceptions
                pass

        return result

    _columns = {
        'datas_checksum': fields.function(_datas_checksum, size=40,
              string="Datas checksum", type='char', store=True, select=True),
        'website_url': fields.function(_website_url_get, string="Attachment URL", type='char'),
        'datas_big': fields.function (_datas_big, type='binary', store=True,
                                      string="Resized file content"),
        'mimetype': fields.char('Mime Type', readonly=True),
    }

    def _add_mimetype_if_needed(self, values):
        if values.get('datas_fname'):
            values['mimetype'] = mimetypes.guess_type(values.get('datas_fname'))[0] or 'application/octet-stream'

    def create(self, cr, uid, values, context=None):
        chk = self._compute_checksum(values)
        if chk:
            match = self.search(cr, uid, [('datas_checksum', '=', chk)], context=context)
            if match:
                return match[0]
        self._add_mimetype_if_needed(values)
        return super(ir_attachment, self).create(
            cr, uid, values, context=context)
Пример #9
0
class sale_order(osv.osv):
    _name = "sale.order"
    _inherit = "sale.order"
        
    _columns = {
        'express_ids': fields.related('order_line', 'express_id', type='many2one', relation='sale.coe', string=u'TMI_JDI收货人'),	
        'tmi_jdi_nos': fields.related('order_line', 'tmi_jdi_no', type='char', string='TMI_JDI_NO'),		
        'is_set_seq': fields.boolean('Set Sequence',default=False, readonly=True),		
        'selected': fields.boolean('Selected'),	
        'shop_id': fields.many2one('loewieec.shop', string=u"EC店铺名", readonly=True),
        'sale_code': fields.char(u'EC单号', readonly=True),				
        'order_state': fields.selection([
            ('WAIT_SELLER_SEND_GOODS', u'等待卖家发货'),
            ('WAIT_BUYER_CONFIRM_GOODS', u'等待买家确认收货'),
            ('TRADE_FINISHED', u'交易成功'),
            ('TRADE_CLOSED', u'交易关闭'),
            ], u'订单状态'),
    }

    def update_orders_seller_memo(self, cr, uid, ids, context=None):
        sale_order_obj = self.pool.get('sale.order').browse(cr,uid,ids[0],context=context)	
        shop = sale_order_obj.shop_id		
        if not shop : return False 
        if shop.code == 'JDI' :
            raise osv.except_osv(u'错误',u'''JDI京东国际订单无需更新备注''') 
            return False			
			
        statement = "select tmi_jdi_no from sale_order_line where order_id=%d group by tmi_jdi_no" % ids[0] 
        cr.execute(statement)
        tids = [item[0] for item in cr.fetchall()]
        if not tids : return False
		
        return shop.update_orders_seller_memo(context=context, tids=tids)	
	
    def delete_lines_of_tmijdi_no(self, cr, uid, ids, context=None):   # 完整删除 天猫京东 订单的 行
        sale_order_obj = self.pool.get('sale.order').browse(cr,uid,ids[0],context=context)

        note = 	sale_order_obj.note or ''
        tmijdi_nos = note.strip().split(',') 		
        tmijdi_no_list = []
	
        for tmijdi_no in tmijdi_nos:
            if tmijdi_no.strip() != '': tmijdi_no_list.append( tmijdi_no.strip() )
			
        statement = "delete from sale_order_line where order_id=%d and tmi_jdi_no in (%s)" %  ( ids[0], ("'" + """','""".join(tmijdi_no_list)	+ "'") )		
        cr.execute(statement)				

        val = val1 = 0.0
        cur = sale_order_obj.pricelist_id.currency_id
        for line in sale_order_obj.order_line:
            val1 += line.price_subtotal
            val += self._amount_line_tax(cr, uid, line, context=context)
			
        cur_obj = self.pool.get('res.currency')			
        amount_tax = cur_obj.round(cr, uid, cur, val)		
        amount_untaxed = cur_obj.round(cr, uid, cur, val1)		
        amount_total = amount_untaxed + amount_tax		
        sale_order_obj.write({'amount_tax':amount_tax, 'amount_untaxed': amount_untaxed,'amount_total':amount_total})	
	
    def update_waybill_no(self, cr, uid, ids, context=None):
        sale_order_obj = self.pool.get('sale.order').browse(cr,uid,ids[0],context=context)	
        shop = sale_order_obj.shop_id		
        if not shop : return False 
        if shop.code == 'JDI' :
            return shop.jdi_order_delivery(salesorder=sale_order_obj, context=context)  		
        
        return shop.update_tmall_waybill(context=context, salesorder=sale_order_obj)			
		
    def string_refactor(self, name):   
        if not name: return False		
        name = name.replace("/","%")
        name = name.replace("|","%")			
        ll = name.split("-")
        ll = [l.strip() for l in ll]
        ll = "%".join(ll)				
        return ll.replace(" ","%")
		
    def get_express_data(self, cr, uid, ids, context=None):			
		
        sale_coe_obj = self.pool.get('sale.coe')
        express_ids = sale_coe_obj.search(cr,uid,[('sale_id','=',ids[0])],context=context)
        if len(express_ids)<1: return False
		
        note = ""		
        for express in sale_coe_obj.browse(cr,uid,express_ids,context=context):
            if not express.name : continue		
            name = express.name
            express_no = express.express_no or 'none'
            expresser = express.expresser and express.expresser.name or 'none'			
            tmp_str =  name + "," + expresser + "," + express_no + chr(10)		
            note += tmp_str
			
        sale_order_obj = self.pool.get('sale.order').browse(cr,uid,ids[0],context=context)
        note_tmp = sale_order_obj.note	or  '.'	
        sale_order_obj.note = note + note_tmp 
        return True		
		
    def view_express_data(self, cr, uid, ids, context=None):	
        sale_order_obj = self.pool.get('sale.order').browse(cr,uid,ids[0],context=context)		
        if not sale_order_obj : 
            raise osv.except_osv(u'Sale order 错误',u'''请先保存销售单草稿''')	
            return False

        #express_ids = sale_coe_obj.search(cr,uid,[('sale_id','=',ids[0])],context=context)
        sale_order_line_ids = self.pool.get('sale.order.line').search(cr,uid,[('order_id','=',ids[0])],context=context)	
        if len(sale_order_line_ids)< 1: return False		
        eids = self.pool.get('sale.order.line').read(cr,uid,sale_order_line_ids,['express_id'],context=context)
        #if len(eids) < 1: return False		
        express_ids = [ eid['express_id'] and eid['express_id'][0] for eid in eids ]			
		
        customer_id = sale_order_obj.partner_id.id
        sale_coe_obj = self.pool.get('sale.coe')
        if len(express_ids)>0:		
            for express_obj in sale_coe_obj.browse(cr,uid,express_ids,context=context):
                express_obj.sale_id = ids[0]		
                express_obj.customer = customer_id	                		
		
        mod_obj = self.pool.get('ir.model.data')
        act_obj = self.pool.get('ir.actions.act_window')

        result = mod_obj.get_object_reference(cr, uid, 'loewieec_sync_sz', 'action_loewieec_salecoe')
        id = result and result[1] or False
        result = act_obj.read(cr, uid, [id], context=context)[0]
        result['domain'] = [('id','in',express_ids)]
        result['res_id'] = express_ids
        result['context'] = {'default_sale_id':ids[0],'default_customer':customer_id}		
		
        return result		
		
    def import_orders_from_note(self, cr, uid, ids, context=None):	
        sale_order_obj = self.pool.get('sale.order').browse(cr,uid,ids[0],context=context)	
        if sale_order_obj.shop_id or sale_order_obj.partner_id.name in [u'TMI天猫国际', u'天猫乐易成人用品专营店'] :
            return self.import_tmall_csv_file(cr, uid, ids, context=context)	# 2边ERP统一收货人信息 的 导入方式 为 从附件导入	
            #return self.import_tmall_consignee_from_note(cr, uid, ids, context=context, order=sale_order_obj)   				
			
        if not sale_order_obj : 
            raise osv.except_osv(u'Sale order 错误',u'''请先保存销售单草稿''')	
            return False
        customer_id = sale_order_obj.partner_id.id	
        carrier_obj = self.pool.get('loewie.carrier')			
        coe_obj = self.pool.get('sale.coe')	
        note = sale_order_obj.note.strip()		
        lines = [ o.split(u',') for o in note.split(chr(10))]	

        express_ids = []		
        pay_way = {'we_pay':u'包邮' , 'customer_pay': u'到付', 'cash_pay': u'现付'}		
        for line in lines:
            if len(line) < 4 : continue		
            if len(line) != 6 or not line[3].strip().isdigit() or line[2].strip().isdigit():
                raise osv.except_osv(u'格式错误',','.join(line) + chr(10) + chr(10) + u"正确格式例子:姓名,手机号码,地址,邮编,韵达,现付" )							
				
            vals = {		
                'sale_id': ids[0],
                'customer': customer_id,				
                'name':line[0].strip(),
                'mobile':line[1].strip(), 					
                'address':line[2].strip(),			
                'zip':line[3].strip(),
                'price':6,				
            }		
            express_id = coe_obj.search(cr, uid, [('name','=',vals["name"]),('mobile','=',vals['mobile']),('sale_id','=',ids[0])], context=context)	
            express_id = express_id and express_id[0] or 0			
            if not express_id :	
								
                way = len(line)>5 and line[5] or ''	
                way = way.strip()				
                way_erp = ''			
                for key in pay_way.keys():
                    if pay_way[key] == way : way_erp = key
                if way_erp in pay_way.keys(): vals.update({'pay_way':way_erp})					
			
                expresser = line[4] or ''
                carrier_id = carrier_obj.search(cr,uid,[('name','=',expresser.strip())],context=context)
                carrier_id = carrier_id and carrier_id[0] or 0			
                if carrier_id : vals.update({'expresser':carrier_id})			
                express_id = coe_obj.create(cr, uid, vals, context=context)
            express_ids.append(express_id)            				
			
        if len(express_ids) != 1:
            return True

        for product in sale_order_obj.order_line:
            product.express_id = express_ids[0]		
			
        return True
		
    def import_tmall_consignee_from_note(self, cr, uid, ids, context=None,order=None):			
        sale_order_obj = order		
        if not sale_order_obj : 
            raise osv.except_osv(u'Sale order 错误',u'''请先保存销售单草稿''')	

        customer_id = sale_order_obj.partner_id.id	
        carrier_obj = self.pool.get('loewie.carrier')			
        coe_obj = self.pool.get('sale.coe')		
        lines = [ o.split(chr(9)) for o in sale_order_obj.note.split(chr(10))]	
		
        statement = "select tmi_jdi_no from sale_order_line where order_id=%d group by tmi_jdi_no" % ids[0]		
        cr.execute(statement)
        tids = [item[0] for item in cr.fetchall()]
        lost_tids = []		
		
        express_ids = {}		
        pay_way = {'we_pay':u'包邮' , 'customer_pay': u'到付', 'cash_pay': u'现付'}		
        for line in lines:
            if len(line) < 4 : continue	
            tmino = line[0].strip()			
            if len(line) != 4 or not tmino.isdigit() or line[1].strip().isdigit() or line[2].strip().isdigit():
                raise osv.except_osv(u'格式错误',','.join(line) + chr(10) + chr(10) + u'正确格式:订单编号,收件人姓名,收件地址,收件人手机号码')	
				
            if tmino not in tids :  # 如果销售订单行中 天猫单号不在
                lost_tids.append(tmino)
                continue
				
            vals = {		
                'sale_id': ids[0],
                'customer': customer_id,
                'tmi_jdi_no': tmino,			
                'name':line[1].strip(),	
                'mobile':line[3].strip(),				
                'address':line[2].strip(), 	
                #'zip':line[4].strip(),
                'expresser':3,
                'pay_way':'cash_pay',				
                'price':6,				
            }		
            express_id = coe_obj.search(cr, uid, [('name','=',vals["name"]),('mobile','=',vals['mobile']),('sale_id','=',ids[0])], context=context)	
            express_id = express_id and express_id[0] or 0			
            if not express_id :			
                express_id = coe_obj.create(cr, uid, vals, context=context)
            express_ids[vals['tmi_jdi_no']] = express_id            			

        for product in sale_order_obj.order_line:
            tmi_no = product.tmi_jdi_no.strip()		
            if tmi_no in express_ids.keys():		
                product.express_id = express_ids[tmi_no]	

        if lost_tids :
            note = sale_order_obj.note	or  '-'	
            note_tmp = u"销售单中不存在以下电商单号:" + ",".join(lost_tids) + chr(10)			
            sale_order_obj.note = note_tmp + note 		
			
        return True
				
    def set_line_express_id(self, cr, uid, ids, context=None):		
        sale_order_obj = self.pool.get('sale.order').browse(cr,uid,ids[0],context=context)	
        express_ids = self.pool.get('sale.coe').search(cr,uid,[('sale_id','=',ids[0])],context=context)
        express_id = len(express_ids)==1 and express_ids[0]	or 0
        if not express_id : return False		
		
        for product in sale_order_obj.order_line:
            product.express_id = express_id		
			
        return True

    def split_address(self, address):
        assert address != None
        addr_list = address.split(" ",2)		
        if len(addr_list) < 3: return None	
		
        length = len( addr_list[2] )
        for i in range( length-1, 0, -1 ):
            if addr_list[2][i] == '(': break

        addr = addr_list[2][0:i]
        zip = addr_list[2][i+1: length-1]		
		
        return {'province':addr_list[0],'city':addr_list[1],'address':addr,'zip':zip}				
		
    def get_full_path(self, cr, uid, path):
        # sanitize ath
        path = re.sub('[.]', '', path)
        path = path.strip('/\\')
        return os.path.join(tools.config.filestore(cr.dbname), path)	
		
    def import_tmall_csv_file(self, cr, uid, ids, context=None):

        attachment_obj = self.pool.get('ir.attachment')
        shop_attach_id = context.get('res_id')	
        shop_attach_id = shop_attach_id or ids[0]		
        attachment_id = attachment_obj.search(cr,uid,[('res_id', '=', shop_attach_id)], context=context)		
        if len(attachment_id)<1: return False
        attach = attachment_obj.browse(cr,uid,attachment_id[0],context=context)
        fname = attach.store_fname
        display_name = attach.name		
        if not fname : return False		
        fname = self.get_full_path(cr, uid, fname)	
		
        csvfile = file(fname, 'rb')		
		
        coe_obj = self.pool.get('sale.coe')    		
        tmi_no = {}
        no_coe_list = []		
        		
        statement = 'select tmi_jdi_no from sale_order_line where order_id=%d group by tmi_jdi_no' % ids[0]
        cr.execute(statement)
        tmi_jdi_no_list = [ str(item[0]).strip() for item in cr.fetchall() ]		
				
        sale_id = ids[0]
        #for line in reader:
        for cols in csvfile.readlines():		
            cols = cols.decode('gbk')
            cols = cols.split(",")	
            line = [ col.replace('"','').strip() for col in cols ]
            line[0] = line[0].replace('=','').strip()			
            if line[0] == u'订单编号' and line[1] == u'买家会员名' or line[0] not in tmi_jdi_no_list :	 continue

            #coeids = coe_obj.search(cr,uid,[('name','=',line[12]),('address','=',addr and addr2 or line[13]),('tel','=',phone)],context=context)
            coeids = coe_obj.search(cr,uid,[('tmi_jdi_no','=',line[0])],context=context)			
            coeid = coeids and coeids[0] or 0				
            if not coeid : 	
			
                addr = self.split_address(line[13])		
                addr2 = addr['province'] + ',' + addr['city'] + ',' + addr['address']
                phone = line[16].replace("'","")
                phone = phone.strip()
			
                if addr : coe_info = {'tmi_jdi_no':line[0], 'name':line[12], 'receive_name':line[12], 'mobile':phone, 'tel':phone, 'address':addr2, 'province':addr['province'], 'city':addr['city'], 'zip':addr['zip']}
                else: coe_info = {'tmi_jdi_no':line[0], 'name':line[12], 'receive_name':line[12], 'mobile':phone, 'tel':phone, 'address':line[13]}				
                coeid = coe_obj.create( cr, uid, coe_info, context=context )
 
            tmi_no[line[0]] = coeid
			
        sale_order = self.pool.get('sale.order').browse(cr,uid,ids[0],context=context)
        coe_in_sale = []		
        for line in sale_order.order_line:
            tmi_jdi_no = line.tmi_jdi_no and line.tmi_jdi_no.strip() or ''
            if not tmi_jdi_no : continue
			
            if tmi_jdi_no in tmi_no.keys():
                line.write( {'express_id': tmi_no[tmi_jdi_no]} )  # 深圳ERP中为 line.express_id 而香港ERP为 line.coe_no
                coe_in_sale.append(tmi_jdi_no)	
                #_logger.info( "Jimmy: have such a order:%s, and coeid:%d " % ( tmi_jdi_no, tmi_no[tmi_jdi_no]) )				
                #tmi_no[tmi_jdi_no] = 0	 # 这里有问题, 如果一个 电商订单有几个产品,则只有第一个产品行 会被添加 coe 条目id			
            else:			
                no_coe_list.append(tmi_jdi_no) 

        if no_coe_list : 
            log = sale_order.note or ''		
            sale_order.note = u'以下销售订单行的TMI_NO在CSV文件中不存在:' + chr(10) + ",".join(no_coe_list) + chr(10) + log
			
        not_in_tmi_no = []
        for key in tmi_no.keys():
            if key not in  coe_in_sale: not_in_tmi_no.append(key)
			
        if not_in_tmi_no : 
            log = sale_order.note or ''		
            sale_order.note = u"以下CSV内的 '订单编号' 无法匹配到 销售订单行:" + chr(10) + ",".join( not_in_tmi_no ) # + chr(10) + log	  #
			
        #_logger.info( "Jimmy: OK....")			
        return True			
Пример #10
0
class crea8s_repair(osv.osv):
    _name = "crea8s.repair"
    _inherit = ['mail.thread', 'ir.needaction_mixin']

    def compute_total(self, cr, uid, ids, field_names, arg=None, context=None,
                  query='', query_params=()):
        result = 0
        res = {}
        for record in self.browse(cr, uid, ids):
            result = record.labor_charge + record.trans_charge + sum([x.amount for x in record.repair_line])
            res[record.id] = result
        return res 

    def onchange_customer(self,cr, uid, ids, customer_id):
        partner_obj = self.pool.get('res.partner.repair')
        partner_br = partner_obj.browse(cr, uid, customer_id)
        return {'value': {'unit_no': partner_br.unit_no and partner_br.unit_no or '',
                          'pos_code': partner_br.postal_code and partner_br.postal_code or '',
                          'block': partner_br.name and partner_br.name or '',}}

    _columns = {
        'name': fields.char('Job Number', size=128),
        'customer_id': fields.many2one('res.partner', 'Customer'),
        'cus_repair_id': fields.many2one('res.partner.repair', 'Customer'),
        'block': fields.char('Block and Street', size=256),
        #related('cus_repair_id','block', type='char', store=True, string='Block'),
        'pos_code': fields.char('Postal Code', size=128),
        'unit_no': fields.char('Unit No', size=128),
        #related('cus_repair_id','postal_code', type='char', store=True, string='Postal Code'),
        'dealer_id': fields.char('Dealer', size=256),
        'telephone1': fields.related('cus_repair_id','telephone1', type='char', string='Telephone', store=True),
        'telephone2': fields.related('cus_repair_id','telephone2', type='char', string='2'),
        'telephone3': fields.related('cus_repair_id','telephone3', type='char', string='3'),
        'date': fields.date('Date'),
        'appointment_date': fields.datetime('Appointment Date'),
        'tech_person': fields.many2one('crea8s.repair.user', 'Technician'),
        'model_no': fields.char('Model No', size=256),
        'purchase_date': fields.char('Purchase Date', size=128),
        'attend_by': fields.many2one('crea8s.repair.user', 'Attend By'),
        'type': fields.selection([('INSTALLING', 'INSTALLING'), ('SERVICING', 'SERVICING')], 'Type'),
        'description': fields.text('Description'),
        'remark': fields.text('Remark'),
        'trans_charge': fields.float('Transport Charge', digits=(16,2)),
        'labor_charge': fields.float('Labour Charge', digits=(16,2)),
        'subtotal_charge': fields.float('Sub-Total Charge', digits=(16,2)),
    #fields.function(compute_total, digits_compute=dp.get_precision('Account'), store=True, string='Sub-Total Charge'),
        'state': fields.selection([('draft', 'Draft'), ('open', 'Open'), ('confirm', 'Confirm')], 'State'),
        'repair_line': fields.one2many('crea8s.repair.line', 'repair_id', 'Repair Line'),
        'is_cash': fields.boolean('CASH'),
        'is_cheque': fields.boolean('CHEQUE'),
        'cheque_num': fields.char('Cheque Number'),
        'hide_remark': fields.text('Internal Remark'),
        'amount_total': fields.function(compute_total, digits_compute=dp.get_precision('Account'), string='Total'),
    }
    
    
    
    def default_name(self, cr, uid, context={}):
        return self.pool.get('ir.sequence').get(cr, uid, 'crea8s.repair') or '/'
    
    _defaults = {

        'date': lambda *a: time.strftime('%Y-%m-%d'),
        'state': 'draft',
        'name': '/',
    }
    
    def insert_telephone(self, cr, uid, ids, partner_id, telephone):
        partner_obj = self.pool.get('res.partner.repair')
        return partner_obj.write(cr, uid, partner_id, {'telephone1': telephone})
        
    
    def get_partner(self, cr, uid, ids, partner_name, partner_unitno, telephone):
        partner_obj = self.pool.get('res.partner.repair')
        
        partner_id = partner_obj.search(cr, uid, [('name', '=',partner_name),
                                                  ('unit_no', '=', partner_unitno)])
        partner_id = partner_id and partner_id[0] or 0
        if not partner_id: 
            partner_id = partner_obj.search(cr, uid, [('name', '=',partner_name),
                                                      ('telephone1', '=', telephone)])
            partner_id = partner_id and partner_id[0] or 0
        return partner_id
    
    def get_user(self, cr, uid, ids, user_name):
        user_obj = self.pool.get('crea8s.repair.user')
        user_id = user_obj.search(cr, uid, [('name', '=', user_name)])
        user_id = user_id and user_id[0] or 0
        if not user_id:
            user_id = user_obj.create(cr, uid, {'name': user_name})
        return user_id
    
    def get_date(self, date_or):
        result = datetime.date(int(date_or[:4]), int(date_or[5:7]), int(date_or[8:10]))
        return result
    
    def get_date_time(self, date_or):
        result = datetime.datetime(int(date_or[:4]), int(date_or[5:7]), int(date_or[8:10]), int(date_or[11:13]), int(date_or[14:16]), int(date_or[17:19]))
        return result
    
    def get_state(self, cr, uid, ids, state):
        result = ''
        if state == 'Draft':
            result = 'draft'
        elif state == 'Open':
            result = 'open'
        else:
            result = 'confirm'
        return result
    
    def import_csv_file(self, cr, uid, ids, context={}):
        user_obj = self.pool.get('crea8s.repair.user')
        partner_obj = self.pool.get('res.partner.repair')
        for record in self.browse(cr, uid, ids):
            ifile = open('C:\\Users\\tri\\Desktop\\import\\July15\\import_fanco.csv', 'rb')
            reader = csv.reader(ifile)
            a = 0
            for row in reader:
                a += 1
                if a > 1:
                    if 2>1:
#                    try:
                        cus_id = self.get_partner(cr, uid, ids, row[2], row[5], row[23])
                        attend_id = self.get_user(cr, uid, ids, row[1])
                        tech_id = self.get_user(cr, uid, ids, row[3])
                        vals_re = {
                                        'name': row[4],
                                        'cus_repair_id': cus_id,
                                        'block': row[9],
                                        'pos_code': row[19],
                                        'unit_no': row[5],
                                        'dealer_id': row[14],
                                        'tech_person': tech_id,
                                        'model_no': row[18],
                                        'purchase_date': row[20],
                                        'attend_by': attend_id,
                                        'type': row[6],
                                        'description': row[15],
                                        'remark': row[21],
                                        'trans_charge': row[24] and float(row[24]) or 0,
                                        'labor_charge': row[17] and float(row[17]) or 0,
                                        'subtotal_charge': row[22] and float(row[22]) or 0,
                                        'state': self.get_state(cr, uid, ids, row[7]),
                                        'is_cash': row[10],
                                        'is_cheque': row[11],
                                        'cheque_num': row[12],
                                        'hide_remark': row[16],}
                        if row[13]:
                            vals_re.update({'date': self.get_date(row[13]),})
                        if row[8]:
                            vals_re.update({'appointment_date': self.get_date_time(row[8])})
                        self.create(cr, uid, vals_re)
#                    except:
#                        print row[4], '  ', row[2], '    ', row[5], '    ', row[23]
        return 1
    
    def create(self, cr, uid, vals, context={}):
        if vals.get('name', False) == '/':
            vals['name'] = self.default_name(cr, uid, context)
        return super(crea8s_repair, self).create(cr, uid, vals, context)
    
    def action_open(self, cr, uid, ids, context={}):
        self.write(cr, uid, ids, {'state': 'open'})
        #print self.pool.get('res.partner.repair').search(cr, uid, [])
        return 1
    
    def action_confirm(self, cr, uid, ids, context={}):
        self.write(cr, uid, ids, {'state': 'confirm'})
        return 1
    
    def action_cancel(self, cr, uid, ids, context={}):
        self.write(cr, uid, ids, {'state': 'draft'})
        return 1

    def button_dummy(self,cr, uid, ids, context={}):
        return 1
            )[0]
            report = self.pool.get("ir.actions.report.xml").browse(cr, uid, rep_id, context=context)
        return report.report_name

    def print_invoice(self, cr, uid, ids, context=None):
        """
        Method called by button print report in wizard, to print report in pdf
        @param self: The object pointer.
        @param cr: A database cursor
        @param uid: ID of the user currently logged in
        @param ids: Ids to invoice's to print ticket
        @param context: A standard dictionary
        @return : retrun report pdf generated
        """
        if context is None:
            context = {}
        if len(context.get("active_ids", [])) > 1:
            return {}
        return {
            "type": "ir.actions.report.xml",
            "report_name": self._get_report_name(cr, uid, context=context),
            "datas": {"ids": context["active_ids"]},
        }

    _columns = {
        "journal": fields.char("Journal", 64, readonly=True, requied=True),
        "report_format": fields.binary("Report", readonly=True, required=True),
    }

    _defaults = {"journal": _get_journal, "report_format": _get_report}
Пример #12
0
class crea8s_warranty(osv.osv):
    _name = "crea8s.warranty"
    _inherit = ['mail.thread', 'ir.needaction_mixin']

    def compute_total(self, cr, uid, ids, field_names, arg=None, context=None,
                  query='', query_params=()):
        result = 0
        res = {}
        for record in self.browse(cr, uid, ids):
            result = record.labor_charge + record.trans_charge
            res[record.id] = result
        return res 

    _columns = {
        'name': fields.char('Warranty No', size=128),
        'cus_war_id': fields.many2one('res.partner.repair', 'customer'),
        'cus_name': fields.related('cus_war_id','type', type='char', string='''Customer's Name'''),
        'block': fields.char('Block and Street', size=256),
        'pos_code': fields.related('cus_war_id','postal_code', type='char', string='Postal Code'),
        'street': fields.related('cus_war_id','name', type='char', string='Street Name'),
        'unit_no': fields.related('cus_war_id','unit_no', type='char', string='Unit No.'),
        'telephone': fields.related('cus_war_id','telephone1', type='char', string='Telephone'),
        'telephone2': fields.related('cus_war_id','telephone2', type='char', string='2'),
        'pur_inv_no': fields.char('Purchase Invoice No', size=256),
        'model_no': fields.char('Model No.', size=256),
        'purchase_date': fields.date('Date of Purchase'),
        'install_date': fields.date('Date of Installation'),
        'install_by': fields.char('Installed By', size=256),
        'dealer_id': fields.many2one('res.partner', '''Dealer's Name'''),
        'contact_no1': fields.char('Contact No.1', size=256),
        'contact_no2': fields.char('Contact No.2', size=256),
        'contact_no3': fields.char('Contact No.3', size=256),
        'email': fields.related('cus_war_id','email', type='char', string='Email'),
        'state': fields.selection([('draft', 'Draft'), ('open', 'Open'), ('confirm', 'Confirm')], 'State'),
        'remark': fields.text('Remark'),
    }
    
    
    
    def default_name(self, cr, uid, context={}):
        return self.pool.get('ir.sequence').get(cr, uid, 'crea8s.warranty') or '/'
    
    _defaults = {
        'purchase_date': lambda *a: time.strftime('%Y-%m-%d'),
        'state': 'draft',
        'name': '/',
    }
    
    def create(self, cr, uid, vals, context={}):
        
        if vals.get('name', False) == '/':
            vals['name'] = self.default_name(cr, uid, context)
        return super(crea8s_warranty, self).create(cr, uid, vals, context)
    
    def action_open(self, cr, uid, ids, context={}):
        self.write(cr, uid, ids, {'state': 'open'})
        return 1
    
    def action_confirm(self, cr, uid, ids, context={}):
        self.write(cr, uid, ids, {'state': 'confirm'})
        return 1
    
    def action_cancel(self, cr, uid, ids, context={}):
        self.write(cr, uid, ids, {'state': 'draft'})
        return 1

    def button_dummy(self,cr, uid, ids, context={}):
        return 1
Пример #13
0
class crea8s_repair_user(osv.osv):
    _name = "crea8s.repair.user"
    _columns = {
        'name': fields.char('Name', size=256),
    }
class tms_expense_loan(osv.osv):
    _name = 'tms.expense.loan'
    _inherit = ['mail.thread', 'ir.needaction_mixin']
    _description = 'TMS Driver Loan Mgmnt'

    def _balance(self, cr, uid, ids, field_name, args, context=None):
        res = {}
        for record in self.browse(cr, uid, ids, context=context):
            cr.execute('select sum(coalesce(price_total, 0.0))::float from tms_expense_line where loan_id = %s' % (record.id))
            data = filter(None, map(lambda x:x[0], cr.fetchall())) or [0.0]
            res[record.id] =   {
                            'balance' : record.amount + data[0],
                            'paid'    : not (record.amount + data[0]) > 0,
                    }            
        return res

    def _get_loan_discounts_from_expense_lines(self, cr, uid, ids, context=None):
        expense_line = {}
        for line in self.pool.get('tms.expense.line').browse(cr, uid, ids, context=context):           
            expense_line[line.loan_id.id] = True            

        expense_line_ids = []
        if expense_line:
            expense_line_ids = self.pool.get('tms.expense.loan').search(cr, uid, [('id','in',expense_line.keys())], context=context)
        return expense_line_ids

    _columns = {
        'name'        : fields.char('Name', size=64, select=True, readonly=True),
        'description' : fields.char('Description', size=128, select=True, required=True, readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}),
        'date'        : fields.date('Date', required=True, select=True, readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}),
        'employee_id' : fields.many2one('hr.employee', 'Driver', required=True, domain=[('tms_category', '=', 'driver')]
                                        , readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}),
        'expense_line_ids'  : fields.one2many('tms.expense.line', 'loan_id', 'Expense Line', readonly=True),
        'state'       : fields.selection([
                                ('draft', 'Draft'),
                                ('approved', 'Approved'),
                                ('confirmed', 'Confirmed'),
                                ('closed', 'Closed'),
                                ('cancel', 'Cancelled')
                                ], 'State', readonly=True, help="State of the Driver Loan. ", select=True),
        'discount_method' : fields.selection([
                                ('each', 'Each Travel Expense Record'),
                                ('weekly', 'Weekly'),
                                ('fortnightly', 'Fortnightly'),
                                ('monthly', 'Monthly'),
                                ], 'Discount Method', readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]},
                                help="""Select Loan Recovery Method:
- Weekly: Discount will be applied every week, considering only 4 weeks in each month
- Fortnightly: Discount will be applied forthnightly, considering only 2 discounts in each month, applied the 14th and 28th day of the month.
- Monthy: Discount will be applied only once a month, applied the 28th day of the month.                                . 
                                """, select=True, required=True),
        'discount_type' : fields.selection([
                                ('fixed', 'Fixed'),
                                ('percent', 'Loan Percentage'),
                                ], 'Discount Type', readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]},
                                required=True,
                                help="""Select Loan Recovery Type:
- Fixed: Discount will a fixed amount
- Percent: Discount will be a percentage of total Loan Amount
                                """, select=True),
        'notes'         : fields.text('Notes'),
        'origin'        : fields.char('Source Document', size=64, help="Reference of the document that generated this Expense Record",
                                    readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}),
        'amount'        : fields.float('Amount', digits_compute=dp.get_precision('Sale Price'), required=True,
                                     readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}),
        'percent_discount' : fields.float('Percent (%)', digits_compute=dp.get_precision('Sale Price'), required=False,
                                          help="Please set percent as 10.00%",
                                          readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}),
        'fixed_discount' : fields.float('Fixed Discount', digits_compute=dp.get_precision('Sale Price'), required=False,
                                        readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}),
        'balance'       : fields.function(_balance, method=True, digits_compute=dp.get_precision('Sale Price'), string='Balance', type='float', multi=True,
                                          store={
                                                 'tms.expense.loan': (lambda self, cr, uid, ids, c={}: ids, ['notes', 'amount','state','expense_line_ids'], 10),
                                                 'tms.expense.line': (_get_loan_discounts_from_expense_lines, ['product_uom_qty', 'price_unit'], 10),
                                                 }),
                                        #store = {'tms.expense.line': (_get_loan_discounts_from_expense_lines, None, 50)}),
        'paid'          : fields.function(_balance, method=True, string='Paid', type='boolean', multi=True, 
                                          store={
                                                 'tms.expense.loan': (lambda self, cr, uid, ids, c={}: ids, ['notes','amount','state','expense_line_ids'], 10),
                                                 'tms.expense.line': (_get_loan_discounts_from_expense_lines, ['product_uom_qty', 'price_unit'], 10),
                                                 }),
                                        #store = {'tms.expense.line': (_get_loan_discounts_from_expense_lines, None, 50)}),
        'product_id'    : fields.many2one('product.product', 'Discount Product', readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]},
                                          required=True, domain=[('tms_category', '=', ('salary_discount'))], ondelete='restrict'),
        'shop_id'       : fields.related('employee_id', 'shop_id', type='many2one', relation='sale.shop', string='Shop', store=True, readonly=True),
        'company_id'    : fields.related('shop_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
        'create_uid'    : fields.many2one('res.users', 'Created by', readonly=True),
        'create_date'   : fields.datetime('Creation Date', readonly=True, select=True),
        'cancelled_by'  : fields.many2one('res.users', 'Cancelled by', readonly=True),
        'date_cancelled': fields.datetime('Date Cancelled', readonly=True),
        'approved_by'   : fields.many2one('res.users', 'Approved by', readonly=True),
        'date_approved' : fields.datetime('Date Approved', readonly=True),
        'confirmed_by'  : fields.many2one('res.users', 'Confirmed by', readonly=True),
        'date_confirmed': fields.datetime('Date Confirmed', readonly=True),
        'closed_by'     : fields.many2one('res.users', 'Closed by', readonly=True),
        'date_closed'   : fields.datetime('Date Closed', readonly=True),

    }
    _defaults = {
        'date'              : lambda *a: time.strftime(DEFAULT_SERVER_DATE_FORMAT),
        'state'             : lambda *a: 'draft',
    }    
    _sql_constraints = [
        ('name_uniq', 'unique(name)', 'Loan record must be unique !'),
    ]

    def create(self, cr, uid, vals, context=None):
        values = vals
        if 'employee_id' in vals and vals['employee_id']:
            employee = self.pool.get('hr.employee').browse(cr, uid, [vals['employee_id']])[0]
            seq_id = employee.shop_id.tms_loan_seq.id
            if seq_id:
                seq_number = self.pool.get('ir.sequence').get_id(cr, uid, seq_id)
                values['name'] = seq_number
            else:
                raise osv.except_osv(_('Loan Sequence Error !'), _('You have not defined Loan Sequence for shop ' + employee.shop_id.name))            
        return super(tms_expense_loan, self).create(cr, uid, values, context=context)

    def action_approve(self, cr, uid, ids, context=None):
        for rec in self.browse(cr, uid, ids, context=context):            
            if rec.amount <= 0.0:
                 raise osv.except_osv(
                    _('Could not approve Loan !'),
                    _('Amount must be greater than zero.'))
            self.write(cr, uid, ids, {'state':'approved', 'approved_by' : uid, 'date_approved':time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)})
            for (id,name) in self.name_get(cr, uid, ids):
                message = _("Loan '%s' is set to Approved.") % name
            self.log(cr, uid, id, message)
        return True

    def action_confirm(self, cr, uid, ids, context=None):
        for rec in self.browse(cr, uid, ids, context=context):            
            self.write(cr, uid, ids, {'state':'confirmed', 'confirmed_by' : uid, 'date_confirmed':time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)})
            for (id,name) in self.name_get(cr, uid, ids):
                message = _("Loan '%s' is set to Confirmed.") % name
            self.log(cr, uid, id, message)
        return True

    def action_cancel(self, cr, uid, ids, context=None):
        for rec in self.browse(cr, uid, ids, context=context):
            self.write(cr, uid, ids, {'state':'cancel', 'cancelled_by' : uid, 'date_cancelled':time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)})
            for (id,name) in self.name_get(cr, uid, ids):
                message = _("Loan '%s' is set to Cancel.") % name
            self.log(cr, uid, id, message)
        return True

    def action_close(self, cr, uid, ids, context=None):
        for rec in self.browse(cr, uid, ids, context=context):
            self.write(cr, uid, ids, {'state':'closed', 'closed_by' : uid, 'date_closed':time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)})
            for (id,name) in self.name_get(cr, uid, ids):                
                message = _("Loan '%s' is set to Closed even when it is not paid.") % name if rec.balance > 0.0 else _("Loan '%s' is set to Closed.") % name 
            self.log(cr, uid, id, message)
        return True

    def get_loan_discounts(self, cr, uid, employee_id, expense_id, context=None):
        expense_line_obj = self.pool.get('tms.expense.line')
        expense_obj = self.pool.get('tms.expense')
        res = expense_line_obj.search(cr, uid, [('expense_id', '=', expense_id),('control','=', 1),('loan_id','!=',False)])
        #print "res: ", res
        if len(res):
            loan_ids = []
            expense_line_ids = []
            for x in expense_obj.browse(cr, uid, [expense_id])[0].expense_line:
                if x.loan_id.id:
                    loan_ids.append(x.loan_id.id)
                    expense_line_ids.append(x.id)
            if len(loan_ids):
                expense_line_obj.unlink(cr, uid, expense_line_ids)
                self.write(cr, uid,loan_ids, {'state':'confirmed', 'closed_by' : False, 'date_closed':False} )
        prod_obj = self.pool.get('product.product')
        loan_ids = self.search(cr, uid, [('employee_id', '=', employee_id),('state','=','confirmed'),('balance', '>', 0.0)])
        flag_each = True
        fecha_liq = expense_obj.read(cr, uid, [expense_id], ['date'])[0]['date']
        for rec in self.browse(cr, uid, loan_ids, context=context):
            if rec.discount_method in ('weekly','fortnightly','monthy'):
                cr.execute('select date from tms_expense_line where loan_id = %s order by date desc limit 1' % (rec.id))
                data = filter(None, map(lambda x:x[0], cr.fetchall()))
                date = data[0] if data else rec.date
                #print "fecha_liq: ", fecha_liq
                dur = datetime.strptime(fecha_liq, '%Y-%m-%d') - datetime.strptime(date, '%Y-%m-%d')
                product = prod_obj.browse(cr, uid, [rec.product_id.id])[0]
                xfactor = 7 if rec.discount_method == 'weekly' else 14.0 if rec.discount_method == 'fortnightly' else 28.0
                rango = 1 if not int(dur.days / xfactor) else int(dur.days / xfactor) + 1
                balance = rec.balance
                while rango and balance:
                    rango -= 1
                    discount = rec.fixed_discount if rec.discount_type == 'fixed' else rec.amount * rec.percent_discount / 100.0
                    discount = balance if discount > balance else discount
                    balance -= discount
                    xline = {
                        'expense_id'        : expense_id,
                        'line_type'         : product.tms_category,
                        'name'              : product.name + ' - ' + rec.name, 
                        'sequence'          : 100,
                        'product_id'        : product.id,
                        'product_uom'       : product.uom_id.id,
                        'product_uom_qty'   : 1,
                        'price_unit'        : discount * -1.0,
                        'control'           : True,
                        'loan_id'           : rec.id,
                        #'operation_id'      : travel.operation_id.id,
                        #'tax_id'            : [(6, 0, [x.id for x in product.supplier_taxes_id])],
                        }                
                    res = expense_line_obj.create(cr, uid, xline)
                    if discount >= rec.balance:
                        self.write(cr, uid, [rec.id], {'state':'closed', 'closed_by' : uid, 'date_closed':time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)})
                        for (id,name) in self.name_get(cr, uid, [rec.id]):                
                            message =  _("Loan '%s' has been Closed.") % rec.name 
                        self.log(cr, uid, id, message)
            elif rec.discount_method == 'each' and flag_each:
                # Buscaoms el ultimo descuento de prestamo de tipo "En cada liquidacion"
                cr.execute("""select date from tms_expense_line where loan_id in 
                                    (select id from tms_expense_loan where employee_id=%s
                                                    and discount_method='each' and state in ('closed','confirmed'))
                                 order by date desc limit 1;
                """ % (rec.employee_id.id))
                data = filter(None, map(lambda x:x[0], cr.fetchall()))           
                date = data and data[0] or rec.date
                if date >= fecha_liq:
                    continue
                flag_each = False
                cr.execute('select date from tms_expense_line where loan_id = %s order by date desc limit 1' % (rec.id))
                data = filter(None, map(lambda x:x[0], cr.fetchall()))
                date = data[0] if data else rec.date
                #print "fecha_liq: ", fecha_liq
                dur = datetime.strptime(fecha_liq, '%Y-%m-%d') - datetime.strptime(date, '%Y-%m-%d')
                product = prod_obj.browse(cr, uid, [rec.product_id.id])[0]
                balance = rec.balance
                discount = rec.fixed_discount if rec.discount_type == 'fixed' else rec.amount * rec.percent_discount / 100.0
                discount = balance if discount > balance else discount
                balance -= discount
                xline = {
                    'expense_id'        : expense_id,
                    'line_type'         : product.tms_category,
                    'name'              : product.name + ' - ' + rec.name, 
                    'sequence'          : 100,
                    'product_id'        : product.id,
                    'product_uom'       : product.uom_id.id,
                    'product_uom_qty'   : 1,
                    'price_unit'        : discount * -1.0,
                    'control'           : True,
                    'loan_id'           : rec.id,
                    #'operation_id'      : travel.operation_id.id,
                    #'tax_id'            : [(6, 0, [x.id for x in product.supplier_taxes_id])],
                    }                
                res = expense_line_obj.create(cr, uid, xline)
                if discount >= rec.balance:
                    self.write(cr, uid, [rec.id], {'state':'closed', 'closed_by' : uid, 'date_closed':time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)})
                    for (id,name) in self.name_get(cr, uid, [rec.id]):                
                        message =  _("Loan '%s' has been Closed.") % rec.name 
                    self.log(cr, uid, id, message)
        return
Пример #15
0
class crm_stage(osv.Model):
    """ Model for case stages. This models the main stages of a document
        management flow. Main CRM objects (leads, opportunities, project
        issues, ...) will now use only stages, instead of state and stages.
        Stages are for example used to display the kanban view of records.
    """
    _name = "crm.stage"
    _description = "Stage of case"
    _rec_name = 'name'
    _order = "sequence"

    _columns = {
        'name':
        fields.char('Stage Name', required=True, translate=True),
        'sequence':
        fields.integer('Sequence',
                       help="Used to order stages. Lower is better."),
        'probability':
        fields.float(
            'Probability (%)',
            required=True,
            help=
            "This percentage depicts the default/average probability of the Case for this stage to be a success"
        ),
        'on_change':
        fields.boolean(
            'Change Probability Automatically',
            help=
            "Setting this stage will change the probability automatically on the opportunity."
        ),
        'requirements':
        fields.text('Requirements'),
        'team_ids':
        fields.many2many(
            'crm.team',
            'crm_team_stage_rel',
            'stage_id',
            'team_id',
            string='Teams',
            help=
            "Link between stages and sales teams. When set, this limitate the current stage to the selected sales teams."
        ),
        'case_default':
        fields.boolean(
            'Default to New Sales Team',
            help=
            "If you check this field, this stage will be proposed by default on each sales team. It will not assign this stage to existing teams."
        ),
        'legend_priority':
        fields.text(
            'Priority Management Explanation',
            translate=True,
            help=
            'Explanation text to help users using the star and priority mechanism on stages or issues that are in this stage.'
        ),
        'fold':
        fields.boolean('Folded in Kanban View',
                       help='This stage is folded in the kanban view when'
                       'there are no records in that stage to display.'),
        'type':
        fields.selection(
            [('lead', 'Lead'), ('opportunity', 'Opportunity'),
             ('both', 'Both')],
            string='Type',
            required=True,
            help=
            "This field is used to distinguish stages related to Leads from stages related to Opportunities, or to specify stages available for both types."
        ),
    }

    _defaults = {
        'sequence': 1,
        'probability': 0.0,
        'on_change': True,
        'fold': False,
        'type': 'both',
        'case_default': True,
    }
Пример #16
0
class contract_init(orm.Model):

    _name = 'hr.contract.init'
    _description = 'Initial Contract Settings'

    _inherit = 'ir.needaction_mixin'

    _columns = {
        'name':
        fields.char(
            'Name',
            size=64,
            required=True,
            readonly=True,
            states={'draft': [('readonly', False)]},
        ),
        'date':
        fields.date(
            'Effective Date',
            required=True,
            readonly=True,
            states={'draft': [('readonly', False)]},
        ),
        'wage_ids':
        fields.one2many(
            'hr.contract.init.wage',
            'contract_init_id',
            'Starting Wages',
            readonly=True,
            states={'draft': [('readonly', False)]},
        ),
        'struct_id':
        fields.many2one(
            'hr.payroll.structure',
            'Payroll Structure',
            readonly=True,
            states={'draft': [('readonly', False)]},
        ),
        'trial_period':
        fields.integer(
            'Trial Period',
            readonly=True,
            states={'draft': [('readonly', False)]},
            help="Length of Trial Period, in days",
        ),
        'active':
        fields.boolean('Active', ),
        'state':
        fields.selection(
            [
                ('draft', 'Draft'),
                ('approve', 'Approved'),
                ('decline', 'Declined'),
            ],
            'State',
            readonly=True,
        ),
    }

    _defaults = {
        'trial_period': 0,
        'active': True,
        'state': 'draft',
    }

    # Return records with latest date first
    _order = 'date desc'

    def _needaction_domain_get(self, cr, uid, context=None):

        users_obj = self.pool.get('res.users')

        if users_obj.has_group(cr, uid, 'base.group_hr_director'):
            domain = [('state', 'in', ['draft'])]
            return domain

        return False

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

        if isinstance(ids, (int, long)):
            ids = [ids]
        data = self.read(cr, uid, ids, ['state'], context=context)
        for d in data:
            if d['state'] in ['approve', 'decline']:
                raise orm.except_orm(
                    _('Error'),
                    _('You may not a delete a record that is not in a '
                      '"Draft" state'))
        return super(contract_init, self).unlink(cr, uid, ids, context=context)

    def set_to_draft(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {
            'state': 'draft',
        }, context=context)
        wf_service = netsvc.LocalService("workflow")
        for i in ids:
            wf_service.trg_delete(uid, 'hr.contract.init', i, cr)
            wf_service.trg_create(uid, 'hr.contract.init', i, cr)
        return True

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

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

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

        self.write(cr, uid, ids, {'state': 'decline'}, context=context)
        return True
Пример #17
0
            try:
                file_data = image_file.read()
                self._logo_image = base64.encodestring(file_data)
                return self._logo_image
            finally:
                image_file.close()
        else:
            self._logo_image = base64.encodestring(im.read())
            return self._logo_image

    def _get_image_fn(self, cr, uid, ids, name, args, context=None):
        image = self._get_image(cr, uid, context)
        return dict.fromkeys(ids, image)  # ok to use .fromkeys() as the image is same for all

    _columns = {
        'soffice': fields.char('Path to LibreOffice executable', size=256, required=True),
        'dir_tmp': fields.char('Temp directory', size=256, required=True),
        'state': fields.selection([
            ('init', 'Init'),
            ('error', 'Error'),
            ('done', 'Done')
        ], 'State', select=True, readonly=True),
        'msg': fields.text('Message', readonly=True),
        'error_details': fields.text('Error Details', readonly=True),
        'config_logo': fields.function(_get_image_fn, string='Image', type='binary', method=True)
    }

    def default_get(self, cr, uid, fields, context=None):
        values = super(AerooConfigInstaller, self).default_get(cr, uid, fields, context=context)
        if platform == "linux" or platform == "linux2":
            # linux
class hr_timesheet_sheet(osv.osv):
    _name = "hr_timesheet_sheet.sheet"
    _inherit = "mail.thread"
    _table = 'hr_timesheet_sheet_sheet'
    _order = "id desc"
    _description="Timesheet"

    def _total(self, cr, uid, ids, name, args, context=None):
        """ Compute the attendances, analytic lines timesheets and differences between them
            for all the days of a timesheet and the current day
        """

        res = {}
        for sheet in self.browse(cr, uid, ids, context=context or {}):
            res.setdefault(sheet.id, {
                'total_attendance': 0.0,
                'total_timesheet': 0.0,
                'total_difference': 0.0,
            })
            for period in sheet.period_ids:
                res[sheet.id]['total_attendance'] += period.total_attendance
                res[sheet.id]['total_timesheet'] += period.total_timesheet
                res[sheet.id]['total_difference'] += period.total_attendance - period.total_timesheet
        return res

    def check_employee_attendance_state(self, cr, uid, sheet_id, context=None):
        ids_signin = self.pool.get('hr.attendance').search(cr,uid,[('sheet_id', '=', sheet_id),('action','=','sign_in')])
        ids_signout = self.pool.get('hr.attendance').search(cr,uid,[('sheet_id', '=', sheet_id),('action','=','sign_out')])

        if len(ids_signin) != len(ids_signout):
            raise osv.except_osv(('Warning!'),_('The timesheet cannot be validated as it does not contain an equal number of sign ins and sign outs.'))
        return True

    def copy(self, cr, uid, ids, *args, **argv):
        raise osv.except_osv(_('Error!'), _('You cannot duplicate a timesheet.'))

    def create(self, cr, uid, vals, *args, **argv):
        if 'employee_id' in vals:
            if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).user_id:
                raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link him/her to a user.'))
            if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).product_id:
                raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link the employee to a product, like \'Consultant\'.'))
            if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).journal_id:
                raise osv.except_osv(_('Configuration Error!'), _('In order to create a timesheet for this employee, you must assign an analytic journal to the employee, like \'Timesheet Journal\'.'))
        return super(hr_timesheet_sheet, self).create(cr, uid, vals, *args, **argv)

    def write(self, cr, uid, ids, vals, *args, **argv):
        if 'employee_id' in vals:
            new_user_id = self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).user_id.id or False
            if not new_user_id:
                raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link him/her to a user.'))
            if not self._sheet_date(cr, uid, ids, forced_user_id=new_user_id):
                raise osv.except_osv(_('Error!'), _('You cannot have 2 timesheets that overlap!\nYou should use the menu \'My Timesheet\' to avoid this problem.'))
            if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).product_id:
                raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link the employee to a product.'))
            if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).journal_id:
                raise osv.except_osv(_('Configuration Error!'), _('In order to create a timesheet for this employee, you must assign an analytic journal to the employee, like \'Timesheet Journal\'.'))
        return super(hr_timesheet_sheet, self).write(cr, uid, ids, vals, *args, **argv)

    def button_confirm(self, cr, uid, ids, context=None):
        for sheet in self.browse(cr, uid, ids, context=context):
            if sheet.employee_id and sheet.employee_id.parent_id and sheet.employee_id.parent_id.user_id:
                self.message_subscribe_users(cr, uid, [sheet.id], user_ids=[sheet.employee_id.parent_id.user_id.id], context=context)
            self.check_employee_attendance_state(cr, uid, sheet.id, context=context)
            di = sheet.user_id.company_id.timesheet_max_difference
            if (abs(sheet.total_difference) < di) or not di:
                self.signal_confirm(cr, uid, [sheet.id])
            else:
                raise osv.except_osv(_('Warning!'), _('Please verify that the total difference of the sheet is lower than %.2f.') %(di,))
        return True

    def attendance_action_change(self, cr, uid, ids, context=None):
        hr_employee = self.pool.get('hr.employee')
        employee_ids = []
        for sheet in self.browse(cr, uid, ids, context=context):
            if sheet.employee_id.id not in employee_ids: employee_ids.append(sheet.employee_id.id)
        return hr_employee.attendance_action_change(cr, uid, employee_ids, context=context)

    _columns = {
        'name': fields.char('Note', size=64, select=1,
                            states={'confirm':[('readonly', True)], 'done':[('readonly', True)]}),
        'employee_id': fields.many2one('hr.employee', 'Employee', required=True),
        'user_id': fields.related('employee_id', 'user_id', type="many2one", relation="res.users", store=True, string="User", required=False, readonly=True),#fields.many2one('res.users', 'User', required=True, select=1, states={'confirm':[('readonly', True)], 'done':[('readonly', True)]}),
        'date_from': fields.date('Date from', required=True, select=1, readonly=True, states={'new':[('readonly', False)]}),
        'date_to': fields.date('Date to', required=True, select=1, readonly=True, states={'new':[('readonly', False)]}),
        'timesheet_ids' : fields.one2many('hr.analytic.timesheet', 'sheet_id',
            'Timesheet lines',
            readonly=True, states={
                'draft': [('readonly', False)],
                'new': [('readonly', False)]}
            ),
        'attendances_ids' : fields.one2many('hr.attendance', 'sheet_id', 'Attendances'),
        'state' : fields.selection([
            ('new', 'New'),
            ('draft','Open'),
            ('confirm','Waiting Approval'),
            ('done','Approved')], 'Status', select=True, required=True, readonly=True,
            help=' * The \'Draft\' status is used when a user is encoding a new and unconfirmed timesheet. \
                \n* The \'Confirmed\' status is used for to confirm the timesheet by user. \
                \n* The \'Done\' status is used when users timesheet is accepted by his/her senior.'),
        'state_attendance' : fields.related('employee_id', 'state', type='selection', selection=[('absent', 'Absent'), ('present', 'Present')], string='Current Status', readonly=True),
        'total_attendance': fields.function(_total, method=True, string='Total Attendance', multi="_total"),
        'total_timesheet': fields.function(_total, method=True, string='Total Timesheet', multi="_total"),
        'total_difference': fields.function(_total, method=True, string='Difference', multi="_total"),
        'period_ids': fields.one2many('hr_timesheet_sheet.sheet.day', 'sheet_id', 'Period', readonly=True),
        'account_ids': fields.one2many('hr_timesheet_sheet.sheet.account', 'sheet_id', 'Analytic accounts', readonly=True),
        'company_id': fields.many2one('res.company', 'Company'),
        'department_id':fields.many2one('hr.department','Department'),
    }

    def _default_date_from(self, cr, uid, context=None):
        user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
        r = user.company_id and user.company_id.timesheet_range or 'month'
        if r=='month':
            return time.strftime('%Y-%m-01')
        elif r=='week':
            return (datetime.today() + relativedelta(weekday=0, days=-6)).strftime('%Y-%m-%d')
        elif r=='year':
            return time.strftime('%Y-01-01')
        return time.strftime('%Y-%m-%d')

    def _default_date_to(self, cr, uid, context=None):
        user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
        r = user.company_id and user.company_id.timesheet_range or 'month'
        if r=='month':
            return (datetime.today() + relativedelta(months=+1,day=1,days=-1)).strftime('%Y-%m-%d')
        elif r=='week':
            return (datetime.today() + relativedelta(weekday=6)).strftime('%Y-%m-%d')
        elif r=='year':
            return time.strftime('%Y-12-31')
        return time.strftime('%Y-%m-%d')

    def _default_employee(self, cr, uid, context=None):
        emp_ids = self.pool.get('hr.employee').search(cr, uid, [('user_id','=',uid)], context=context)
        return emp_ids and emp_ids[0] or False

    _defaults = {
        'date_from' : _default_date_from,
        'date_to' : _default_date_to,
        'state': 'new',
        'employee_id': _default_employee,
        'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'hr_timesheet_sheet.sheet', context=c)
    }

    def _sheet_date(self, cr, uid, ids, forced_user_id=False, context=None):
        for sheet in self.browse(cr, uid, ids, context=context):
            new_user_id = forced_user_id or sheet.user_id and sheet.user_id.id
            if new_user_id:
                cr.execute('SELECT id \
                    FROM hr_timesheet_sheet_sheet \
                    WHERE (date_from <= %s and %s <= date_to) \
                        AND user_id=%s \
                        AND id <> %s',(sheet.date_to, sheet.date_from, new_user_id, sheet.id))
                if cr.fetchall():
                    return False
        return True


    _constraints = [
        (_sheet_date, 'You cannot have 2 timesheets that overlap!\nPlease use the menu \'My Current Timesheet\' to avoid this problem.', ['date_from','date_to']),
    ]

    def action_set_to_draft(self, cr, uid, ids, *args):
        self.write(cr, uid, ids, {'state': 'draft'})
        self.create_workflow(cr, uid, ids)
        return True

    def name_get(self, cr, uid, ids, context=None):
        if not ids:
            return []
        if isinstance(ids, (long, int)):
            ids = [ids]
        return [(r['id'], _('Week ')+datetime.strptime(r['date_from'], '%Y-%m-%d').strftime('%U')) \
                for r in self.read(cr, uid, ids, ['date_from'],
                    context=context, load='_classic_write')]

    def unlink(self, cr, uid, ids, context=None):
        sheets = self.read(cr, uid, ids, ['state','total_attendance'], context=context)
        for sheet in sheets:
            if sheet['state'] in ('confirm', 'done'):
                raise osv.except_osv(_('Invalid Action!'), _('You cannot delete a timesheet which is already confirmed.'))
            elif sheet['total_attendance'] <> 0.00:
                raise osv.except_osv(_('Invalid Action!'), _('You cannot delete a timesheet which have attendance entries.'))
        return super(hr_timesheet_sheet, self).unlink(cr, uid, ids, context=context)

    def onchange_employee_id(self, cr, uid, ids, employee_id, context=None):
        department_id =  False
        user_id = False
        if employee_id:
            empl_id = self.pool.get('hr.employee').browse(cr, uid, employee_id, context=context)
            department_id = empl_id.department_id.id
            user_id = empl_id.user_id.id
        return {'value': {'department_id': department_id, 'user_id': user_id,}}

    # ------------------------------------------------
    # OpenChatter methods and notifications
    # ------------------------------------------------

    def _needaction_domain_get(self, cr, uid, context=None):
        emp_obj = self.pool.get('hr.employee')
        empids = emp_obj.search(cr, uid, [('parent_id.user_id', '=', uid)], context=context)
        if not empids:
            return False
        dom = ['&', ('state', '=', 'confirm'), ('employee_id', 'in', empids)]
        return dom
Пример #19
0
class wizard(osv.TransientModel):
    """
        A wizard to manage the modification of protocol object
    """
    _name = 'protocollo.modify.wizard'
    _description = 'Modify Protocollo Management'

    def set_before(self, before, label, value):
        if not value:
            value = ''
        before += label + ': ' + value + '\n'
        return before

    def set_after(self, after, label, value):
        after += label + ': ' + value + '\n'
        return after

    def _get_write_date(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'])
        return protocollo.write_date

    def on_change_typology(self, cr, uid, ids, typology_id, context=None):
        values = {'pec': False, 'sharedmail': False, 'email_error': ''}
        if typology_id:
            typology_obj = self.pool.get('protocollo.typology')
            typology = typology_obj.browse(cr, uid, typology_id)
            protocollo_obj = self.pool.get('protocollo.protocollo')
            protocollo = protocollo_obj.browse(cr, uid, context['active_id'],
                                               {'skip_check': True})
            if typology.pec:
                values['pec'] = True
                values['sharedmail'] = False
                if protocollo.type == 'out':
                    for sender_receiver in protocollo.sender_receivers:
                        if not sender_receiver.pec_mail:
                            values[
                                'email_error'] = "Attenzione!\nIl mezzo di trasmissione 'PEC' non può essere usato perchè ci sono dei destinatari privi di email PEC!"
                            break
            if typology.sharedmail:
                values['pec'] = False
                values['sharedmail'] = True
                if protocollo.type == 'out':
                    for sender_receiver in protocollo.sender_receivers:
                        if not sender_receiver.email:
                            values[
                                'email_error'] = "Attenzione!\nIl mezzo di trasmissione 'Email' non può essere usato perchè ci sono dei destinatari privi di email!"
                            break

            if protocollo.typology.id != typology.id:
                if protocollo.typology.pec:
                    values[
                        'email_error'] = "Attenzione!\nIl mezzo di trasmissione 'PEC' non può essere modificato!"
                elif typology.pec:
                    values[
                        'email_error'] = "Attenzione!\nIl mezzo di trasmissione 'PEC' non può essere inserito in questa fase!"

        return {'value': values}

    _columns = {
        'name':
        fields.char('Numero Protocollo',
                    size=256,
                    required=True,
                    readonly=True),
        'registration_date':
        fields.datetime('Data Registrazione', readonly=True),
        'type':
        fields.selection(
            [('out', 'Uscita'), ('in', 'Ingresso')],
            'Tipo',
            size=32,
            required=True,
            readonly=True,
        ),
        'typology':
        fields.many2one('protocollo.typology',
                        'Mezzo di Trasmissione',
                        help="Mezzo di Trasmissione: \
                Raccomandata, Fax, PEC, etc. \
                si possono inserire nuove tipologie \
                dal menu Tipologie."),
        'pec':
        fields.related('typology',
                       'pec',
                       type='boolean',
                       string='PEC',
                       readonly=False,
                       store=False),
        'sharedmail':
        fields.related('typology',
                       'sharedmail',
                       type='boolean',
                       string='Sharedmail',
                       readonly=False,
                       store=False),
        'receiving_date':
        fields.datetime(
            'Data Ricezione',
            required=False,
        ),
        'subject':
        fields.text('Oggetto', required=True),
        'email_pec_sending_mode':
        fields.selection(
            [('all_receivers', 'Un messaggio per tutti i destinatari')],
            'Modalità Invio',
            size=32),
        'body':
        fields.html('Corpo della mail'),
        'classification':
        fields.many2one(
            'protocollo.classification',
            'Titolario di Classificazione',
            required=False,
        ),
        'sender_protocol':
        fields.char(
            'Protocollo Mittente',
            required=False,
        ),
        'server_sharedmail_id':
        fields.many2one(
            'fetchmail.server',
            'Account Email',
            domain=
            "[('sharedmail', '=', True),('user_sharedmail_ids', 'in', uid),('state','=','done')]"
        ),
        'server_pec_id':
        fields.many2one(
            'fetchmail.server',
            'Account PEC',
            domain=
            "[('pec', '=', True),('user_ids', 'in', uid),('state','=','done')]"
        ),
        'dossier_ids':
        fields.many2many('protocollo.dossier', 'dossier_protocollo_pec_rel',
                         'wizard_id', 'dossier_id', 'Fascicoli'),
        'notes':
        fields.text('Note'),
        'cause':
        fields.text('Motivo della Modifica', required=True),
        'last_write_date':
        fields.datetime('Ultimo salvataggio', required=True),
        'email_error':
        fields.text('Errore', readonly=True),
    }

    def _default_name(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.name

    def _default_registration_date(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.registration_date

    def _default_type(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.type

    def _default_typology(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.typology.id

    def _default_receiving_date(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.receiving_date

    def _default_subject(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.subject

    def _default_body(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.body

    def _default_email_pec_sending_mode(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.email_pec_sending_mode

    def _default_classification(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.classification.id

    def _default_sender_protocol(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.sender_protocol

    def _default_dossier_ids(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        dossier_ids = []
        for dossier_id in protocollo.dossier_ids:
            dossier_ids.append(dossier_id.id)
        return [(6, 0, dossier_ids)]

    def _default_notes(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.notes

    def _default_last_write_date(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.write_date

    def _default_server_sharedmail_id(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.server_sharedmail_id

    def _default_server_pec_id(self, cr, uid, context):
        protocollo = self.pool.get('protocollo.protocollo').browse(
            cr, uid, context['active_id'], {'skip_check': True})
        return protocollo.server_pec_id

    _defaults = {
        'name': _default_name,
        'registration_date': _default_registration_date,
        'type': _default_type,
        'typology': _default_typology,
        'receiving_date': _default_receiving_date,
        'subject': _default_subject,
        'body': _default_body,
        'email_pec_sending_mode': _default_email_pec_sending_mode,
        'classification': _default_classification,
        'sender_protocol': _default_sender_protocol,
        'dossier_ids': _default_dossier_ids,
        'notes': _default_notes,
        'last_write_date': _default_last_write_date,
        'server_sharedmail_id': _default_server_sharedmail_id,
        'server_pec_id': _default_server_pec_id,
        'email_error': ''
    }

    def action_save(self, cr, uid, ids, context=None):
        vals = {}
        wizard = self.browse(cr, uid, ids[0], context)
        protocollo_obj = self.pool.get('protocollo.protocollo')
        protocollo = protocollo_obj.browse(cr, uid, context['active_id'],
                                           {'skip_check': True})

        if wizard.last_write_date != protocollo.write_date:
            raise osv.except_osv(
                _('Attenzione!'),
                _('Il protocollo corrente e\' stato modificato di recente da un altro utente.\nAggiornare la pagina prima di modificare il protocollo.'
                  ))

        vals['typology'] = wizard.typology.id
        if wizard.typology.id != protocollo.typology.id:
            if protocollo.typology.pec:
                raise orm.except_orm(
                    _('Attenzione!'),
                    _('Il metodo di spedizione PEC'
                      ' non puo\' essere modificato.'))
            elif wizard.typology.pec:
                raise orm.except_orm(
                    _('Attenzione!'),
                    _('Il metodo di spedizione PEC'
                      ' non puo\' essere inserito in questa fase.'))

        if wizard.server_sharedmail_id.id != protocollo.server_sharedmail_id.id:
            vals['server_sharedmail_id'] = wizard.server_sharedmail_id.id

        if wizard.server_pec_id.id != protocollo.server_pec_id.id:
            vals['server_pec_id'] = wizard.server_pec_id.id

        if wizard.subject != protocollo.subject:
            vals['subject'] = wizard.subject

        if wizard.email_pec_sending_mode != protocollo.email_pec_sending_mode:
            vals['email_pec_sending_mode'] = wizard.email_pec_sending_mode

        if wizard.body != protocollo.body:
            vals['body'] = wizard.body

        if protocollo.receiving_date != wizard.receiving_date:
            vals['receiving_date'] = wizard.receiving_date

        protocollo_obj.write(cr, uid, [context['active_id']], vals,
                             {'cause': wizard.cause})
        if vals and \
                ('subject' in vals or 'server_sharedmail_id' in vals or 'server_pec_id' in vals) and \
                protocollo.registration_date:
            protocollo_obj.aggiorna_segnatura_xml(cr,
                                                  uid, [protocollo.id],
                                                  force=True,
                                                  log=False,
                                                  commit=False,
                                                  context=context)

        return {
            'name': 'Protocollo',
            'view_type': 'form',
            'view_mode': 'form,tree',
            'res_model': 'protocollo.protocollo',
            'res_id': context['active_id'],
            'context': context,
            'type': 'ir.actions.act_window',
            'flags': {
                'initial_mode': 'edit'
            }
        }
Пример #20
0
class account_invoice(orm.Model):
    _inherit = 'account.invoice'

    # def _get_sale_order(self, cr, uid, ids, field_name, model_name, context=None):
    #     result = {}
    #     crm_lead_obj = self.pool['crm.lead']
    #     sale_order_obj = self.pool['sale.order']
    #
    #     for crm_lead in crm_lead_obj.browse(cr, uid, ids, context):
    #         partner_id = crm_lead.partner_id.id
    #         contact_id = crm_lead.partner_address_id.id
    #         if contact_id:
    #             result[crm_lead.id] = sale_order_obj.search(cr, uid, [('partner_id', '=', partner_id), ('partner_order_id', '=', contact_id)])
    #         else:
    #             result[crm_lead.id] = sale_order_obj.search(cr, uid, [('partner_id', '=', partner_id)])
    #     return result

    def name_get(self, cr, uid, ids, context=None):
        context = context or self.pool['res.users'].context_get(cr, uid)
        if not ids:
            return []
        if isinstance(ids, (int, long)):
            ids = [ids]

        return [(x['id'], unicode(x.type in ['in_invoice', 'in_refund'] and x.supplier_invoice_number or x.number or x.name)) for x in self.browse(cr, uid, ids, context=context)]

    def _get_stock_picking(self, cr, uid, ids, field_name, model_name, context=None):
        context = context or self.pool['res.users'].context_get(cr, uid)
        result = {}
        stock_picking_obj = self.pool['stock.picking']

        for invoice in self.browse(cr, uid, ids, context):
            origins = {}

            for line in invoice.invoice_line:
                line_origin = line.origin or False
                if line_origin not in origins:
                    origins[line_origin] = invoice.id
            if invoice.origin:
                for invoice_origin in invoice.origin.split(', '):
                    if invoice_origin not in origins:
                        origins[invoice_origin] = invoice.id
            picking_ids = []
            for origin in origins:
                if origin:
                    # OUTxxx:SOyy
                    if len(origin.split(':')) == 2:
                        pickings_name = origin.split(':')[0]
                    else:
                        pickings_name = origin
                    picking_ids += stock_picking_obj.search(cr, uid, [('name', '=', pickings_name)], context=context)
                    print picking_ids

            result[invoice.id] = picking_ids

        return result

    _columns = {
        'supplier_invoice_number': fields.char('Supplier invoice nr', size=32),
        # 'sale_order_ids': fields.function(_get_sale_order, 'Sale Order', type='one2many', relation="sale.order", readonly=True, method=True),
        'stock_picking_ids': fields.function(_get_stock_picking, 'Stock Picking', type='one2many', relation="stock.picking", readonly=True, method=True),
        'sale_order_ids': fields.many2many(
            'sale.order', 'sale_order_invoice_rel', 'invoice_id', 'order_id', 'Sale orders'
        )
    }
    
    def copy(self, cr, uid, order_id, default, context=None):
        context = context or self.pool['res.users'].context_get(cr, uid)
        if not default:
            default = {}
        default['user_id'] = uid
        return super(account_invoice, self).copy(cr, uid, order_id, default, context)

    def invoice_validate_check(self, cr, uid, ids, context=None):
        context = context or self.pool['res.users'].context_get(cr, uid)
        for invoice in self.browse(cr, uid, ids, context):
            if invoice.type == 'out_invoice' and invoice.fiscal_position and invoice.fiscal_position.sale_journal_id and invoice.fiscal_position.sale_journal_id != invoice.journal_id:
                raise orm.except_orm(_('Fattura Cliente'),
                    _('Impossibile to valide invoice of {partner} because journal on invoive \'{invoice_journal}\' is different from journal \'{fiscal_position_journal}\' set on fiscal position \'{invoice_fiscal_position}\'').format(
                        partner=invoice.partner_id.name, invoice_journal=invoice.journal_id.name, fiscal_position_journal=invoice.fiscal_position.sale_journal_id.name, invoice_fiscal_position=invoice.fiscal_position.name))
                return False
        return True

    def invoice_cancel_check(self, cr, uid, ids, context=None):
        context = context or self.pool['res.users'].context_get(cr, uid)
        return True

    def invoice_proforma_check(self, cr, uid, ids, context=None):
        context = context or self.pool['res.users'].context_get(cr, uid)
        return True

    def onchange_fiscal_position(self, cr, uid, ids, journal_id, fiscal_position, ttype, context=None):
        context = context or self.pool['res.users'].context_get(cr, uid)
        if not fiscal_position:
            return False

        fpos_obj = self.pool['account.fiscal.position']
        new_fiscal_position = fpos_obj.browse(cr, uid, fiscal_position, context)
        if ttype in ['out_invoice']:
            journal_id = new_fiscal_position.sale_journal_id and new_fiscal_position.sale_journal_id.id or journal_id
        elif ttype in ['in_invoice']:
            journal_id = new_fiscal_position.purchase_journal_id and new_fiscal_position.purchase_journal_id.id or journal_id

        # if is an exiting invoice, also change tax inside line to new fiscal position

        warning = {}
        for inv in self.browse(cr, uid, ids, context):
            if inv.fiscal_position != new_fiscal_position:
                for line in inv.invoice_line:
                    if line.product_id:
                        result = {}
                        if inv.type in ('out_invoice', 'out_refund'):
                            account_id = line.product_id.product_tmpl_id.property_account_income.id
                            if not account_id:
                                account_id = line.product_id.categ_id.property_account_income_categ.id
                        else:
                            account_id = line.product_id.product_tmpl_id.property_account_expense.id
                            if not account_id:
                                account_id = line.product_id.categ_id.property_account_expense_categ.id

                        account_id = fpos_obj.map_account(cr, uid, new_fiscal_position, account_id)

                        if inv.type in ('out_invoice', 'out_refund'):
                            taxes = line.product_id.taxes_id and line.product_id.taxes_id or (
                            account_id and self.pool['account.account'].browse(cr, uid, account_id, context=context).tax_ids or False)
                        else:
                            taxes = line.product_id.supplier_taxes_id and line.product_id.supplier_taxes_id or (
                            account_id and self.pool['account.account'].browse(cr, uid, account_id, context=context).tax_ids or False)

                        new_taxes = fpos_obj.map_tax(cr, uid, new_fiscal_position, taxes)
                        if new_taxes:
                            result['invoice_line_tax_id'] = [(6, 0, new_taxes)]
                        result['account_id'] = fpos_obj.map_account(cr, uid, new_fiscal_position, account_id, context=None)

                        self.pool['account.invoice.line'].write(cr, uid, line.id, result, context=context)
                inv.button_reset_taxes()
                warning = {
                    'title': _('Fiscal Position'),
                    'message': _('Is Change from \n{old_fiscal_position} to \n{new_fiscal_position}: \nPlease Press Button for recalculate tax').format(
                        old_fiscal_position=inv.fiscal_position and inv.fiscal_position.name or _('None'), new_fiscal_position=new_fiscal_position.name)
                }

        return {'value': {'journal_id': journal_id}, 'warning': warning}

    def _invoice_adaptative_function(self, invoice, vals):
        partner_vals = {}
        if set(vals.keys()).intersection(['fiscal_position', 'carriage_condition_id', 'goods_description_id', 'payment_term']):
            if not invoice.partner_id.carriage_condition_id and vals.get('carriage_condition_id', False):
                partner_vals['carriage_condition_id'] = vals.get('carriage_condition_id')
            if not invoice.partner_id.goods_description_id and vals.get('goods_description_id', False):
                partner_vals['goods_description_id'] = vals.get('goods_description_id')
            if not invoice.partner_id.property_payment_term and vals.get('payment_term', False):
                partner_vals['property_payment_term'] = vals.get('payment_term')
            if not invoice.partner_id.property_account_position and vals.get('fiscal_position', False):
                partner_vals['property_account_position'] = vals.get('fiscal_position')
            if 'company_bank_id' in invoice.partner_id._table._columns and not invoice.partner_id.company_bank_id and vals.get('partner_bank_id', False):
                partner_vals['company_bank_id'] = vals.get('partner_bank_id')

            if partner_vals:
                invoice.partner_id.write(partner_vals)
        return True

    def create(self, cr, uid, vals, context=None):
        context = context or self.pool['res.users'].context_get(cr, uid)
        # adaptative function: the system learn
        invoice_id = super(account_invoice, self).create(cr, uid, vals, context=context)
        # create function return only 1 id
        invoice = self.browse(cr, uid, invoice_id, context)
        self._invoice_adaptative_function(invoice, vals)
        return invoice_id

    def write(self, cr, uid, ids, vals, context=None):
        context = context or self.pool['res.users'].context_get(cr, uid)
        if not ids:
            return True
        if isinstance(ids, (int, long)):
            ids = [ids]
        res = super(account_invoice, self).write(cr, uid, ids, vals, context=context)

        for invoice in self.browse(cr, uid, ids, context=context):
            # adaptative function: the system learn
            self._invoice_adaptative_function(invoice, vals)
        return res

    # def button_change_fiscal_position(self, cr, uid, ids, context=None):
    #     if context is None:
    #         context = self.pool['res.users'].context_get(cr, uid)
    #
    #     fpos_obj = self.pool['account.fiscal.position']
    #
    #     for inv in self.browse(cr, uid, ids, context):
    #         for line in inv.invoice_line:
    #             if line.product_id:
    #                 new_taxes = fpos_obj.map_tax(cr, uid, inv.fiscal_position, line.product_id.taxes_id)
    #                 line.write({'invoice_line_tax_id': [(6, 0, new_taxes)]})
    #         inv.button_reset_taxes()
    #
    #     return True

    # override to group product_id too
    def inv_line_characteristic_hashcode(self, invoice, invoice_line):
        """Overridable hashcode generation for invoice lines. Lines having the same hashcode
        will be grouped together if the journal has the 'group line' option. Of course a module
        can add fields to invoice lines that would need to be tested too before merging lines
        or not."""
        return "%s-%s-%s-%s"%(
            invoice_line['account_id'],
            invoice_line.get('tax_code_id', "False"),  # invoice_line.get('product_id',"False"),
            invoice_line.get('analytic_account_id', "False"),
            invoice_line.get('date_maturity', "False"))

    # override to merge description (after will be trunked to x character everyway)
    def group_lines(self, cr, uid, iml, line, inv):
        """Merge account move lines (and hence analytic lines) if invoice line hashcodes are equals"""
        if inv.journal_id.group_invoice_lines:
            line2 = {}
            for x, y, l in line:
                tmp = self.inv_line_characteristic_hashcode(inv, l)

                if tmp in line2:
                    am = line2[tmp]['debit'] - line2[tmp]['credit'] + (l['debit'] - l['credit'])
                    line2[tmp]['debit'] = (am > 0) and am or 0.0
                    line2[tmp]['credit'] = (am < 0) and -am or 0.0
                    line2[tmp]['tax_amount'] += l['tax_amount']
                    line2[tmp]['analytic_lines'] += l['analytic_lines']
                    line2[tmp]['amount_currency'] += l['amount_currency']
                    line2[tmp]['quantity'] += l['quantity']
                    line2[tmp]['name'] += l['name']
                else:
                    line2[tmp] = l
            line = []
            for key, val in line2.items():
                line.append((0, 0, val))
        return line

    def unlink(self, cr, uid, ids, context=None):
        context = context or self.pool['res.users'].context_get(cr, uid)
        if not isinstance(ids, (list, tuple)):
            ids = [ids]

        # account_invoice_line_obj = self.pool['account.invoice.line']
        stock_picking_obj = self.pool['stock.picking']
        origins = {}
        for invoice in self.browse(cr, uid, ids, context):
            for line in invoice.invoice_line:
                if line.origin_document and line.origin_document._name == 'sale.order.line':
                    # the invoice line is create directly form sale order.line
                    if self.pool['account.invoice.line'].unlink(cr, uid, line.id, context):
                        continue

                line_origin = line.origin or False
                if line_origin not in origins:
                    origins[line_origin] = invoice.id

            if invoice.origin:
                for invoice_origin in invoice.origin.split(', '):
                    if invoice_origin not in origins:
                        origins[invoice_origin] = invoice.id

        # now on origins i have all the origin and invoice.id
        for origin in origins:
            if origin:
                # OUTxxx:SOyy
                if len(origin.split(':')) == 2:
                    pickings_name = origin.split(':')[0]
                else:
                    pickings_name = origin
                picking_id = stock_picking_obj.search(cr, uid, [('name', '=', pickings_name)], context=context)
                if super(account_invoice, self).unlink(cr, uid, [origins[origin]], context=context):
                    if picking_id:
                        stock_picking_obj.write(cr, uid, [picking_id[0]], {'invoice_state': '2binvoiced'}, context=context)
                # now i need to eliminate other ids
                if origins[origin] in ids:
                    del ids[ids.index(origins[origin])]

        return super(account_invoice, self).unlink(cr, uid, ids, context=context)
Пример #21
0
                    raise osv.except_osv(
                        _('Wrong Certificate file format'),
                        _('Be sure you have BEGIN CERTIFICATE string in'
                          ' your first line.'))
                else:
                    raise osv.except_osv(
                        _('Unknown error'),
                        _('X509 return this message:\n %s') % e[0])

            wz.wsafip_request_id.write({'state': 'confirmed'})

    _name = 'l10n_ar_wsafip.loadcert_config'
    _inherit = 'res.config'
    _columns = {
        'wsafip_request_id': fields.many2one(
            'crypto.certificate', 'Certificate Request', required=True),
        'wsafip_request_file': fields.binary(
            'Download Signed Certificate Request', readonly=True),
        'wsafip_request_filename': fields.char(
            'Filename', readonly=True),
        'wsafip_response_file': fields.binary(
            'Upload Certificate', required=True),
    }
    _defaults = {
        'wsafip_request_filename': 'request.csr',
    }
l10n_ar_wsafip_loadcert_config()


# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
Пример #22
0
class AccountReportBudgetWizard(osv.osv_memory):

    _inherit = "account.report.budget"

    _columns = {
        'summary':
        fields.boolean('Summary'),
        'closure':
        fields.char('Closure', ),
        'unit_type':
        fields.selection([('ministry', 'ministry'), ('locality', 'locality'),
                          ('other', 'other')], "Type"),
    }

    def _get_analytic_account(self, cr, uid, context=None):
        """
        Method to return the root analytic account in logged in user     
        @return: int root analytic account id or False
        """
        analytic_obj = self.pool.get('account.analytic.account')
        company = self.pool.get('res.users').browse(
            cr, uid, uid, context=context).company_id.id
        analytic_account = self.pool.get('account.analytic.account').search(
            cr,
            uid, [('parent_id', '=', False), ('company_id', '=', company)],
            context=context,
            limit=1)
        #Use this code for none Accounting user
        if not self.pool.get('res.users').has_group(
                cr, uid, 'account.group_account_user'):
            analytic_account = self.pool.get(
                'account.analytic.account').search(cr,
                                                   uid,
                                                   [('type', '=', 'normal')],
                                                   context=context)
            temp_analytic = []
            cr.execute(
                "SELECT gid as group_id FROM res_groups_users_rel WHERE uid='%s'"
                % (str(uid), ))
            #group_ids = list(cr.fetchall())
            user_group_ids = [x for x, in cr.fetchall()]
            for analytic in analytic_obj.browse(cr,
                                                uid,
                                                analytic_account,
                                                context=context):
                if set([group.id for group in analytic.group_ids
                        ]) & set(user_group_ids):
                    temp_analytic.append(analytic.id)
            analytic_account = temp_analytic
        return analytic_account and analytic_account[0] or False

    _defaults = {
        'summary': 0,
        'report_type': '1',
        'date_from': time.strftime('%Y-01-01'),
        'date_to': time.strftime('%Y-%m-%d'),
        'chart_analytic_account_id': _get_analytic_account,
    }

    def onchange_fiscalyear_id(self,
                               cr,
                               uid,
                               ids,
                               fiscalyear_id=False,
                               context=None):
        """
        Inherit method to update date_from, date_to values

        @param fiscalyear_id: fiscalyear_id
        @return: dictionary of values 
        """
        fiscalyear = self.pool.get('account.fiscalyear').browse(
            cr, uid, fiscalyear_id, context=context)
        analytic_obj = self.pool.get('account.analytic.account')
        analytic_domain = [('type', 'in', ('normal', 'view'))]
        #Use this code for none Accounting user
        if not self.pool.get('res.users').has_group(
                cr, uid, 'account.group_account_user'):
            analytic_account = self.pool.get(
                'account.analytic.account').search(cr,
                                                   uid, [('type', '=',
                                                          ('normal', 'view'))],
                                                   context=context)
            temp_analytic = []
            cr.execute(
                "SELECT gid as group_id FROM res_groups_users_rel WHERE uid='%s'"
                % (str(uid), ))
            #group_ids = list(cr.fetchall())
            user_group_ids = [x for x, in cr.fetchall()]
            for analytic in analytic_obj.browse(cr,
                                                uid,
                                                analytic_account,
                                                context=context):
                if set([group.id for group in analytic.group_ids
                        ]) & set(user_group_ids):
                    temp_analytic.append(analytic.id)
            analytic_domain = [('id', 'in', temp_analytic)]

        res = {'domain': {'chart_analytic_account_id': analytic_domain}}
        if fiscalyear_id:
            res.update({
                'value': {
                    'date_from': fiscalyear.date_start,
                    'date_to': fiscalyear.date_stop,
                }
            })
        return res

    def print_report(self, cr, uid, ids, context=None):
        """
        Method to send wizards fields value to the report
        @return: dictionary call the report service 
        """

        res = super(AccountReportBudgetWizard,
                    self).print_report(cr, uid, ids, context)

        #Mudathir : Get analytic_account From Wizard to set it in report
        res['datas']['form'].update({
            'chart_analytic_account_report':
            self.read(cr, uid, ids, [],
                      context)[0]['chart_analytic_account_id'][1]
        })

        summary = res['datas']['form']['summary']
        if summary and res['datas']['form']['type_selection'] == 'detail':
            res['report_name'] = 'account.budget.summary'
        if summary and res['datas']['form']['type_selection'] == 'consol':
            res['report_name'] = 'account.budget.consol'
        if summary and res['datas']['form']['type_selection'] == 'dept':
            res['report_name'] = 'account.budget.dep'
        if summary and res['datas']['form']['type_selection'] == 'unit':
            res['report_name'] = 'account.budget.unit'
        return res
        '''
Пример #23
0
                user_id = res[0]
        elif conf["create_user"]:
            _logger.debug('Creating new OpenERP user "%s" from LDAP' % login)
            user_obj = self.pool.get("res.users")
            values = self.map_ldap_attributes(cr, uid, conf, login, ldap_entry)
            if conf["user"]:
                user_id = user_obj.copy(cr, SUPERUSER_ID, conf["user"], default={"active": True})
                user_obj.write(cr, SUPERUSER_ID, user_id, values)
            else:
                user_id = user_obj.create(cr, SUPERUSER_ID, values)
        return user_id

    _columns = {
        "sequence": fields.integer("Sequence"),
        "company": fields.many2one("res.company", "Company", required=True, ondelete="cascade"),
        "ldap_server": fields.char("LDAP Server address", size=64, required=True),
        "ldap_server_port": fields.integer("LDAP Server port", required=True),
        "ldap_binddn": fields.char(
            "LDAP binddn",
            size=64,
            help=(
                "The user account on the LDAP server that is used to query "
                "the directory. Leave empty to connect anonymously."
            ),
        ),
        "ldap_password": fields.char(
            "LDAP password",
            size=64,
            help=("The password of the user account on the LDAP server that is " "used to query the directory."),
        ),
        "ldap_filter": fields.char("LDAP filter", size=256, required=True),
Пример #24
0
class crm_segmentation_line(osv.osv):
    """ Segmentation line """
    _name = "crm.segmentation.line"
    _description = "Segmentation line"

    _columns = {
        'name': fields.char('Rule Name', size=64, required=True),
        'segmentation_id': fields.many2one('crm.segmentation', 'Segmentation'),
        'expr_name': fields.selection([('sale','Sale Amount'),
                        ('purchase','Purchase Amount')], 'Control Variable', size=64, required=True),
        'expr_operator': fields.selection([('<','<'),('=','='),('>','>')], 'Operator', required=True),
        'expr_value': fields.float('Value', required=True),
        'operator': fields.selection([('and','Mandatory Expression'),\
                        ('or','Optional Expression')],'Mandatory / Optional', required=True),
    }
    _defaults = {
        'expr_name': lambda *a: 'sale',
        'expr_operator': lambda *a: '>',
        'operator': lambda *a: 'and'
    }

    def test(self, cr, uid, ids, partner_id):
        """ @param self: The object pointer
            @param cr: the current row, from the database cursor,
            @param uid: the current user’s ID for security checks,
            @param ids: List of Test’s IDs """

        expression = {
            '<': lambda x, y: x < y,
            '=': lambda x, y: x == y,
            '>': lambda x, y: x > y
        }
        ok = False
        lst = self.read(cr, uid, ids)
        for l in lst:
            cr.execute(
                'select * from ir_module_module where name=%s and state=%s',
                ('account', 'installed'))
            if cr.fetchone():
                if l['expr_name'] == 'sale':
                    cr.execute('SELECT SUM(l.price_unit * l.quantity) ' \
                            'FROM account_invoice_line l, account_invoice i ' \
                            'WHERE (l.invoice_id = i.id) ' \
                                'AND i.partner_id = %s '\
                                'AND i.type = \'out_invoice\'',
                            (partner_id,))
                    value = cr.fetchone()[0] or 0.0
                    cr.execute('SELECT SUM(l.price_unit * l.quantity) ' \
                            'FROM account_invoice_line l, account_invoice i ' \
                            'WHERE (l.invoice_id = i.id) ' \
                                'AND i.partner_id = %s '\
                                'AND i.type = \'out_refund\'',
                            (partner_id,))
                    value -= cr.fetchone()[0] or 0.0
                elif l['expr_name'] == 'purchase':
                    cr.execute('SELECT SUM(l.price_unit * l.quantity) ' \
                            'FROM account_invoice_line l, account_invoice i ' \
                            'WHERE (l.invoice_id = i.id) ' \
                                'AND i.partner_id = %s '\
                                'AND i.type = \'in_invoice\'',
                            (partner_id,))
                    value = cr.fetchone()[0] or 0.0
                    cr.execute('SELECT SUM(l.price_unit * l.quantity) ' \
                            'FROM account_invoice_line l, account_invoice i ' \
                            'WHERE (l.invoice_id = i.id) ' \
                                'AND i.partner_id = %s '\
                                'AND i.type = \'in_refund\'',
                            (partner_id,))
                    value -= cr.fetchone()[0] or 0.0
                res = expression[l['expr_operator']](value, l['expr_value'])
                if (not res) and (l['operator'] == 'and'):
                    return False
                if res:
                    return True
        return True
    def _default_location(self, cr, uid, ids, context=None):
        try:
            loc_model, location_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_stock')
        except ValueError, e:
            return False
        return location_id or False

    _columns = {
        'location_id': fields.many2one('stock.location', 'Location', required=True),
        'import_file': fields.binary('File', filters="*.xls"),
        #to consider the product current inventory or not, if yes then add the current inventory to the upload excel quantity as the quantity to do physical inventory
        'consider_inventory': fields.boolean('Consider Current Inventory', select=True), 
        'all_done': fields.boolean('All Data Imported', readonly=True, select=True), 
        'result_line': fields.one2many('stock.import.inventory.result', 'import_id', 'Importing Result', readonly=True), 
        'file_template': fields.binary('Template File', readonly=True),
        'file_template_name': fields.char('Template File Name'),
    }
    
    def _get_template(self, cr, uid, context):
        cur_path = os.path.split(os.path.realpath(__file__))[0]
        path = os.path.join(cur_path,'stock_import_template.xls')
        data = open(path,'rb').read().encode('base64')
#        data = os.path.getsize(path)
        return data
    
    _defaults = {
        'location_id': _default_location,
        'file_template': _get_template,
        'file_template_name': 'stock_import_template.xls'
    }
Пример #26
0
class crm_segmentation(osv.osv):
    '''
        A segmentation is a tool to automatically assign categories on partners.
        These assignations are based on criterions.
    '''
    _name = "crm.segmentation"
    _description = "Partner Segmentation"

    _columns = {
        'name': fields.char('Name', size=64, required=True, help='The name of the segmentation.'),
        'description': fields.text('Description'),
        'categ_id': fields.many2one('res.partner.category', 'Partner Category',\
                         required=True, help='The partner category that will be \
added to partners that match the segmentation criterions after computation.'                                                                            ),
        'exclusif': fields.boolean('Exclusive', help='Check if the category is limited to partners that match the segmentation criterions.\
                        \nIf checked, remove the category from partners that doesn\'t match segmentation criterions'                                                                                                                    ),
        'state': fields.selection([('not running','Not Running'),\
                    ('running','Running')], 'Execution Status', readonly=True),
        'partner_id': fields.integer('Max Partner ID processed'),
        'segmentation_line': fields.one2many('crm.segmentation.line', \
                            'segmentation_id', 'Criteria', required=True),
        'sales_purchase_active': fields.boolean('Use The Sales Purchase Rules', help='Check if you want to use this tab as part of the segmentation rule. If not checked, the criteria beneath will be ignored')
    }
    _defaults = {
        'partner_id': lambda *a: 0,
        'state': lambda *a: 'not running',
    }

    def process_continue(self, cr, uid, ids, start=False):
        """ @param self: The object pointer
            @param cr: the current row, from the database cursor,
            @param uid: the current user’s ID for security checks,
            @param ids: List of Process continue’s IDs"""

        partner_obj = self.pool.get('res.partner')
        categs = self.read(cr, uid, ids, ['categ_id', 'exclusif', 'partner_id',\
                                 'sales_purchase_active', 'profiling_active'])
        for categ in categs:
            if start:
                if categ['exclusif']:
                    cr.execute(
                        'delete from res_partner_res_partner_category_rel \
                            where category_id=%s', (categ['categ_id'][0], ))

            id = categ['id']

            cr.execute('select id from res_partner order by id ')
            partners = [x[0] for x in cr.fetchall()]

            if categ['sales_purchase_active']:
                to_remove_list = []
                cr.execute(
                    'select id from crm_segmentation_line where segmentation_id=%s',
                    (id, ))
                line_ids = [x[0] for x in cr.fetchall()]

                for pid in partners:
                    if (not self.pool.get('crm.segmentation.line').test(
                            cr, uid, line_ids, pid)):
                        to_remove_list.append(pid)
                for pid in to_remove_list:
                    partners.remove(pid)

            for partner in partner_obj.browse(cr, uid, partners):
                category_ids = [
                    categ_id.id for categ_id in partner.category_id
                ]
                if categ['categ_id'][0] not in category_ids:
                    cr.execute(
                        'insert into res_partner_res_partner_category_rel (category_id,partner_id) \
                            values (%s,%s)',
                        (categ['categ_id'][0], partner.id))

            self.write(cr, uid, [id], {
                'state': 'not running',
                'partner_id': 0
            })
        return True

    def process_stop(self, cr, uid, ids, *args):
        """ @param self: The object pointer
            @param cr: the current row, from the database cursor,
            @param uid: the current user’s ID for security checks,
            @param ids: List of Process stop’s IDs"""

        return self.write(cr, uid, ids, {
            'state': 'not running',
            'partner_id': 0
        })

    def process_start(self, cr, uid, ids, *args):
        """ @param self: The object pointer
            @param cr: the current row, from the database cursor,
            @param uid: the current user’s ID for security checks,
            @param ids: List of Process start’s IDs """

        self.write(cr, uid, ids, {'state': 'running', 'partner_id': 0})
        return self.process_continue(cr, uid, ids, start=True)
Пример #27
0
    def _get_extras(self, cr, uid, ids, *args, **kwargs):
        result = []
        if _aeroo_ooo_test(cr):
            result.append('aeroo_ooo')
        ##### Check deferred_processing module #####
        cr.execute("SELECT id, state FROM ir_module_module WHERE name='deferred_processing'")
        deferred_proc_module = cr.dictfetchone()
        if deferred_proc_module and deferred_proc_module['state'] in ('installed', 'to upgrade'):
            result.append('deferred_processing')
        ############################################
        return dict.fromkeys(ids, ','.join(result))

    _columns = {
        'charset':fields.selection(_get_encodings, string='Charset', required=True),
        'content_fname': fields.char('Override Extension',size=64, help='Here you can override output file extension'),
        'styles_mode': fields.selection([
            ('default','Not used'),
            ('global', 'Global'),
            ('specified', 'Specified'),
            ], string='Stylesheet'),
        'stylesheet_id':fields.many2one('report.stylesheets', 'Template Stylesheet'),
        'preload_mode':fields.selection([
            ('static',_('Static')),
            ('preload',_('Preload')),
        ],'Preload Mode'),
        'tml_source':fields.selection([
            ('database','Database'),
            ('file','File'),
            ('parser','Parser'),
        ],'Template source', select=True),
Пример #28
0
class sav(osv.osv):
    _inherit = 'crm.claim'

    def create(self, cr, user, vals, context=None):
        if ('n_reclamation' not in vals) or (vals.get('n_reclamation') == '/'):
            vals['n_reclamation'] = self.pool.get('ir.sequence').get(
                cr, user, 'crm.claim')
        return super(sav, self).create(cr, user, vals, context)

    _columns = {
        'n_reclamation':
        fields.char('N reclamation', required=True, readonly=True),
        'company_id1':
        fields.many2one('res.company', 'Societe Client'),
        'partner_id':
        fields.many2one('res.partner', u'Partner', required=True),
        'partner_id1':
        fields.many2one('res.partner',
                        u'Client',
                        required=True,
                        domain=[('customer', '=', True)]),
        'email_from1':
        fields.char('Email client',
                    size=128,
                    help="Destination email for email gateway."),
        'partner_phone1':
        fields.char('Phone client', size=32),
        'street01':
        fields.char('Address client', size=128),
        'city1':
        fields.char('Ville client', size=128),
        'company_id2':
        fields.many2one('res.company', 'Societe Distributeur'),
        'partner_id2':
        fields.many2one('res.partner',
                        'Distributeur',
                        domain=[('supplier', '=', True)]),
        'email_from2':
        fields.char('Email Distributeur',
                    size=128,
                    help="Destination email for email gateway."),
        'partner_phone2':
        fields.char('Phone Distributeur', size=32),
        'company_id3':
        fields.many2one('res.company', 'Societe Revendeur'),
        'partner_id3':
        fields.many2one('res.partner', 'Revendeur'),
        'email_from3':
        fields.char('Email Revendeur',
                    size=128,
                    help="Destination email for email gateway."),
        'partner_phone3':
        fields.char('Phone Revendeur', size=32),
        'produit':
        fields.many2one('product.product', 'Prouduit'),
        'Modele':
        fields.char('Model Produit', size=64),
        'date_achat':
        fields.datetime('Date Achat'),
        'Desc':
        fields.text('description pane '),
        'Marque':
        fields.many2one('product.marque',
                        u'Marque',
                        domain="[('partner_id2','=',partner_id2)]"),
        'Serial':
        fields.char('N de serie', size=64),
        'File_upload':
        fields.binary("Bonne d'achat"),
        'follow_ids':
        fields.one2many('claim.follow', 'follow', u'Suivi'),
        'product_ids':
        fields.many2many('product.product', 'product_equipment_rel',
                         'product_id', 'equipment_id', 'Piece of change'),
        'num_facture':
        fields.char(u'N facture'),
        'selection':
        fields.boolean(u'Selection'),
        'cde_piece':
        fields.boolean(u'Commande piece'),
        'administratif':
        fields.boolean(u'Administratif'),
        'reference':
        fields.char(u'Réference'),
        'klm':
        fields.integer(u'Kilometrage'),
    }

    _defaults = {
        'n_reclamation': lambda self, cr, uid, context: 'Num auto',
    }

    def onchange_partner_id1(self, cr, uid, ids, part, context={}):
        data = {}
        if part:
            data_sav_model = self.pool.get('res.partner').read(
                cr, uid, part, ['phone', 'street', 'city'])
            if data_sav_model:
                data['partner_phone1'] = data_sav_model['phone']
                data['street01'] = data_sav_model['street']
                data['city1'] = data_sav_model['city']
        return {'value': data}

    def onchange_partner_id2(self, cr, uid, ids, part, context={}):
        data = {}
        if part:
            data_sav_model = self.pool.get('res.partner').read(
                cr, uid, part, ['email', 'phone'])
            if data_sav_model:
                data['email_from2'] = data_sav_model['email']
                data['partner_phone2'] = data_sav_model['phone']
        return {'value': data}

    def onchange_partner3(self, cr, uid, ids, part, context={}):
        data = {}
        if part:
            data_sav_model = self.pool.get('res.partner').read(
                cr, uid, part, ['email', 'phone'])
            if data_sav_model:
                data['email_from3'] = data_sav_model['email']
                data['partner_phone3'] = data_sav_model['phone']
        return {'value': data}
                        move_line_obj.create(cr, uid, credit_values,
                                                         context)
                        asset_lines_obj.write(cr, uid, asset_line.get('id'),
                            {'move_check': True, 'move_id': created_id})
                        logging.getLogger(self._name).info("""account.move.line created for {0}""".format(asset_name))
                    except:
                        logging.getLogger('account.asset.asset').error(
                            """ERROR creating the entries of
                            account move from {0}.""".format(__name__))
                        raise orm.except_orm('Error', 'Failure creating the'
                            ' account move lines.')
                else:
                    logging.getLogger(self._name).info("Este activo ya esta asentado!")

    _columns = {
        'asset_code': fields.char('Codigo', size=32, required=False, readonly=False),
        'category_id': fields.many2one('account.asset.category', 'Asset Category', required=True,
                                       change_default=True, readonly=True, states={'draft':[('readonly',False)]},
                                       domain=[('type','=','normal')]),
        'category_parent_id': fields.many2one("account.asset.category", string="Categoria Padre del Activo",
                                              required=False, readonly=True, states={'draft':[('readonly',False)]},
                                              domain=[('type','=','view')] ),
        'account_analytic_id': fields.many2one("account.analytic.account", string="Cuenta analitica",
                                               required=True, domain=[('type','=','normal')]),
        'asset_move_ids': fields.one2many('account.asset.move', 'asset_id','Movimientos'),

        #'asset_move_ids': fields.one2many('account.asset.move', 'asset_id', 'Movements')
    }

    _defaults = {
        'asset_code': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'asset.number')
Пример #30
0
class ir_mail_server(osv.osv):
    """Represents an SMTP server, able to send outgoing emails, with SSL and TLS capabilities."""
    _name = "ir.mail_server"

    NO_VALID_RECIPIENT = ("At least one valid recipient address should be "
                          "specified for outgoing emails (To/Cc/Bcc)")

    _columns = {
        'name':
        fields.char('Description', required=True, select=True),
        'smtp_host':
        fields.char('SMTP Server',
                    required=True,
                    help="Hostname or IP of SMTP server"),
        'smtp_port':
        fields.integer(
            'SMTP Port',
            size=5,
            required=True,
            help=
            "SMTP Port. Usually 465 for SSL, and 25 or 587 for other cases."),
        'smtp_user':
        fields.char('Username',
                    size=64,
                    help="Optional username for SMTP authentication"),
        'smtp_pass':
        fields.char('Password',
                    size=64,
                    help="Optional password for SMTP authentication"),
        'smtp_encryption':
        fields.selection(
            [('none', 'None'), ('starttls', 'TLS (STARTTLS)'),
             ('ssl', 'SSL/TLS')],
            string='Connection Security',
            required=True,
            help="Choose the connection encryption scheme:\n"
            "- None: SMTP sessions are done in cleartext.\n"
            "- TLS (STARTTLS): TLS encryption is requested at start of SMTP session (Recommended)\n"
            "- SSL/TLS: SMTP sessions are encrypted with SSL/TLS through a dedicated port (default: 465)"
        ),
        'smtp_debug':
        fields.boolean(
            'Debugging',
            help="If enabled, the full output of SMTP sessions will "
            "be written to the server log at DEBUG level"
            "(this is very verbose and may include confidential info!)"),
        'sequence':
        fields.integer(
            'Priority',
            help=
            "When no specific mail server is requested for a mail, the highest priority one "
            "is used. Default priority is 10 (smaller number = higher priority)"
        ),
        'active':
        fields.boolean('Active')
    }

    _defaults = {
        'smtp_port': 25,
        'active': True,
        'sequence': 10,
        'smtp_encryption': 'none',
    }

    def __init__(self, *args, **kwargs):
        # Make sure we pipe the smtplib outputs to our own DEBUG logger
        if not isinstance(smtplib.stderr, WriteToLogger):
            logpiper = WriteToLogger(_logger)
            smtplib.stderr = logpiper
            smtplib.stdout = logpiper
        super(ir_mail_server, self).__init__(*args, **kwargs)

    def name_get(self, cr, uid, ids, context=None):
        return [(a["id"], "(%s)" % (a['name']))
                for a in self.read(cr, uid, ids, ['name'], context=context)]

    def test_smtp_connection(self, cr, uid, ids, context=None):
        for smtp_server in self.browse(cr, uid, ids, context=context):
            smtp = False
            try:
                smtp = self.connect(smtp_server.smtp_host,
                                    smtp_server.smtp_port,
                                    user=smtp_server.smtp_user,
                                    password=smtp_server.smtp_pass,
                                    encryption=smtp_server.smtp_encryption,
                                    smtp_debug=smtp_server.smtp_debug)
            except Exception, e:
                raise osv.except_osv(
                    _("Connection Test Failed!"),
                    _("Here is what we got instead:\n %s") % tools.ustr(e))
            finally:
Пример #31
0
    def _save_file(self, path, b64_file):
        """Save a file encoded in base 64"""
        self._check_filestore(path)
        with open(path, 'w') as ofile:
            ofile.write(base64.b64decode(b64_file))
        return True

    def _set_image(self, cr, uid, id, name, value, arg, context=None):
        image = self.browse(cr, uid, id, context=context)
        full_path = self._image_path(cr, uid, image, context=context)
        if full_path:
            return self._save_file(full_path, value)
        return self.write(cr, uid, id, {'file_db_store': value}, context=context)

    _columns = {
        'name': fields.char('Image Title', required=True),
        'extension': fields.char('file extension', oldname='extention'),
        'link': fields.boolean('Link?',
                               help="Images can be linked from files on "
                                    "your file system or remote (Preferred)"),
        'file_db_store': fields.binary('Image stored in database'),
        'file': fields.function(_get_image,
                                fnct_inv=_set_image,
                                type="binary",
                                string="File",
                                filters='*.png,*.jpg,*.gif'),
        'url': fields.char('File Location'),
        'comments': fields.text('Comments'),
        'product_id': fields.many2one('product.product', 'Product')
        }
Пример #32
0
                    res[user1.id] =  user1.host_name.lower() + '.'+ user1.server.server_addres +':' + user1.server.rpc_port
                else :
                    res[user1.id] = user1.server.server_addres +':' + user1.server.rpc_port+'/web?db='+ user1.host_name.lower()
        return res

    def get_counter(self,cr,uid,context=None):
        myids = self.search(cr, uid, [], context=context)
        for user in self.browse(cr,uid,myids,context=context):
            res = user.counter +1;
            isTrue =   self.write(cr, uid, user.id, {'counter': res}, context=context)
        return isTrue

    _name = "saas.user.info"
    _description = "saas.user.info"
    _columns = {
        'name': fields.char('Note', required=False,track_visibility='always', help=""),
        'user': fields.many2one('res.partner', 'partner', help=""),
        'host_name': fields.char('host_name',required=True, help=""),
        'host_type': fields.char('host_type',required=False , help=""),
        'server': fields.many2one('saas.server', 'server',required=True, help=""),
        'url_addres': fields.function(_get_full_url, type='char',string='url_addres'),
        'start_date': fields.datetime('start_date',required=False, help=""),
        'end_date': fields.function(_compute_exp_date, type = 'datetime',string='end_date'),
        'product_id':fields.many2one('product.product','product_id',required = False,help=''),
        'state': fields.function(_get_server_state, type='char', string='state'),
        'counter': fields.integer('counter',required=False , help=""),
    }
    _defaults = {
        'start_date': fields.datetime.now,
    }
    _sql_constraints = [
Пример #33
0
#             return {'value':{'cc_charge':False, 'cc_p_authorize':True } }
#         return {'value':{'cc_charge':True, 'cc_p_authorize':False } }
# 
#     def onchange_cc_charge(self, cr, uid, ids, cc_charge, context={}):
#         if cc_charge:
#             return {'value':{'cc_charge':True, 'cc_p_authorize':False } }            
#         return {'value':{'cc_charge':False, 'cc_p_authorize':True } }

    def onchange_amount(self, cr, uid, ids, amount, rate, partner_id, journal_id, currency_id, ttype, date, payment_rate_currency_id, company_id, context=None):
        res = super(account_voucher, self).onchange_amount(cr, uid, ids, amount, rate, partner_id, journal_id, currency_id, ttype, date, payment_rate_currency_id, company_id, context=context)
        res['value'].update({'cc_order_amt':amount, 'cc_refund_amt':amount}) 
        return res

    _inherit = 'account.voucher'
    _columns = {
        'cc_name':fields.char("Card Holder's Name", size=32,),
        'cc_b_addr_1':fields.char('Billing Address1', size=32,),
        'cc_b_addr_2':fields.char('Billing Address2', size=32,),
        'cc_city': fields.char('City', size=32,),
        'cc_state':fields.char('State', size=32,),
        'cc_zip':fields.char('Postal/Zip', size=32,),
        'cc_country':fields.char('Country', size=32,),
        'cc_order_date':fields.date('Order Date',),
<<<<<<< HEAD
        'cc_order_amt':fields.float('Order Amt'),
=======
        'cc_order_amt':fields.float('Order Amt',required=True),
>>>>>>> c1979f64b3360c86d60e00c92be0271d89f97f2d
        'cc_number':fields.char('Credit Card Number', size=256),
        'cc_v':fields.char('Card Code Verification', size=3),
        'cc_e_d_month':fields.char('Expiration Date MM', size=32),
Пример #34
0
        if new_passphrase == old_passphrase:
            raise osv.except_osv(_('Error'), _('Old passphrase and new passphrase cannot be same'))

        ### Use Endicia API
        try:
            request = endicia.ChangePasswordRequest(ship_endicia.requester_id, ship_endicia.account_id, old_passphrase, new_passphrase, ship_endicia.test)
            response = request.send()
            change_passphrase_resp = response._get_value()            
        except Exception, e:
            raise osv.except_osv(_('Error'), _('Error changing passphrase'))

        if change_passphrase_resp['status'] != '0':
            raise osv.except_osv(_('Error'), _('Error changing passphrase'))

        res = ship_endicia_obj.write_passphrase(cr,uid,new_passphrase)
        if res:
            message = _('Passphrase Changed successfully')
            self.log(cr, uid, ids[0], message)
        else:
            message = _('Error changing passphrase')
            self.log(cr, uid, ids[0], message)

        return {'type': 'ir.actions.act_window_close'}


    _columns = {
        'name': fields.char('New Passphrase', size=100, required=True),
    }
change_passphrase()
Пример #35
0
class account_analytic_account_summary_month(osv.osv):
    _name = "account_analytic_analysis.summary.month"
    _description = "Hours summary by month"
    _auto = False
    _rec_name = 'month'

    _columns = {
        'account_id':
        fields.many2one('account.analytic.account',
                        'Analytic Account',
                        readonly=True),
        'unit_amount':
        fields.float('Total Time'),
        'month':
        fields.char('Month', size=32, readonly=True),
    }

    def init(self, cr):
        openerp.tools.sql.drop_view_if_exists(
            cr, 'account_analytic_analysis_summary_month')
        cr.execute('CREATE VIEW account_analytic_analysis_summary_month AS (' \
                'SELECT ' \
                    '(TO_NUMBER(TO_CHAR(d.month, \'YYYYMM\'), \'999999\') + (d.account_id  * 1000000::bigint))::bigint AS id, ' \
                    'd.account_id AS account_id, ' \
                    'TO_CHAR(d.month, \'Mon YYYY\') AS month, ' \
                    'TO_NUMBER(TO_CHAR(d.month, \'YYYYMM\'), \'999999\') AS month_id, ' \
                    'COALESCE(SUM(l.unit_amount), 0.0) AS unit_amount ' \
                'FROM ' \
                    '(SELECT ' \
                        'd2.account_id, ' \
                        'd2.month ' \
                    'FROM ' \
                        '(SELECT ' \
                            'a.id AS account_id, ' \
                            'l.month AS month ' \
                        'FROM ' \
                            '(SELECT ' \
                                'DATE_TRUNC(\'month\', l.date) AS month ' \
                            'FROM account_analytic_line AS l, ' \
                                'account_analytic_journal AS j ' \
                            'WHERE j.type = \'general\' ' \
                            'GROUP BY DATE_TRUNC(\'month\', l.date) ' \
                            ') AS l, ' \
                            'account_analytic_account AS a ' \
                        'GROUP BY l.month, a.id ' \
                        ') AS d2 ' \
                    'GROUP BY d2.account_id, d2.month ' \
                    ') AS d ' \
                'LEFT JOIN ' \
                    '(SELECT ' \
                        'l.account_id AS account_id, ' \
                        'DATE_TRUNC(\'month\', l.date) AS month, ' \
                        'SUM(l.unit_amount) AS unit_amount ' \
                    'FROM account_analytic_line AS l, ' \
                        'account_analytic_journal AS j ' \
                    'WHERE (j.type = \'general\') and (j.id=l.journal_id) ' \
                    'GROUP BY l.account_id, DATE_TRUNC(\'month\', l.date) ' \
                    ') AS l '
                    'ON (' \
                        'd.account_id = l.account_id ' \
                        'AND d.month = l.month' \
                    ') ' \
                'GROUP BY d.month, d.account_id ' \
                ')')
Пример #36
0
class loewieec_shop(osv.osv):
    _name = 'loewieec.shop'
    _description = u"电商店铺"

    _columns = {
        'tmall_time':
        fields.datetime(string='TMall Time'),
        'name':
        fields.char(u'店铺名称', size=16, required=True),
        'code':
        fields.char(u'店铺前缀',
                    size=8,
                    required=True,
                    help=u"系统会自动给该店铺的订单编号.客户昵称加上此前缀.通常同一个平台的店铺前缀设置成一样"),
        'platform':
        fields.selection([
            ('tb', u'淘宝天猫'),
            ('sb', u'淘宝沙箱'),
        ],
                         string=u'电商平台',
                         required=True,
                         help=u"淘宝、京东等电商平台"),
        #'categ_id': fields.many2one('product.category', string=u"商品默认分类", required=True),
        'location_id':
        fields.many2one('stock.location', string=u"店铺库位", required=True),
        'journal_id':
        fields.many2one('account.journal', string=u"默认销售账簿", required=True),
        'post_product_id':
        fields.many2one('product.product', string=u"邮费"),
        #'coupon_product_id': fields.many2one('product.product', string=u"优惠减款", required=True),
        'gift_product_id':
        fields.many2one(
            'product.product',
            string=u"赠品",
        ),
        'partner_id':
        fields.many2one('res.partner', string='Partner'),
        'pricelist_id':
        fields.many2one('product.pricelist', string='Price List'),
        'warehouse_id':
        fields.many2one('stock.warehouse', string='Warehouse'),
        'appkey':
        fields.char(u'App Key', ),
        'appsecret':
        fields.char(u'App Secret', ),
        'sessionkey':
        fields.char(u'Session Key', ),
        'apiurl':
        fields.char(u'API URL', ),
        'authurl':
        fields.char(u'Auth URL', ),
        'tokenurl':
        fields.char(u'Token URL', ),
        'products':
        fields.one2many('product.tmalljd', 'ec_shop_id', string="Products"),
        'orders':
        fields.one2many('sale.order', 'shop_id', string="Orders"),
        'start_modified':
        fields.datetime(string='Start Modified'),
        'end_modified':
        fields.datetime(string='End Modified'),
    }

    def get_full_path(self, cr, uid, path):
        # sanitize ath
        path = re.sub('[.]', '', path)
        path = path.strip('/\\')
        return os.path.join(tools.config.filestore(cr.dbname), path)

    def create_order_from_excel(self, cr, uid, ids, trade, context=None):
        order_obj = self.pool.get('sale.order')
        shop = self.browse(cr, uid, ids[0], context=context)
        partner_id = shop.partner_id.id
        #{"no":order_no, "coe":coe, "name":name, "tel":tel, "address":address, "city":city, "state":state, "zip":zip, "products":[line]}
        shipping_id = self.create_shipping_address(
            cr,
            uid,
            partner_id, {
                'name': trade["name"],
                'phone': trade["tel"],
                'street': trade["address"],
                'city': trade["city"],
                'state': trade["state"],
                'zip': trade["zip"]
            },
            context=context)
        note = u"COE:%s, 姓名:%s, 电话:%s, 省份:%s, 城市%s, 收货地址:%s, 邮编:%s." % (
            trade["coe"], trade["name"], trade["tel"], trade["state"],
            trade["city"], trade["address"], trade["zip"])
        order_val = {
            'name': "%s_%s" % (shop.code, trade.get('no')),
            'shop_id': shop.id,
            'date_order': datetime.now(),  #订单支付时间
            #'create_date': datetime.now(),       #订单创建时间
            'partner_id': partner_id,
            'partner_invoice_id': partner_id,
            'partner_shipping_id': shipping_id,
            'warehouse_id': shop.warehouse_id.id,
            'pricelist_id': shop.pricelist_id.id,
            'company_id': 1,
            'all_discounts': 0,
            'picking_policy': 'one',
            'state': 'draft',
            'user_id': uid,
            'order_policy': 'picking',
            'client_order_ref': "COE: %s" % trade["coe"],
            'order_line': [],
            'note': note,
        }

        post_vals = {
            'product_uos_qty': 1,
            'product_id': 1,
            'product_uom': 1,
            'price_unit': 1,
            'product_uom_qty': 1,
            'name': '.',
            'delay': 7,
            'discount': 0,
        }

        products = trade.get('products', [])
        for o in products:
            line_vals = {
                'product_uos_qty': o.get('qty', 0),
                'product_id': 1,
                'product_uom': 1,
                'price_unit': o.get('price', 0),
                'product_uom_qty': o.get('qty', 0),
                'name': '.',
                'delay': 7,
                'discount': 0,
            }

            product_name = o.get('product', "").strip()
            product_ids = self.pool.get('product.product').search(
                cr,
                uid, [('name_template', '=', product_name)],
                context=context)
            if not product_ids:
                name = self.string_refactor(product_name)
                product_ids = self.pool.get('product.product').search(
                    cr,
                    uid, [('name_template', 'like', name)],
                    context=context)
                if product_ids: line_vals.update({'name': u"产品名未能精确匹配"})

            #如果没有匹配到产品,报同步异常
            if not product_ids:
                raise osv.except_osv(
                    u'Excel产品名错误',
                    u'''无法再ERP中找到 - %s. \r\n请检查名字 并纠正如下情况:\r\n 1. 125 ml -> 125ml. \r\n 2. Eros - Eros Warming - 150ml  -> Eros - Warming - 150ml'''
                    % product_name)
                #syncerr = u"订单导入错误: 匹配不到商品。tid=%s, 商品【%s】, outer_iid=%s, num_iid=%s, outer_sku_id=%s, sku_id=%s " % ( trade.get('tid'), o.get('title', ''), o.get('outer_iid', ''), o.get('num_iid', ''),  o.get('outer_sku_id', ''), o.get('sku_id', '') )
                #self.pool.get('loewieec.error').create(cr, uid, {'name':syncerr, 'shop_id':shop.id }, context = context )
                return False

            #添加订单明细行
            line_vals.update({'product_id': product_ids[0]})
            order_val['order_line'].append((0, 0, line_vals))

        post_vals.update({
            'product_id': shop.gift_product_id.id,
            'price_unit': 0,
            'product_uos_qty': 1,
            'product_uom_qty': 1,
            'product_uom': 1
        })
        order_val['order_line'].append((0, 0, post_vals))
        order_id = order_obj.create(cr, uid, order_val, context=context)

        return order_id

    def string_refactor(self, name):

        if not name: return False

        name = name.replace("/", "%")
        name = name.replace("|", "%")
        ll = name.split("-")
        ll = [l.strip() for l in ll]

        return "%".join(ll)

    def import_orders_from_excel(self, cr, uid, ids, context=None):
        attachment_obj = self.pool.get('ir.attachment')
        attachment_id = attachment_obj.search(cr,
                                              uid, [('res_id', '=', ids[0])],
                                              context=context)
        if len(attachment_id) < 1: return False

        attach = attachment_obj.browse(cr,
                                       uid,
                                       attachment_id[0],
                                       context=context)
        fname = attach.store_fname
        display_name = attach.name
        if not fname: return False
        fname = self.get_full_path(cr, uid, fname)
        wb = load_workbook(filename=fname)
        #ws = wb.get_sheet_by_name("Sheet1")
        ws = wb.get_sheet_by_name(wb.get_sheet_names()[0])
        highest_row = ws.get_highest_row()
        highest_col = ws.get_highest_column()
        title_order = ws.cell(row=1, column=1).value
        title_product = ws.cell(row=1, column=2).value
        title_qty = ws.cell(row=1, column=3).value
        title_coe = ws.cell(row=1, column=5).value

        if highest_col < 12 or title_order != u"订单編號" or title_product != u"产品名称" or title_coe != u"COE":
            attach.unlink()
            raise osv.except_osv(u'Excel错误',
                                 u'''文件:%s 格式不正确.''' % display_name)

        row_start = 2
        orders = {}
        last_order_no = None
        while row_start <= highest_row and ws.cell(row=row_start,
                                                   column=2).value:
            line = {}
            col_start = 1

            line["product"] = ws.cell(row=row_start, column=2).value
            line["qty"] = ws.cell(row=row_start, column=3).value
            cell_price = ws.cell(row=row_start, column=4)
            line["price"] = cell_price.get_original_value()

            order_no = ws.cell(row=row_start, column=1).value
            if order_no:
                coe = ws.cell(row=row_start, column=5).value
                name = ws.cell(row=row_start, column=6).value
                tel = ws.cell(row=row_start, column=7).value
                address = ws.cell(row=row_start, column=8).value
                city = ws.cell(row=row_start, column=9).value
                state = ws.cell(row=row_start, column=10).value
                zip = str(ws.cell(row=row_start, column=11).value)
                last_order_no = order_no = str(order_no)

                orders[last_order_no] = {
                    "no": order_no,
                    "coe": coe,
                    "name": name,
                    "tel": tel,
                    "address": address,
                    "city": city,
                    "state": state,
                    "zip": zip,
                    "products": [line]
                }
            else:
                orders[last_order_no]["products"].append(line)

            row_start += 1

        order_ids = []
        for key in orders.keys():
            order_id = self.create_order_from_excel(cr,
                                                    uid,
                                                    ids,
                                                    orders[key],
                                                    context=context)
            order_ids.append(order_id)
        attach.unlink()
        return order_ids

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

        port = 80
        shop = self.browse(cr, uid, ids[0], context=context)
        setDefaultAppInfo(shop.appkey, shop.appsecret)
        req = ProductsSearchRequest(shop.apiurl, port)
        req.fields = "name, sale_props, binds, product_id, outer_id, barcode_str"

        #resp= req.getResponse(shop.sessionkey)
        #skus = resp.get('items_inventory_get_response',False).get('items',False).get('item', False)
        req.page_no = 1
        req.page_size = 100
        req.q = "Fun Factory"
        total_get = 0
        total_results = 100
        res = []
        while total_get < total_results:
            resp = req.getResponse(shop.sessionkey)
            total_results = resp.get('products_search_response').get(
                'total_results')

            if total_results > 0:
                res += resp.get('products_search_response').get(
                    'products').get('product')
            total_get += req.page_size
            req.page_no = req.page_no + 1

        return res

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

        port = 80
        shop = self.browse(cr, uid, ids[0], context=context)
        setDefaultAppInfo(shop.appkey, shop.appsecret)
        req = ItemsInventoryGetRequest(shop.apiurl, port)
        req.fields = "skus, num_iid, title, type, product_id, props_name, outer_id, barcode, sub_title, shop_type, price"

        #resp= req.getResponse(shop.sessionkey)
        #skus = resp.get('items_inventory_get_response',False).get('items',False).get('item', False)
        req.page_no = 1
        req.page_size = 100
        #req.is_ex = "true"
        req.is_taobao = "true"
        total_get = 0
        total_results = 100
        res = []
        while total_get < total_results:
            resp = req.getResponse(shop.sessionkey)
            total_results = resp.get('items_inventory_get_response').get(
                'total_results')

            if total_results > 0:
                res += resp.get('items_inventory_get_response').get(
                    'items').get('item')
            total_get += req.page_size
            req.page_no = req.page_no + 1

        return res

    def bad_sync_stock_qty(self, cr, uid, ids, context=None):
        """
         同步本条记录的库存数量到 电商店铺
        """
        port = 80
        shop = self.pool.get('loewieec.shop').browse(cr,
                                                     uid,
                                                     ids[0],
                                                     context=context)
        for product in shop.products:

            qty = product.erp_stock
            if qty < 1: continue

            setDefaultAppInfo(shop.appkey, shop.appsecret)
            req = SkusQuantityUpdateRequest(shop.apiurl, port)
            req.num_iid = long(product.ec_num_iid)

            req.skuid_quantities = "%s:%d" % (product.ec_sku_id, int(qty))
            req.type = 1

            resp = req.getResponse(shop.sessionkey)

        return True

    def _sync_stock_qty(self, cr, uid, ids, context=None):
        """
         同步本条记录的库存数量到 电商店铺
        """
        port = 80
        shop = self.pool.get('loewieec.shop').browse(cr,
                                                     uid,
                                                     ids[0],
                                                     context=context)
        for product in shop.products:

            qty = product.erp_stock
            if qty < 1: continue

            setDefaultAppInfo(shop.appkey, shop.appsecret)
            req = ItemQuantityUpdateRequest(shop.apiurl, port)
            req.num_iid = long(product.ec_num_iid)

            req.sku_id = product.ec_sku_id

            if qty < 0: qty = 0
            req.quantity = int(qty)
            req.type = 1

            resp = req.getResponse(shop.sessionkey)

        return True

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

        port = 80
        shop = self.browse(cr, uid, ids[0], context=context)
        setDefaultAppInfo(shop.appkey, shop.appsecret)
        req = ItemSkusGetRequest(shop.apiurl, port)
        req.fields = "sku_id, num_iid, properties, price, status, memo, properties_name, outer_id,quantity,barcode,change_prop,sku_spec_id,extra_id"

        if not num_iids:
            req.num_iids = shop.tokenurl
        else:
            req.num_iids = num_iids

        resp = req.getResponse(shop.sessionkey)
        skus = resp.get('item_skus_get_response').get('skus',
                                                      False).get('sku', False)

        return skus

    def search_product(self, cr, uid, ids, context=None):
        this = self.browse(cr, uid, ids, context=context)[0]
        res = self._search_product(cr,
                                   uid,
                                   ids,
                                   product_name=None,
                                   start_modified=this.start_modified,
                                   end_modified=this.end_modified,
                                   context=context)

        if len(res) < 1: return
        product_tmalljd_objs = self.pool.get('product.tmalljd')
        num_iids = [str(o['num_iid']) for o in res]
        titles = {}
        for item in res:
            titles[item.get('num_iid')] = item.get('title')

        skus_list = []
        interval = 39
        start = end = 0
        final_end = len(num_iids) - 1

        while start <= final_end:
            if start + interval > final_end: end = final_end
            else: end = start + interval
            sub_num_iids = ",".join(num_iids[start:end])
            skus_list += self.search_product_sku(cr,
                                                 uid,
                                                 ids,
                                                 num_iids=sub_num_iids,
                                                 context=context)
            start = end + 1

        for sku in skus_list:

            product_vals = {
                'ec_shop_id': this.id,
                'ec_price': float(sku['price']),
                'ec_qty': sku['quantity'],
                'ec_outer_code': sku['outer_id'],
                'ec_sku_id': str(sku['sku_id']),
                'ec_ean13': sku['barcode']
            }
            num_iid = sku['num_iid']
            product_vals['ec_num_iid'] = str(num_iid)
            product_vals['ec_title'] = titles[num_iid]
            pids = product_tmalljd_objs.search(
                cr,
                uid, [('ec_sku_id', '=', str(sku['sku_id'])),
                      ('ec_shop_id', '=', this.id)],
                context=context)
            if len(pids) > 0:
                product_tmalljd_objs.write(cr, uid, pids[0], product_vals)
            else:
                product_tmalljd_objs.create(cr, uid, product_vals)

        return True

    def _search_product(self,
                        cr,
                        uid,
                        ids,
                        product_name=None,
                        start_modified=None,
                        end_modified=None,
                        context=None):
        """
        1) 按商品名称,商品修改时间搜索店铺商品
        2) start_modified、end_modified 都是UTC时间,需要加上8小时传给电商平台
        """
        shop_id = self.browse(cr, uid, ids[0], context=context)
        setDefaultAppInfo(shop_id.appkey, shop_id.appsecret)
        req = ItemsOnsaleGetRequest(shop_id.apiurl, 80)
        #req.fields="approve_status,num_iid,title,nick,outer_id,modified,num,type,price"
        req.fields = "approve_status,num_iid,title,nick,type,num,list_time,price,modified,delist_time,outer_id"
        if product_name:
            req.q = product_name
        #if start_modified:
        #    start_modified = (datetime.strptime(str(start_modified),'%Y-%m-%d %H:%M:%S',) + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
        #    req.start_modified = start_modified
        #if end_modified:
        #    end_modified = (datetime.strptime(str(end_modified),'%Y-%m-%d %H:%M:%S',) + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
        #    req.end_modified = end_modified

        req.page_no = 1
        req.page_size = 100
        total_get = 0
        total_results = 100
        res = []
        while total_get < total_results:
            resp = req.getResponse(shop_id.sessionkey)
            total_results = resp.get('items_onsale_get_response').get(
                'total_results')
            #_logger.info("Jimmy total_results :%d" % total_results)
            if total_results > 0:
                res += resp.get('items_onsale_get_response').get('items').get(
                    'item')
            total_get += req.page_size
            #_logger.info("Jimmy page_size :%d" % req.page_size)
            #_logger.info("Jimmy total_get :%d" % total_get)
            req.page_no = req.page_no + 1
        #
        # 时间需要减去8小时
        for r in res:
            r['modified'] = (datetime.strptime(
                r['modified'],
                '%Y-%m-%d %H:%M:%S',
            ) - timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
        return res

    def create_shipping_address(self, cr, uid, partner_id, vals, context=None):

        partner_objs = self.pool.get('res.partner')
        #state_objs = self.pool.get('res.country.state')
        state_id = 0
        if vals.get('state', False):
            state_id = self.pool.get('res.country.state').search(
                cr, uid, [('name', 'like', vals.get('state'))])

        if not partner_id: return 0
        partner_vals = {
            'parent_id': partner_id,
            'name': vals.get('name'),
            'phone': vals.get('phone'),
            'street': vals.get('street'),
            'mobile': vals.get('mobile'),
            'city': vals.get('city'),
            'zip': vals.get('zip'),
            'type': 'delivery',
            'is_company': False,
            'customer': False,
            'supplier': False,
        }

        if state_id:
            partner_vals.update({'state': state_id[0]})

        id = partner_objs.create(cr, uid, partner_vals, context=context)
        return id or 0

    def remove_duplicate_orders(self, cr, uid, orders, context=None):
        sale_obj = self.pool.get('sale.order')
        submitted_references = [o['sale_code'] for o in orders]
        existing_order_ids = sale_obj.search(
            cr, uid, [('name', 'in', submitted_references)], context=context)
        existing_orders = sale_obj.read(cr,
                                        uid,
                                        existing_order_ids, ['name'],
                                        context=context)
        existing_references = set([o['name'] for o in existing_orders])
        orders_to_save = [
            o for o in orders if o['sale_code'] not in existing_references
        ]
        return orders_to_save

    def search_orders_by_modified_time(self,
                                       cr,
                                       uid,
                                       ids,
                                       status='WAIT_SELLER_SEND_GOODS',
                                       date_start=None,
                                       date_end=None,
                                       context=None):
        port = 80
        shop = self.browse(cr, uid, ids[0], context=context)
        partner_id = shop.partner_id.id
        setDefaultAppInfo(shop.appkey, shop.appsecret)
        req = TradesSoldIncrementGetRequest(shop.apiurl, port)
        req.fields = "type,seller_nick,buyer_nick,created,sid,tid,status,buyer_memo,seller_memo,payment,discount_fee,adjust_fee,post_fee,total_fee, pay_time,end_time,modified,received_payment,price,alipay_id,receiver_name,receiver_state,receiver_city,receiver_district,receiver_address, receiver_zip,receiver_mobile,receiver_phone,orders.price,orders.num,orders.iid,orders.num_iid,orders.sku_id,orders.refund_status,orders.status,orders.oid, orders.total_fee,orders.payment,orders.discount_fee,orders.adjust_fee,orders.sku_properties_name,orders.outer_iid,orders.outer_sku_id"
        #req.status = status
        req.type = "instant_trade,auto_delivery,guarantee_trade,tmall_i18n"

        if shop.start_modified:
            #date_start = (datetime.strptime( shop.start_modified, '%Y-%m-%d %H:%M:%S',)  + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
            #req.start_modified = date_start
            req.start_modified = shop.start_modified
        if shop.end_modified:
            #date_end = (datetime.strptime(  shop.end_modified, '%Y-%m-%d %H:%M:%S',)  + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
            #req.end_modified = date_end
            req.end_modified = shop.end_modified

        res = []
        req.page_no = 1
        req.page_size = 100

        total_get = 0
        total_results = 100
        while total_get < total_results:
            resp = req.getResponse(shop.sessionkey)
            trades = resp.get('trades_sold_increment_get_response').get(
                'trades', False)
            total_results = resp.get('trades_sold_increment_get_response').get(
                'total_results')
            _logger.info("Jimmy total_results :%d" % total_results)
            if total_results > 0:
                res += trades.get('trade')
            total_get += req.page_size
            req.page_no = req.page_no + 1
            _logger.info("Jimmy page_size :%d" % req.page_size)
            _logger.info("Jimmy total_get :%d" % total_get)
        # 时间需要减去8小时
        # 单号加上店铺前缀
        order_ids = []
        for trade in res:
            trade['created'] = (datetime.strptime(
                trade['created'],
                '%Y-%m-%d %H:%M:%S',
            ) - timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
            trade['pay_time'] = (datetime.strptime(
                trade.get('pay_time'),
                '%Y-%m-%d %H:%M:%S',
            ) - timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
            trade['sale_code'] = '%s_%s' % (shop.code, trade.get('tid'))

        orders = self.remove_duplicate_orders(cr, uid, res, context=context)
        #orders = res
        for trade in orders:
            #try:
            #    #_logger.info("Jimmy before create_order")
            #order_id = self.create_order(cr, uid, ids, trade, context = context )
            order_id = self.create_order(cr, uid, ids, trade, context=context)
            #    _logger.info("Jimmy after create_order")
            #    order_ids.append(order_id)
            #except Exception, e:
            #    syncerr = u"店铺[%s]订单[%s]同步错误: %s" % (shop.name, trade['tid'], e)
            #    self.pool.get('loewieec.error').create(cr, uid, {'name':syncerr, 'shop_id': shop.id}, context = context )
            #    continue
        return order_ids

    def create_order(self, cr, uid, ids, trade, context=None):
        order_obj = self.pool.get('sale.order')
        shop = self.browse(cr, uid, ids[0], context=context)
        partner_id = shop.partner_id.id

        shipping_id = self.create_shipping_address(
            cr,
            uid,
            partner_id, {
                'name': trade.get('receiver_name'),
                'phone': trade.get('receiver_phone'),
                'street': address,
                'mobile': trade.get('receiver_mobile')
            },
            context=context)
        #_logger.info("Jimmy create_shipping_address : %d" % shipping_id )
        order_val = {
            'name': "%s_%s" % (shop.code, trade.get('tid')),
            'shop_id': shop.id,
            'date_order': trade.get('pay_time') or datetime.now(),  #订单支付时间
            'create_date': trade.get('created'),  #订单创建时间
            'partner_id': partner_id,
            'partner_invoice_id': partner_id,
            'partner_shipping_id': shipping_id,
            'warehouse_id': shop.warehouse_id.id,
            'pricelist_id': shop.pricelist_id.id,
            'company_id': 1,
            'all_discounts': 0,
            'picking_policy': 'one',
            'state': 'draft',
            'user_id': uid,
            'order_policy': 'picking',
            'client_order_ref': u'Loewieec_sync Generated',
            'order_line': [],
        }

        post_vals = {
            'product_uos_qty': 1,
            'product_id': 1,
            'product_uom': 1,
            'price_unit': 1,
            'product_uom_qty': 1,
            'name': '.',
            'delay': 7,
            'discount': 0,
        }

        orders = trade.get('orders', {}).get('order', [])
        for o in orders:
            line_vals = {
                'product_uos_qty': 1,
                'product_id': 1,
                'product_uom': 1,
                'price_unit': 1,
                'product_uom_qty': 1,
                'name': '.',
                'delay': 7,
                'discount': 0,
            }
            product_tmalljd_ids = self.pool.get('product.tmalljd').search(
                cr,
                uid, [('ec_sku_id', '=', o.get('sku_id'))],
                context=context)
            #_logger.info("Jimmy num_iid : %s" % o.get('num_iid') )
            #如果没有匹配到产品,报同步异常
            if not product_tmalljd_ids:
                syncerr = u"订单导入错误: 匹配不到商品。tid=%s, 商品【%s】, outer_iid=%s, num_iid=%s, outer_sku_id=%s, sku_id=%s " % (
                    trade.get('tid'), o.get('title', ''), o.get(
                        'outer_iid', ''), o.get('num_iid', ''),
                    o.get('outer_sku_id', ''), o.get('sku_id', ''))
                self.pool.get('loewieec.error').create(cr,
                                                       uid, {
                                                           'name': syncerr,
                                                           'shop_id': shop.id
                                                       },
                                                       context=context)
                return False

            product_tmalljd_obj = self.pool.get('product.tmalljd').browse(
                cr, uid, product_tmalljd_ids[0], context=context)
            product_id = product_tmalljd_obj.erp_product_id.id
            uom_id = product_tmalljd_obj.erp_product_id.uom_id.id
            #添加订单明细行
            price_unit = float(o.get('payment', 0)) / o.get('num') or float(
                o.get('total_fee', 0)) / o.get('num')
            line_vals.update({
                'product_id': product_id,
                'price_unit': price_unit,
                'product_uos_qty': o.get('num'),
                'product_uom_qty': o.get('num'),
                'product_uom': uom_id
            })
            order_val['order_line'].append((0, 0, line_vals))

        post_vals.update({
            'product_id': shop.gift_product_id.id,
            'price_unit': 0,
            'product_uos_qty': 1,
            'product_uom_qty': 1,
            'product_uom': 1
        })
        order_val['order_line'].append((0, 0, post_vals))
        order_id = order_obj.create(cr, uid, order_val, context=context)

        return order_id

    def get_tmall_time(self, cr, uid, ids, context=None):
        shop = self.browse(cr, uid, ids[0], context=context)
        setDefaultAppInfo(shop.appkey, shop.appsecret)
        req = TimeGetRequest(shop.apiurl, 80)
        resp = req.getResponse(shop.sessionkey)
        ttime = resp.get('time_get_response').get('time', False)

        if ttime:
            shop.tmall_time = ttime
        return True

    def search_orders_by_created_time(self,
                                      cr,
                                      uid,
                                      ids,
                                      status='WAIT_SELLER_SEND_GOODS',
                                      date_start=None,
                                      date_end=None,
                                      context=None):
        port = 80
        shop = self.browse(cr, uid, ids[0], context=context)
        partner_id = shop.partner_id.id
        setDefaultAppInfo(shop.appkey, shop.appsecret)
        req = TradesSoldGetRequest(shop.apiurl, port)
        req.fields = "type,seller_nick,buyer_nick,created,sid,tid,status,buyer_memo,seller_memo,payment,discount_fee,adjust_fee,post_fee,total_fee, pay_time,end_time,modified,received_payment,price,alipay_id,receiver_name,receiver_state,receiver_city,receiver_district,receiver_address, receiver_zip,receiver_mobile,receiver_phone,orders.price,orders.num,orders.iid,orders.num_iid,orders.sku_id,orders.refund_status,orders.status,orders.oid, orders.total_fee,orders.payment,orders.discount_fee,orders.adjust_fee,orders.sku_properties_name,orders.outer_iid,orders.outer_sku_id"
        #req.status = status
        req.type = "instant_trade,auto_delivery,guarantee_trade,tmall_i18n"

        #if shop.start_modified:
        #date_start = (datetime.strptime( shop.start_modified, '%Y-%m-%d %H:%M:%S',)  + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
        #req.start_modified = date_start
        #req.start_created = shop.start_modified
        #req.start_created = (datetime.now()- timedelta(hours=64)).strftime('%Y-%m-%d %H:%M:%S')
        req.start_created = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        #if shop.end_modified:
        #date_end = (datetime.strptime(  shop.end_modified, '%Y-%m-%d %H:%M:%S',)  + timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
        #req.end_modified = date_end
        #req.end_created = shop.end_modified
        req.end_created = (datetime.now() +
                           timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')

        res = []
        req.page_no = 1
        req.page_size = 100

        total_get = 0
        total_results = 100
        while total_get < total_results:
            resp = req.getResponse(shop.sessionkey)
            trades = resp.get('trades_sold_get_response').get('trades', False)
            total_results = resp.get('trades_sold_get_response').get(
                'total_results')
            _logger.info("Jimmy total_results :%d" % total_results)
            if total_results > 0:
                res += trades.get('trade')
            total_get += req.page_size
            req.page_no = req.page_no + 1
            _logger.info("Jimmy page_size :%d" % req.page_size)
            _logger.info("Jimmy total_get :%d" % total_get)
        # 时间需要减去8小时
        # 单号加上店铺前缀
        order_ids = []
        for trade in res:
            trade['created'] = (datetime.strptime(
                trade.get('created'),
                '%Y-%m-%d %H:%M:%S',
            ) - timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
            trade['pay_time'] = (datetime.strptime(
                (trade.get('pay_time', False) or '2016-01-01 00:00:01'),
                '%Y-%m-%d %H:%M:%S',
            ) - timedelta(hours=8)).strftime('%Y-%m-%d %H:%M:%S')
            trade['sale_code'] = '%s_%s' % (shop.code, trade.get('tid'))

        orders = self.remove_duplicate_orders(cr, uid, res, context=context)
        #orders = res
        for trade in orders:
            #try:
            #    #_logger.info("Jimmy before create_order")
            #order_id = self.create_order(cr, uid, ids, trade, context = context )
            order_id = self.create_order(cr, uid, ids, trade, context=context)
            #    _logger.info("Jimmy after create_order")
            #    order_ids.append(order_id)
            #except Exception, e:
            #    syncerr = u"店铺[%s]订单[%s]同步错误: %s" % (shop.name, trade['tid'], e)
            #    self.pool.get('loewieec.error').create(cr, uid, {'name':syncerr, 'shop_id': shop.id}, context = context )
            #    continue
        return order_ids

    def search_orders_by_tid(self, cr, uid, ids, context=None):
        port = 80
        shop = self.browse(cr, uid, ids[0], context=context)
        partner_id = shop.partner_id.id
        setDefaultAppInfo(shop.appkey, shop.appsecret)
        req = TradeFullinfoGetRequest(shop.apiurl, port)
        #req.fields="type,seller_nick,buyer_nick,created,sid,tid,status,buyer_memo,seller_memo,payment,discount_fee,adjust_fee,post_fee,total_fee, pay_time,end_time,modified,received_payment,price,alipay_id,receiver_name,receiver_state,receiver_city,receiver_district,receiver_address, receiver_zip,receiver_mobile,receiver_phone,orders.price,orders.num,orders.iid,orders.num_iid,orders.sku_id,orders.refund_status,orders.status,orders.oid, orders.total_fee,orders.payment,orders.discount_fee,orders.adjust_fee,orders.sku_properties_name,orders.outer_iid,orders.outer_sku_id"
        req.fields = "type,receiver_name,receiver_state,receiver_city,receiver_district,receiver_address, receiver_zip,receiver_mobile,receiver_phone"
        req.tid = shop.authurl

        resp = req.getResponse(shop.sessionkey)
        trade = resp.get('trade_fullinfo_get_response').get('trade', False)
        _logger.info("Jimmy type :%s" % trade.get('type'))
        _logger.info("Jimmy receiver_name :%s" % trade.get('receiver_name'))
        _logger.info("Jimmy receiver_address :%s" %
                     trade.get('receiver_address'))
        _logger.info("Jimmy receiver_mobile :%s" %
                     trade.get('receiver_mobile'))
        _logger.info("Jimmy receiver_phone :%s" % trade.get('receiver_phone'))

        return True
Пример #37
0
            logger.debug('Trying to get connection to SERVER %s, PORT %s, USER %s, PWD %s, DRIVER %s' % (tk_pyodbc.server, tk_pyodbc.port, tk_pyodbc.user, tk_pyodbc.pwd, tk_pyodbc.driver))
            logger.debug("DRIVER=%s;SERVER=%s;UID=%s;PWD=%s;PORT=%s;%s" % (tk_pyodbc.driver, tk_pyodbc.server, tk_pyodbc.user, tk_pyodbc.pwd, tk_pyodbc.port, tk_pyodbc.optional_params))
            conn = pyodbc.connect("DRIVER=%s;SERVER=%s;UID=%s;PWD=%s;PORT=%s;%s" % (tk_pyodbc.driver, tk_pyodbc.server, tk_pyodbc.user, tk_pyodbc.pwd, tk_pyodbc.port, tk_pyodbc.optional_params), timeout=timeout or 0)
            logger.debug("Connection acquired")
            return conn
        except Exception, e:
            raise orm.except_orm(_('Error !'), _('Could not get a valid connection. %s') % e)

    def check_download_connection(self, cr, uid, ids, context=None):
        """
        checks the connection to the sql server
        """
        conn = self.get_connection(cr, uid, ids, context)
        conn.close()
        raise orm.except_orm(_('Success'), _('Connection to Oscar was successful!'))

    _columns = {
        'name': fields.char('Name', size=64, required=True),
        'database_type': fields.selection(__database_types, 'Database Type'),
        'server': fields.char('Server address', size=256, required=False),
        'database': fields.char('Database name', size=256, required=False),
        'port': fields.integer('Database port'),
        'user': fields.char('Username', size=256, required=False),
        'pwd': fields.char('Password', size=256, required=False),
        'driver': fields.char('Driver location', size=256),
        'optional_params': fields.char('Optional parameters', size=256),
    }


tk_pyodbc()
Пример #38
0
class wkf_activity(osv.osv):
    _name = "workflow.activity"
    _table = "wkf_activity"
    _order = "name"
    _columns = {
        'name':
        fields.char('Name', required=True),
        'wkf_id':
        fields.many2one('workflow',
                        'Workflow',
                        required=True,
                        select=True,
                        ondelete='cascade'),
        'split_mode':
        fields.selection([('XOR', 'Xor'), ('OR', 'Or'), ('AND', 'And')],
                         'Split Mode',
                         size=3,
                         required=True),
        'join_mode':
        fields.selection([('XOR', 'Xor'), ('AND', 'And')],
                         'Join Mode',
                         size=3,
                         required=True),
        'kind':
        fields.selection([('dummy', 'Dummy'), ('function', 'Function'),
                          ('subflow', 'Subflow'), ('stopall', 'Stop All')],
                         'Kind',
                         required=True),
        'action':
        fields.text('Python Action'),
        'action_id':
        fields.many2one('ir.actions.server',
                        'Server Action',
                        ondelete='set null'),
        'flow_start':
        fields.boolean('Flow Start'),
        'flow_stop':
        fields.boolean('Flow Stop'),
        'subflow_id':
        fields.many2one('workflow', 'Subflow'),
        'signal_send':
        fields.char('Signal (subflow.*)'),
        'out_transitions':
        fields.one2many('workflow.transition', 'act_from',
                        'Outgoing Transitions'),
        'in_transitions':
        fields.one2many('workflow.transition', 'act_to',
                        'Incoming Transitions'),
    }
    _defaults = {
        'kind': lambda *a: 'dummy',
        'join_mode': lambda *a: 'XOR',
        'split_mode': lambda *a: 'XOR',
    }

    def unlink(self, cr, uid, ids, context=None):
        if context is None: context = {}
        if not context.get('_force_unlink') and self.pool.get(
                'workflow.workitem').search(cr, uid, [('act_id', 'in', ids)]):
            raise osv.except_osv(
                _('Operation Forbidden'),
                _('Please make sure no workitems refer to an activity before deleting it!'
                  ))
        super(wkf_activity, self).unlink(cr, uid, ids, context=context)
Пример #39
0
        except Exception, e:
            cr.rollback()
            logger.log(logging.WARNING, str(e))


    def get(self):
        return self.__connection

    def set(self, connection):
        self.__connection = connection

    def remove(self):
        self.__connection = None

    _columns = {
        'host':fields.char('Host', size=128, required=True),
        'port': fields.integer('Port', required=True),
        'ooo_restart_cmd': fields.char('OOO restart command', size=256, \
            help='Enter the shell command that will be executed to restart the LibreOffice/OpenOffice background process. '+ \
                'The command will be executed as the user of the OpenERP server process,'+ \
                'so you may need to prefix it with sudo and configure your sudoers file to have this command executed without password.'),
        
    }


class report_xml(osv.osv):
    _name = 'ir.actions.report.xml'
    _inherit = 'ir.actions.report.xml'

    _columns = {
        'process_sep':fields.boolean('Process Separately'),
Пример #40
0
class im_livechat_channel(osv.Model):
    _name = 'im_livechat.channel'

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

    def _get_image(self, cr, uid, ids, name, args, context=None):
        result = dict.fromkeys(ids, False)
        for obj in self.browse(cr, uid, ids, context=context):
            result[obj.id] = tools.image_get_resized_images(obj.image)
        return result

    def _set_image(self, cr, uid, id, name, value, args, context=None):
        return self.write(cr,
                          uid, [id],
                          {'image': tools.image_resize_image_big(value)},
                          context=context)

    def _are_you_inside(self, cr, uid, ids, name, arg, context=None):
        res = {}
        for record in self.browse(cr, uid, ids, context=context):
            res[record.id] = False
            for user in record.user_ids:
                if user.id == uid:
                    res[record.id] = True
                    break
        return res

    def _script_external(self, cr, uid, ids, name, arg, context=None):
        values = {
            "url":
            self.pool.get('ir.config_parameter').get_param(
                cr, openerp.SUPERUSER_ID, 'web.base.url'),
            "dbname":
            cr.dbname
        }
        res = {}
        for record in self.browse(cr, uid, ids, context=context):
            values["channel"] = record.id
            res[record.id] = self.pool['ir.ui.view'].render(
                cr,
                uid,
                'im_livechat.external_loader',
                values,
                context=context)
        return res

    def _script_internal(self, cr, uid, ids, name, arg, context=None):
        values = {
            "url":
            self.pool.get('ir.config_parameter').get_param(
                cr, openerp.SUPERUSER_ID, 'web.base.url'),
            "dbname":
            cr.dbname
        }
        res = {}
        for record in self.browse(cr, uid, ids, context=context):
            values["channel"] = record.id
            res[record.id] = self.pool['ir.ui.view'].render(
                cr,
                uid,
                'im_livechat.internal_loader',
                values,
                context=context)
        return res

    def _web_page(self, cr, uid, ids, name, arg, context=None):
        res = {}
        for record in self.browse(cr, uid, ids, context=context):
            res[record.id] = self.pool.get('ir.config_parameter').get_param(cr, openerp.SUPERUSER_ID, 'web.base.url') + \
                "/im_livechat/support/%s/%i" % (cr.dbname, record.id)
        return res

    _columns = {
        'name': fields.char(string="Channel Name", size=200, required=True),
        'user_ids': fields.many2many('res.users', 'im_livechat_channel_im_user', 'channel_id', 'user_id', string="Users"),
        'are_you_inside': fields.function(_are_you_inside, type='boolean', string='Are you inside the matrix?', store=False),
        'script_internal': fields.function(_script_internal, type='text', string='Script (internal)', store=False),
        'script_external': fields.function(_script_external, type='text', string='Script (external)', store=False),
        'web_page': fields.function(_web_page, type='char', string='Web Page', store=False),
        'button_text': fields.char(string="Text of the Button"),
        'input_placeholder': fields.char(string="Chat Input Placeholder"),
        'default_message': fields.char(string="Welcome Message", help="This is an automated 'welcome' message that your visitor will see when they initiate a new chat session."),
        # image: all image fields are base64 encoded and PIL-supported
        'image': fields.binary("Photo",
            help="This field holds the image used as photo for the group, limited to 1024x1024px."),
        'image_medium': fields.function(_get_image, fnct_inv=_set_image,
            string="Medium-sized photo", type="binary", multi="_get_image",
            store={
                'im_livechat.channel': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
            },
            help="Medium-sized photo of the group. It is automatically "\
                 "resized as a 128x128px image, with aspect ratio preserved. "\
                 "Use this field in form views or some kanban views."),
        'image_small': fields.function(_get_image, fnct_inv=_set_image,
            string="Small-sized photo", type="binary", multi="_get_image",
            store={
                'im_livechat.channel': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
            },
            help="Small-sized photo of the group. It is automatically "\
                 "resized as a 64x64px image, with aspect ratio preserved. "\
                 "Use this field anywhere a small image is required."),
    }

    def _default_user_ids(self, cr, uid, context=None):
        return [(6, 0, [uid])]

    _defaults = {
        'button_text': "Have a Question? Chat with us.",
        'input_placeholder': "How may I help you?",
        'default_message': '',
        'user_ids': _default_user_ids,
        'image': _get_default_image,
    }

    def get_available_users(self, cr, uid, channel_id, context=None):
        """ get available user of a given channel """
        channel = self.browse(cr, uid, channel_id, context=context)
        users = []
        for user_id in channel.user_ids:
            if (user_id.im_status == 'online'):
                users.append(user_id)
        return users

    def get_channel_session(self,
                            cr,
                            uid,
                            channel_id,
                            anonymous_name,
                            context=None):
        """ return a session given a channel : create on with a registered user, or return false otherwise """
        # get the avalable user of the channel
        users = self.get_available_users(cr, uid, channel_id, context=context)
        if len(users) == 0:
            return False
        user_id = random.choice(users).id
        # create the session, and add the link with the given channel
        Session = self.pool["im_chat.session"]
        newid = Session.create(cr,
                               uid, {
                                   'user_ids': [(4, user_id)],
                                   'channel_id': channel_id,
                                   'anonymous_name': anonymous_name
                               },
                               context=context)
        return Session.session_info(cr, uid, [newid], context=context)

    def test_channel(self, cr, uid, channel, context=None):
        if not channel:
            return {}
        return {
            'url': self.browse(cr, uid, channel[0], context=context
                               or {}).web_page,
            'type': 'ir.actions.act_url'
        }

    def get_info_for_chat_src(self, cr, uid, channel, context=None):
        url = self.pool.get('ir.config_parameter').get_param(
            cr, uid, 'web.base.url')
        chan = self.browse(cr, uid, channel, context=context)
        return {
            "url": url,
            'buttonText': chan.button_text,
            'inputPlaceholder': chan.input_placeholder,
            'defaultMessage': chan.default_message,
            "channelName": chan.name,
        }

    def join(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'user_ids': [(4, uid)]})
        return True

    def quit(self, cr, uid, ids, context=None):
        self.write(cr, uid, ids, {'user_ids': [(3, uid)]})
        return True
Пример #41
0
            try:
                file_data = image_file.read()
                self._logo_image = base64.encodestring(file_data)
                return self._logo_image
            finally:
                image_file.close()
        else:
            self._logo_image = base64.encodestring(im.read())
            return self._logo_image

    def _get_image_fn(self, cr, uid, ids, name, args, context=None):
        image = self._get_image(cr, uid, context)
        return dict.fromkeys(ids, image) # ok to use .fromkeys() as the image is same for all 

    _columns = {
        'host':fields.char('Host', size=64, required=True),
        'port':fields.integer('Port', required=True),
        'ooo_restart_cmd': fields.char('OOO restart command', size=256, \
            help='Enter the shell command that will be executed to restart the LibreOffice/OpenOffice background process.'+ \
                'The command will be executed as the user of the OpenERP server process,'+ \
                'so you may need to prefix it with sudo and configure your sudoers file to have this command executed without password.'),
        'state':fields.selection([
            ('init','Init'),
            ('error','Error'),
            ('done','Done'),
            
        ],'State', select=True, readonly=True),
        'msg': fields.text('Message', readonly=True),
        'error_details': fields.text('Error Details', readonly=True),
        'link':fields.char('Installation Manual', size=128, help='Installation (Dependencies and Base system setup)', readonly=True),
        'config_logo': fields.function(_get_image_fn, string='Image', type='binary', method=True),
Пример #42
0
class formulir_1111_a2(osv.osv):
    _name = 'pajak.formulir_1111_a2'
    _description = 'Formulir 1111 A2'
    _inherit = ['mail.thread']

    def default_state(self, cr, uid, context={}):
        return 'draft'

    def default_name(self, cr, uid, context={}):
        return '/'

    def default_created_time(self, cr, uid, context={}):
        #TODO: Ticket #47

        return datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    def default_created_user_id(self, cr, uid, context={}):
        return uid

    def function_amount_all(self, cr, uid, ids, name, args, context=None):
        #TODO: Ticket #48
        res = {}

        for formulir in self.browse(cr, uid, ids):
            total_dpp = 0.0
            total_ppn = 0.0
            total_ppnbm = 0.0
            if formulir.detail_ids:
                for detail in formulir.detail_ids:
                    total_dpp += detail.dpp
                    total_ppn += detail.ppn
                    total_ppnbm += detail.ppnbm
            res[id] = {
                'total_dpp': total_dpp,
                'total_ppn': total_ppn,
                'total_ppnbm': total_ppnbm
            }
        return res

    _columns = {
        'name':
        fields.char(string='# Dokumen', size=30, required=True, readonly=True),
        'company_id':
        fields.many2one(string='Perusahaan',
                        obj='res.company',
                        required=True,
                        readonly=True,
                        states={'draft':
                                [('readonly', False)]}),  #TODO: Ticket #54
        'nama_pkp':
        fields.char(string='Nama PKP',
                    size=255,
                    required=True,
                    readonly=True,
                    states={'draft':
                            [('readonly', False)]}),  #TODO: Ticket #54
        'npwp':
        fields.char(string='NPWP',
                    size=50,
                    required=True,
                    readonly=True,
                    states={'draft':
                            [('readonly', False)]}),  #TODO: Ticket #54
        'masa_pajak_id':
        fields.many2one(string='Masa Pajak',
                        obj='pajak.masa_pajak',
                        required=True,
                        readonly=True,
                        states={'draft':
                                [('readonly', False)]}),  #TODO: Ticket #54
        'pembetulan_ke':
        fields.integer(string='Pembetulan Ke-',
                       required=True,
                       readonly=True,
                       states={'draft':
                               [('readonly', False)]}),  #TODO: Ticket #54
        'detail_ids':
        fields.one2many(string='Detail',
                        obj='pajak.detail_formulir_1111_a2',
                        fields_id='formulir_id',
                        readonly=True,
                        states={'draft':
                                [('readonly', False)]}),  #TODO: Ticket #54
        'total_dpp':
        fields.function(fnct=function_amount_all,
                        string='Total DPP',
                        type='float',
                        digits_compute=dp.get_precision('Account'),
                        method=True,
                        store=True,
                        multi='all'),
        'total_ppn':
        fields.function(fnct=function_amount_all,
                        string='Total PPN',
                        type='float',
                        digits_compute=dp.get_precision('Account'),
                        method=True,
                        store=True,
                        multi='all'),
        'total_ppnbm':
        fields.function(fnct=function_amount_all,
                        string='Total PPnBM',
                        type='float',
                        digits_compute=dp.get_precision('Account'),
                        method=True,
                        store=True,
                        multi='all'),
        'note':
        fields.text(string='Note'),
        'state':
        fields.selection([('draft', 'Draft'),
                          ('confirm', 'Waiting For Approval'),
                          ('approve', 'Ready To Process'), ('done', 'Done'),
                          ('cancel', 'Cancel')],
                         'Status',
                         readonly=True),
        'created_time':
        fields.datetime(string='Created Time', readonly=True),
        'created_user_id':
        fields.many2one(string='Created By', obj='res.users', readonly=True),
        'confirmed_time':
        fields.datetime(string='Confirmed Time', readonly=True),
        'confirmed_user_id':
        fields.many2one(string='Confirmed By', obj='res.users', readonly=True),
        'approved_time':
        fields.datetime(string='Approved Time', readonly=True),
        'approved_user_id':
        fields.many2one(string='Approved By', obj='res.users', readonly=True),
        'processed_time':
        fields.datetime(string='Processed Time', readonly=True),
        'processed_user_id':
        fields.many2one(string='Process By', obj='res.users', readonly=True),
        'cancelled_time':
        fields.datetime(string='Processed Time', readonly=True),
        'cancelled_user_id':
        fields.many2one(string='Process By', obj='res.users', readonly=True),
        'cancelled_reason':
        fields.text(string='Cancelled Reason', readonly=True),
    }

    _defaults = {
        'name': default_name,
        'state': default_state,
        'created_time': default_created_time,
        'created_user_id': default_created_user_id,
    }

    def workflow_action_confirm(self, cr, uid, ids, context={}):
        for id in ids:
            if not self.create_seqence(cr, uid, id):
                return False

            if not self.log_audit_trail(cr, uid, id, 'confirmed'):
                return False
        return True

    def workflow_action_approve(self, cr, uid, ids, context={}):
        for id in ids:
            if not self.log_audit_trail(cr, uid, id, 'approved'):
                return False
        return True

    def workflow_action_done(self, cr, uid, ids, context={}):
        for id in ids:
            if not self.log_audit_trail(cr, uid, id, 'processed'):
                return False
        return True

    def workflow_action_cancel(self, cr, uid, ids, context={}):
        for id in ids:
            if not self.log_audit_trail(cr, uid, id, 'cancelled'):
                return False
        return True

    def button_action_set_to_draft(self, cr, uid, ids, context={}):
        for id in ids:
            if not self.delete_workflow_instance(cr, uid, id):
                return False

            if not self.create_workflow_instance(cr, uid, id):
                return False

            if not self.clear_log_audit(cr, uid, id):
                return False

            if not self.log_audit_trail(cr, uid, 'created'):
                return False

        return True

    def button_action_cancel(self, cr, uid, ids, context={}):
        wkf_service = netsvc.LocalService('workflow')
        for id in ids:
            if not self.delete_workflow_instance(cr, uid, id):
                return False

            if not self.create_workflow_instance(cr, uid, id):
                return False

            wkf_service.trg_validate(uid, 'pajak.formulir_1111_a2', id,
                                     'button_cancel', cr)

            return True

    def write_cancel_descriprion(self, cr, uid, reason):
        self.write(cr, uid, [id], {'cancelled_descriprion': reason})
        return True

    def log_audit_trail(self, cr, uid, id, state):
        #TODO: Ticket #50
        if state not in [
                'created', 'confirmed', 'approved', 'processed', 'cancelled'
        ]:
            raise osv.except_osv(_('Peringatan!'),
                                 _('Error pada method log_audit'))
            return False

            state_dict = {
                'created': 'draft',
                'confirmed': 'confirm',
                'approved': 'approve',
                'processed': 'done',
                'cancelled': 'cancel'
            }

            val = {
                '%s_user_id' % (state): uid,
                '%s_time' % (state):
                datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'state': state_dict.get(state, False),
            }

            self.write(cr, uid, [id], val)
        return True

    def delete_workflow_instance(self, cr, uid, id):
        #TODO: Ticket #51

        wkf_service = netsvc.LocalService('workflow')
        wkf_service.trg_delete(uid, 'pajak.formulir_1111_a2', id, cr)

        return True

    def create_workflow_instance(self, cr, uid, id):
        #TODO: Ticket #52

        wkf_service = netsvc.LocalService('workflow')
        wkf_service.trg_create(uid, 'pajak.formulir_1111_a2', id, cr)

        return True

    def onchange_company_id(self, cr, uid, ids, comapny_id):
        #TODO: Ticket #53
        obj_res_company = self.pool.get('res.company')

        value = {}
        domain = {}
        warning = {}

        if company_id:
            npwp = obj_res_company.browse(cr, uid, company_id).partner_id.npwp
            value.update({'npwp': npwp})

        return {'value': value, 'domain': domain, 'warning': warning}

    def create_sequence(cr, uid, id):
        #TODO: Ticket #49
        obj_sequence = self.pool.get('ir.sequence')
        obj_company = self.pool.get('res.company')

        formulir = self.browse(cr, uid, [id])[0]

        if formulir.name == '/':

            if formulir.company_id.sequence_formulir_1111_a2.id:
                sequence = obj_sequence.next_by_id(
                    cr, uid, formulir.company_id.sequence_formulir_1111_a2.id)
                self.write(cr, uid, [id], {'name': sequence})
            else:
                raise osv.except_osv(
                    _('Peringatan'),
                    _('Sequence Formulir 1111 A2 Belum Di-Set'))
                return False
        return True
Пример #43
0
                                               'remarks': kail.remarks
                                               }
                                kail.asset_id.write({'asset_usage_ids':[(0,0, create_data)]})
                                kail.write({'state':'done'})                            
                        except Exception, e:
                            kail.write({'reason':e})
                            done = False
            if done: 
                kai.write({'state':'done'})
        pass
        
    IMPORT_TYPE = (('lq','Liquidation'),('usage','Usage'),('spec','Specification'))
    _columns={
              'name':fields.date("Import Date", 
                                    states={'done':[('readonly',True)]}, required=True),              
              'remarks':fields.char('Remarks',size=256, 
                                    states={'done':[('readonly',True)]}),                                                               
                
              'state':fields.selection((('draft','Draft'),('done','Completed')),'State',readonly=True),
              
              'detail_ids':fields.one2many('kderp.import.asset.detail','import_id','Details',states={'done':[('readonly',True)]}),
              'detail_spec_ids':fields.one2many('kderp.import.asset.detail','import_id','Details',states={'done':[('readonly',True)]}),
              'detail_usage_ids':fields.one2many('kderp.import.asset.detail','import_id','Details',states={'done':[('readonly',True)]}),
              'import_type':fields.selection(IMPORT_TYPE,'Import type',states={'done':[('readonly',True)]}),
              }
    _defaults={
               'name':lambda *a: time.strftime('%Y-%m-%d'),
               'state':lambda *a: 'draft'
               }    
    
kderp_asset_import()  
Пример #44
0
class module(osv.osv):
    _name = "ir.module.module"
    _rec_name = "shortdesc"
    _description = "Module"

    def fields_view_get(self,
                        cr,
                        uid,
                        view_id=None,
                        view_type='form',
                        context=None,
                        toolbar=False,
                        submenu=False):
        res = super(module, self).fields_view_get(cr,
                                                  uid,
                                                  view_id=view_id,
                                                  view_type=view_type,
                                                  context=context,
                                                  toolbar=toolbar,
                                                  submenu=False)
        result = self.pool.get('ir.model.data').get_object_reference(
            cr, uid, 'base', 'action_server_module_immediate_install')[1]
        if view_type == 'form':
            if res.get('toolbar', False):
                list = [
                    rec for rec in res['toolbar']['action']
                    if rec.get('id', False) != result
                ]
                res['toolbar'] = {'action': list}
        return res

    @classmethod
    def get_module_info(cls, name):
        info = {}
        try:
            info = modules.load_information_from_description_file(name)
        except Exception:
            _logger.debug(
                'Error when trying to fetch information for '
                'module %s',
                name,
                exc_info=True)
        return info

    def _get_desc(self, cr, uid, ids, field_name=None, arg=None, context=None):
        res = dict.fromkeys(ids, '')
        for module in self.browse(cr, uid, ids, context=context):
            path = get_module_resource(module.name,
                                       'static/description/index.html')
            if path:
                with tools.file_open(path, 'rb') as desc_file:
                    doc = desc_file.read()
                    html = lxml.html.document_fromstring(doc)
                    for element, attribute, link, pos in html.iterlinks():
                        if element.get('src') and not '//' in element.get(
                                'src') and not 'static/' in element.get('src'):
                            element.set(
                                'src', "/%s/static/description/%s" %
                                (module.name, element.get('src')))
                    res[module.id] = html_sanitize(lxml.html.tostring(html))
            else:
                overrides = {
                    'embed_stylesheet': False,
                    'doctitle_xform': False,
                    'output_encoding': 'unicode',
                    'xml_declaration': False,
                }
                output = publish_string(source=module.description or '',
                                        settings_overrides=overrides,
                                        writer=MyWriter())
                res[module.id] = html_sanitize(output)
        return res

    def _get_latest_version(self,
                            cr,
                            uid,
                            ids,
                            field_name=None,
                            arg=None,
                            context=None):
        default_version = modules.adapt_version('1.0')
        res = dict.fromkeys(ids, default_version)
        for m in self.browse(cr, uid, ids):
            res[m.id] = self.get_module_info(m.name).get(
                'version', default_version)
        return res

    def _get_views(self,
                   cr,
                   uid,
                   ids,
                   field_name=None,
                   arg=None,
                   context=None):
        res = {}
        model_data_obj = self.pool.get('ir.model.data')

        dmodels = []
        if field_name is None or 'views_by_module' in field_name:
            dmodels.append('ir.ui.view')
        if field_name is None or 'reports_by_module' in field_name:
            dmodels.append('ir.actions.report.xml')
        if field_name is None or 'menus_by_module' in field_name:
            dmodels.append('ir.ui.menu')
        assert dmodels, "no models for %s" % field_name

        for module_rec in self.browse(cr, uid, ids, context=context):
            res_mod_dic = res[module_rec.id] = {
                'menus_by_module': [],
                'reports_by_module': [],
                'views_by_module': []
            }

            # Skip uninstalled modules below, no data to find anyway.
            if module_rec.state not in ('installed', 'to upgrade',
                                        'to remove'):
                continue

            # then, search and group ir.model.data records
            imd_models = dict([(m, []) for m in dmodels])
            imd_ids = model_data_obj.search(cr, uid,
                                            [('module', '=', module_rec.name),
                                             ('model', 'in', tuple(dmodels))])

            for imd_res in model_data_obj.read(cr,
                                               uid,
                                               imd_ids, ['model', 'res_id'],
                                               context=context):
                imd_models[imd_res['model']].append(imd_res['res_id'])

            def browse(model):
                M = self.pool[model]
                # as this method is called before the module update, some xmlid may be invalid at this stage
                # explictly filter records before reading them
                ids = M.exists(cr, uid, imd_models.get(model, []), context)
                return M.browse(cr, uid, ids, context)

            def format_view(v):
                aa = v.inherit_id and '* INHERIT ' or ''
                return '%s%s (%s)' % (aa, v.name, v.type)

            res_mod_dic['views_by_module'] = map(format_view,
                                                 browse('ir.ui.view'))
            res_mod_dic['reports_by_module'] = map(
                attrgetter('name'), browse('ir.actions.report.xml'))
            res_mod_dic['menus_by_module'] = map(attrgetter('complete_name'),
                                                 browse('ir.ui.menu'))

        for key in res.iterkeys():
            for k, v in res[key].iteritems():
                res[key][k] = "\n".join(sorted(v))
        return res

    def _get_icon_image(self,
                        cr,
                        uid,
                        ids,
                        field_name=None,
                        arg=None,
                        context=None):
        res = dict.fromkeys(ids, '')
        for module in self.browse(cr, uid, ids, context=context):
            path = get_module_resource(module.name, 'static', 'description',
                                       'icon.png')
            if path:
                image_file = tools.file_open(path, 'rb')
                try:
                    res[module.id] = image_file.read().encode('base64')
                finally:
                    image_file.close()
        return res

    _columns = {
        'name':
        fields.char("Technical Name",
                    readonly=True,
                    required=True,
                    select=True),
        'category_id':
        fields.many2one('ir.module.category',
                        'Category',
                        readonly=True,
                        select=True),
        'shortdesc':
        fields.char('Module Name', readonly=True, translate=True),
        'summary':
        fields.char('Summary', readonly=True, translate=True),
        'description':
        fields.text("Description", readonly=True, translate=True),
        'description_html':
        fields.function(_get_desc,
                        string='Description HTML',
                        type='html',
                        method=True,
                        readonly=True),
        'author':
        fields.char("Author", readonly=True),
        'maintainer':
        fields.char('Maintainer', readonly=True),
        'contributors':
        fields.text('Contributors', readonly=True),
        'website':
        fields.char("Website", readonly=True),

        # attention: Incorrect field names !!
        #   installed_version refers the latest version (the one on disk)
        #   latest_version refers the installed version (the one in database)
        #   published_version refers the version available on the repository
        'installed_version':
        fields.function(_get_latest_version,
                        string='Latest Version',
                        type='char'),
        'latest_version':
        fields.char('Installed Version', readonly=True),
        'published_version':
        fields.char('Published Version', readonly=True),
        'url':
        fields.char('URL', readonly=True),
        'sequence':
        fields.integer('Sequence'),
        'dependencies_id':
        fields.one2many('ir.module.module.dependency',
                        'module_id',
                        'Dependencies',
                        readonly=True),
        'auto_install':
        fields.boolean(
            'Automatic Installation',
            help='An auto-installable module is automatically installed by the '
            'system when all its dependencies are satisfied. '
            'If the module has no dependency, it is always installed.'),
        'state':
        fields.selection([('uninstallable', 'Not Installable'),
                          ('uninstalled', 'Not Installed'),
                          ('installed', 'Installed'),
                          ('to upgrade', 'To be upgraded'),
                          ('to remove', 'To be removed'),
                          ('to install', 'To be installed')],
                         string='Status',
                         readonly=True,
                         select=True),
        'demo':
        fields.boolean('Demo Data', readonly=True),
        'license':
        fields.selection(
            [('GPL-2', 'GPL Version 2'),
             ('GPL-2 or any later version', 'GPL-2 or later version'),
             ('GPL-3', 'GPL Version 3'),
             ('GPL-3 or any later version', 'GPL-3 or later version'),
             ('AGPL-3', 'Affero GPL-3'), ('LGPL-3', 'LGPL Version 3'),
             ('Other OSI approved licence', 'Other OSI Approved Licence'),
             ('OEEL-1', 'Odoo Enterprise Edition License v1.0'),
             ('Other proprietary', 'Other Proprietary')],
            string='License',
            readonly=True),
        'menus_by_module':
        fields.function(_get_views,
                        string='Menus',
                        type='text',
                        multi="meta",
                        store=True),
        'reports_by_module':
        fields.function(_get_views,
                        string='Reports',
                        type='text',
                        multi="meta",
                        store=True),
        'views_by_module':
        fields.function(_get_views,
                        string='Views',
                        type='text',
                        multi="meta",
                        store=True),
        'application':
        fields.boolean('Application', readonly=True),
        'icon':
        fields.char('Icon URL'),
        'icon_image':
        fields.function(_get_icon_image, string='Icon', type="binary"),
    }

    _defaults = {
        'state': 'uninstalled',
        'sequence': 100,
        'demo': False,
        'license': 'LGPL-3',
    }
    _order = 'sequence,name'

    def _name_uniq_msg(self, cr, uid, ids, context=None):
        return _('The name of the module must be unique !')

    _sql_constraints = [
        ('name_uniq', 'UNIQUE (name)', _name_uniq_msg),
    ]

    def unlink(self, cr, uid, ids, context=None):
        if not ids:
            return True
        if isinstance(ids, (int, long)):
            ids = [ids]
        mod_names = []
        for mod in self.read(cr, uid, ids, ['state', 'name'], context):
            if mod['state'] in ('installed', 'to upgrade', 'to remove',
                                'to install'):
                raise UserError(
                    _('You try to remove a module that is installed or will be installed'
                      ))
            mod_names.append(mod['name'])
        #Removing the entry from ir_model_data
        #ids_meta = self.pool.get('ir.model.data').search(cr, uid, [('name', '=', 'module_meta_information'), ('module', 'in', mod_names)])

        #if ids_meta:
        #    self.pool.get('ir.model.data').unlink(cr, uid, ids_meta, context)

        self.clear_caches()
        return super(module, self).unlink(cr, uid, ids, context=context)

    @staticmethod
    def _check_external_dependencies(terp):
        depends = terp.get('external_dependencies')
        if not depends:
            return
        for pydep in depends.get('python', []):
            try:
                importlib.import_module(pydep)
            except ImportError:
                raise ImportError('No module named %s' % (pydep, ))

        for binary in depends.get('bin', []):
            try:
                tools.find_in_path(binary)
            except IOError:
                raise Exception('Unable to find %r in path' % (binary, ))

    @classmethod
    def check_external_dependencies(cls, module_name, newstate='to install'):
        terp = cls.get_module_info(module_name)
        try:
            cls._check_external_dependencies(terp)
        except Exception, e:
            if newstate == 'to install':
                msg = _(
                    'Unable to install module "%s" because an external dependency is not met: %s'
                )
            elif newstate == 'to upgrade':
                msg = _(
                    'Unable to upgrade module "%s" because an external dependency is not met: %s'
                )
            else:
                msg = _(
                    'Unable to process module "%s" because an external dependency is not met: %s'
                )
            raise UserError(msg % (module_name, e.args[0]))
Пример #45
0
#the Free Software Foundation, either version 3 of the License, or            #
#(at your option) any later version.                                          #
#                                                                             #
#This program is distributed in the hope that it will be useful,              #
#but WITHOUT ANY WARRANTY; without even the implied warranty of               #
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
#GNU Affero General Public License for more details.                          #
#                                                                             #
#You should have received a copy of the GNU Affero General Public License     #
#along with this program.  If not, see <http://www.gnu.org/licenses/>.        #
###############################################################################

from openerp.osv import orm, fields

FISCAL_POSITION_COLUMNS = {
    'name': fields.char('Fiscal Position', size=128, required=True),
    'fiscal_category_id': fields.many2one(
        'l10n_br_account.fiscal.category', 'Categoria Fiscal'),
    'fiscal_category_fiscal_type': fields.related(
        'fiscal_category_id', 'fiscal_type', type='char', readonly=True,
        relation='l10n_br_account.fiscal.category', store=True,
        string='Fiscal Type'),
    'type': fields.selection([('input', 'Entrada'), ('output', 'Saida')],
                             'Tipo'),
    'type_tax_use': fields.selection(
        [('sale', 'Sale'), ('purchase', 'Purchase'), ('all', 'All')],
        'Tax Application'),
    'inv_copy_note': fields.boolean(u'Copiar Observação na Nota Fiscal'),
    'asset_operation': fields.boolean(u'Operação de Aquisição de Ativo',
        help=u"""Caso seja marcada essa opção, será incluido o IPI na base de
            calculo do ICMS."""),
Пример #46
0
class mrp_repair(osv.osv):
    _name = 'mrp.repair'
    _inherit = 'mail.thread'
    _description = 'Repair Order'

    def _amount_untaxed(self, cr, uid, ids, field_name, arg, context=None):
        """ Calculates untaxed amount.
        @param self: The object pointer
        @param cr: The current row, from the database cursor,
        @param uid: The current user ID for security checks
        @param ids: List of selected IDs
        @param field_name: Name of field.
        @param arg: Argument
        @param context: A standard dictionary for contextual values
        @return: Dictionary of values.
        """
        res = {}
        cur_obj = self.pool.get('res.currency')

        for repair in self.browse(cr, uid, ids, context=context):
            res[repair.id] = 0.0
            for line in repair.operations:
                res[repair.id] += line.price_subtotal
            for line in repair.fees_lines:
                res[repair.id] += line.price_subtotal
            cur = repair.pricelist_id.currency_id
            res[repair.id] = cur_obj.round(cr, uid, cur, res[repair.id])
        return res

    def _amount_tax(self, cr, uid, ids, field_name, arg, context=None):
        """ Calculates taxed amount.
        @param field_name: Name of field.
        @param arg: Argument
        @return: Dictionary of values.
        """
        res = {}
        #return {}.fromkeys(ids, 0)
        cur_obj = self.pool.get('res.currency')
        tax_obj = self.pool.get('account.tax')
        for repair in self.browse(cr, uid, ids, context=context):
            val = 0.0
            cur = repair.pricelist_id.currency_id
            for line in repair.operations:
                #manage prices with tax included use compute_all instead of compute
                if line.to_invoice and line.tax_id:
                    tax_calculate = tax_obj.compute_all(
                        cr, uid, line.tax_id, line.price_unit, cur,
                        line.product_uom_qty, line.product_id.id,
                        repair.partner_id.id)
                    for c in tax_calculate['taxes']:
                        val += c['amount']
            for line in repair.fees_lines:
                if line.to_invoice and line.tax_id:
                    tax_calculate = tax_obj.compute_all(
                        cr, uid, line.tax_id, line.price_unit, cur,
                        line.product_uom_qty, line.product_id.id,
                        repair.partner_id.id)
                    for c in tax_calculate['taxes']:
                        val += c['amount']
            res[repair.id] = cur_obj.round(cr, uid, cur, val)
        return res

    def _amount_total(self, cr, uid, ids, field_name, arg, context=None):
        """ Calculates total amount.
        @param field_name: Name of field.
        @param arg: Argument
        @return: Dictionary of values.
        """
        res = {}
        untax = self._amount_untaxed(cr,
                                     uid,
                                     ids,
                                     field_name,
                                     arg,
                                     context=context)
        tax = self._amount_tax(cr, uid, ids, field_name, arg, context=context)
        cur_obj = self.pool.get('res.currency')
        for id in ids:
            repair = self.browse(cr, uid, id, context=context)
            cur = repair.pricelist_id.currency_id
            res[id] = cur_obj.round(cr, uid, cur,
                                    untax.get(id, 0.0) + tax.get(id, 0.0))
        return res

    def _get_default_address(self,
                             cr,
                             uid,
                             ids,
                             field_name,
                             arg,
                             context=None):
        res = {}
        partner_obj = self.pool.get('res.partner')
        for data in self.browse(cr, uid, ids, context=context):
            adr_id = False
            if data.partner_id:
                adr_id = partner_obj.address_get(cr, uid, [data.partner_id.id],
                                                 ['default'])['default']
            res[data.id] = adr_id
        return res

    def _get_lines(self, cr, uid, ids, context=None):
        return self.pool['mrp.repair'].search(cr,
                                              uid, [('operations', 'in', ids)],
                                              context=context)

    def _get_fee_lines(self, cr, uid, ids, context=None):
        return self.pool['mrp.repair'].search(cr,
                                              uid, [('fees_lines', 'in', ids)],
                                              context=context)

    _columns = {
        'name':
        fields.char('Repair Reference',
                    required=True,
                    states={'confirmed': [('readonly', True)]},
                    copy=False),
        'product_id':
        fields.many2one('product.product',
                        string='Product to Repair',
                        required=True,
                        readonly=True,
                        states={'draft': [('readonly', False)]}),
        'product_qty':
        fields.float(
            'Product Quantity',
            digits_compute=dp.get_precision('Product Unit of Measure'),
            required=True,
            readonly=True,
            states={'draft': [('readonly', False)]}),
        'product_uom':
        fields.many2one('product.uom',
                        'Product Unit of Measure',
                        required=True,
                        readonly=True,
                        states={'draft': [('readonly', False)]}),
        'partner_id':
        fields.many2one(
            'res.partner',
            'Partner',
            select=True,
            help=
            'Choose partner for whom the order will be invoiced and delivered.',
            states={'confirmed': [('readonly', True)]}),
        'address_id':
        fields.many2one('res.partner',
                        'Delivery Address',
                        domain="[('parent_id','=',partner_id)]",
                        states={'confirmed': [('readonly', True)]}),
        'default_address_id':
        fields.function(_get_default_address,
                        type="many2one",
                        relation="res.partner"),
        'state':
        fields.selection(
            [('draft', 'Quotation'), ('cancel', 'Cancelled'),
             ('confirmed', 'Confirmed'), ('under_repair', 'Under Repair'),
             ('ready', 'Ready to Repair'), ('2binvoiced', 'To be Invoiced'),
             ('invoice_except', 'Invoice Exception'), ('done', 'Repaired')],
            'Status',
            readonly=True,
            track_visibility='onchange',
            copy=False,
            help=
            ' * The \'Draft\' status is used when a user is encoding a new and unconfirmed repair order. \
            \n* The \'Confirmed\' status is used when a user confirms the repair order. \
            \n* The \'Ready to Repair\' status is used to start to repairing, user can start repairing only after repair order is confirmed. \
            \n* The \'To be Invoiced\' status is used to generate the invoice before or after repairing done. \
            \n* The \'Done\' status is set when repairing is completed.\
            \n* The \'Cancelled\' status is used when user cancel repair order.'
        ),
        'location_id':
        fields.many2one('stock.location',
                        'Current Location',
                        select=True,
                        required=True,
                        readonly=True,
                        states={
                            'draft': [('readonly', False)],
                            'confirmed': [('readonly', True)]
                        }),
        'location_dest_id':
        fields.many2one('stock.location',
                        'Delivery Location',
                        readonly=True,
                        required=True,
                        states={
                            'draft': [('readonly', False)],
                            'confirmed': [('readonly', True)]
                        }),
        'lot_id':
        fields.many2one('stock.production.lot',
                        'Repaired Lot',
                        domain="[('product_id','=', product_id)]",
                        help="Products repaired are all belonging to this lot",
                        oldname="prodlot_id"),
        'guarantee_limit':
        fields.date('Warranty Expiration',
                    states={'confirmed': [('readonly', True)]}),
        'operations':
        fields.one2many('mrp.repair.line',
                        'repair_id',
                        'Operation Lines',
                        readonly=True,
                        states={'draft': [('readonly', False)]},
                        copy=True),
        'pricelist_id':
        fields.many2one('product.pricelist',
                        'Pricelist',
                        help='Pricelist of the selected partner.'),
        'partner_invoice_id':
        fields.many2one('res.partner', 'Invoicing Address'),
        'invoice_method':
        fields.selection(
            [("none", "No Invoice"), ("b4repair", "Before Repair"),
             ("after_repair", "After Repair")],
            "Invoice Method",
            select=True,
            required=True,
            states={'draft': [('readonly', False)]},
            readonly=True,
            help=
            'Selecting \'Before Repair\' or \'After Repair\' will allow you to generate invoice before or after the repair is done respectively. \'No invoice\' means you don\'t want to generate invoice for this repair order.'
        ),
        'invoice_id':
        fields.many2one('account.invoice',
                        'Invoice',
                        readonly=True,
                        track_visibility="onchange",
                        copy=False),
        'move_id':
        fields.many2one('stock.move',
                        'Move',
                        readonly=True,
                        help="Move created by the repair order",
                        track_visibility="onchange",
                        copy=False),
        'fees_lines':
        fields.one2many('mrp.repair.fee',
                        'repair_id',
                        'Fees',
                        readonly=True,
                        states={'draft': [('readonly', False)]},
                        copy=True),
        'internal_notes':
        fields.text('Internal Notes'),
        'quotation_notes':
        fields.text('Quotation Notes'),
        'company_id':
        fields.many2one('res.company', 'Company'),
        'invoiced':
        fields.boolean('Invoiced', readonly=True, copy=False),
        'repaired':
        fields.boolean('Repaired', readonly=True, copy=False),
        'amount_untaxed':
        fields.function(_amount_untaxed,
                        string='Untaxed Amount',
                        store={
                            'mrp.repair':
                            (lambda self, cr, uid, ids, c={}: ids,
                             ['operations', 'fees_lines'], 10),
                            'mrp.repair.line': (_get_lines, [
                                'price_unit', 'price_subtotal', 'product_id',
                                'tax_id', 'product_uom_qty', 'product_uom'
                            ], 10),
                            'mrp.repair.fee': (_get_fee_lines, [
                                'price_unit', 'price_subtotal', 'product_id',
                                'tax_id', 'product_uom_qty', 'product_uom'
                            ], 10),
                        }),
        'amount_tax':
        fields.function(_amount_tax,
                        string='Taxes',
                        store={
                            'mrp.repair':
                            (lambda self, cr, uid, ids, c={}: ids,
                             ['operations', 'fees_lines'], 10),
                            'mrp.repair.line': (_get_lines, [
                                'price_unit', 'price_subtotal', 'product_id',
                                'tax_id', 'product_uom_qty', 'product_uom'
                            ], 10),
                            'mrp.repair.fee': (_get_fee_lines, [
                                'price_unit', 'price_subtotal', 'product_id',
                                'tax_id', 'product_uom_qty', 'product_uom'
                            ], 10),
                        }),
        'amount_total':
        fields.function(_amount_total,
                        string='Total',
                        store={
                            'mrp.repair':
                            (lambda self, cr, uid, ids, c={}: ids,
                             ['operations', 'fees_lines'], 10),
                            'mrp.repair.line': (_get_lines, [
                                'price_unit', 'price_subtotal', 'product_id',
                                'tax_id', 'product_uom_qty', 'product_uom'
                            ], 10),
                            'mrp.repair.fee': (_get_fee_lines, [
                                'price_unit', 'price_subtotal', 'product_id',
                                'tax_id', 'product_uom_qty', 'product_uom'
                            ], 10),
                        }),
    }

    def _default_stock_location(self, cr, uid, context=None):
        try:
            warehouse = self.pool.get('ir.model.data').get_object(
                cr, uid, 'stock', 'warehouse0')
            return warehouse.lot_stock_id.id
        except:
            return False

    _defaults = {
        'state':
        lambda *a: 'draft',
        'name':
        lambda obj, cr, uid, context: obj.pool.get('ir.sequence').next_by_code(
            cr, uid, 'mrp.repair'),
        'invoice_method':
        lambda *a: 'none',
        'company_id':
        lambda self, cr, uid, context: self.pool.get('res.company').
        _company_default_get(cr, uid, 'mrp.repair', context=context),
        'pricelist_id':
        lambda self, cr, uid, context: self.pool.get(
            'product.pricelist').search(cr, uid, [('type', '=', 'sale')])[0],
        'product_qty':
        1.0,
        'location_id':
        _default_stock_location,
    }

    _sql_constraints = [
        ('name', 'unique (name)',
         'The name of the Repair Order must be unique!'),
    ]

    def onchange_product_id(self, cr, uid, ids, product_id=None):
        """ On change of product sets some values.
        @param product_id: Changed product
        @return: Dictionary of values.
        """
        product = False
        if product_id:
            product = self.pool.get("product.product").browse(
                cr, uid, product_id)
        return {
            'value': {
                'guarantee_limit': False,
                'lot_id': False,
                'product_uom': product and product.uom_id.id or False,
            }
        }

    def onchange_product_uom(self,
                             cr,
                             uid,
                             ids,
                             product_id,
                             product_uom,
                             context=None):
        res = {'value': {}}
        if not product_uom or not product_id:
            return res
        product = self.pool.get('product.product').browse(cr,
                                                          uid,
                                                          product_id,
                                                          context=context)
        uom = self.pool.get('product.uom').browse(cr,
                                                  uid,
                                                  product_uom,
                                                  context=context)
        if uom.category_id.id != product.uom_id.category_id.id:
            res['warning'] = {
                'title':
                _('Warning'),
                'message':
                _('The Product Unit of Measure you chose has a different category than in the product form.'
                  )
            }
            res['value'].update({'product_uom': product.uom_id.id})
        return res

    def onchange_location_id(self, cr, uid, ids, location_id=None):
        """ On change of location
        """
        return {'value': {'location_dest_id': location_id}}

    def button_dummy(self, cr, uid, ids, context=None):
        return True

    def onchange_partner_id(self, cr, uid, ids, part, address_id):
        """ On change of partner sets the values of partner address,
        partner invoice address and pricelist.
        @param part: Changed id of partner.
        @param address_id: Address id from current record.
        @return: Dictionary of values.
        """
        part_obj = self.pool.get('res.partner')
        pricelist_obj = self.pool.get('product.pricelist')
        if not part:
            return {
                'value': {
                    'address_id':
                    False,
                    'partner_invoice_id':
                    False,
                    'pricelist_id':
                    pricelist_obj.search(cr, uid, [('type', '=', 'sale')])[0]
                }
            }
        addr = part_obj.address_get(cr, uid, [part],
                                    ['delivery', 'invoice', 'default'])
        partner = part_obj.browse(cr, uid, part)
        pricelist = partner.property_product_pricelist and partner.property_product_pricelist.id or False
        return {
            'value': {
                'address_id': addr['delivery'] or addr['default'],
                'partner_invoice_id': addr['invoice'],
                'pricelist_id': pricelist
            }
        }

    def action_cancel_draft(self, cr, uid, ids, *args):
        """ Cancels repair order when it is in 'Draft' state.
        @param *arg: Arguments
        @return: True
        """
        if not len(ids):
            return False
        mrp_line_obj = self.pool.get('mrp.repair.line')
        for repair in self.browse(cr, uid, ids):
            mrp_line_obj.write(cr, uid, [l.id for l in repair.operations],
                               {'state': 'draft'})
        self.write(cr, uid, ids, {'state': 'draft'})
        return self.create_workflow(cr, uid, ids)

    def action_confirm(self, cr, uid, ids, *args):
        """ Repair order state is set to 'To be invoiced' when invoice method
        is 'Before repair' else state becomes 'Confirmed'.
        @param *arg: Arguments
        @return: True
        """
        mrp_line_obj = self.pool.get('mrp.repair.line')
        for o in self.browse(cr, uid, ids):
            if (o.invoice_method == 'b4repair'):
                self.write(cr, uid, [o.id], {'state': '2binvoiced'})
            else:
                self.write(cr, uid, [o.id], {'state': 'confirmed'})
                for line in o.operations:
                    if line.product_id.track_production:
                        raise UserError(
                            _("Serial number is required for operation line with product '%s'"
                              ) % (line.product_id.name))
                mrp_line_obj.write(cr, uid, [l.id for l in o.operations],
                                   {'state': 'confirmed'})
        return True

    def action_cancel(self, cr, uid, ids, context=None):
        """ Cancels repair order.
        @return: True
        """
        mrp_line_obj = self.pool.get('mrp.repair.line')
        for repair in self.browse(cr, uid, ids, context=context):
            if not repair.invoiced:
                mrp_line_obj.write(cr,
                                   uid, [l.id for l in repair.operations],
                                   {'state': 'cancel'},
                                   context=context)
            else:
                raise UserError(_('Repair order is already invoiced.'))
        return self.write(cr, uid, ids, {'state': 'cancel'})

    def wkf_invoice_create(self, cr, uid, ids, *args):
        self.action_invoice_create(cr, uid, ids)
        return True

    def action_invoice_create(self, cr, uid, ids, group=False, context=None):
        """ Creates invoice(s) for repair order.
        @param group: It is set to true when group invoice is to be generated.
        @return: Invoice Ids.
        """
        res = {}
        invoices_group = {}
        inv_line_obj = self.pool.get('account.invoice.line')
        inv_obj = self.pool.get('account.invoice')
        repair_line_obj = self.pool.get('mrp.repair.line')
        repair_fee_obj = self.pool.get('mrp.repair.fee')
        for repair in self.browse(cr, uid, ids, context=context):
            res[repair.id] = False
            if repair.state in ('draft', 'cancel') or repair.invoice_id:
                continue
            if not (repair.partner_id.id and repair.partner_invoice_id.id):
                raise UserError(
                    _('You have to select a Partner Invoice Address in the repair form!'
                      ))
            comment = repair.quotation_notes
            if (repair.invoice_method != 'none'):
                if group and repair.partner_invoice_id.id in invoices_group:
                    inv_id = invoices_group[repair.partner_invoice_id.id]
                    invoice = inv_obj.browse(cr, uid, inv_id)
                    invoice_vals = {
                        'name':
                        invoice.name + ', ' + repair.name,
                        'origin':
                        invoice.origin + ', ' + repair.name,
                        'comment':
                        (comment and
                         (invoice.comment and invoice.comment + "\n" + comment
                          or comment))
                        or (invoice.comment and invoice.comment or ''),
                    }
                    inv_obj.write(cr,
                                  uid, [inv_id],
                                  invoice_vals,
                                  context=context)
                else:
                    if not repair.partner_id.property_account_receivable_id:
                        raise UserError(
                            _('No account defined for partner "%s".') %
                            repair.partner_id.name)
                    account_id = repair.partner_id.property_account_receivable_id.id
                    inv = {
                        'name':
                        repair.name,
                        'origin':
                        repair.name,
                        'type':
                        'out_invoice',
                        'account_id':
                        account_id,
                        'partner_id':
                        repair.partner_invoice_id.id or repair.partner_id.id,
                        'currency_id':
                        repair.pricelist_id.currency_id.id,
                        'comment':
                        repair.quotation_notes,
                        'fiscal_position_id':
                        repair.partner_id.property_account_position_id.id
                    }
                    inv_id = inv_obj.create(cr, uid, inv)
                    invoices_group[repair.partner_invoice_id.id] = inv_id
                self.write(cr, uid, repair.id, {
                    'invoiced': True,
                    'invoice_id': inv_id
                })

                for operation in repair.operations:
                    if operation.to_invoice:
                        if group:
                            name = repair.name + '-' + operation.name
                        else:
                            name = operation.name

                        if operation.product_id.property_account_income_id:
                            account_id = operation.product_id.property_account_income_id.id
                        elif operation.product_id.categ_id.property_account_income_categ_id:
                            account_id = operation.product_id.categ_id.property_account_income_categ_id.id
                        else:
                            raise UserError(
                                _('No account defined for product "%s".') %
                                operation.product_id.name)

                        invoice_line_id = inv_line_obj.create(
                            cr, uid, {
                                'invoice_id':
                                inv_id,
                                'name':
                                name,
                                'origin':
                                repair.name,
                                'account_id':
                                account_id,
                                'quantity':
                                operation.product_uom_qty,
                                'invoice_line_tax_ids': [
                                    (6, 0, [x.id for x in operation.tax_id])
                                ],
                                'uos_id':
                                operation.product_uom.id,
                                'price_unit':
                                operation.price_unit,
                                'price_subtotal':
                                operation.product_uom_qty *
                                operation.price_unit,
                                'product_id':
                                operation.product_id
                                and operation.product_id.id or False
                            })
                        repair_line_obj.write(
                            cr, uid, [operation.id], {
                                'invoiced': True,
                                'invoice_line_id': invoice_line_id
                            })
                for fee in repair.fees_lines:
                    if fee.to_invoice:
                        if group:
                            name = repair.name + '-' + fee.name
                        else:
                            name = fee.name
                        if not fee.product_id:
                            raise UserError(_('No product defined on Fees!'))

                        if fee.product_id.property_account_income_id:
                            account_id = fee.product_id.property_account_income_id.id
                        elif fee.product_id.categ_id.property_account_income_categ_id:
                            account_id = fee.product_id.categ_id.property_account_income_categ_id.id
                        else:
                            raise UserError(
                                _('No account defined for product "%s".') %
                                fee.product_id.name)

                        invoice_fee_id = inv_line_obj.create(
                            cr, uid, {
                                'invoice_id':
                                inv_id,
                                'name':
                                name,
                                'origin':
                                repair.name,
                                'account_id':
                                account_id,
                                'quantity':
                                fee.product_uom_qty,
                                'invoice_line_tax_ids':
                                [(6, 0, [x.id for x in fee.tax_id])],
                                'uos_id':
                                fee.product_uom.id,
                                'product_id':
                                fee.product_id and fee.product_id.id or False,
                                'price_unit':
                                fee.price_unit,
                                'price_subtotal':
                                fee.product_uom_qty * fee.price_unit
                            })
                        repair_fee_obj.write(cr, uid, [fee.id], {
                            'invoiced': True,
                            'invoice_line_id': invoice_fee_id
                        })
                #inv_obj.button_reset_taxes(cr, uid, inv_id, context=context)
                res[repair.id] = inv_id
        return res

    def action_repair_ready(self, cr, uid, ids, context=None):
        """ Writes repair order state to 'Ready'
        @return: True
        """
        for repair in self.browse(cr, uid, ids, context=context):
            self.pool.get('mrp.repair.line').write(
                cr,
                uid, [l.id for l in repair.operations], {'state': 'confirmed'},
                context=context)
            self.write(cr, uid, [repair.id], {'state': 'ready'})
        return True

    def action_repair_start(self, cr, uid, ids, context=None):
        """ Writes repair order state to 'Under Repair'
        @return: True
        """
        repair_line = self.pool.get('mrp.repair.line')
        for repair in self.browse(cr, uid, ids, context=context):
            repair_line.write(cr,
                              uid, [l.id for l in repair.operations],
                              {'state': 'confirmed'},
                              context=context)
            repair.write({'state': 'under_repair'})
        return True

    def action_repair_end(self, cr, uid, ids, context=None):
        """ Writes repair order state to 'To be invoiced' if invoice method is
        After repair else state is set to 'Ready'.
        @return: True
        """
        for order in self.browse(cr, uid, ids, context=context):
            val = {}
            val['repaired'] = True
            if (not order.invoiced and order.invoice_method == 'after_repair'):
                val['state'] = '2binvoiced'
            elif (not order.invoiced and order.invoice_method == 'b4repair'):
                val['state'] = 'ready'
            else:
                pass
            self.write(cr, uid, [order.id], val)
        return True

    def wkf_repair_done(self, cr, uid, ids, *args):
        self.action_repair_done(cr, uid, ids)
        return True

    def action_repair_done(self, cr, uid, ids, context=None):
        """ Creates stock move for operation and stock move for final product of repair order.
        @return: Move ids of final products
        """
        res = {}
        move_obj = self.pool.get('stock.move')
        repair_line_obj = self.pool.get('mrp.repair.line')
        for repair in self.browse(cr, uid, ids, context=context):
            move_ids = []
            for move in repair.operations:
                move_id = move_obj.create(
                    cr, uid, {
                        'name':
                        move.name,
                        'product_id':
                        move.product_id.id,
                        'restrict_lot_id':
                        move.lot_id.id,
                        'product_uom_qty':
                        move.product_uom_qty,
                        'product_uom':
                        move.product_uom.id,
                        'partner_id':
                        repair.address_id and repair.address_id.id or False,
                        'location_id':
                        move.location_id.id,
                        'location_dest_id':
                        move.location_dest_id.id,
                    })
                move_ids.append(move_id)
                repair_line_obj.write(cr,
                                      uid, [move.id], {
                                          'move_id': move_id,
                                          'state': 'done'
                                      },
                                      context=context)
            move_id = move_obj.create(
                cr, uid, {
                    'name':
                    repair.name,
                    'product_id':
                    repair.product_id.id,
                    'product_uom':
                    repair.product_uom.id or repair.product_id.uom_id.id,
                    'product_uom_qty':
                    repair.product_qty,
                    'partner_id':
                    repair.address_id and repair.address_id.id or False,
                    'location_id':
                    repair.location_id.id,
                    'location_dest_id':
                    repair.location_dest_id.id,
                    'restrict_lot_id':
                    repair.lot_id.id,
                })
            move_ids.append(move_id)
            move_obj.action_done(cr, uid, move_ids, context=context)
            self.write(cr,
                       uid, [repair.id], {
                           'state': 'done',
                           'move_id': move_id
                       },
                       context=context)
            res[repair.id] = move_id
        return res
Пример #47
0
                carrier_grid = self.grid_get(cr, uid, [carrier.id], order.partner_shipping_id.id, context)
                if carrier_grid:
                    try:
                        price = grid_obj.get_price(cr, uid, carrier_grid, order, time.strftime("%Y-%m-%d"), context)
                        available = True
                    except osv.except_osv, e:
                        # no suitable delivery method found, probably configuration error
                        _logger.error("Carrier %s: %s\n%s" % (carrier.name, e.name, e.value))
                        price = 0.0
                else:
                    price = 0.0
            res[carrier.id] = {"price": price, "available": available}
        return res

    _columns = {
        "name": fields.char("Delivery Method", required=True),
        "partner_id": fields.many2one(
            "res.partner", "Transport Company", required=True, help="The partner that is doing the delivery service."
        ),
        "product_id": fields.many2one("product.product", "Delivery Product", required=True),
        "grids_id": fields.one2many("delivery.grid", "carrier_id", "Delivery Grids"),
        "available": fields.function(
            get_price,
            string="Available",
            type="boolean",
            multi="price",
            help="Is the carrier method possible with the current order.",
        ),
        "price": fields.function(get_price, string="Price", multi="price"),
        "active": fields.boolean(
            "Active",
Пример #48
0
class mrp_repair_fee(osv.osv, ProductChangeMixin):
    _name = 'mrp.repair.fee'
    _description = 'Repair Fees Line'

    def _amount_line(self, cr, uid, ids, field_name, arg, context=None):
        """ Calculates amount.
        @param field_name: Name of field.
        @param arg: Argument
        @return: Dictionary of values.
        """
        res = {}
        tax_obj = self.pool.get('account.tax')
        cur_obj = self.pool.get('res.currency')
        for line in self.browse(cr, uid, ids, context=context):
            if line.to_invoice:
                cur = line.repair_id.pricelist_id.currency_id
                taxes = tax_obj.compute_all(cr, uid, line.tax_id,
                                            line.price_unit, cur.id,
                                            line.product_uom_qty,
                                            line.product_id.id,
                                            line.repair_id.partner_id.id)
                res[line.id] = taxes['total_included']
            else:
                res[line.id] = 0
        return res

    _columns = {
        'repair_id':
        fields.many2one('mrp.repair',
                        'Repair Order Reference',
                        required=True,
                        ondelete='cascade',
                        select=True),
        'name':
        fields.char('Description', select=True, required=True),
        'product_id':
        fields.many2one('product.product', 'Product'),
        'product_uom_qty':
        fields.float(
            'Quantity',
            digits_compute=dp.get_precision('Product Unit of Measure'),
            required=True),
        'price_unit':
        fields.float('Unit Price', required=True),
        'product_uom':
        fields.many2one('product.uom',
                        'Product Unit of Measure',
                        required=True),
        'price_subtotal':
        fields.function(_amount_line, string='Subtotal', digits=0),
        'tax_id':
        fields.many2many('account.tax', 'repair_fee_line_tax',
                         'repair_fee_line_id', 'tax_id', 'Taxes'),
        'invoice_line_id':
        fields.many2one('account.invoice.line',
                        'Invoice Line',
                        readonly=True,
                        copy=False),
        'to_invoice':
        fields.boolean('To Invoice'),
        'invoiced':
        fields.boolean('Invoiced', readonly=True, copy=False),
    }

    _defaults = {
        'to_invoice': lambda *a: True,
    }
Пример #49
0
					gd_client = gdata.spreadsheet.service.SpreadsheetsService()
					gd_client.email = username
					gd_client.password =passwd
					gd_client.ProgrammaticLogin()
					q = gdata.spreadsheet.service.DocumentQuery()
					q['title'] = doc_title
					q['title-exact'] = 'true'
					feed = gd_client.GetSpreadsheetsFeed(query=q)
					spreadsheet_id = feed.entry[0].id.text.rsplit('/',1)[1]
					feed = gd_client.GetWorksheetsFeed(spreadsheet_id)
					worksheet_id = feed.entry[0].id.text.rsplit('/',1)[1]
					rows = gd_client.GetListFeed(spreadsheet_id, worksheet_id).entry
					row = rows[43]
					row2 = rows[44]
					row_key = row.custom.keys()[2]
					factor =row.custom[row_key].text
					row2_key = row2.custom.keys()[1]
					labor_factor = row2.custom[row2_key].text 
					sale_price = float(factor) * float(cost_price)
					labor_cost = float(labor_factor) * float(time_factor)
					line.write({'purchase_price': sale_price,'labor_cost':labor_cost, 'calculate': True})
				except Exception, e:
					raise osv.except_osv(_('User Error!'), _('Authenticate with Google Spreadsheet Fail Please see Configuration in Setting/User/Syncronization.'))   			
		return True

	_name = 'calculate.line'
	_columns = {
		'name': fields.char('Name', size=64),
	}
calulate_line()
Пример #50
0
class mrp_repair_line(osv.osv, ProductChangeMixin):
    _name = 'mrp.repair.line'
    _description = 'Repair Line'

    def _amount_line(self, cr, uid, ids, field_name, arg, context=None):
        """ Calculates amount.
        @param field_name: Name of field.
        @param arg: Argument
        @return: Dictionary of values.
        """
        res = {}
        tax_obj = self.pool.get('account.tax')
        # cur_obj = self.pool.get('res.currency')
        for line in self.browse(cr, uid, ids, context=context):
            if line.to_invoice:
                cur = line.repair_id.pricelist_id.currency_id
                taxes = tax_obj.compute_all(cr, uid, line.tax_id,
                                            line.price_unit, cur.id,
                                            line.product_uom_qty,
                                            line.product_id.id,
                                            line.repair_id.partner_id.id)
                #res[line.id] = cur_obj.round(cr, uid, cur, taxes['total'])
                res[line.id] = taxes['total_included']
            else:
                res[line.id] = 0
        return res

    _columns = {
        'name':
        fields.char('Description', required=True),
        'repair_id':
        fields.many2one('mrp.repair',
                        'Repair Order Reference',
                        ondelete='cascade',
                        select=True),
        'type':
        fields.selection([('add', 'Add'), ('remove', 'Remove')],
                         'Type',
                         required=True),
        'to_invoice':
        fields.boolean('To Invoice'),
        'product_id':
        fields.many2one('product.product', 'Product', required=True),
        'invoiced':
        fields.boolean('Invoiced', readonly=True, copy=False),
        'price_unit':
        fields.float('Unit Price',
                     required=True,
                     digits_compute=dp.get_precision('Product Price')),
        'price_subtotal':
        fields.function(_amount_line, string='Subtotal', digits=0),
        'tax_id':
        fields.many2many('account.tax', 'repair_operation_line_tax',
                         'repair_operation_line_id', 'tax_id', 'Taxes'),
        'product_uom_qty':
        fields.float(
            'Quantity',
            digits_compute=dp.get_precision('Product Unit of Measure'),
            required=True),
        'product_uom':
        fields.many2one('product.uom',
                        'Product Unit of Measure',
                        required=True),
        'invoice_line_id':
        fields.many2one('account.invoice.line',
                        'Invoice Line',
                        readonly=True,
                        copy=False),
        'location_id':
        fields.many2one('stock.location',
                        'Source Location',
                        required=True,
                        select=True),
        'location_dest_id':
        fields.many2one('stock.location',
                        'Dest. Location',
                        required=True,
                        select=True),
        'move_id':
        fields.many2one('stock.move',
                        'Inventory Move',
                        readonly=True,
                        copy=False),
        'lot_id':
        fields.many2one('stock.production.lot', 'Lot'),
        'state':
        fields.selection(
            [('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'),
             ('cancel', 'Cancelled')],
            'Status',
            required=True,
            readonly=True,
            copy=False,
            help=
            ' * The \'Draft\' status is set automatically as draft when repair order in draft status. \
                        \n* The \'Confirmed\' status is set automatically as confirm when repair order in confirm status. \
                        \n* The \'Done\' status is set automatically when repair order is completed.\
                        \n* The \'Cancelled\' status is set automatically when user cancel repair order.'
        ),
    }
    _defaults = {
        'state': lambda *a: 'draft',
        'product_uom_qty': lambda *a: 1,
    }

    def onchange_operation_type(self,
                                cr,
                                uid,
                                ids,
                                type,
                                guarantee_limit,
                                company_id=False,
                                context=None):
        """ On change of operation type it sets source location, destination location
        and to invoice field.
        @param product: Changed operation type.
        @param guarantee_limit: Guarantee limit of current record.
        @return: Dictionary of values.
        """
        if not type:
            return {'value': {'location_id': False, 'location_dest_id': False}}
        location_obj = self.pool.get('stock.location')
        warehouse_obj = self.pool.get('stock.warehouse')
        location_id = location_obj.search(cr,
                                          uid, [('usage', '=', 'production')],
                                          context=context)
        location_id = location_id and location_id[0] or False

        if type == 'add':
            # TOCHECK: Find stock location for user's company warehouse or
            # repair order's company's warehouse (company_id field is added in fix of lp:831583)
            args = company_id and [('company_id', '=', company_id)] or []
            warehouse_ids = warehouse_obj.search(cr,
                                                 uid,
                                                 args,
                                                 context=context)
            stock_id = False
            if warehouse_ids:
                stock_id = warehouse_obj.browse(
                    cr, uid, warehouse_ids[0], context=context).lot_stock_id.id
            to_invoice = (guarantee_limit and datetime.strptime(
                guarantee_limit, '%Y-%m-%d') < datetime.now())

            return {
                'value': {
                    'to_invoice': to_invoice,
                    'location_id': stock_id,
                    'location_dest_id': location_id
                }
            }
        scrap_location_ids = location_obj.search(
            cr, uid, [('scrap_location', '=', True)], context=context)

        return {
            'value': {
                'to_invoice':
                False,
                'location_id':
                location_id,
                'location_dest_id':
                scrap_location_ids and scrap_location_ids[0] or False,
            }
        }
Пример #51
0
    return list(enumerate(["Corge", "Grault", "Wheee", "Moog"]))

def function_fn(model, cr, uid, ids, field_name, arg, context):
    return dict((id, 3) for id in ids)

def function_fn_write(model, cr, uid, id, field_name, field_value, fnct_inv_arg, context):
    """ just so CreatorCase.export can be used
    """
    pass

models = [
    ('boolean', fields.boolean()),
    ('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
class account_cutoff(orm.Model):
    _name = 'account.cutoff'
    _rec_name = 'cutoff_date'
    _order = 'cutoff_date desc'
    _inherit = ['mail.thread']
    _description = 'Account Cut-off'
    _track = {
        'state': {
            'account_cutoff_base.cutoff_done':
            lambda self, cr, uid, obj, ctx=None: obj['state'] == 'done',
            }
        }

    def copy(self, cr, uid, id, default=None, context=None):
        if default is None:
            default = {}
        default.update({
            'cutoff_date': '%d-12-31' % datetime.today().year,
            'move_id': False,
            'state': 'draft',
            'line_ids': False,
            })
        return super(account_cutoff, self).copy(
            cr, uid, id, default=default, context=context)

    def _compute_total_cutoff(self, cr, uid, ids, name, arg, context=None):
        res = {}
        for cutoff in self.browse(cr, uid, ids, context=context):
            res[cutoff.id] = 0
            for line in cutoff.line_ids:
                res[cutoff.id] += line.cutoff_amount
        return res

    _columns = {
        'cutoff_date': fields.date(
            'Cut-off Date', required=True, readonly=True,
            states={'draft': [('readonly', False)]},
            track_visibility='always'),
        'type': fields.selection([
            ('accrued_revenue', 'Accrued Revenue'),
            ('accrued_expense', 'Accrued Expense'),
            ('prepaid_revenue', 'Prepaid Revenue'),
            ('prepaid_expense', 'Prepaid Expense'),
            ], 'Type', required=True, readonly=True,
            states={'draft': [('readonly', False)]}),
        'move_id': fields.many2one(
            'account.move', 'Cut-off Journal Entry', readonly=True),
        'move_label': fields.char(
            'Label of the Cut-off Journal Entry',
            size=64, required=True, readonly=True,
            states={'draft': [('readonly', False)]},
            help="This label will be written in the 'Name' field of the "
            "Cut-off Account Move Lines and in the 'Reference' field of "
            "the Cut-off Account Move."),
        'cutoff_account_id': fields.many2one(
            'account.account', 'Cut-off Account',
            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
            required=True, readonly=True,
            states={'draft': [('readonly', False)]}),
        'cutoff_journal_id': fields.many2one(
            'account.journal', 'Cut-off Account Journal', required=True,
            readonly=True, states={'draft': [('readonly', False)]}),
        'total_cutoff_amount': fields.function(
            _compute_total_cutoff, type='float', string="Total Cut-off Amount",
            readonly=True, track_visibility='always'),
        'company_id': fields.many2one(
            'res.company', 'Company', required=True, readonly=True,
            states={'draft': [('readonly', False)]}),
        'company_currency_id': fields.related(
            'company_id', 'currency_id', readonly=True, type='many2one',
            relation='res.currency', string='Company Currency'),
        'line_ids': fields.one2many(
            'account.cutoff.line', 'parent_id', 'Cut-off Lines', readonly=True,
            states={'draft': [('readonly', False)]}),
        'state': fields.selection([
            ('draft', 'Draft'),
            ('done', 'Done'),
            ],
            'State', select=True, readonly=True, track_visibility='onchange',
            help="State of the cutoff. When the Journal Entry is created, "
            "the state is set to 'Done' and the fields become read-only."),
    }

    def _get_default_journal(self, cr, uid, context=None):
        cur_user = self.pool['res.users'].browse(cr, uid, uid, context=context)
        return cur_user.company_id.default_cutoff_journal_id.id or None

    def _default_move_label(self, cr, uid, context=None):
        if context is None:
            context = {}
        type = context.get('type')
        cutoff_date = context.get('cutoff_date')
        if cutoff_date:
            cutoff_date_label = ' dated %s' % cutoff_date
        else:
            cutoff_date_label = ''
        label = ''
        if type == 'accrued_expense':
            label = _('Accrued Expense%s') % cutoff_date_label
        elif type == 'accrued_revenue':
            label = _('Accrued Revenue%s') % cutoff_date_label
        elif type == 'prepaid_revenue':
            label = _('Prepaid Revenue%s') % cutoff_date_label
        elif type == 'prepaid_expense':
            label = _('Prepaid Expense%s') % cutoff_date_label
        return label

    def _default_type(self, cr, uid, context=None):
        if context is None:
            context = {}
        return context.get('type')

    def _inherit_default_cutoff_account_id(self, cr, uid, context=None):
        '''Function designed to be inherited by other cutoff modules'''
        return None

    def _default_cutoff_account_id(self, cr, uid, context=None):
        '''This function can't be inherited, so we use a second function'''
        return self._inherit_default_cutoff_account_id(
            cr, uid, context=context)

    _defaults = {
        'state': 'draft',
        'company_id': lambda self, cr, uid, context:
        self.pool['res.users'].browse(
            cr, uid, uid, context=context).company_id.id,
        'cutoff_journal_id': _get_default_journal,
        'move_label': _default_move_label,
        'type': _default_type,
        'cutoff_account_id': _default_cutoff_account_id,
        }

    _sql_constraints = [(
        'date_type_company_uniq',
        'unique(cutoff_date, company_id, type)',
        'A cutoff of the same type already exists with this cut-off date !'
        )]

    def cutoff_date_onchange(
            self, cr, uid, ids, type, cutoff_date, move_label):
        res = {'value': {}}
        if type and cutoff_date:
            context = {'type': type, 'cutoff_date': cutoff_date}
            res['value']['move_label'] = self._default_move_label(
                cr, uid, context=context)
        return res

    def back2draft(self, cr, uid, ids, context=None):
        assert len(ids) == 1,\
            'This function should only be used for a single id at a time'
        cur_cutoff = self.browse(cr, uid, ids[0], context=context)
        if cur_cutoff.move_id:
            self.pool['account.move'].unlink(
                cr, uid, [cur_cutoff.move_id.id], context=context)
        self.write(cr, uid, ids[0], {'state': 'draft'}, context=context)
        return True

    def _prepare_move(self, cr, uid, cur_cutoff, to_provision, context=None):
        if context is None:
            context = {}
        movelines_to_create = []
        amount_total = 0
        move_label = cur_cutoff.move_label
        for (cutoff_account_id, analytic_account_id), amount in \
                to_provision.items():
            movelines_to_create.append((0, 0, {
                'account_id': cutoff_account_id,
                'name': move_label,
                'debit': amount < 0 and amount * -1 or 0,
                'credit': amount >= 0 and amount or 0,
                'analytic_account_id': analytic_account_id,
            }))
            amount_total += amount

        # add contre-partie
        counterpart_amount = amount_total * -1
        movelines_to_create.append((0, 0, {
            'account_id': cur_cutoff.cutoff_account_id.id,
            'debit': counterpart_amount < 0 and counterpart_amount * -1 or 0,
            'credit': counterpart_amount >= 0 and counterpart_amount or 0,
            'name': move_label,
            'analytic_account_id': False,
        }))

        # Select period
        local_ctx = context.copy()
        local_ctx['account_period_prefer_normal'] = True
        period_search = self.pool['account.period'].find(
            cr, uid, cur_cutoff.cutoff_date, context=local_ctx)
        if len(period_search) != 1:
            raise orm.except_orm(
                'Error:', "No matching period for date '%s'"
                % cur_cutoff.cutoff_date)
        period_id = period_search[0]

        res = {
            'journal_id': cur_cutoff.cutoff_journal_id.id,
            'date': cur_cutoff.cutoff_date,
            'period_id': period_id,
            'ref': move_label,
            'line_id': movelines_to_create,
            }
        return res

    def create_move(self, cr, uid, ids, context=None):
        assert len(ids) == 1, \
            'This function should only be used for a single id at a time'
        move_obj = self.pool['account.move']
        cur_cutoff = self.browse(cr, uid, ids[0], context=context)
        if cur_cutoff.move_id:
            raise orm.except_orm(
                _('Error:'),
                _("The Cut-off Journal Entry already exists. You should "
                    "delete it before running this function."))
        if not cur_cutoff.line_ids:
            raise orm.except_orm(
                _('Error:'),
                _("There are no lines on this Cut-off, so we can't create "
                    "a Journal Entry."))
        to_provision = {}
        # key = (cutoff_account_id, analytic_account_id)
        # value = amount
        for line in cur_cutoff.line_ids:
            # if it is already present
            if (
                    line.cutoff_account_id.id,
                    line.analytic_account_id.id or False
                    ) in to_provision:
                to_provision[(
                    line.cutoff_account_id.id,
                    line.analytic_account_id.id or False
                    )] += line.cutoff_amount
            else:
            # if not already present
                to_provision[(
                    line.cutoff_account_id.id,
                    line.analytic_account_id.id or False
                    )] = line.cutoff_amount
            # Same for tax lines
            for tax_line in line.tax_line_ids:
                if (
                        tax_line.cutoff_account_id.id,
                        tax_line.analytic_account_id.id or False
                        ) in to_provision:
                    to_provision[(
                        tax_line.cutoff_account_id.id,
                        tax_line.analytic_account_id.id or False
                        )] += tax_line.cutoff_amount
                else:
                    to_provision[(
                        tax_line.cutoff_account_id.id,
                        tax_line.analytic_account_id.id or False
                        )] = tax_line.cutoff_amount

        vals = self._prepare_move(
            cr, uid, cur_cutoff, to_provision, context=context)
        move_id = move_obj.create(cr, uid, vals, context=context)
        move_obj.validate(cr, uid, [move_id], context=context)
        self.write(cr, uid, ids[0], {
            'move_id': move_id,
            'state': 'done',
            }, context=context)

        action = {
            'name': 'Cut-off Account Move',
            'view_type': 'form',
            'view_mode': 'form,tree',
            'res_id': move_id,
            'view_id': False,
            'res_model': 'account.move',
            'type': 'ir.actions.act_window',
            'nodestroy': False,
            'target': 'current',
            }
        return action
Пример #53
0
                    price=grid_obj.get_price(cr, uid, carrier_grid, order, time.strftime('%Y-%m-%d'), context)
                    available = True
                  except UserError, e:
                    # no suitable delivery method found, probably configuration error
                    _logger.info("Carrier %s: %s", carrier.name, e.name)
                    price = 0.0
              else:
                  price = 0.0
            res[carrier.id] = {
                'price': price,
                'available': available
            }
        return res

    _columns = {
        'name': fields.char('Delivery Method', required=True, translate=True),
        'sequence': fields.integer('Sequence', help="Determine the display order"),
        'partner_id': fields.many2one('res.partner', 'Transport Company', required=True, help="The partner that is doing the delivery service."),
        'product_id': fields.many2one('product.product', 'Delivery Product', required=True),
        'grids_id': fields.one2many('delivery.grid', 'carrier_id', 'Delivery Grids'),
        'available' : fields.function(get_price, string='Available',type='boolean', multi='price',
            help="Is the carrier method possible with the current order."),
        'price' : fields.function(get_price, string='Price', multi='price'),
        'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the delivery carrier without removing it."),
        'normal_price': fields.float('Normal Price', help="Keep empty if the pricing depends on the advanced pricing per destination"),
        'free_if_more_than': fields.boolean('Free If Order Total Amount Is More Than', help="If the order is more expensive than a certain amount, the customer can benefit from a free shipping"),
        'amount': fields.float('Amount', help="Amount of the order to benefit from a free shipping, expressed in the company currency"),
        'use_detailed_pricelist': fields.boolean('Advanced Pricing per Destination', help="Check this box if you want to manage delivery prices that depends on the destination, the weight, the total of the order, etc."),
        'pricelist_ids': fields.one2many('delivery.grid', 'carrier_id', 'Advanced Pricing'),
    }
Пример #54
0
class MassObject(orm.Model):
    _name = "mass.object"

    _columns = {
        'name':
        fields.char("Name", size=64, required=True, select=1),
        'model_id':
        fields.many2one('ir.model', 'Model', required=True, select=1),
        'field_ids':
        fields.many2many('ir.model.fields', 'mass_field_rel', 'mass_id',
                         'field_id', 'Fields'),
        'ref_ir_act_window':
        fields.many2one(
            'ir.actions.act_window',
            'Sidebar Action',
            readonly=True,
            help="Sidebar action to make this template available on records \
                 of the related document model"),
        'ref_ir_value':
        fields.many2one('ir.values',
                        'Sidebar Button',
                        readonly=True,
                        help="Sidebar button to open the sidebar action"),
        'model_ids':
        fields.many2many('ir.model', string='Model List')
    }

    _sql_constraints = [
        ('name_uniq', 'unique (name)', _('Name must be unique!')),
    ]

    def onchange_model(self, cr, uid, ids, model_id, context=None):
        if context is None:
            context = {}
        if not model_id:
            return {'value': {'model_ids': [(6, 0, [])]}}
        model_ids = [model_id]
        model_obj = self.pool['ir.model']
        active_model_obj = self.pool.get(
            model_obj.browse(cr, uid, model_id).model)
        if active_model_obj._inherits:
            for key, val in active_model_obj._inherits.items():
                found_model_ids = model_obj.search(cr,
                                                   uid, [('model', '=', key)],
                                                   context=context)
                model_ids += found_model_ids
        return {'value': {'model_ids': [(6, 0, model_ids)]}}

    def create_action(self, cr, uid, ids, context=None):
        vals = {}
        action_obj = self.pool['ir.actions.act_window']
        ir_values_obj = self.pool['ir.values']
        for data in self.browse(cr, uid, ids, context=context):
            src_obj = data.model_id.model
            button_name = _('Mass Editing (%s)') % data.name
            vals['ref_ir_act_window'] = action_obj.create(
                cr, SUPERUSER_ID, {
                    'name': button_name,
                    'type': 'ir.actions.act_window',
                    'res_model': 'mass.editing.wizard',
                    'src_model': src_obj,
                    'view_type': 'form',
                    'context': "{'mass_editing_object' : %d}" % (data.id),
                    'view_mode': 'form,tree',
                    'target': 'new',
                    'auto_refresh': 1,
                }, context)
            vals['ref_ir_value'] = ir_values_obj.create(
                cr, SUPERUSER_ID, {
                    'name':
                    button_name,
                    'model':
                    src_obj,
                    'key2':
                    'client_action_multi',
                    'value': ("ir.actions.act_window," +
                              str(vals['ref_ir_act_window'])),
                    'object':
                    True,
                }, context)
        self.write(
            cr, uid, ids, {
                'ref_ir_act_window': vals.get('ref_ir_act_window', False),
                'ref_ir_value': vals.get('ref_ir_value', False),
            }, context)
        return True

    def unlink_action(self, cr, uid, ids, context=None):
        for template in self.browse(cr, uid, ids, context=context):
            try:
                if template.ref_ir_act_window:
                    act_window_obj = self.pool['ir.actions.act_window']
                    act_window_obj.unlink(cr,
                                          SUPERUSER_ID,
                                          [template.ref_ir_act_window.id],
                                          context=context)
                if template.ref_ir_value:
                    ir_values_obj = self.pool['ir.values']
                    ir_values_obj.unlink(cr,
                                         SUPERUSER_ID,
                                         template.ref_ir_value.id,
                                         context=context)
            except:
                raise orm.except_orm(
                    _("Warning"), _("Deletion of the action record failed."))
        return True

    def unlink(self, cr, uid, ids, context=None):
        self.unlink_action(cr, uid, ids, context=context)
        return super(MassObject, self).unlink(cr, uid, ids, context=context)

    def copy(self, cr, uid, record_id, default=None, context=None):
        if default is None:
            default = {}
        default.update({'name': '', 'field_ids': []})
        return super(MassObject, self).copy(cr,
                                            uid,
                                            record_id,
                                            default,
                                            context=context)
Пример #55
0
        return res

    def _get_icon_image(self, cr, uid, ids, field_name=None, arg=None, context=None):
        res = dict.fromkeys(ids, '')
        for module in self.browse(cr, uid, ids, context=context):
            path = addons.get_module_resource(module.name, 'static', 'src', 'img', 'icon.png')
            if path:
                image_file = tools.file_open(path, 'rb')
                try:
                    res[module.id] = image_file.read().encode('base64')
                finally:
                    image_file.close()
        return res

    _columns = {
        'name': fields.char("Technical Name", size=128, readonly=True, required=True, select=True),
        'category_id': fields.many2one('ir.module.category', 'Category', readonly=True, select=True),
        'shortdesc': fields.char('Module Name', size=64, readonly=True, translate=True),
        'summary': fields.char('Summary', size=64, readonly=True, translate=True),
        'description': fields.text("Description", readonly=True, translate=True),
        'description_html': fields.function(_get_desc, string='Description HTML', type='html', method=True, readonly=True),
        'author': fields.char("Author", size=128, readonly=True),
        'maintainer': fields.char('Maintainer', size=128, readonly=True),
        'contributors': fields.text('Contributors', readonly=True),
        'website': fields.char("Website", size=256, readonly=True),

        # attention: Incorrect field names !!
        #   installed_version refers the latest version (the one on disk)
        #   latest_version refers the installed version (the one in database)
        #   published_version refers the version available on the repository
        'installed_version': fields.function(_get_latest_version, string='Latest Version', type='char'),
Пример #56
0
class posix_forward(osv.Model):
    def _get_email(self, cr, uid, ids, field_names, arg, context=None):
        cr.execute(
            "SELECT f.id, f.from_name, from_d.complete_name, f.to_name, to_d.complete_name FROM posix_mailforward AS f "
            "    LEFT JOIN posix_domain AS from_d ON from_d.id = f.from_domain_id "
            "    LEFT JOIN posix_domain AS to_d ON to_d.id = f.to_domain_id "
            " WHERE f.id IN %s", (tuple(ids), ))
        res = dict.fromkeys(ids)
        for row in cr.fetchall():
            forward_id = row[0]
            from_name = row[1]
            from_domain = row[2]
            to_name = row[3]
            to_domain = row[4]

            from_mail = None
            to_mail = None

            if from_name and from_domain:
                from_mail = ("%s@%s" % (from_name, from_domain))
            elif not from_name and from_domain:
                from_mail = ("@%s" % (from_domain, ))

            if to_name and to_domain:
                to_mail = ("%s@%s" % (to_name, to_domain))

            elif not to_name and to_domain:
                to_mail = ("@%s" % (to_domain, ))

            res[forward_id] = {"from_email": from_mail, "to_email": to_mail}
        return res

    def _relids_from_domain(self, cr, uid, ids, context=None):
        forward_obj = self.pool.get("posix.mailforward")
        res = forward_obj.search(cr, uid, [("from_domain_id", "in", ids)])
        return res

    def _relids_to_domain(self, cr, uid, ids, context=None):
        forward_obj = self.pool.get("posix.mailforward")
        res = forward_obj.search(cr, uid, [("to_domain_id", "in", ids)])
        return res

    _name = "posix.mailforward"
    _description = "Mail Forward"
    _columns = {
        "from_name":
        fields.char("From", size=64, required=False),
        "from_domain_id":
        fields.many2one("posix.domain",
                        string="From Domain",
                        required=True,
                        ondelete="restrict"),
        "from_domain_name":
        fields.related("from_domain_id",
                       "complete_name",
                       string="From Domain",
                       type="char",
                       size=64,
                       store=True),
        "to_name":
        fields.char("To", size=64, required=False),
        "to_domain_id":
        fields.many2one("posix.domain",
                        string="To Domain",
                        required=True,
                        ondelete="restrict"),
        "to_domain_name":
        fields.related("to_domain_id",
                       "complete_name",
                       string="To Domain",
                       type="char",
                       size=64,
                       store=True),
        "from_email":
        fields.function(_get_email,
                        string="From E-Mail",
                        type="char",
                        size=128,
                        readonly=True,
                        select=True,
                        multi="email",
                        store={
                            "posix.mailforward":
                            (lambda self, cr, uid, ids, context=None: ids,
                             ["from_name", "from_domain_id"], 10),
                            "posix.domain":
                            (_relids_from_domain, ["name", "parent_id"], 11)
                        }),
        "to_email":
        fields.function(_get_email,
                        string="To E-Mail",
                        type="char",
                        size=128,
                        readonly=True,
                        select=True,
                        multi="email",
                        store={
                            "posix.mailforward":
                            (lambda self, cr, uid, ids, context=None: ids,
                             ["to_name", "to_domain_id"], 10),
                            "posix.domain":
                            (_relids_to_domain, ["name", "parent_id"], 11)
                        })
    }
ATTR_USE_DOM_PINVOICE = ('i', 'Invoice Address')
ATTR_USE_DOM_PSHIPPER = ('s', 'Shipping Address')
ATTR_USE_DOM_PRODUCT = ('p', 'Product')
ATTR_USE = (ATTR_USE_DOM_COMPANY, ATTR_USE_DOM_PINVOICE, ATTR_USE_DOM_PSHIPPER, ATTR_USE_DOM_PRODUCT)
# Thank you!

ACC_FISC_ALLOC_RULE_COLS_TMPL = {

    # Note: This are template style fields.
    # For nontemplate fields you might add aditional constraints to specific nontemplate fields (eg. company_id).
    # The chain method from itertools updates fields. Consider using this from within the nontemplate class when adding
    # new fields.

    # --- GENERAL SECTION ---

    'name': fields.char('Name', required=True),
    'description': fields.char('Description'),
    # This fiscal domain will narrow down the available fiscal attributes / fiscal allocations.
    # It should help clustering and reducing complexity. Rules are applied *additionally*
    # preserving the result (reed: taxes applied) of previous iterations.
    # However it is optional. You can construct more complex "cross-domain" rules leaving it empty.
    'fiscal_domain_id': fields.many2one('account.fiscal.domain', 'Fiscal Domain', required=True, select=True),
    'is_account_allocation': fields.boolean(u'Account Allocation?'),

    # --- CRITERION SECTION ---

    '{0}_country'.format(ATTR_USE_DOM_COMPANY[0]): fields.many2one('res.country', 'Country'),
    '{0}_state'.format(ATTR_USE_DOM_COMPANY[0]): fields.many2one(
        'res.country.state', 'State',
        domain="[('country_id','=',{0}_country)]".format(ATTR_USE_DOM_COMPANY[0])),
    'to_{0}_country'.format(ATTR_USE_DOM_PINVOICE[0]): fields.many2one(
Пример #58
0
class account_sequence_installer(osv.osv_memory):
    _name = 'account.sequence.installer'
    _inherit = 'res.config.installer'

    _columns = {
        'name':
        fields.char('Name', required=True),
        'prefix':
        fields.char('Prefix',
                    size=64,
                    help="Prefix value of the record for the sequence"),
        'suffix':
        fields.char('Suffix',
                    size=64,
                    help="Suffix value of the record for the sequence"),
        'number_next':
        fields.integer('Next Number',
                       required=True,
                       help="Next number of this sequence"),
        'number_increment':
        fields.integer(
            'Increment Number',
            required=True,
            help=
            "The next number of the sequence will be incremented by this number"
        ),
        'padding':
        fields.integer(
            'Number padding',
            required=True,
            help=
            "Odoo will automatically adds some '0' on the left of the 'Next Number' to get the required padding size."
        ),
        'company_id':
        fields.many2one('res.company', 'Company'),
    }
    _defaults = {
        'company_id':
        lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(
            cr, uid, 'ir.sequence', context=c),
        'number_increment':
        1,
        'number_next':
        1,
        'padding':
        0,
        'name':
        'Internal Sequence Journal',
    }

    def execute(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        record = self.browse(cr, uid, ids, context=context)[0]
        j_ids = []
        if record.company_id:
            company_id = record.company_id.id,
            search_criteria = [('company_id', '=', company_id)]
        else:
            company_id = False
            search_criteria = []
        vals = {
            'id': 'internal_sequence_journal',
            'code': 'account.journal',
            'name': record.name,
            'prefix': record.prefix,
            'suffix': record.suffix,
            'number_next': record.number_next,
            'number_increment': record.number_increment,
            'padding': record.padding,
            'company_id': company_id,
        }

        obj_sequence = self.pool.get('ir.sequence')
        ir_seq = obj_sequence.create(cr, uid, vals, context)
        res = super(account_sequence_installer, self).execute(cr,
                                                              uid,
                                                              ids,
                                                              context=context)
        #jou_obj = self.pool.get('account.journal')
        #journal_ids = jou_obj.search(cr, uid, search_criteria, context=context)
        #for journal in jou_obj.browse(cr, uid, journal_ids, context=context):
        #    if not journal.internal_sequence_id:
        #        j_ids.append(journal.id)
        #if j_ids:
        #    jou_obj.write(cr, uid, j_ids, {'internal_sequence_id': ir_seq})
        #ir_values_obj = self.pool.get('ir.values')
        #ir_values_obj.set(cr, uid, key='default', key2=False, name='internal_sequence_id', models =[('account.journal', False)], value=ir_seq)
        return res
Пример #59
0
                url_medium = name + "medium" + extention
                url_small = name + "small" + extention
                return self.write(
                    cr,
                    uid,
                    id,
                    {"url": url, "url_big": url_big, "url_medium": url_medium, "url_small": url_small},
                    context=context,
                )
            else:
                return False

        return self.write(cr, uid, id, {"file_db_store": value}, context=context)

    _columns = {
        "name": fields.char("Image Title", size=64),
        "filename": fields.char("Filename", size=64),
        "extension": fields.char("file extension", oldname="extention"),
        "link": fields.boolean(
            "Link?", help="Images can be linked from files on " "your file system or remote (Preferred)"
        ),
        "file_db_store": fields.binary("Image stored in database"),
        "file": fields.function(
            _get_image, fnct_inv=_set_image, type="binary", string="File", filters="*.png,*.jpg,*.gif"
        ),
        "url": fields.char("File Location"),
        "url_big": fields.char("File Location Image Size Big"),
        "url_medium": fields.char("File Location Image Size Medium"),
        "url_small": fields.char("File Location Image Size Small"),
        "comments": fields.text("Comments"),
        "product_id": fields.many2one("product.product", "Product"),
Пример #60
0
class cuti_kuliah(osv.Model):
    _name = 'cuti.kuliah'

    _columns = {
        'name':
        fields.char('Kode Cuti', size=36, required=True),
        'partner_id':
        fields.many2one('res.partner',
                        'Mahasiswa',
                        required=True,
                        readonly=True,
                        domain="[('status_mahasiswa','=','Mahasiswa')]"),
        'from_semester_id':
        fields.many2one('master.semester', 'Dari Semester', required=True),
        'to_semester_id':
        fields.many2one('master.semester', 'Sampai Semester', required=True),
        'kelas_id':
        fields.many2one('master.kelas', string='Kelas', required=False),
        'prodi_id':
        fields.many2one('master.prodi', 'Program Studi', required=True),
        # 'jurusan_id':fields.many2one('master.jurusan','Jurusan',required=True,readonly=True, states={'draft': [('readonly', False)]}),
        'fakultas_id':
        fields.many2one('master.fakultas', 'Fakultas', required=True),
        'tahun_ajaran_id':
        fields.many2one('academic.year', 'Angkatan', required=True),
        'state':
        fields.selection([('draft', 'Draft'), ('waiting', 'Waiting Approval'),
                          ('confirm', 'Confirmed'), ('cancel', 'Canceled'),
                          ('refuse', 'Refused'), ('done', 'Done')], 'Status'),
        'notes':
        fields.text('Alasan', required=True),
        'user_id':
        fields.many2one('res.users', 'User', readonly=True),
        'date':
        fields.date('Tanggal Aktif Kembali'),
        'automatic_done':
        fields.boolean('Automatic Done'),
    }

    _defaults = {
        'state':
        'draft',
        'user_id':
        lambda obj, cr, uid, context: uid,
        'name':
        lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(
            cr, uid, 'cuti.kuliah'),
    }

    _sql_constraints = [('name_uniq', 'unique(name)',
                         'Kode cuti kuliah tidak boleh sama')]

    # def onchange_partner(self, cr, uid, ids, tahun_ajaran_id, fakultas_id, jurusan_id, prodi_id, kelas_id, partner_id, context=None):
    def onchange_partner(self,
                         cr,
                         uid,
                         ids,
                         tahun_ajaran_id,
                         fakultas_id,
                         prodi_id,
                         kelas_id,
                         partner_id,
                         context=None):
        results = {}
        if not partner_id:
            return results

        par_obj = self.pool.get('res.partner')
        par_ids = par_obj.search(cr,
                                 uid, [('id', '=', partner_id)],
                                 context=context)

        #import pdb;pdb.set_trace()
        par_id = par_obj.browse(cr, uid, par_ids, context=context)[0]
        kelas_id = par_id.kelas_id.id
        tahun_ajaran_id = par_id.tahun_ajaran_id.id
        fakultas_id = par_id.fakultas_id.id
        # jurusan_id = par_id.jurusan_id.id
        prodi_id = par_id.prodi_id.id

        results = {
            'value': {
                'kelas_id': kelas_id,
                'tahun_ajaran_id': tahun_ajaran_id,
                'fakultas_id': fakultas_id,
                # 'jurusan_id' : jurusan_id,
                'prodi_id': prodi_id,
            }
        }
        return results

    def confirm(self, cr, uid, ids, context=None):
        for ct in self.browse(cr, uid, ids):
            self.write(cr, uid, ct.id, {'state': 'waiting'}, context=context)
        return True

    def approve(self, cr, uid, ids, context=None):
        for ct in self.browse(cr, uid, ids):
            mhs_id = ct.partner_id.id
            self.pool.get('res.partner').write(cr,
                                               uid,
                                               mhs_id,
                                               {'status_mahasiswa': 'cuti'},
                                               context=context)
            self.write(cr, uid, ct.id, {'state': 'confirm'}, context=context)
        return True

    def cancel(self, cr, uid, ids, context=None):
        for ct in self.browse(cr, uid, ids):
            self.write(cr, uid, ct.id, {'state': 'cancel'}, context=context)
        return True

    def set_draft(self, cr, uid, ids, context=None):
        for ct in self.browse(cr, uid, ids):
            self.write(cr, uid, ct.id, {'state': 'draft'}, context=context)
        return True

    def refuse(self, cr, uid, ids, context=None):
        for ct in self.browse(cr, uid, ids):
            self.write(cr, uid, ct.id, {'state': 'refuse'}, context=context)
        return True

    def done(self, cr, uid, ids, context=None):
        for ct in self.browse(cr, uid, ids):
            mhs_id = ct.partner_id.id
            self.pool.get('res.partner').write(
                cr,
                uid,
                mhs_id, {'status_mahasiswa': 'Mahasiswa'},
                context=context)
            self.write(cr, uid, ct.id, {'state': 'done'}, context=context)
        return True

    def unlink(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        """Allows to delete in draft state"""
        for rec in self.browse(cr, uid, ids, context=context):
            if rec.state != 'draft':
                raise osv.except_osv(
                    _('Error!'),
                    _('Data yang dapat dihapus hanya yang berstatus draft'))
        return super(cuti_kuliah, self).unlink(cr, uid, ids, context=context)

    ####################################################################################################
    # Cron Job untuk activate otomatis mahasiswa yang habis masa cutinya
    ####################################################################################################
    def cron_aktivasi_cuti_mahasiswa(self, cr, uid, ids=None, context=None):
        partner_obj = self.pool.get('res.partner')
        #import pdb;pdb.set_trace()
        mahasiswa_cuti = self.search(
            cr,
            uid,
            [('date', '=', time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)[:10]),
             ('state', '=', 'confirm'), ('automatic_done', '=', True)],
            context=context)
        if mahasiswa_cuti:
            for mhs in self.browse(cr, uid, mahasiswa_cuti):
                self.write(cr, uid, mhs.id, {'state': 'done'})
                partner_obj.write(cr, uid, mhs.partner_id.id,
                                  {'status_mahasiswa': 'Mahasiswa'})

        return True

    ####################################################################################################
    # Cron Job untuk generate cuti jika mahasiswa telat bayar uang ujian (UAS)
    ####################################################################################################
    def cron_cuti_mahasiswa_karena_nunggak(self,
                                           cr,
                                           uid,
                                           ids=None,
                                           context=None):
        partner_obj = self.pool.get('res.partner')
        invoice_obj = self.pool.get('account.invoice')
        event_obj = self.pool.get('event.event')

        now = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
        date_now = datetime.strptime(now[:10], "%Y-%m-%d")
        start_date = date_now.strftime("%Y-%m-%d 00:00:00")
        start_end = date_now.strftime("%Y-%m-%d 23:59:59")

        event_exist = event_obj.search(cr, uid,
                                       [('date_begin', '>=', start_date),
                                        ('date_begin', '<=', start_end),
                                        ('state', '=', 'confirm')])
        if event_exist:
            mahasiswa_nunggak = invoice_obj.search(
                cr, uid, [('date_invoice', '=', now[:10]),
                          ('state', '=', 'open'), ('krs_id', '!=', False)])
            if mahasiswa_nunggak:
                mhs_ids = []
                for inv in invoice_obj.browse(cr, uid, mahasiswa_nunggak):
                    if inv.id not in mhs_ids:
                        mhs_ids.append(inv.partner_id.id)
                        self.create(
                            cr, uid, {
                                'partner_id': inv.partner_id.id,
                                'tahun_ajaran_id':
                                inv.partner_id.tahun_ajaran_id.id,
                                'fakultas_id': inv.partner_id.fakultas_id.id,
                                'prodi_id': inv.partner_id.prodi_id.id,
                                'kelas_id': inv.partner_id.kelas_id.id
                                or False,
                                'state': 'confirm',
                                'notes':
                                'Ada tunggakan invoice ' + str(inv.number),
                                'from_semester_id': inv.krs_id.semester_id.id,
                                'to_semester_id': 8
                            })
                    partner_obj.write(cr, uid, inv.partner_id.id,
                                      {'status_mahasiswa': 'cuti'})
                    invoice_obj.write(
                        cr, uid, inv.id, {
                            'comment':
                            'Mahasiswa ini sedang dicutikan oleh sistem karena ada keterlambatan pembayaran atas invoice ini'
                        })

        return True