def view_init(self, cr, uid, fields_list, context=None): """ Creates view dynamically and adding fields at runtime. @param self: The object pointer. @param cr: A database cursor @param uid: ID of the user currently logged in @param context: A standard dictionary @return: New arch of view with new columns. """ res = super(AccountProfitAndLossLedgerWizard, self).view_init(cr, uid, fields_list, context=context) for index in range(LEVEL_STYLES): # create columns for each comparison page self._columns.update({ "level%s_print" % (index,): fields.boolean('Print'), "level%s_size" % (index,): fields.integer('Size', required=True), "level%s_bold" % (index,): fields.boolean('Bold'), "level%s_italic" % (index,): fields.boolean('Italic'), "level%s_underline" % (index,): fields.boolean('Underline'), "level%s_uppercase" % (index,): fields.boolean('Uppercase'), }) return res
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
def view_init(self, cr, uid, fields_list, context=None): """ Creates view dynamically and adding fields at runtime. @param self: The object pointer. @param cr: A database cursor @param uid: ID of the user currently logged in @param context: A standard dictionary @return: New arch of view with new columns. """ res = super(mrp_track_move, self).view_init(cr, uid, fields_list, context=context) record_id = context and context.get('active_id', False) or False if record_id: prod_obj = self.pool.get('mrp.production') try: prod = prod_obj.browse(cr, uid, record_id, context=context) for m in [line for line in prod.move_created_ids]: if 'track%s'%(m.id) not in self._columns: self._columns['track%s'%(m.id)] = fields.boolean(string=m.product_id.name) except: return res return res
class product_icecat_wizard(osv.osv_memory): _name = 'product.icecat.wizard' _columns = { 'name': fields.boolean('Name'), 'description': fields.boolean('Description'), 'description_sale': fields.boolean('Description Śale'), 'attributes': fields.boolean('Attributes'), 'language_id': fields.many2one('res.lang', 'Language'), 'image': fields.boolean('Image'), 'html': fields.boolean('HTML Code'), 'result': fields.text('Result', readonly=True), 'resimg': fields.text('Image', readonly=True), 'state': fields.selection([ ('first', 'First'), ('done', 'Done'), ], 'State'), } _defaults = { 'state': lambda *a: 'first', 'name': lambda *a: 1, 'description': lambda *a: 1, 'description_sale': lambda *a: 1, 'attributes': lambda *a: 1, 'html': lambda *a: 1, } # ========================================== # save XML file into product_icecat/xml dir # ========================================== def save_file(self, name, value): path = os.path.abspath(os.path.dirname(__file__)) path += '/icecat/%s' % name path = re.sub('wizard/', '', path) f = open(path, 'w') try: f.write(value) finally: f.close() return path # ========================================== # Convert HTML to text # ========================================== def StripTags(self, text): finished = 0 while not finished: finished = 1 start = text.find("<") if start >= 0: stop = text[start:].find(">") if stop >= 0: text = text[:start] + text[start + stop + 1:] finished = 0 return text # ========================================== # Convert icecat values to OpenERP mapline # ========================================== def icecat2oerp(self, cr, uid, form, product, icecat, pathxml, language, data, context): #check if attributes product exists. If exists, raise error. Not update attributes values if form.attributes: attributes_ids = self.pool.get( 'product.manufacturer.attribute').search( cr, uid, [('product_id', '=', product.id)]) if len(attributes_ids) > 0: raise osv.except_osv( _('Error'), _("There are attributes avaible in this product. Delete this attributes or uncheck attributes option" )) if form.language_id.code: language = form.language_id.code doc = libxml2.parseFile(pathxml) for prod in doc.xpathEval('//Product'): if prod.xpathEval('@ErrorMessage'): if prod.xpathEval('@ErrorMessage')[0].content: return prod.xpathEval('@ErrorMessage')[0].content exit # product info short_summary = doc.xpathEval( '//SummaryDescription//ShortSummaryDescription') long_summary = doc.xpathEval( '//SummaryDescription//LongSummaryDescription') short_description = short_summary[0].content description = long_summary[0].content name = description.split('.')[0] for prod in doc.xpathEval('//ProductDescription'): if prod.xpathEval('@ShortDesc'): short_description = prod.xpathEval('@ShortDesc')[0].content if prod.xpathEval('@LongDesc'): description = prod.xpathEval('@LongDesc')[0].content # product details category categoryId = [] categoryName = [] for cat in doc.xpathEval('//CategoryFeatureGroup'): categoryId.append(cat.xpathEval('@ID')[0].content) for cat in doc.xpathEval('//CategoryFeatureGroup//FeatureGroup//Name'): categoryName.append(cat.xpathEval('@Value')[0].content) # join categorys lists category = zip(categoryId, categoryName) # product details feature prodFeatureId = [] prodFeatureName = [] values = {} for prod in doc.xpathEval('//ProductFeature'): prodFeatureId.append( prod.xpathEval('@CategoryFeatureGroup_ID')[0].content + "#" + prod.xpathEval('@Presentation_Value')[0].content) for prod in doc.xpathEval('//ProductFeature//Feature//Name'): prodFeatureName.append(prod.xpathEval('@Value')[0].content) # ordered id, name & description Product Feature prodFeature = {} i = 0 for feature in prodFeatureId: if not prodFeatureName[i] == 'Source data-sheet': values = feature.split('#') if values[1] == "Y": value = _("Yes") elif values[1] == "N": value = _("No") else: value = values[1] if values[0] not in prodFeature: prodFeature[values[0]] = [] prodFeature[values[0]].append('<strong>' + prodFeatureName[i] + ':</strong>' + ' ' + value) i += 1 mapline_ids = self.pool.get('product.icecat.mapline').search( cr, uid, [('icecat_id', '=', icecat.id)]) mapline_fields = [] for mapline_id in mapline_ids: mapline = self.pool.get('product.icecat.mapline').browse( cr, uid, mapline_id) mapline_fields.append({ 'icecat': mapline.name, 'oerp': mapline.field_id.name }) #show details product #TODO: HTML template use Mako template for not hardcode HTML tags mapline_values = [] attributes_values = [] sequence = 0 for cat in category: catID = cat[0] catName = cat[1] #product_manufacturer if form.attributes: attributes_values.append({ 'name': catName, 'icecat_category': catID, 'product_id': product.id, 'sequence': sequence }) sequence + 1 if catID in prodFeature and len(prodFeature[catID]): for feature in prodFeature[catID]: prod_value = feature.split(":") if len(prod_value) > 0: attributes_values.append({ 'name': '>' + self.StripTags(prod_value[0]), 'value': self.StripTags(prod_value[1]), 'icecat_category': catID, 'product_id': product.id, 'sequence': sequence }) sequence + 1 for mapline_field in mapline_fields: if mapline_field['icecat'] == catID: source = '<h3>%s</h3>' % catName i = True for feature in prodFeature[catID]: if i == True: source += '<ul>' source += '<li>%s</li>' % feature i = False source += '</ul>' if not form.html: source = self.StripTags(source) mapline_values.append({ 'field': mapline_field['oerp'], 'source': source }) # This is not hardcode. Short description is avaible in antother fields, for example meta_description website fields (magento, djnago,...) if mapline_field['icecat'] == 'ShortSummaryDescription': mapline_values.append({ 'field': mapline_field['oerp'], 'source': short_description }) # update icecat values at product # default values. It is not hardcode ;) values = {} if form.name: trans_name_id = self.pool.get('ir.translation').search( cr, uid, [('lang', '=', language), ('name', '=', 'product.template,name'), ('res_id', '=', product.id)]) if trans_name_id: self.pool.get('ir.translation').write(cr, uid, trans_name_id, {'value': name}, context) else: values['name'] = name if form.description_sale: trans_descsale_id = self.pool.get('ir.translation').search( cr, uid, [('lang', '=', language), ('name', '=', 'product.template,description_sale'), ('res_id', '=', product.id)]) if trans_descsale_id: self.pool.get('ir.translation').write( cr, uid, trans_descsale_id, {'value': short_description}, context) else: values['description_sale'] = short_description if form.description: if not form.html: description = self.StripTags(description) trans_description_id = self.pool.get('ir.translation').search( cr, uid, [('lang', '=', language), ('name', '=', 'product.template,description'), ('res_id', '=', product.id)]) if trans_description_id: self.pool.get('ir.translation').write(cr, uid, trans_description_id, {'value': description}, context) else: values['description'] = description #manufacturer product manufacturers = [] for supplier in doc.xpathEval('//Supplier'): manufacturers.append(supplier.xpathEval('@Name')[0].content) if len(manufacturers) > 0: partner_id = self.pool.get('res.partner').search( cr, uid, [('name', 'ilike', manufacturers[len(manufacturers) - 1])]) if len(partner_id) > 0: values['manufacturer'] = partner_id[0] values['manufacturer_pname'] = name ref = [] for prod in doc.xpathEval('//Product'): ref.append(prod.xpathEval('@Prod_id')[0].content) values['manufacturer_pref'] = ref[0] # add mapline values calculated for mapline_value in mapline_values: values[mapline_value['field']] = mapline_value['source'] self.pool.get('product.product').write(cr, uid, [product.id], values, context) #create manufacturer attribute if form.attributes: for values in attributes_values: self.pool.get('product.manufacturer.attribute').create( cr, uid, values, context) result = _("Product %s XML Import successfully") % name return result # ========================================== # Convert icecat values to OpenERP mapline # ========================================== def iceimg2oerpimg(self, cr, uid, form, product, icecat, pathxml, data, context): doc = libxml2.parseFile(pathxml) #product image for prod in doc.xpathEval('//Product'): if prod.xpathEval('@HighPic'): image = prod.xpathEval('@HighPic')[0].content if image: fname = image.split('/') fname = fname[len(fname) - 1] path = os.path.abspath(os.path.dirname(__file__)) path += '/icecat/%s' % fname path = re.sub('wizard/', '', path) #download image urllib.urlretrieve(image, path) #send ftp server ftp = FTP(icecat.ftpip) ftp.login(icecat.ftpusername, icecat.ftppassword) ftp.cwd(icecat.ftpdirectory) f = file(path, 'rb') ftp.storbinary('STOR ' + os.path.basename(path), f) ftp.quit() # add values into product_image # product info long_summary = doc.xpathEval( '//SummaryDescription//LongSummaryDescription') description = long_summary[0].content name = description.split('.')[0] values = { 'name': name, 'link': 1, 'filename': icecat.ftpurl + fname, 'product_id': product.id, } self.pool.get('product.images').create(cr, uid, values, context) return icecat.ftpurl + fname else: return _("Not exist %s image") % fname # ========================================== # wizard # ========================================= def import_xml(self, cr, uid, ids, data, context={}): icecat_id = self.pool.get('product.icecat').search( cr, uid, [('active', '=', 1)]) if not icecat_id: raise osv.except_osv(_('Error'), _("Configure your icecat preferences!")) icecat = self.pool.get('product.icecat').browse(cr, uid, icecat_id[0]) form = self.browse(cr, uid, ids[0]) if not form.language_id: language = self.pool.get('res.users').browse(cr, uid, uid).context_lang lang = language.split('_')[0] else: language = form.language_id.code lang = language.split('_')[0] resimg = '' for prod in data['active_ids']: product = self.pool.get('product.product').browse(cr, uid, prod) ean = product.ean13 if ean: url = 'http://data.icecat.biz/xml_s3/xml_server3.cgi?ean_upc=%s;lang=%s;output=productxml' % ( ean, lang) fileName = '%s.xml' % ean passman = urllib2.HTTPPasswordMgrWithDefaultRealm() # this creates a password manager passman.add_password(None, url, icecat.username, icecat.password) authhandler = urllib2.HTTPBasicAuthHandler(passman) # create the AuthHandler openerp = urllib2.build_opener(authhandler) urllib2.install_opener(openerp) # All calls to urllib2.urlopen will now use our handler try: pagehandle = urllib2.urlopen(url) req = urllib2.Request(url) handle = urllib2.urlopen(req) content = handle.read() #save file pathxml = self.save_file(fileName, content) #import values icecat2oerp result = self.icecat2oerp(cr, uid, form, product, icecat, pathxml, language, data, context) #import image icecat2oerp if icecat.ftp and form.image: resimg += self.iceimg2oerpimg(cr, uid, form, product, icecat, pathxml, data, context) resimg += "\n" else: resimg += _("Import image not avaible") resimg += "\n" except URLError, e: result = e.code else: result = _("EAN not avaible") resimg = False values = { 'state': 'done', 'result': result, 'resimg': resimg, } self.write(cr, uid, ids, values) return True
class OeMedicalPatient(osv.Model): def _compute_age(self, cr, uid, ids, field_name, field_value, arg, context={}): result = {} now = datetime.now() for r in self.browse(cr, uid, ids, context=context): if r.dob: dob = datetime.strptime(r.dob, '%Y-%M-%d') delta = relativedelta(now, dob) result[r.id] = str(delta.years) else: result[r.id] = "" return result _name = 'oemedical.patient' _inherits = { 'res.partner': 'partner_id', } _columns={ 'partner_id': fields.many2one( 'res.partner', 'Related Partner', required=True, ondelete='cascade', help='Partner-related data of the patient'), 'family': fields.many2one('oemedical.family', string='Family', help='Family Code'), 'photo': fields.binary(string='Picture'), 'sex': fields.selection([('m', 'Male'), ('f', 'Female'), ], string='Sex', required=True), 'blood_type': fields.selection([('A', 'A'), ('B', 'B'), ('AB', 'AB'), ('O', 'O'), ], string='Blood Type'), 'general_info': fields.text(string='General Information', help='General information about the patient'), 'primary_care_doctor': fields.many2one('oemedical.physician', 'Primary Care Doctor', help='Current primary care / family doctor'), 'childbearing_age': fields.boolean('Potential for Childbearing'), 'medications': fields.one2many('oemedical.patient.medication', 'patient_id', string='Medications',), 'evaluations': fields.one2many('oemedical.patient.evaluation', 'patient_id', string='Evaluations',), 'critical_info': fields.text( string='Important disease, allergy or procedures information', help='Write any important information on the patient\'s disease,'\ ' surgeries, allergies, ...'), 'rh': fields.selection([('+', '+'), ('-', '-'), ], string='Rh'), 'current_address': fields.many2one('res.partner', string='Address', help='Contact information. You may choose from the different contacts'\ ' and addresses this patient has.'), 'diseases': fields.one2many('oemedical.patient.disease', 'patient_id', string='Diseases', help='Mark if the patient has died'), 'lastname': fields.char(size=256, string='Lastname',), 'slastname': fields.char(size=256, string='Second Lastname',), 'ethnic_group': fields.many2one('oemedical.ethnicity', string='Ethnic group',), 'ssn': fields.char(size=256, string='SSN',), 'vaccinations': fields.one2many('oemedical.vaccination', 'patient_id', 'Vaccinations',), 'dob': fields.date(string='DoB'), #'age': fields.char(size=256, string='Age Age',), 'age': fields.function(_compute_age, string= "Age",arg=None, fnct_inv=None, fnct_inv_arg=None, type="char",fnct_search=None, obj=None, method=True, store=False, multi=False,), 'marital_status': fields.selection([('s', 'Single'), ('m', 'Married'), ('w', 'Widowed'), ('d', 'Divorced'), ('x', 'Separated'), ], string='Marital Status', sort=False), 'dod': fields.datetime(string='Date of Death'), 'current_insurance': fields.many2one('oemedical.insurance', string='Insurance', help='Insurance information. You may choose from the different'\ ' insurances belonging to the patient'), 'cod': fields.many2one('oemedical.pathology', string='Cause of Death',), 'identification_code': fields.char(size=256, string='ID', help='Patient Identifier provided by the Health Center.Is not the'\ ' Social Security Number'), 'deceased': fields.boolean(string='Deceased'), } _defaults = { 'ref': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get( cr, uid, 'oemedical.patient'), }
# -*- encoding: utf-8 -*- import pooler from osv import fields, osv _columns = { 'domain': fields.char('Domain', size=32, help="This field is only used if you develop your own module allowing developers to create specific taxes in a custom domain."), 'tax_discount': fields.boolean('Tax Discounted in Price', help="Mark it for (ICMS, PIS e etc.)."), 'tax_include': fields.boolean('Include the Tax Amount in Price', help="Mark it to include the Tax Amount in Price."), } class account_tax_code_template(osv.osv): _inherit = 'account.tax.code.template' _columns = _columns account_tax_code_template() class account_tax_code(osv.osv): _inherit = 'account.tax.code' _columns = _columns account_tax_code() def change_digit_tax(cr): res = pooler.get_pool(cr.dbname).get('decimal.precision').precision_get(cr, 1, 'Account') return (16, res + 2)
return True _columns = { 'name': fields.char(string='Name', select="1", size=150, readonly=True), 'service_type': fields.many2one('ups.codes', 'Service Type', domain=[('type', '=', 'service')], select="1"), 'package_det': fields.one2many('ups.shippingregister.package', 'shipping_register_rel', string='Packages',), 'to_address': fields.many2one('res.partner.address', 'Shipping Address', required=True), 'from_address': fields.many2one('res.partner.address', 'From Address', required=True), 'shipper_address': fields.many2one('res.partner.address', 'Shipper Address', required=True), 'saturday_delivery': fields.boolean('Saturday Delivery?'), 'description': fields.text('Description'), 'state':fields.selection(STATE_SELECTION, 'Status', readonly=True,), # The following are UPS filled information 'billed_weight':fields.float('Billed Weight', digits=(10, 4), readonly=True, help=( 'The billed weght may be different from the actual weight.' 'This is computed by UPS.')), 'billed_weight_uom':fields.many2one('product.uom', 'Billed Weight UOM', readonly=True), 'total_amount':fields.float('Total Amount', digits=(14, 4), select="1", readonly=True), 'total_amount_currency':fields.many2one('res.currency', 'Total Amount Currency', select="2", readonly=True,), 'digest': fields.binary('Information digest for DIGEST'),
('file','File'), ('parser','Parser'), ],'Template source', select=True), 'parser_def': fields.text('Parser Definition'), 'parser_loc':fields.char('Parser location', size=128, help="Path to the parser location. Beginning of the path must be start with the module name!\nLike this: {module name}/{path to the parser.py file}"), 'parser_state':fields.selection([ ('default',_('Default')), ('def',_('Definition')), ('loc',_('Location')), ],'State of Parser', select=True), 'in_format': fields.selection(_get_in_mimetypes, 'Template Mime-type'), 'out_format':fields.many2one('report.mimetypes', 'Output Mime-type'), 'report_sxw_content': fields.function(_report_content, fnct_inv=_report_content_inv, method=True, type='binary', string='SXW content',), 'active':fields.boolean('Active'), 'report_wizard':fields.boolean('Report Wizard'), 'copies': fields.integer('Number of copies'), 'fallback_false':fields.boolean('Disable format fallback'), 'xml_id': fields.function(_get_xml_id, type='char', size=128, string="XML ID", method=True, help="ID of the report defined in xml file"), } def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'): ##### check new model fields, that while not exist in database ##### cr.execute("SELECT name FROM ir_model_fields WHERE model = 'ir.actions.report.xml'") true_fields = [val[0] for val in cr.fetchall()] true_fields.append(self.CONCURRENCY_CHECK_FIELD) if fields: exclude_fields = set(fields).difference(set(true_fields))
string='Latest version', type='char'), 'latest_version': fields.char('Installed version', size=64, readonly=True), 'published_version': fields.char('Published Version', size=64, readonly=True), 'url': fields.char('URL', size=128, readonly=True), 'dependencies_id': fields.one2many('ir.module.module.dependency', 'module_id', 'Dependencies', readonly=True), '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='State', readonly=True, select=True), 'demo': fields.boolean('Demo data'), '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'), ('Other OSI approved licence', 'Other OSI Approved Licence'), ('Other proprietary', 'Other Proprietary') ], string='License', readonly=True), 'menus_by_module': fields.function(_get_views, method=True, string='Menus', type='text', multi="meta", store=True), 'reports_by_module': fields.function(_get_views, method=True, string='Reports', type='text', multi="meta", store=True), 'views_by_module': fields.function(_get_views, method=True, string='Views', type='text', multi="meta", store=True), 'certificate' : fields.char('Quality Certificate', size=64, readonly=True), 'web': fields.boolean('Has a web component', readonly=True), }
class ir_values(osv.osv): _name = 'ir.values' def _value_unpickle(self, cursor, user, ids, name, arg, context=None): res = {} for report in self.browse(cursor, user, ids, context=context): value = report[name[:-9]] if not report.object and value: try: value = str(pickle.loads(value)) except: pass res[report.id] = value return res def _value_pickle(self, cursor, user, id, name, value, arg, context=None): if context is None: context = {} ctx = context.copy() if self.CONCURRENCY_CHECK_FIELD in ctx: del ctx[self.CONCURRENCY_CHECK_FIELD] if not self.browse(cursor, user, id, context=context).object: value = pickle.dumps(value) self.write(cursor, user, id, {name[:-9]: value}, context=ctx) def onchange_object_id(self, cr, uid, ids, object_id, context={}): if not object_id: return {} act = self.pool.get('ir.model').browse(cr, uid, object_id, context=context) return {'value': {'model': act.model}} def onchange_action_id(self, cr, uid, ids, action_id, context={}): if not action_id: return {} act = self.pool.get('ir.actions.actions').browse(cr, uid, action_id, context=context) return {'value': {'value_unpickle': act.type + ',' + str(act.id)}} _columns = { 'name': fields.char('Name', size=128), 'model_id': fields.many2one( 'ir.model', 'Object', size=128, help= "This field is not used, it only helps you to select a good model." ), 'model': fields.char('Object Name', size=128, select=True), 'action_id': fields.many2one( 'ir.actions.actions', 'Action', help= "This field is not used, it only helps you to select the right action." ), 'value': fields.text('Value'), 'value_unpickle': fields.function(_value_unpickle, fnct_inv=_value_pickle, method=True, type='text', string='Value'), 'object': fields.boolean('Is Object'), 'key': fields.selection([('action', 'Action'), ('default', 'Default')], 'Type', size=128, select=True), 'key2': fields.char( 'Event Type', help= "The kind of action or button in the client side that will trigger the action.", size=128, select=True), 'meta': fields.text('Meta Datas'), 'meta_unpickle': fields.function(_value_unpickle, fnct_inv=_value_pickle, method=True, type='text', string='Metadata'), 'res_id': fields.integer( 'Object ID', help="Keep 0 if the action must appear on all resources.", select=True), 'user_id': fields.many2one('res.users', 'User', ondelete='cascade', select=True), 'company_id': fields.many2one('res.company', 'Company', select=True) } _defaults = { 'key': lambda *a: 'action', 'key2': lambda *a: 'tree_but_open', 'company_id': lambda *a: False } def _auto_init(self, cr, context=None): super(ir_values, self)._auto_init(cr, context) cr.execute( 'SELECT indexname FROM pg_indexes WHERE indexname = \'ir_values_key_model_key2_res_id_user_id_idx\'' ) if not cr.fetchone(): cr.execute( 'CREATE INDEX ir_values_key_model_key2_res_id_user_id_idx ON ir_values (key, model, key2, res_id, user_id)' ) def set(self, cr, uid, key, key2, name, models, value, replace=True, isobject=False, meta=False, preserve_user=False, company=False): if isinstance(value, unicode): value = value.encode('utf8') if not isobject: value = pickle.dumps(value) if meta: meta = pickle.dumps(meta) ids_res = [] for model in models: if isinstance(model, (list, tuple)): model, res_id = model else: res_id = False if replace: search_criteria = [('key', '=', key), ('key2', '=', key2), ('model', '=', model), ('res_id', '=', res_id), ('user_id', '=', preserve_user and uid)] if key in ('meta', 'default'): search_criteria.append(('name', '=', name)) else: search_criteria.append(('value', '=', value)) self.unlink(cr, uid, self.search(cr, uid, search_criteria)) vals = { 'name': name, 'value': value, 'model': model, 'object': isobject, 'key': key, 'key2': key2 and key2[:200], 'meta': meta, 'user_id': preserve_user and uid, } if company: cid = self.pool.get('res.users').browse( cr, uid, uid, context={}).company_id.id vals['company_id'] = cid if res_id: vals['res_id'] = res_id ids_res.append(self.create(cr, uid, vals)) return ids_res def get(self, cr, uid, key, key2, models, meta=False, context={}, res_id_req=False, without_user=True, key2_req=True): result = [] for m in models: if isinstance(m, (list, tuple)): m, res_id = m else: res_id = False where = ['key=%s', 'model=%s'] params = [key, str(m)] if key2: where.append('key2=%s') params.append(key2[:200]) elif key2_req and not meta: where.append('key2 is null') if res_id_req and (models[-1][0] == m): if res_id: where.append('res_id=%s') params.append(res_id) else: where.append('(res_id is NULL)') elif res_id: if (models[-1][0] == m): where.append('(res_id=%s or (res_id is null))') params.append(res_id) else: where.append('res_id=%s') params.append(res_id) where.append('(user_id=%s or (user_id IS NULL)) order by id') params.append(uid) clause = ' and '.join(where) cr.execute( 'select id,name,value,object,meta, key from ir_values where ' + clause, params) result = cr.fetchall() if result: break if not result: return [] def _result_get(x, keys): if x[1] in keys: return False keys.append(x[1]) if x[3]: model, id = x[2].split(',') # FIXME: It might be a good idea to opt-in that kind of stuff # FIXME: instead of arbitrarily removing random fields fields = [ field for field in self.pool.get(model).fields_get_keys(cr, uid) if field not in EXCLUDED_FIELDS ] try: datas = self.pool.get(model).read(cr, uid, [int(id)], fields, context) except except_orm, e: return False datas = datas and datas[0] if not datas: return False else:
class sale_report(osv.osv): _name = "sale.report2" _description = "Sales Orders Statistics" _auto = False _rec_name = 'date' _inherit = 'sale.report2' _columns = { 'date': fields.date('Date Order', readonly=True), 'date_confirm': fields.date('Date Confirm', readonly=True), 'shipped': fields.boolean('Shipped', readonly=True), 'shipped_qty_1': fields.integer('Shipped Qty', readonly=True), 'year': fields.char('Year', size=4, readonly=True), 'month': fields.selection([('01', 'January'), ('02', 'February'), ('03', 'March'), ('04', 'April'), ('05', 'May'), ('06', 'June'), ('07', 'July'), ('08', 'August'), ('09', 'September'), ('10', 'October'), ('11', 'November'), ('12', 'December')], 'Month', readonly=True), 'day': fields.char('Day', size=128, readonly=True), 'product_id': fields.many2one('product.product', 'Product', readonly=True), 'uom_name': fields.char('Reference UoM', size=128, readonly=True), 'product_uom_qty': fields.float('# of Qty', readonly=True), 'partner_id': fields.many2one('res.partner', 'Partner', readonly=True), 'shop_id': fields.many2one('sale.shop', 'Shop', readonly=True), 'company_id': fields.many2one('res.company', 'Company', readonly=True), 'user_id': fields.many2one('res.users', 'Salesman', readonly=True), 'price_total': fields.float('Total Price', readonly=True), 'delay': fields.float('Commitment Delay', digits=(16, 2), readonly=True), 'categ_id': fields.many2one('product.category', 'Category of Product', readonly=True), 'nbr': fields.integer('# of Lines', readonly=True), 'file_number': fields.many2one('crm.lead', 'File Number', readonly=True), 'state': fields.selection([('draft', 'Quotation'), ('q_lost', 'Quote Lost'), ('q_converted', 'Quote Converted'), ('waiting_date', 'Waiting Schedule'), ('manual', 'Manual In Progress'), ('progress', 'In Progress'), ('shipping_except', 'Shipping Exception'), ('invoice_except', 'Invoice Exception'), ('done', 'Done'), ('cancel', 'Cancelled')], 'Order State', readonly=True), 'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', readonly=True), 'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True), 'name': fields.char('Order Reference', size=64, readonly=True), 'currency': fields.char('Currency', size=16, readonly=True), 'categ1_id': fields.many2one('product.category', 'Product Category 1', readonly=True), 'categ2_id': fields.many2one('product.category', 'Product Category 2', readonly=True), 'level1_id': fields.many2one('res.partner.category', 'Partner Level 1', readonly=True), 'level2_id': fields.many2one('res.partner.category', 'Partner Level 2', readonly=True), } _order = 'date desc' def init(self, cr): tools.drop_view_if_exists(cr, 'sale_report2') cr.execute(""" create or replace view sale_report2 as ( select el.*, -- (select count(1) from sale_order_line where order_id = s.id) as nbr, (select 1) as nbr, s.date_order as date, s.date_confirm as date_confirm, to_char(s.date_order, 'YYYY') as year, to_char(s.date_order, 'MM') as month, to_char(s.date_order, 'YYYY-MM-DD') as day, s.partner_id as partner_id, s.user_id as user_id, s.shop_id as shop_id, s.company_id as company_id, extract(epoch from avg(date_trunc('day',s.date_confirm)-date_trunc('day',s.create_date)))/(24*60*60)::decimal(16,2) as delay, s.state, s.file_number as file_number, s.shipped, s.shipped::integer as shipped_qty_1, s.pricelist_id as pricelist_id, s.project_id as analytic_account_id, s.name, c.name as currency, rp.level1_id, rp.level2_id from sale_order s, product_pricelist pl, res_currency c,res_partner rp, ( select l.id as id, l.product_id as product_id, (case when u.uom_type not in ('reference') then (select name from product_uom where uom_type='reference' and category_id=u.category_id and active LIMIT 1) else u.name end) as uom_name, sum(l.product_uom_qty * u.factor) as product_uom_qty, sum(l.product_uom_qty * l.price_unit) as price_total, pt.categ_id, l.order_id, pt.categ1_id, pt.categ2_id from sale_order_line l ,product_uom u, product_product p, product_template pt where u.id = l.product_uom and pt.id = p.product_tmpl_id and p.id = l.product_id group by l.id, l.order_id, l.product_id, u.name, pt.categ_id, u.uom_type, u.category_id, pt.categ1_id, pt.categ2_id) el where s.id = el.order_id and rp.id=s.partner_id and pl.id=s.pricelist_id and c.id=pl.currency_id group by el.id, el.product_id, el.uom_name, el.product_uom_qty, el.price_total, el.categ_id, el.categ1_id, el.categ2_id, el.order_id, s.date_order, s.date_confirm, s.partner_id, s.user_id, s.shop_id, s.company_id, s.state, s.file_number, s.shipped, s.pricelist_id, s.project_id, s.name, c.name, rp.level1_id, rp.level2_id ) """)
class account_account(osv.osv): _name = 'account.account' _inherit = ["account.account", "mail.thread"] _columns = { 'force_reconcile': fields.boolean( 'Force as write-off account', help= "Check to force this account as a write-off account in customer and supplier payments" ), } def write(self, cr, uid, ids, vals, context=None): """ This function write an entry in the openchatter whenever we change important information on the account like the model, the drive, the state of the account or its license plate """ for account in self.browse(cr, uid, ids, context): changes = [] if 'code' in vals and account.code != vals['code']: value = vals['code'] oldmodel = account.code or _('None') changes.append( _("Code: from '%s' to '%s'") % (oldmodel, value)) if 'name' in vals and account.name != vals['name']: value = vals['name'] oldmodel = account.name or _('None') changes.append( _("Name: from '%s' to '%s'") % (oldmodel, value)) if 'parent_id' in vals and account.parent_id.id != vals[ 'parent_id']: value = self.pool.get('account.account').browse( cr, uid, vals['parent_id'], context=context).name oldmodel = account.parent_id.name or _('None') changes.append( _("Type: from '%s' to '%s'") % (oldmodel, value)) if 'type' in vals and account.type != vals['type']: value = vals['type'] oldmodel = account.type or _('None') changes.append( _("Type: from '%s' to '%s'") % (oldmodel, value)) if 'user_type' in vals and account.user_type != vals['user_type']: value = self.pool.get('account.account.type').browse( cr, uid, vals['user_type'], context=context).name oldmodel = account.user_type.name or _('None') changes.append( _("User type: from '%s' to '%s'") % (oldmodel, value)) if 'active' in vals and account.active != vals['active']: value = vals['active'] oldmodel = account.active or _('None') changes.append( _("Active: from '%s' to '%s'") % (oldmodel, value)) if 'tax_ids' in vals and account.tax_ids != vals['tax_ids'][0][2]: list_tax = [] list = [] "Guarda en las listas los campos removidor o agragados" list_tax_new = sorted(vals['tax_ids'][0][2]) for a in account.tax_ids: list_tax.append(a.id) sorted(list_tax) sorted(list_tax_new) "ve cuales son los camos q se mantienen" for a in list_tax: for t in list_tax_new: if a == t: list.append(a) "elimina de las listas los campos repetidos" for a in list: del (list_tax_new[list_tax_new.index(a)]) del (list_tax[list_tax.index(a)]) "Guarda e imprime los campos no repetidos en msn" for id in list_tax: value = self.pool.get('account.tax').browse( cr, uid, id, context=context).name or _('None') changes.append(_("Tax Removed: '%s'") % (value)) for id in list_tax_new: value = self.pool.get('account.tax').browse( cr, uid, id, context=context).name or _('None') changes.append(_("Added tax: '%s'") % (value)) if 'reconcile' in vals and account.reconcile != vals['reconcile']: value = vals['reconcile'] oldmodel = account.reconcile or _('None') changes.append( _("Reconcile: from '%s' to '%s'") % (oldmodel, value)) if 'child_consol_ids' in vals and account.child_consol_ids != vals[ 'child_consol_ids'][0][2]: list_consol = [] list = [] "Guarda en las listas los campos removidor o agragados" list_consol_new = sorted(vals['child_consol_ids'][0][2]) for a in account.child_consol_ids: list_consol.append(a.id) sorted(list_consol) sorted(list_consol_new) "ve cuales son los camos q se mantienen" for a in list_consol: for t in list_consol_new: if a == t: list.append(a) "elimina de las listas los campos repetidos" for a in list: del (list_consol_new[list_consol_new.index(a)]) del (list_consol[list_consol.index(a)]) "Guarda e imprime los campos no repetidos en msn" for id in list_consol: value = self.pool.get('account.account').browse( cr, uid, id, context=context).name or _('None') changes.append(_("Consolidation Removed: '%s'") % (value)) for id in list_consol_new: value = self.pool.get('account.account').browse( cr, uid, id, context=context).name or _('None') changes.append(_("Added Consolidation: '%s'") % (value)) if 'force_reconcile' in vals and account.force_reconcile != vals[ 'force_reconcile']: value = vals['force_reconcile'] oldmodel = account.force_reconcile or _('None') changes.append( _("Force as write-off account: from '%s' to '%s'") % (oldmodel, value)) if 'note' in vals and account.note != vals['note']: value = vals['note'] oldmodel = account.note or _('None') changes.append( _("Note: from '%s' to '%s'") % (oldmodel, value)) if len(changes) > 0: self.message_post(cr, uid, [account.id], body=", ".join(changes), context=context) account_id = super(account_account, self).write(cr, uid, ids, vals, context) return True def _check_allow_code_change(self, cr, uid, ids, context=None): ''' Se anula toda validacion del modulo base ''' return True
class tcv_payroll_import_job(osv.osv): _name = 'tcv.payroll.import.job' _description = '' ##------------------------------------------------------------------------- ##------------------------------------------------------- _internal methods def name_get(self, cr, uid, ids, context): ids = isinstance(ids, (int, long)) and [ids] or ids res = [] for item in self.browse(cr, uid, ids, context={}): res.append( (item.id, '[%s] %s' % (item.hr_job_id.code, item.hr_job_id.name))) return res #~ #~ def name_search(self, cr, user, name, args=None, operator='ilike', #~ context=None, limit=100): #~ res = super(tcv_payroll_import_job, self).\ #~ name_search(cr, user, name, args, operator, context, limit) #~ if not res and name: #~ ids = self.search( #~ cr, user, [('code', 'ilike', name.upper())] + args, #~ limit=limit) #~ if ids: #~ res = self.name_get(cr, user, ids, context=context) #~ return res ##--------------------------------------------------------- function fields _columns = { 'hr_job_id': fields.many2one('hr.job', 'Job', required=False, ondelete='restrict'), #~ 'code': fields.char( #~ 'Code', size=16, required=True, readonly=False), #~ 'name': fields.char( #~ 'Name', size=64, required=True, readonly=False), 'concepts_table_id': fields.many2one('tcv.payroll.import.table', 'Concept\'s table', required=False, ondelete='restrict'), 'analytic_account_id': fields.many2one( 'account.analytic.account', 'Analytic Account', readonly=False, ondelete='restrict', ), 'payable_account_id': fields.many2one('account.account', 'Payable account', required=False, ondelete='restrict', domain=[('type', '=', 'payable')]), 'company_id': fields.many2one('res.company', 'Company', required=True, readonly=True, ondelete='restrict'), 'need_review': fields.boolean('Need data', required=True), } _defaults = { 'company_id': lambda self, cr, uid, c: self.pool.get('res.company'). _company_default_get(cr, uid, self._name, context=c), 'need_review': lambda *a: False, } _sql_constraints = [ ('hr_job_id', 'UNIQUE(hr_job_id)', 'The job must be unique!'), ] ##------------------------------------------------------------------------- ##---------------------------------------------------------- public methods ##-------------------------------------------------------- buttons (object) ##------------------------------------------------------------ on_change... ##----------------------------------------------------- create write unlink def write(self, cr, uid, ids, vals, context=None): ''' Assign: context = {'need_review': True} to set need_review value else need_review = false ''' context = context or {} vals.update({'need_review': context.get('need_review', False)}) res = super(tcv_payroll_import_job, self).\ write(cr, uid, ids, vals, context) return res
class account_installer(osv.osv_memory): _name = 'account.installer' _inherit = 'res.config.installer' __logger = logging.getLogger(_name) def _get_charts(self, cr, uid, context=None): modules = self.pool.get('ir.module.module') # Looking for the module with the 'Account Charts' category category_name, category_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'module_category_localization_account_charts') ids = modules.search(cr, uid, [('category_id', '=', category_id)], context=context) charts = list( sorted(((m.name, m.shortdesc) for m in modules.browse(cr, uid, ids, context=context)), key=itemgetter(1))) charts.insert(0, ('configurable', 'Generic Chart Of Accounts')) return charts _columns = { # Accounting 'charts': fields.selection(_get_charts, 'Chart of Accounts', required=True, help="Installs localized accounting charts to match as closely as " "possible the accounting needs of your company based on your " "country."), 'date_start': fields.date('Start Date', required=True), 'date_stop': fields.date('End Date', required=True), 'period': fields.selection([('month', 'Monthly'), ('3months','3 Monthly')], 'Periods', required=True), 'company_id': fields.many2one('res.company', 'Company', required=True), 'has_default_company' : fields.boolean('Has Default Company', readonly=True), } def _default_company(self, cr, uid, context=None): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) return user.company_id and user.company_id.id or False def _default_has_default_company(self, cr, uid, context=None): count = self.pool.get('res.company').search_count(cr, uid, [], context=context) return bool(count == 1) _defaults = { 'date_start': lambda *a: time.strftime('%Y-01-01'), 'date_stop': lambda *a: time.strftime('%Y-12-31'), 'period': 'month', 'company_id': _default_company, 'has_default_company': _default_has_default_company, 'charts': 'configurable' } def get_unconfigured_cmp(self, cr, uid, context=None): """ get the list of companies that have not been configured yet but don't care about the demo chart of accounts """ cmp_select = [] company_ids = self.pool.get('res.company').search(cr, uid, [], context=context) cr.execute("SELECT company_id FROM account_account WHERE active = 't' AND account_account.parent_id IS NULL AND name != %s", ("Chart For Automated Tests",)) configured_cmp = [r[0] for r in cr.fetchall()] return list(set(company_ids)-set(configured_cmp)) def check_unconfigured_cmp(self, cr, uid, context=None): """ check if there are still unconfigured companies """ if not self.get_unconfigured_cmp(cr, uid, context=context): raise osv.except_osv(_('No unconfigured company !'), _("There are currently no company without chart of account. The wizard will therefore not be executed.")) def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): res = super(account_installer, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False) cmp_select = [] # display in the widget selection only the companies that haven't been configured yet unconfigured_cmp = self.get_unconfigured_cmp(cr, uid, context=context) for field in res['fields']: if field == 'company_id': res['fields'][field]['domain'] = [('id','in',unconfigured_cmp)] res['fields'][field]['selection'] = [('', '')] if unconfigured_cmp: cmp_select = [(line.id, line.name) for line in self.pool.get('res.company').browse(cr, uid, unconfigured_cmp)] res['fields'][field]['selection'] = cmp_select return res def on_change_start_date(self, cr, uid, id, start_date=False): if start_date: start_date = datetime.datetime.strptime(start_date, "%Y-%m-%d") end_date = (start_date + relativedelta(months=12)) - relativedelta(days=1) return {'value': {'date_stop': end_date.strftime('%Y-%m-%d')}} return {} def execute(self, cr, uid, ids, context=None): self.execute_simple(cr, uid, ids, context) super(account_installer, self).execute(cr, uid, ids, context=context) def execute_simple(self, cr, uid, ids, context=None): if context is None: context = {} fy_obj = self.pool.get('account.fiscalyear') for res in self.read(cr, uid, ids, context=context): if 'charts' in res and res['charts'] == 'configurable': #load generic chart of account fp = tools.file_open(opj('account', 'configurable_account_chart.xml')) tools.convert_xml_import(cr, 'account', fp, {}, 'init', True, None) fp.close() if 'date_start' in res and 'date_stop' in res: f_ids = fy_obj.search(cr, uid, [('date_start', '<=', res['date_start']), ('date_stop', '>=', res['date_stop']), ('company_id', '=', res['company_id'][0])], context=context) if not f_ids: name = code = res['date_start'][:4] if int(name) != int(res['date_stop'][:4]): name = res['date_start'][:4] +'-'+ res['date_stop'][:4] code = res['date_start'][2:4] +'-'+ res['date_stop'][2:4] vals = { 'name': name, 'code': code, 'date_start': res['date_start'], 'date_stop': res['date_stop'], 'company_id': res['company_id'][0] } fiscal_id = fy_obj.create(cr, uid, vals, context=context) if res['period'] == 'month': fy_obj.create_period(cr, uid, [fiscal_id]) elif res['period'] == '3months': fy_obj.create_period3(cr, uid, [fiscal_id]) def modules_to_install(self, cr, uid, ids, context=None): modules = super(account_installer, self).modules_to_install( cr, uid, ids, context=context) chart = self.read(cr, uid, ids, ['charts'], context=context)[0]['charts'] self.__logger.debug('Installing chart of accounts %s', chart) return modules | set([chart])
locate_val = 'Active' cr.execute("UPDATE product_listing SET state='%s' where id=%d"%(locate_val,each_ids.id,)) cr.commit() res[each_ids.id] = { 'time_remain_function': locate, 'state':locate_val, } return res _columns = { 'name': fields.char('Item ID', size=64), 'prod_list':fields.many2one('product.product', string='Product Name',readonly= True), 'shop_id':fields.many2one('sale.shop', string='Shop Name'), 'ebay_end_time':fields.datetime('End Time',size=64), 'start_time':fields.datetime('Start Time',size=64), 'is_cancel':fields.boolean('Is Cancelled',readonly=True), 'cancel_listing' : fields.boolean('Cancel Listing'), 'ending_reason': fields.selection([('Incorrect','The start price or reserve price is incorrect'),('LostOrBroken','The item was lost or broken'),('NotAvailable','The item is no longer available for sale'),('OtherListingError','The listing contained an error'),('SellToHighBidder','The listing has qualifying bids')],'Ending Reason'), 'type': fields.char('Type',size=64), 'related_template':fields.many2one('ebayerp.template','Template'), 'listing_duration' : fields.char('Listing Duration',size=64), 'time_remain' : fields.char('Time Remaining',size=64), 'time_remain_function': fields.function(_get_time_remain_funtion, method=True, string='Remaining Time', type='char', multi='_get_time_remain_funtion'), 'product_listing_id': fields.one2many('current.details', 'current_details_ids','Product listing id'), 'state':fields.selection([('Active','Active'),('Inactive','Expired')],'Status',readonly=True), 'condtn':fields.selection([('1000','New'),('1500','New other (see details)'),('2000','Manufacturer refurbished'),('2500','Seller refurbished'),('3000','Used'),('7000','For parts or not working')],'Condition'), 'ebay_name':fields.char('Ebay Title',size=256), 'time_rem':fields.char('Time Remain',size=256), } _defaults = { 'state': 'Active',
class hr_applicant(osv.osv): ''' override the message_new for adding job code,state, stage rename the file name ''' _inherit = 'hr.applicant' _columns = { 'imp_pending': fields.boolean('IMP Empoyee'), 'not_visiblel': fields.char('test', size=56), 'resume_note': fields.text('Resume'), } def message_new(self, cr, uid, msg, custom_values=None, context=None): """Automatically called when new email message arrives""" subject = msg.get('subject') or _("No Subject") body = msg.get('body_text') # body=smart_str(body) unicodedata.normalize('NFKD', body).encode('ascii', 'ignore') if body.find("
") > -1: body = body.replace(" ", "") body = body.replace("\n", "#") body2 = body.split('####') list1 = [] if subject.find("Naukri.com") == -1: body = body body = body.replace("#", "\n") else: for i in body2: dict = {} if i.find("Resume Headline") > -1: dict['Resume Headline'] = i.replace( "#Resume Headline #: #", "") list1.append(dict) if i.find("Key Skills ") > -1: dict['Key Skills'] = i.replace("Key Skills #: ##", "") list1.append(dict) if i.find("Name") > -1: dict['Name'] = i.replace("Name #: #", "") list1.append(dict) if i.find("Total Experience ") > -1: dict['Total Experience'] = i.replace( "Total Experience #: #", "") list1.append(dict) if i.find("CTC ") > -1: dict['CTC'] = i.replace("CTC #: #", "") list1.append(dict) if i.find("Current Employer ") > -1: dict['Current Employer'] = i.replace( "Current Employer #: #", "") list1.append(dict) if i.find("Current Designation ") > -1: dict['Current Designation'] = i.replace( "Current Designation #: #", "") list1.append(dict) if i.find("Last Employer ") > -1: dict['Last Employer'] = i.replace("Last Employer ##: #", "") list1.append(dict) if i.find("Preferred Location ") > -1: dict['Preferred Location'] = i.replace( "Preferred Location #: #", "") list1.append(dict) if i.find("Current Location ") > -1: dict['Current Location'] = i.replace( "Current Location #: #", "") list1.append(dict) if i.find("Education ") > -1: dict['Education'] = i.replace("Education #: #", "") list1.append(dict) if i.find("Mobile ") > -1: dict['Mobile'] = i.replace("Mobile #: #", "") list1.append(dict) if i.find("Landline ") > -1: dict['Landline'] = i.replace("Landline #: #", "") list1.append(dict) if i.find("Recommendations ") > -1: dict['Recommendations'] = i.replace( "Recommendations #: #", "") list1.append(dict) if i.find("Last modified on ") > -1: dict['Last modified on'] = i.replace( "Last modified on #: #", "") list1.append(dict) body = "" for l in list1: body += l.keys()[0] + ":" + " " + l.values()[0] + "\n\n" msg_from = msg.get('from') priority = msg.get('priority') msg['attachments'] resume = "" for i in range(len(msg['attachments'])): l = list(msg['attachments'][i]) att_name = msg['attachments'][i][0] a = att_name.split('.') #======================================Find Current working path================================== cwd_path = os.getcwd() report_path = cwd_path + '/temp' if not os.path.exists(report_path): os.makedirs(report_path) #print report_path text_file = report_path + '/' + "resume.txt" resume_file = report_path + '/' + "resume." + a[-1] #================================================================================================= if a[-1] == 'doc': filename = open(resume_file, 'w') filename.write(str(msg['attachments'][i][1])) filename.close() commands.getoutput("catdoc '%s'> '%s'" % (resume_file, text_file)) resume_file = open(text_file, 'r') resume = resume_file.read() elif a[-1] == 'docx': filename = open(resume_file, 'w') filename.write(str(msg['attachments'][i][1])) filename.close() commands.getoutput("docx2txt.pl '%s' '%s' " % (resume_file, text_file)) resume_file = open(text_file, 'r') resume = resume_file.read() elif a[-1] == 'pdf': filename = open(resume_file, 'w') filename.write(str(msg['attachments'][i][1])) filename.close() commands.getoutput("pdftotext '%s' " % (resume_file)) resume_file = open(text_file, 'r') resume = resume_file.read() name = msg['attachments'][i][0] + ' ' + str( time.strftime('%Y-%m-%d %H:%M:%S')) l[0] = name msg['attachments'][i] = tuple(l) cr.execute('SELECT * FROM hr_job') ids = map(lambda x: x[0], cr.fetchall()) rows = self.pool.get('hr.job').browse(cr, uid, ids, context=None) k = [] for row in rows: job_code = row.job_code if job_code: if subject.find(job_code) > -1: code = subject.find(job_code) k.append(row) cr.execute( 'SELECT state,stage_id FROM hr_applicant where email_from=%s and not_visiblel=%s ', (msg_from, "TEST")) hr_applicant_ids = cr.fetchall() stage_id = False state = 'draft' if hr_applicant_ids: state = hr_applicant_ids[0][0] stage_id = hr_applicant_ids[0][1] hr_app_ids = self.pool.get('hr.applicant').search( cr, uid, [('email_from', '=', msg_from), ('state', '=', 'cancel'), ('not_visiblel', '=', 'TEST')]) if hr_app_ids and k: hr_app_obj = self.pool.get('hr.applicant').browse( cr, uid, hr_app_ids[0]) create_date = hr_app_obj.create_date c1 = create_date.split(' ') c_main = c1[0].split('-') create_date_last = datetime.datetime(int(c_main[0]), int(c_main[1]), int(c_main[2]), 0, 0, 0, 0) today = datetime.datetime.today() mon = int(k[0].month) after_six_months = create_date_last + relativedelta(months=mon) if after_six_months <= today: vals = { 'name': subject, 'email_from': msg_from, 'email_cc': msg.get('cc'), 'job_id': k[0].id, 'state': 'draft', 'description': body, 'user_id': False, 'resume_note': resume, 'not_visiblel': "TEST", } else: vals = { 'name': subject, 'email_from': msg_from, 'email_cc': msg.get('cc'), 'job_id': k[0].id, 'state': 'cancel', 'description': body, 'resume_note': resume, 'user_id': False, 'not_visiblel': "TEST", } if priority: vals['priority'] = priority vals.update( self.message_partner_by_email(cr, uid, msg.get('from', False))) res_id = super(hr_applicant, self).message_new(cr, uid, msg, custom_values=custom_values, context=context) self.write(cr, uid, [res_id], vals, context) if after_six_months <= today: self.write(cr, uid, hr_app_ids, {'state': 'draft'}, context) return res_id elif k and not hr_app_ids: vals = { 'name': subject, 'email_from': msg_from, 'email_cc': msg.get('cc'), 'job_id': k[0].id, 'state': state, 'stage_id': stage_id or False, 'description': body, 'resume_note': resume, 'user_id': False, 'not_visiblel': "TEST", } if priority: vals['priority'] = priority vals.update( self.message_partner_by_email(cr, uid, msg.get('from', False))) res_id = super(hr_applicant, self).message_new(cr, uid, msg, custom_values=custom_values, context=context) self.write(cr, uid, [res_id], vals, context) return res_id else: vals = { 'name': subject, 'email_from': msg_from, 'email_cc': msg.get('cc'), 'stage_id': stage_id or False, 'description': body, 'resume_note': resume, 'user_id': False, 'not_visiblel': "NOTEST", } if priority: vals['priority'] = priority vals.update( self.message_partner_by_email(cr, uid, msg.get('from', False))) res_id = super(hr_applicant, self).message_new(cr, uid, msg, custom_values=custom_values, context=context) self.write(cr, uid, [res_id], vals, context) return res_id
'product_asin' : data['ASIN'], 'product_category' : prod_category, 'product_id' : ids[0], 'amazon_product_attributes' : data } amazon_prod_master_obj = self.pool.get('amazon.products.master') amazon_prod_master_id = amazon_prod_master_obj.create(cr,uid,prodvals) else: raise osv.except_osv(_('Warning !'),'No products found on Amazon as per your search query. Please try again') return True _columns = { 'amazon_sku': fields.char('Amazon SKU', size=126), 'amazon_asin': fields.char('ASIN', size=16,readonly=True), 'orderitemid': fields.char('Orderitemid', size=16), 'product_order_item_id': fields.char('Order_item_id', size=256), 'amazon_export':fields.boolean('Exported to Amazon'), 'amazon_category':fields.many2one('amazon.category','Amazon Category'), 'amz_type': fields.selection([('',''),('IBSN','IBSN'),('UPC','UPC'),('EAN','EAN'),('ASIN','ASIN')],'Type'), 'amz_type_value': fields.char('Amazon Type Value', size=126), 'amzn_condtn': fields.selection([('',''),('New','New'),('UsedLikeNew','Used Like New'),('UsedVeryGood','Used Very Good'),('UsedGood','UsedGood') ,('UsedAcceptable','Used Acceptable'),('CollectibleLikeNew','Collectible Like New'),('CollectibleVeryGood','Collectible Very Good'),('CollectibleGood','Collectible Good') ,('CollectibleAcceptable','Collectible Acceptable'),('Refurbished','Refurbished'),('Club','Club')],'Amazon Condition'), 'prod_query': fields.char('Product Search Query', size=200, help="A search string with the same support as that is provided on Amazon marketplace websites."), 'prod_query_contextid': fields.selection(_amazon_browse_node_get,'Query ContextId', help="An identifier for the context within which the given search will be performed."), 'amazon_instance_id': fields.selection(_amazon_instance_get,'Amazon Instance', help="Select the Amazon instance where you want to perform search."), 'amazon_products_ids': fields.one2many('amazon.products.master', 'product_id', 'Amazon Searched Products'), 'amazon_prod_status': fields.selection([('active','Active'),('fail','Failure')],'Status',readonly="True"), 'operation_performed': fields.char('Operation Performed', size=126), 'submit_feed_result' : fields.text('Submit Feed Result',readonly=True), 'amazon_updated_price':fields.float('Amazon Updated Price',digits=(16,2)), 'condition_note' : fields.text('Condition Note'),
class network_software_logpass(osv.osv): """ Couples of login/password """ _inherit = "network.software.logpass" _columns = { 'name': fields.char('Name', size=100), 'note': fields.text('Note'), 'material': fields.related('software_id', 'material_id', type='many2one', relation='network.material', string='Material', readonly=True), 'encrypted': fields.boolean('Encrypted'), 'superuser': fields.boolean('Super User'), } _defaults = { 'encrypted': lambda obj, cursor, user, context: False, } def onchange_password(self, cr, uid, ids, encrypted, context={}): return {'value': {'encrypted': False}} def _encrypt_password(self, cr, uid, ids, *args): for rec in self.browse(cr, uid, ids): try: from Crypto.Cipher import ARC4 except ImportError: raise osv.except_osv(_('Error !'), _('Package python-crypto no installed.')) if not rec.encrypted: obj_encrypt_password = self.pool.get( 'network.encrypt.password') encrypt_password_ids = obj_encrypt_password.search( cr, uid, [('create_uid', '=', uid), ('write_uid', '=', uid)]) encrypt_password_id = encrypt_password_ids and encrypt_password_ids[ 0] or False if encrypt_password_id: passwordkey = obj_encrypt_password.browse( cr, uid, encrypt_password_id).name enc = ARC4.new(passwordkey) try: encripted = base64.b64encode(enc.encrypt(rec.password)) except UnicodeEncodeError: break self.write(cr, uid, [rec.id], { 'password': encripted, 'encrypted': True }) else: raise osv.except_osv( _('Error !'), _('Not encrypt/decrypt password has given.')) return True def _decrypt_password(self, cr, uid, ids, *args): for rec in self.browse(cr, uid, ids): try: from Crypto.Cipher import ARC4 except ImportError: raise osv.except_osv(_('Error !'), _('Package python-crypto no installed.')) if rec.encrypted: obj_encrypt_password = self.pool.get( 'network.encrypt.password') encrypt_password_ids = obj_encrypt_password.search( cr, uid, [('create_uid', '=', uid), ('write_uid', '=', uid)]) encrypt_password_id = encrypt_password_ids and encrypt_password_ids[ 0] or False if encrypt_password_id: passwordkey = obj_encrypt_password.browse( cr, uid, encrypt_password_id).name dec = ARC4.new(passwordkey) try: desencripted = dec.decrypt( base64.b64decode(rec.password)) unicode(desencripted, 'ascii') raise osv.except_osv(rec.login + _(' password:'******'Error !'), _('Wrong encrypt/decrypt password.')) else: raise osv.except_osv( _('Error !'), _('Not encrypt/decrypt password has given.')) return True
'height': fields.integer('Height (mm)'), 'weight': fields.integer('Weight (kg)') 'product_id': fields.many2one('product.product', 'Pallet Product'), } _defaults = { 'active': lambda *a, 1, } _sql_constraints = [('name_uniq', 'unique(name)', 'Pallet names must be unique!')] pallet_types() class pallet_stack_layout(osv.osv): _name = 'pallet.stack.layout' _columns = { 'name': fields.char('Description', size=128, required=True), 'active': fields.boolean('Active'), 'program': fields.integer('Program Number', help='If this is stacked on a palletiser, this is the palletiser program number'), 'pallet_type_id': fields.many2one('pallet.types','Pallet Type', ondelete='set null'), 'layout_diagram': fields.binary('Layout diagram', filters='*.bmp,*.jpg,*.gif') 'slipsheeted': fields.boolean('Slipsheeted', help='If product is stacked onto slipsheets, this box should be ticked.'), 'layer_qty': fields.integer('Packages per layer'), 'layer_height': fields.integer('Height per layer (mm)'), 'layer_ids': fields.one2many('pallet_stack_layers', 'layout_id','Layer options'), } _defaults = { 'active': lambda *a, 1, } pallet_stack_layout() class pallet_stack_layers(osv.osv): _name = 'pallet.stack.layers'
class accounting_report(osv.osv_memory): _name = "accounting.report" _inherit = "account.common.report" _description = "Accounting Report" _columns = { 'enable_filter': fields.boolean('Enable Comparison'), 'account_report_id': fields.many2one('account.financial.report', 'Account Reports', required=True), 'label_filter': fields.char( 'Column Label', size=32, help= "This label will be displayed on report to show the balance computed for the given comparison filter." ), 'fiscalyear_id_cmp': fields.many2one('account.fiscalyear', 'Fiscal Year', help='Keep empty for all open fiscal year'), 'filter_cmp': fields.selection([('filter_no', 'No Filters'), ('filter_date', 'Date'), ('filter_period', 'Periods')], "Filter by", required=True), 'period_from_cmp': fields.many2one('account.period', 'Start Period'), 'period_to_cmp': fields.many2one('account.period', 'End Period'), 'date_from_cmp': fields.date("Start Date"), 'date_to_cmp': fields.date("End Date"), 'debit_credit': fields.boolean( 'Display Debit/Credit Columns', help= "This option allow you to get more details about your the way your balances are computed. Because it is space consumming, we do not allow to use it while doing a comparison" ), } def _get_account_report(self, cr, uid, context=None): # TODO deprecate this it doesnt work in web menu_obj = self.pool.get('ir.ui.menu') report_obj = self.pool.get('account.financial.report') report_ids = [] if context.get('active_id'): menu = menu_obj.browse(cr, uid, context.get('active_id')).name report_ids = report_obj.search(cr, uid, [('name', 'ilike', menu)]) return report_ids and report_ids[0] or False _defaults = { 'filter_cmp': 'filter_no', 'target_move': 'posted', 'account_report_id': _get_account_report, } def _build_comparison_context(self, cr, uid, ids, data, context=None): if context is None: context = {} result = {} result['fiscalyear'] = 'fiscalyear_id_cmp' in data['form'] and data[ 'form']['fiscalyear_id_cmp'] or False result['journal_ids'] = 'journal_ids' in data['form'] and data['form'][ 'journal_ids'] or False result['chart_account_id'] = 'chart_account_id' in data[ 'form'] and data['form']['chart_account_id'] or False if data['form']['filter_cmp'] == 'filter_date': result['date_from'] = data['form']['date_from_cmp'] result['date_to'] = data['form']['date_to_cmp'] elif data['form']['filter_cmp'] == 'filter_period': if not data['form']['period_from_cmp'] or not data['form'][ 'period_to_cmp']: raise osv.except_osv( _('Error'), _('Select a starting and an ending period')) result['period_from'] = data['form']['period_from_cmp'] result['period_to'] = data['form']['period_to_cmp'] return result def check_report(self, cr, uid, ids, context=None): if context is None: context = {} res = super(accounting_report, self).check_report(cr, uid, ids, context=context) data = {} data['form'] = self.read( cr, uid, ids, [ 'account_report_id', 'date_from_cmp', 'date_to_cmp', 'fiscalyear_id_cmp', 'journal_ids', 'period_from_cmp', 'period_to_cmp', 'filter_cmp', 'chart_account_id', 'target_move' ], context=context)[0] for field in [ 'fiscalyear_id_cmp', 'chart_account_id', 'period_from_cmp', 'period_to_cmp', 'account_report_id' ]: if isinstance(data['form'][field], tuple): data['form'][field] = data['form'][field][0] comparison_context = self._build_comparison_context(cr, uid, ids, data, context=context) res['datas']['form']['comparison_context'] = comparison_context return res def _print_report(self, cr, uid, ids, data, context=None): data['form'].update( self.read(cr, uid, ids, [ 'date_from_cmp', 'debit_credit', 'date_to_cmp', 'fiscalyear_id_cmp', 'period_from_cmp', 'period_to_cmp', 'filter_cmp', 'account_report_id', 'enable_filter', 'label_filter' ], context=context)[0]) return { 'type': 'ir.actions.report.xml', 'report_name': 'account.financial.report', 'datas': data, }
ofile.write(base64.decodestring(b64_file)) finally: ofile.close() return True def _set_image(self, cr, uid, id, name, value, arg, context=None): local_media_repository = self.pool.get('res.company').get_local_media_repository(cr, uid, context=context) if local_media_repository: image = self.browse(cr, uid, id, context=context) return self._save_file(os.path.join(local_media_repository, image.product_id.default_code), '%s%s'%(image.name, image.extention), 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", method=True, 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'))] product_images()
def _get_calendars(self, cr, uid, context=None): user_obj = self.pool.get('res.users').browse(cr, uid, uid) google = self.pool.get('google.login') res = [] try: gd_client = google.google_login(user_obj.gmail_user, user_obj.gmail_password, type='calendar') calendars = gd_client.GetAllCalendarsFeed() for cal in calendars.entry: res.append((cal.id.text, cal.title.text)) except Exception, e: return [('failed', 'Connection to google fail')] res.append(('all', 'All Calendars')) return res _columns = { 'customer': fields.boolean('Customer', help="Check this box to set newly created partner as Customer."), 'supplier': fields.boolean('Supplier', help="Check this box to set newly created partner as Supplier."), 'group_name': fields.selection(_get_group, "Group Name",help="Choose which group to import, By default it takes all."), 'calendar_name': fields.selection(_get_calendars, "Calendar Name"), } _defaults = { 'group_name': 'all', } def import_google(self, cr, uid, ids, context=None): if context == None: context = {} if not ids: return {'type': 'ir.actions.act_window_close'} obj = self.browse(cr, uid, ids, context=context)[0]
"parser_loc": fields.char( "Parser location", size=128, help="Path to the parser location. Beginning of the path must be start with the module name!\nLike this: {module name}/{path to the parser.py file}", ), "parser_state": fields.selection( [("default", _("Default")), ("def", _("Definition")), ("loc", _("Location"))], "State of Parser", select=True, ), "in_format": fields.selection(_get_in_mimetypes, "Template Mime-type"), "out_format": fields.many2one("report.mimetypes", "Output Mime-type"), "report_sxw_content": fields.function( _report_content, fnct_inv=_report_content_inv, method=True, type="binary", string="SXW content" ), "active": fields.boolean("Active"), "report_wizard": fields.boolean("Report Wizard"), "copies": fields.integer("Number of copies"), "fallback_false": fields.boolean("Disable format fallback"), "xml_id": fields.function( _get_xml_id, type="char", size=128, string="XML ID", method=True, help="ID of the report defined in xml file", ), "page_count": fields.char( "Page Count", size=128, help="Line count on each page, in format 'first_last_page, first_page, middle_page,last_page', for example,'17,22,26,21'. ",
#=========================================================================== def get_image(self, value, width, hight, hr, code='QR'): options = {} if width:options['width'] = width if hight:options['hight'] = hight if hr:options['humanReadable'] = hr try: ret_val = createBarcodeDrawing(code, value=str(value), **options) except Exception, e: raise osv.except_osv('Error', e) return base64.encodestring(ret_val.asString('jpg')) def generate_image(self, cr, uid, ids, context=None): if not context: context = {} for self_obj in self.browse(cr, uid, ids, context=context): image = self.get_image(self_obj.code, code=self_obj.barcode_type or 'qrcode', width=self_obj.width, hight=self_obj.hight, hr=self_obj.hr_form) self.write(cr, uid, self_obj.id, {'image':image},context=context) return True _columns = { 'barcode_code' : fields.char('Other Barcode',size=20), 'barcode_type' : fields.selection(_get_code, 'Barcode Type'), 'barcode_hr' : fields.boolean('Human Readable'), 'barcode_image' : fields.function(_get_image, string="Image", type="binary"), } product_product()
class sale_order_line(osv.osv): """ Heredamos de la clase sale.order.line, se agregan las columnas(pack_depth,bom_line,parent_sale_order_line,child_sale_order_lines) y se definen nuevos metodos """ _inherit = 'sale.order.line' def price_change(self, cr, uid, ids, price, discount, context=None): """ Impedimos el cambio de precio y descuento, o registramos cambio y que se debe reexpandir :param cr: :param uid: :param ids: :param price: :param discount: :return: """ ids = ids if isinstance(ids, (list, tuple, set, frozenset)) else [ids] for obj in self.browse(cr, uid, ids, context): if not (obj.price_unit == price and obj.discount == discount) and obj.bom_line: return { 'value': { 'price_unit': obj.price_unit, 'discount': obj.discount }, 'warning': { 'title': 'Error!', 'message': 'No se puede cambiar el precio ni el descuento de una línea ' 'perteneciente a una receta' } } else: if not obj.bom_line: self.pool['sale.order'].write( cr, uid, [obj.order_id and obj.order_id.id], {}, context=dict(context or {}, should_expand=True)) return {'value': {}} return {'value': {}} def create(self, cr, uid, vals, context=None): """ Si le especificamos sequence_preset=False, o no se lo especificamos, entonces la creacion de una linea de orden de compra tendra un indice de secuencial igual al maximo que encuentre (tomando lineas de orden de compra dentro de la misma orden) +1. """ if context is None: context = {} if not context.get('sequence_preset', False): order_line_ids = self.search(cr, uid, [('order_id', '=', vals['order_id'])], context=context) order_lines = self.read(cr, uid, order_line_ids, fields=('sequence', ), context=context) vals['sequence'] = max([ obj['sequence'] if obj['sequence'] is not False else -1 for obj in order_lines ] or [-1]) + 1 return super(sale_order_line, self).create(cr, uid, vals, context=context) def product_id_change(self, cr, uid, ids, pricelist, product, qty=0, uom=False, qty_uos=0, uos=False, name='', partner_id=False, lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False, context=None): """ Impedimos el cambio de producto y de cantidad, o registramos cambio y que se debe reexpandir :param args: :param kwargs: :return: """ result = {'warning': {}, 'value': {}} if not context: context = {} ids = ids if isinstance(ids, (list, tuple, set, frozenset)) else [ids] result = super(sale_order_line, self).product_id_change( cr, uid, ids, pricelist, product, qty, uom, qty_uos, uos, name, partner_id, lang, update_tax, date_order, packaging, fiscal_position, flag, context or {}) for obj in self.browse(cr, uid, ids, context): if not (obj.product_id and obj.product_id.id == product and obj.product_uom_qty == qty) and obj.bom_line: result.setdefault('value', {}) result['value'].update({ 'product_uom_qty': obj.product_uom_qty, 'product_id': obj.product_id and obj.product_id.id }) result.setdefault('warning', {}) result['warning'].update({ 'title': 'Error!', 'message': 'No se puede cambiar el producto ni la cantidad de una linea perteneciente a una receta' }) else: if not obj.bom_line and not context.get( 'already_expanding', False): self.pool['sale.order'].write( cr, uid, [obj.order_id and obj.order_id.id], {}, context=dict(context or {}, should_expand=True)) if self.search(cr, uid, [('parent_sale_order_line', '=', obj.id)], context=context): # No solo estamos editando una linea que no es BOM y que no ocurre durante el proceso de # expansion, sino que ademas estamos editando una linea que tiene lineas hijas. Por esto, # tenemos que tirar una alerta para indicarle que esto no se verá hasta que to' esté guardado. result['warning'].update({ 'title': u'Información', 'message': u'Usted se encuentra realizando cambios en una línea de producto que despliega ingredientes. Los cambios en los mismos se reflejarán cuando se guarde la orden de venta.' }) return result def product_uom_change(self, cursor, user, ids, pricelist, product, qty=0, uom=False, qty_uos=0, uos=False, name='', partner_id=False, lang=False, update_tax=True, date_order=False, context=None): result = super(sale_order_line, self).product_uom_change( cursor, user, ids, pricelist, product, qty, uom, qty_uos, uos, name, partner_id, lang, update_tax, date_order, context) for obj in self.browse(cursor, user, ids, context=context): if obj.bom_line: result['value'] = {} return result def unlink(self, cr, uid, ids, context=None): """ Desvincula desde el padre, jalando por cascade a los hijos :param cr: :param uid: :param ids: :param context: :return: """ context = context or {} sale_order_line_obj = self.pool.get('sale.order.line') ids = ids if isinstance(ids, (list, tuple, set, frozenset)) else [ids] for line in sale_order_line_obj.browse(cr, uid, ids, context=context): # para cada objeto, navegamos hacia el padre superior if context.get('upwards', True): try: while line.parent_sale_order_line: line = line.parent_sale_order_line except ValueError: # Absorbemos cualquier excepcion en este punto. # Estas pueden darse por alguna cuestion relacionada a integridad referencial # ya que el objeto padre puede haberse borrado en alguna otra iteracion anterior. pass try: super(sale_order_line, self).unlink(cr, uid, [line.id], context=context) except ValueError: # Absorbemos cualquier excepcion en este punto. # Estas pueden darse por alguna cuestion relacionada a integridad referencial # ya que el objeto padre puede haberse borrado en alguna otra iteracion anterior. pass _columns = { 'pack_depth': fields.integer('Depth', required=True, help='Depth of the product if it is part of a pack.'), 'bom_line': fields.boolean('Bom Lines'), 'parent_sale_order_line': fields.many2one( 'sale.order.line', string='Parent sale order line', required=False, help= 'Id of parent line when the line is an ingredient in Bill of Material of type Break Down on Sale Order', ondelete="cascade"), 'child_sale_order_lines': fields.one2many( 'sale.order.line', 'parent_sale_order_line', 'Child sale order lines', required=False, help= 'Ids of children lines when the line is an ingredient in Bill of Material of type Break Down on Sale Order' ) } _defaults = {'pack_depth': 0, 'parent_sale_order_line': 0}
from osv import osv, fields FISCAL_POSITION_COLUMNS = { 'cfop_id': fields.many2one('l10n_br_account.cfop', 'CFOP'), 'fiscal_category_id': fields.many2one('l10n_br_account.fiscal.category', 'Categoria Fiscal'), 'type': fields.selection([('input', 'Entrada'), ('output', 'Saida')], 'Tipo'), 'type_tax_use': fields.selection([('sale', 'Sale'), ('purchase', 'Purchase'), ('all', 'All')], 'Tax Application'), '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'), 'inv_copy_note': fields.boolean('Copiar Observação na Nota Fiscal'), 'asset_operation': fields.boolean('Operação de Aquisição de Ativo', help="Caso seja marcada essa opção, \ será incluido o IPI na base de \ calculo do ICMS.")} class account_fiscal_position_template(osv.Model): _inherit = 'account.fiscal.position.template' _columns = FISCAL_POSITION_COLUMNS def onchange_type(self, cr, uid, ids, type=False, context=None): type_tax = {'input': 'purhcase', 'output': 'sale'} return {'value': {'type_tax_use': type_tax.get(type, 'all'), 'tax_ids': False}}
# attention: Incorrect field names !! # installed_version refer the latest version (the one on disk) # latest_version refer the installed version (the one in database) # published_version refer the version available on the repository 'installed_version': fields.function(_get_latest_version, string='Latest version', type='char'), 'latest_version': fields.char('Installed version', size=64, readonly=True), 'published_version': fields.char('Published Version', size=64, readonly=True), 'url': fields.char('URL', size=128, 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='State', 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'),
class sale_order(osv.osv): """ Heredamos de la clase sale.order, se agrega la columna should_expand y nuevos metodos """ _inherit = 'sale.order' def create_bom_line(self, cr, uid, line, order, main_discount=0.0, hierarchy=(), context=None): """ Dado el BOM de un producto en una linea de orden de venta, y teniendo en cuenta la cantidad del producto en dicha linea de orden de venta, se evalua si se deben crear nuevas lineas de orden de venta "hijas" de la línea actual (es decir: describen la línea actual de orden de venta, dividiendo el producto en la línea por sus componentes, creando las nuevas líneas, y teniendo en cuenta la cantidad del producto de la línea en cuestion). Como ejemplo: si estamos viendo una línea de "Combo de Canguil Grande" en un cine, el cual incluya dos gaseosas y una bolsa grande de canguil, y se piden tres (3) de estos combos, se crearían líneas "hijas" que tendrían cantidades consideradas: 3 bolsas grandes de canguil, y 6 colas (se multiplica la cantidad). Las líneas "hijas" son creadas únicamente si la línea actual tiene un producto que tiene un BOM y, ademas, dicho BOM es de tipo "Break Down on Sale" (otros BOM no atraviesan este proceso). Todas las líneas hijas tienen un precio unitario de 0, ya que el precio se especifica por la línea "ancestra" (aquella que no es hija de ninguna otra) que originó todo. Esta construcción es recursiva (por lo que varias lineas hijas pueden ser, a su vez, combos de tipo "Break Down on Sale"), y las líneas hijas son marcadas (tabuladas) en su descripción. """ bom_obj = self.pool.get('mrp.bom') sale_line_obj = self.pool.get('sale.order.line') bom_ids = bom_obj.search(cr, uid, [('product_id', '=', line.product_id.id), ('type', '=', 'break_down_on_sale')]) warnings = '' hierarchy = hierarchy + (line.product_id.id, ) if bom_ids: bom_data = bom_obj.browse(cr, uid, bom_ids[0]) factor = line.product_uos_qty / (bom_data.product_efficiency or 1.0) factor = rounding(factor, bom_data.product_rounding) if factor < bom_data.product_rounding: factor = bom_data.product_rounding for bom_line in bom_data.bom_lines: quantity = bom_line.product_qty * factor date_start = bom_line.date_start date_stop = bom_line.date_stop now = datetime.now().date() if date_start: date_start = datetime.strptime( date_start, DEFAULT_SERVER_DATE_FORMAT).date() if date_start > now: continue if date_stop: date_stop = datetime.strptime( date_stop, DEFAULT_SERVER_DATE_FORMAT).date() if date_stop < now: continue result = sale_line_obj.product_id_change( cr, uid, [], order.pricelist_id.id, bom_line.product_id.id, quantity, bom_line.product_id.uom_id.id, quantity, bom_line.product_id.uos_id.id, '', order.partner_id.id, False, True, order.date_order, False, order.fiscal_position.id, False, context=context or {}) discount = result.get('value', {}).get('discount') or 0.0, if order.pricelist_id.visible_discount == True: # if visible discount is installed and if enabled # use the discount provided by list price discount = result.get('value', {}).get('discount') or 0.0 else: # we asume the visible discount is not enabled # then we use as discount the discount of the main product. print main_discount discount = main_discount if bom_line.product_id.id in hierarchy: pass # Comentamos el mensaje que agregamos porque a los de SF no les va a gustar ver esto asi. # sin embargo, el codigo de abajo NO es erroneo. ########################################################################################### # warnings += """ # Cannot expand BoM line for product: [%d] %s. Such product is misconfigured since it belongs to a BoM hierarchy it's also an ancestor for. # """ % (line.product_id.id, line.product_id.name) else: warnings += result.get('warning') and result.get('warning').get('message') and \ "\nProduct :- %s\n%s\n" % (bom_line.product_id.name, result.get('warning').get('message')) or '' vals = { 'order_id': order.id, 'name': '%s%s' % ('>' * (line.pack_depth + 1), result.get('value', {}).get('name')), 'sequence': context['_shared']['sequence'], 'delay': bom_line.product_id.sale_delay or 0.0, 'product_id': bom_line.product_id.id, # TODO: Esta funcionalidad deberia ser parametrizable 'price_unit': 0.0, # result.get('value',{}).get('price_unit'), 'tax_id': [(6, 0, result.get('value', {}).get('tax_id'))], 'type': bom_line.product_id.procure_method, 'product_uom_qty': result.get('value', {}).get('product_uos_qty'), 'product_uom': result.get('value', {}).get('product_uom') or line.product_id.uom_id.id, 'product_uos_qty': result.get('value', {}).get('product_uos_qty'), 'product_uos': result.get('value', {}).get('product_uos') or line.product_id.uos_id.id, 'product_packaging': result.get('value', {}).get('product_packaging'), 'discount': discount, 'bom_line': True, 'th_weight': result.get('value', {}).get('th_weight'), 'pack_depth': line.pack_depth + 1, 'parent_sale_order_line': line.id } sale_id = sale_line_obj.create( cr, uid, vals, dict(context or {}, sequence_preset=True)) line_data = sale_line_obj.browse(cr, uid, sale_id, context) context['_shared']['sequence'] += 1 warnings += self.create_bom_line(cr, uid, line_data, order, main_discount, hierarchy, context) return warnings def expand_bom(self, cr, uid, ids, context=None, depth=0): """ Para cada orden de venta se expanden las líneas que sean combos de tipo "Break Down on Sale Order". La descripción de dicho proceso está descrita en create_bom_line(). Hay que tener en claro que este proceso elimina las líneas "hijas" existentes y vuelve a recrearlas, actualizando según el nuevo producto y/o cantidad de las líneas que no son "hijas" y que tienen un BOM de tipo "Break Down on Sale Order". """ if context is None: context = {} context.update({'_shared': {'sequence': 0}}) if depth == 10: return True if type(ids) in [int, long]: ids = [ids] sale_line_obj = self.pool.get('sale.order.line') warnings = '' for order in self.browse(cr, uid, ids, context): delete_line_ids = sale_line_obj.search( cr, uid, [('bom_line', '=', True), ('order_id', '=', order.id)]) if delete_line_ids: sale_line_obj.unlink(cr, uid, delete_line_ids, context=dict(context, upwards=False)) for line in sale_line_obj.browse( cr, uid, sale_line_obj.search(cr, uid, [('order_id', '=', order.id)], order='sequence', context=context), context=context): # El descuento del producto principal del combo main_discount = line.discount if line.product_id and line.state == 'draft': sale_line_obj.write( cr, uid, [line.id], {'sequence': context['_shared']['sequence']}, dict(context, already_expanding=True)) context['_shared']['sequence'] += 1 warnings += self.create_bom_line(cr, uid, line, order, main_discount, hierarchy=(), context=dict( context, already_expanding=True)) context.update({'default_name': warnings}) context.pop('_shared', None) vals = True if warnings: vals = { 'name': ('Expand BOM Warnings'), 'context': context, 'view_type': 'form', 'view_mode': 'form', 'res_model': 'expand.bom.message', 'res_id': False, 'type': 'ir.actions.act_window', 'target': 'new', } return vals def create(self, cr, uid, vals, context=None): """ Se invoca el super de create para llamar el metodo expand_bom en el boton guardar """ if context is None: context = {} if 'order_line' in vals: # Obtenemos todas las lineas que sean padres y lineas regulares notchilds = [ line for line in vals['order_line'] if isinstance(line[2], dict) and not line[2].get('parent_sale_order_line') ] # Seteamos a todas estas lineas sus hijos en [] (vacio) hijos solo es el nombre de la variable # no se me ocurrio otro hijos = [ notchild[2].update({'child_sale_order_lines': []}) for notchild in notchilds ] # La variable order_line se setea con los nuevos valores de notchilds vals['order_line'] = notchilds res = super(sale_order, self).create(cr, uid, vals, context=context) self.expand_bom(cr, uid, [res], context=context, depth=0) return res def write(self, cr, uid, ids, vals, context=None): """ Debemos contemplar que, al guardar, puede que la guardada sea autonoma y que tengamos que refrescar todo el contenido, si así fue encargado. Si la guardada NO es autonoma, sino que pertenece a algun cambio registrado, entonces invocamos que se guarde y se marque para expandir. :param cr: :param uid: :param ids: :param vals: :param context: :return: """ if context is None: context = {} ids = ids if isinstance(ids, (list, tuple, set, frozenset)) else [ids] # Nos quedamos con los elementos que existan en la base de datos. LA RAZON ES QUE si no filtramos asi, # vamos a tener elementos para el WRITE que se refiere a elementos que no estan en la base de datos, # y vamos a tener un bonito error. # # OJO tambien conservamos los nuevos eeh. existent_lines = self.pool['sale.order.line'].search( cr, uid, [('order_id', 'in', ids)], context=context) if 'order_line' in vals: vals['order_line'] = [ e for e in vals.get('order_line', []) if (e[0] == 0 or e[1] in existent_lines) ] # Nos quedamos con los elementos NUEVOS de sale.order.line new_order_lines = [e for e in vals.get('order_line', []) if e[0] == 0] if not context.get('should_expand', False): """ Entramos aca si cualquiera de las dos condiciones se cumple: 1. Es una guardada normal (es decir, no es una guardada que preguarda la indicación de expandir. En este sentido, ya que no estamos preindicando, lo que nos toca es revisar si teniamos anteriormente una preindicacion para expandir, y obedecerla. 2. Es una guardada que modifica las lineas que existen en la orden de venta. En tal caso deberiamos forzar una expansion, como si hubieramos tenido la indicacion de expandir puesta explicitamente. """ ids = ids if isinstance(ids, (list, tuple, set, frozenset)) else [ids] for values in self.read(cr, uid, ids, fields=('id', 'should_expand', 'state'), context=context): if (values['should_expand'] or new_order_lines) and (values.get('state') not in [ 'cancel', 'waiting_date', 'progress', 'manual', 'shipping_except', 'invoice_except', 'done' ]): super(sale_order, self).write(cr, uid, [values['id']], dict(vals, should_expand=False), context) self.expand_bom(cr, uid, [values['id']], context=context, depth=0) else: super(sale_order, self).write(cr, uid, [values['id']], vals, context) else: # Esta llamada se realiza cuando guardamos mediante write() con el contexto explicito. super(sale_order, self).write(cr, uid, ids, dict(vals, should_expand=True), context) return True _columns = { 'should_expand': fields.boolean(string='Should Expand BoM', required=True) } _defaults = {'should_expand': lambda *a, **kwa: False}
class profit_and_loss_wizard(osv.osv_memory): _name = 'profit.loss.wizard' _description = 'Profit and Loss' def _get_account(self, cr, uid, context=None): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) accounts = self.pool.get('account.account').search( cr, uid, [('parent_id', '=', False), ('company_id', '=', user.company_id.id)], limit=1) return accounts and accounts[0] or False def _get_from_date(self, cr, uid, context=None): fiscalyear_obj = self.pool.get('account.fiscalyear') now = time.strftime('%Y-%m-%d') fiscalyears = fiscalyear_obj.search(cr, uid, [('date_start', '<=', now), ('date_stop', '>=', now)], limit=1) fiscal_year_id = fiscalyears and fiscalyears[0] or False start_date = fiscalyear_obj.browse(cr, uid, fiscal_year_id, context=context).date_start report_type = context.get('print_report_type', 'pl') if report_type == 'bl': start_date = "2014-01-01" return start_date def default_get(self, cr, uid, fields, context=None): if context is None: context = {} fin_report_pool = self.pool.get('account.financial.report') res = super(profit_and_loss_wizard, self).default_get(cr, uid, fields, context=context) report_type = context.get('print_report_type', 'pl') fin_report_ids = fin_report_pool.search( cr, uid, [('parent_id', '=', False), ('report_type', '=', report_type)]) if not fin_report_ids: raise osv.except_osv(_("Error!!!"), _("Please Configure Financial Report!!!")) res['account_report_id'] = fin_report_ids[0] fin_report_obj = fin_report_pool.browse(cr, uid, fin_report_ids[0], context=context) res['fin_report_type'] = fin_report_obj.report_type return res _columns = { 'chart_account_id': fields.many2one('account.account', 'Chart of Account', help='Select Charts of Accounts', required=True, domain=[('parent_id', '=', False)]), 'date_from': fields.date('From Date'), 'date_to': fields.date('To Date'), 'cost_center_ids': fields.many2many('account.analytic.account', 'cost_center_ana_rel1', 'wizard_id1', 'cc_id1', 'Cost Center'), 'account_report_id': fields.many2one('account.financial.report', 'Account Reports', required=True), 'view_all': fields.boolean('View All Account ?'), 'fin_report_type': fields.selection([('bl', 'Balance Sheet'), ('pl', 'Profit & Loss')], 'Report Type'), 'report_type': fields.selection([('pdf', 'PDF'), ('xls', 'Excel')], 'Report Type'), } _defaults = { 'chart_account_id': _get_account, 'date_from': _get_from_date, 'date_to': lambda *a: time.strftime('%Y-%m-%d'), 'report_type': 'pdf' } def print_report(self, cr, uid, ids, context=None): data = self.read(cr, uid, ids, context={})[0] data['chart_account_id'] = data['chart_account_id'][0] data['filter_cmp'] = 'filter_no' data['filter'] = 'filter_date' data['debit_credit'] = False data['enable_filter'] = False report_name = 'balance_sheet_jasper' if data['report_type'] == 'xls': report_name = 'balance_sheet_jasper_xls' datas = {'form': data} return { 'type': 'ir.actions.report.xml', 'report_name': report_name, 'datas': datas, 'nodestroy': True, }
from tools.translate import _ class stock_fill_inventory(osv.osv_memory): _name = "stock.fill.inventory" _description = "Import Inventory" 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), 'recursive': fields.boolean("Include children",help="If checked, products contained in child locations of selected location will be included as well."), 'set_stock_zero': fields.boolean("Set to zero",help="If checked, all product quantities will be set to zero to help ensure a real physical inventory is done"), } _defaults = { 'location_id': _default_location, } def view_init(self, cr, uid, fields_list, context=None): """ Creates view dynamically and adding fields at runtime. @param self: The object pointer. @param cr: A database cursor @param uid: ID of the user currently logged in @param context: A standard dictionary @return: New arch of view with new columns. """
class newsletter_newsletter(osv.osv): _name = "newsletter.newsletter" _description = "Newsletter" def name_get(self, cr, uid, ids, context=None): if not len(ids): return [] reads = self.read(cr, uid, ids, ['name', 'parent_id'], context=context) res = [] for record in reads: name = record['name'] if record['parent_id']: name = record['parent_id'][1] + ' / ' + name res.append((record['id'], name)) return res def _name_get_fnc(self, cr, uid, ids, prop, unknow_none, context=None): res = self.name_get(cr, uid, ids, context=context) return dict(res) def _check_recursion(self, cr, uid, ids): level = 100 while len(ids): cr.execute( 'select distinct parent_id from newsletter_newsletter where id in (' + ','.join(map(str, ids)) + ')') ids = filter(None, map(lambda x: x[0], cr.fetchall())) if not level: return False level -= 1 return True _columns = { 'name': fields.char('Name', size=64, required=True), 'parent_id': fields.many2one('newsletter.newsletter', 'Partner Newsletter', select=True), 'complete_name': fields.function(_name_get_fnc, method=True, type="char", string='Full Name'), 'child_ids': fields.one2many('newsletter.newsletter', 'parent_id', 'Child Newsletter'), 'active': fields.boolean( 'Active', help= "The active field allows you to hide the newsletter without removing it." ), } _constraints = [ (_check_recursion, 'Error ! You can not create recursive records.', ['parent_id']) ] _defaults = { 'active': lambda *a: 1, } _order = 'parent_id,name'
class resource_resource(osv.osv): _name = "resource.resource" _description = "Resource Detail" _columns = { 'name': fields.char("Name", size=64, required=True), 'code': fields.char('Code', size=16), 'active': fields.boolean( 'Active', help= "If the active field is set to False, it will allow you to hide the resource record without removing it." ), 'company_id': fields.many2one('res.company', 'Company'), 'resource_type': fields.selection([('user', 'Human'), ('material', 'Material')], 'Resource Type', required=True), 'user_id': fields.many2one( 'res.users', 'User', help='Related user name for the resource to manage its access.'), 'time_efficiency': fields.float( 'Efficiency factor', size=8, required=True, help= "This field depict the efficiency of the resource to complete tasks. e.g resource put alone on a phase of 5 days with 5 tasks assigned to him, will show a load of 100% for this phase by default, but if we put a efficency of 200%, then his load will only be 50%." ), 'calendar_id': fields.many2one("resource.calendar", "Working Period", help="Define the schedule of resource"), } _defaults = { 'resource_type': 'user', 'time_efficiency': 1, 'active': True, 'company_id': lambda self, cr, uid, context: self.pool.get('res.company'). _company_default_get(cr, uid, 'resource.resource', context=context) } def copy(self, cr, uid, id, default=None, context=None): if default is None: default = {} if not default.get('name', False): default['name'] = self.browse(cr, uid, id, context=context).name + _(' (copy)') return super(resource_resource, self).copy(cr, uid, id, default, context) def generate_resources(self, cr, uid, user_ids, calendar_id, context=None): """ Return a list of Resource Class objects for the resources allocated to the phase. """ resource_objs = {} user_pool = self.pool.get('res.users') for user in user_pool.browse(cr, uid, user_ids, context=context): resource_ids = self.search(cr, uid, [('user_id', '=', user.id)], context=context) #assert len(resource_ids) < 1, "User should not has more than one resources" leaves = [] resource_eff = 1.0 if resource_ids: resource_id = resource_ids[0] resource = self.browse(cr, uid, resource_id, context=context) resource_eff = resource.time_efficiency resource_cal = resource.calendar_id.id if resource_cal: leaves = self.compute_vacation(cr, uid, calendar_id, resource.id, resource_cal, context=context) temp = { 'name': resource.name, 'vacation': tuple(leaves), 'efficiency': resource_eff, } resource_objs[resource_id] = temp # resource_objs.append(classobj(str(user.name), (Resource,),{ # '__doc__': user.name, # '__name__': user.name, # 'vacation': tuple(leaves), # 'efficiency': resource_eff, # })) return resource_objs def compute_vacation(self, cr, uid, calendar_id, resource_id=False, resource_calendar=False, context=None): """ Compute the vacation from the working calendar of the resource. @param calendar_id : working calendar of the project @param resource_id : resource working on phase/task @param resource_calendar : working calendar of the resource """ resource_calendar_leaves_pool = self.pool.get( 'resource.calendar.leaves') leave_list = [] if resource_id: leave_ids = resource_calendar_leaves_pool.search( cr, uid, [ '|', ('calendar_id', '=', calendar_id), ('calendar_id', '=', resource_calendar), ('resource_id', '=', resource_id) ], context=context) else: leave_ids = resource_calendar_leaves_pool.search( cr, uid, [('calendar_id', '=', calendar_id), ('resource_id', '=', False)], context=context) leaves = resource_calendar_leaves_pool.read(cr, uid, leave_ids, ['date_from', 'date_to'], context=context) for i in range(len(leaves)): dt_start = datetime.strptime(leaves[i]['date_from'], '%Y-%m-%d %H:%M:%S') dt_end = datetime.strptime(leaves[i]['date_to'], '%Y-%m-%d %H:%M:%S') no = dt_end - dt_start [ leave_list.append( (dt_start + timedelta(days=x)).strftime('%Y-%m-%d')) for x in range(int(no.days + 1)) ] leave_list.sort() return leave_list def compute_working_calendar(self, cr, uid, calendar_id=False, context=None): """ Change the format of working calendar from 'Openerp' format to bring it into 'Faces' format. @param calendar_id : working calendar of the project """ if not calendar_id: # Calendar is not specified: working days: 24/7 return [('fri', '1:0-12:0', '12:0-24:0'), ('thu', '1:0-12:0', '12:0-24:0'), ('wed', '1:0-12:0', '12:0-24:0'), ('mon', '1:0-12:0', '12:0-24:0'), ('tue', '1:0-12:0', '12:0-24:0'), ('sat', '1:0-12:0', '12:0-24:0'), ('sun', '1:0-12:0', '12:0-24:0')] resource_attendance_pool = self.pool.get( 'resource.calendar.attendance') time_range = "8:00-8:00" non_working = "" week_days = { "0": "mon", "1": "tue", "2": "wed", "3": "thu", "4": "fri", "5": "sat", "6": "sun" } wk_days = {} wk_time = {} wktime_list = [] wktime_cal = [] week_ids = resource_attendance_pool.search( cr, uid, [('calendar_id', '=', calendar_id)], context=context) weeks = resource_attendance_pool.read( cr, uid, week_ids, ['dayofweek', 'hour_from', 'hour_to'], context=context) # Convert time formats into appropriate format required # and create a list like [('mon', '8:00-12:00'), ('mon', '13:00-18:00')] for week in weeks: res_str = "" day = None if week_days.has_key(week['dayofweek']): day = week_days[week['dayofweek']] wk_days[week['dayofweek']] = week_days[week['dayofweek']] hour_from_str = convert_timeformat(week['hour_from']) hour_to_str = convert_timeformat(week['hour_to']) res_str = hour_from_str + '-' + hour_to_str wktime_list.append((day, res_str)) # Convert into format like [('mon', '8:00-12:00', '13:00-18:00')] for item in wktime_list: if wk_time.has_key(item[0]): wk_time[item[0]].append(item[1]) else: wk_time[item[0]] = [item[0]] wk_time[item[0]].append(item[1]) for k, v in wk_time.items(): wktime_cal.append(tuple(v)) # Add for the non-working days like: [('sat, sun', '8:00-8:00')] for k, v in wk_days.items(): if week_days.has_key(k): week_days.pop(k) for v in week_days.itervalues(): non_working += v + ',' if non_working: wktime_cal.append((non_working[:-1], time_range)) return wktime_cal #TODO: Write optimized alogrothem for resource availability. : Method Yet not implemented def check_availability(self, cr, uid, ids, start, end, context=None): if context == None: contex = {} allocation = {} return allocation
class sale_order(osv.osv): """ Modificaciones de sale order para añadir la posibilidad de versionar el pedido de venta. """ _inherit = "sale.order" def action_previous_version(self, cr, uid, id, default=None, context=None): if not default: default = {} sale_obj = self.browse(cr, uid, id, context=context) sale_ids = [] for sale in sale_obj: vals = {} if not sale.sale_version_id: vals.update({'sale_version_id': sale.id, 'version': 1}) else: vals.update({'version': sale.version + 1}) new = self.copy(cr, uid, sale.id, vals) if not sale.sale_version_id: self.write(cr, uid, [new], {'name': sale.name + u" V.1"}) else: self.write( cr, uid, [new], { 'name': sale.sale_version_id.name + u" V." + ustr(sale.version + 1) }) sale.write({'active': False}) sale_ids.append(new) mod_obj = self.pool.get('ir.model.data') res = mod_obj.get_object_reference(cr, uid, 'sale', 'view_order_form') res_id = res and res[1] or False, return { 'name': 'Sale Order', 'view_type': 'form', 'view_mode': 'form', 'view_id': res_id, 'res_model': 'sale.order', 'type': 'ir.actions.act_window', 'nodestroy': True, 'target': 'current', 'res_id': sale_ids and sale_ids[0] or False, } def _get_version_ids(self, cr, uid, ids, field_name, arg, context=None): if context is None: context = {} res = {} for sale in self.browse(cr, uid, ids): if sale.sale_version_id: res[sale.id] = self.search(cr, uid, [ '|', ('sale_version_id', '=', sale.sale_version_id.id), ('id', '=', sale.sale_version_id.id), ('version', '<', sale.version), '|', ('active', '=', False), ('active', '=', True) ]) else: res[sale.id] = [] return res _columns = { 'sale_version_id': fields.many2one('sale.order', 'Orig version', required=False, readonly=False), 'version': fields.integer('Version no.', readonly=True), 'active': fields.boolean('Active', readonly=False, help="It indicates that the sales order is active."), 'version_ids': fields.function(_get_version_ids, method=True, type="one2many", relation='sale.order', string='Versions', readonly=True) } _defaults = {'active': True, 'version': 0}
class smile_activity_report_cell(osv.osv): _name = 'smile.activity.report.cell' _order = "date" ## Function fields def _get_cell_value(self, cr, uid, ids, name, arg, context=None): """ Transform the quantity according the line rendering mode """ result = {} for cell in self.browse(cr, uid, ids, context): val = cell.quantity if cell.line_id.line_rendering == 'boolean': val = (cell.quantity != 0) and True or False result[cell.id] = val return result def _set_cell_value(self, cr, uid, ids, name, value, arg, context=None): """ Transform and save the cell value to the quantity """ if isinstance(ids, (int, long)): ids = [ids] for cell in self.browse(cr, uid, ids, context=context): # Float conversion if type(value) is type(''): value = float(value) self.write(cr, uid, cell.id, {'quantity': value}, context) return True def _get_cell_value_range(self, cr, uid, ids, name, value, arg, context=None): """ Return a random range a cell value is allowed to take """ result = {} for cell in self.browse(cr, uid, ids, context): # Pick a random range to demonstrate the dynamic capability if random.randrange(0, 2): value_range = [0, 1, 2, 3] else: value_range = [-4, -3, -2, -1] result[cell.id] = value_range return result ## Fields definition _columns = { 'date': fields.date('Date', required=True), 'quantity': fields.float('Quantity', required=True), 'line_id': fields.many2one('smile.activity.report.line', "Activity report line", required=True, ondelete='cascade'), 'active': fields.boolean("Active"), 'read_only': fields.boolean("Read-only"), # cell_value is a proxy of quantity that is transforming the value according the line_rendering mode 'cell_value': fields.function(_get_cell_value, fnct_inv=_set_cell_value, string="Cell value", type='string', readonly=True, method=True), 'cell_value_range': fields.function(_get_cell_value_range, string="Cell value range", type='selection', readonly=True, method=True), } _defaults = { 'quantity': 0.0, 'active': True, 'read_only': False, } ## Constraints def _check_quantity(self, cr, uid, ids, context=None): for cell in self.browse(cr, uid, ids, context): if cell.quantity < 0: return False return True def _check_date(self, cr, uid, ids, context=None): for cell in self.browse(cr, uid, ids, context): date = datetime.datetime.strptime(cell.date, '%Y-%m-%d') report = cell.line_id.report_id start_date = datetime.datetime.strptime(report.start_date, '%Y-%m-%d') end_date = datetime.datetime.strptime(report.end_date, '%Y-%m-%d') if date < start_date or date > end_date: return False return True def _check_duplicate(self, cr, uid, ids, context=None): for cell in self.browse(cr, uid, ids, context): if len( self.search(cr, uid, [('date', '=', cell.date), ('line_id', '=', cell.line_id.id)], context=context)) > 1: return False return True _constraints = [ #(_check_quantity, "Quantity can't be negative.", ['quantity']), (_check_duplicate, "Two cells can't share the same date.", ['date']), # Constraint below is not required as the matrix code will remove out of range cells #(_check_date, "Cell date is out of the activity report date range.", ['date']), ]
class product_product(osv.osv): _inherit = "product.product" def create(self,cr,uid,vals,context={}): id = super(product_product, self).create(cr, uid, vals, context=context) if id: category_id1 = vals.get('cat1',False) category_id2 = vals.get('cat2',False) if category_id1 != False and category_id2 != False: if category_id1 == category_id2: raise osv.except_osv(_('Warning !'), _("Please Select Two Different Categories")) return id def write(self,cr,uid,ids,vals,context={}): if ids: if type(ids) == type(int()): ids = [ids] if type(ids) == type(long()): ids = [ids] if 'cat1' in vals: category_id1 = vals.get('cat1',False) else: category_id1 = self.browse(cr, uid, ids[0]).cat1.id if 'cat2' in vals: category_id2 = vals.get('cat2',False) else: category_id2 = self.browse(cr, uid, ids[0]).cat2.id if category_id1 != False and category_id2 != False: if category_id1 == category_id2: raise osv.except_osv(_('Warning !'), _("Please Select Two Different Categories")) return super(product_product, self).write(cr, uid, ids, vals, context=context) def onchange_clear_attributes(self, cr, uid, ids,cat1 ,cat2,category_name,context=None): result ={} domain = {} if category_name == 'category1': if ids: cat1_database = self.browse(cr,uid,ids[0]).cat1 if cat1: if cat1 != cat1_database.id: result['product_reference_id'] = '' result['details_url'] = '' result['stock_photo_url'] = '' if cat1: condition_ids = self.pool.get('condition.class').search(cr,uid,[('category_id','=',cat1)]) condition_enabled = self.pool.get('category.master').browse(cr,uid,cat1).condition_enabled if condition_enabled == False: if cat2: condition_enabled = self.pool.get('category.master').browse(cr,uid,cat2).condition_enabled if condition_enabled == True: condition_ids = self.pool.get('condition.class').search(cr,uid,[('category_id','=',cat2)]) domain['ebay_condtn'] = [('id', 'in', condition_ids)] else: domain['ebay_condtn'] = [('id', 'in', [])] else: domain['ebay_condtn'] = [('id', 'in', [])] else: domain['ebay_condtn'] = [('id', 'in', condition_ids)] if condition_ids: result['ebay_condtn'] = condition_ids[0] else: result['ebay_condtn'] = False item_specifics = self.pool.get('category.master').browse(cr,uid,cat1).item_specifics catlg_enbld = self.pool.get('category.master').browse(cr,uid,cat1).catlog_enabled if catlg_enbld == True: result['catalog_en'] = 'checked' else: if cat2: catlg_enbld = self.pool.get('category.master').browse(cr,uid,cat2).catlog_enabled if catlg_enbld == True: result['catalog_en'] = 'checked' else: result['catalog_en'] = 'unchecked' else: result['catalog_en'] = 'unchecked' if item_specifics == True: result['item_specifics_enabled_prod1'] = 'checked' else: if cat2: item_specifics = self.pool.get('category.master').browse(cr,uid,cat2).item_specifics if item_specifics == True: result['item_specifics_enabled_prod1'] = 'checked' else: result['item_specifics_enabled_prod1'] = 'unchecked' if ids: custom_attributes = self.browse(cr,uid,ids[0]).custom_item_specifics_prod_cat_gene if custom_attributes: for each_specifics in custom_attributes: each_specifics_id = each_specifics.id if each_specifics_id: delete = cr.execute('delete from custom_item_specifics where id=%s',(each_specifics_id,)) else: result['item_specifics_enabled_prod1'] = 'unchecked' if ids: custom_attributes = self.browse(cr,uid,ids[0]).custom_item_specifics_prod_cat_gene if custom_attributes: for each_specifics in custom_attributes: each_specifics_id = each_specifics.id if each_specifics_id: delete = cr.execute('delete from custom_item_specifics where id=%s',(each_specifics_id,)) elif cat2: item_specifics = self.pool.get('category.master').browse(cr,uid,cat2).item_specifics catlg_enbld = self.pool.get('category.master').browse(cr,uid,cat2).catlog_enabled if catlg_enbld == True: result['catalog_en'] = 'checked' else: result['catalog_en'] = 'unchecked' if item_specifics == True: result['item_specifics_enabled_prod1'] = 'checked' else: result['item_specifics_enabled_prod1'] = 'unchecked' if ids: custom_attributes = self.browse(cr,uid,ids[0]).custom_item_specifics_prod_cat_gene if custom_attributes: for each_specifics in custom_attributes: each_specifics_id = each_specifics.id print"each_specifics_id",each_specifics_id ##delete from the attribute matching if each_specifics_id: delete = cr.execute('delete from custom_item_specifics where id=%s',(each_specifics_id,)) else: result['item_specifics_enabled_prod1'] = 'unchecked' result['catalog_en'] = 'unchecked' result['product_reference_id'] = '' result['details_url'] = '' result['stock_photo_url'] = '' result['ebay_condtn'] = False domain['ebay_condtn'] = [('id', 'in', [])] if ids: custom_attributes = self.browse(cr,uid,ids[0]).custom_item_specifics_prod_cat_gene if custom_attributes: for each_specifics in custom_attributes: each_specifics_id = each_specifics.id if each_specifics_id: delete = cr.execute('delete from custom_item_specifics where id=%s',(each_specifics_id,)) if len(ids): attribute_matching = self.browse(cr,uid,ids[0]).match_att_cat1 if attribute_matching: for each_attribute in attribute_matching: attribute_matching_id = each_attribute.id ##delete from the attribute matching if attribute_matching_id: delete = cr.execute('delete from attribute_matching where id=%s',(attribute_matching_id,)) return {'value':result,'domain':domain} def onchange_clear_attributes_cat2(self, cr, uid, ids,cat2,cat1,category_name,context=None): result ={} domain = {} if category_name == 'category2': if ids: cat2_database = self.browse(cr,uid,ids[0]).cat2 if cat2: if cat2 != cat2_database.id: result['product_reference_id'] = '' result['details_url'] = '' result['stock_photo_url'] = '' else: result['product_reference_id'] = '' result['details_url'] = '' result['stock_photo_url'] = '' if cat1: condition_ids = self.pool.get('condition.class').search(cr,uid,[('category_id','=',cat1)]) condition_enabled = self.pool.get('category.master').browse(cr,uid,cat1).condition_enabled if condition_enabled == False: if cat2: condition_enabled = self.pool.get('category.master').browse(cr,uid,cat2).condition_enabled if condition_enabled == True: condition_ids = self.pool.get('condition.class').search(cr,uid,[('category_id','=',cat2)]) domain['ebay_condtn'] = [('id', 'in', condition_ids)] else: domain['ebay_condtn'] = [('id', 'in', [])] else: domain['ebay_condtn'] = [('id', 'in', [])] else: domain['ebay_condtn'] = [('id', 'in', condition_ids)] if condition_ids: result['ebay_condtn'] = condition_ids[0] else: result['ebay_condtn'] = False item_specifics = self.pool.get('category.master').browse(cr,uid,cat1).item_specifics catlg_enbld = self.pool.get('category.master').browse(cr,uid,cat1).catlog_enabled if catlg_enbld == True: result['catalog_en'] = 'checked' else: if cat2: catlg_enbld = self.pool.get('category.master').browse(cr,uid,cat2).catlog_enabled if catlg_enbld == True: result['catalog_en'] = 'checked' else: result['catalog_en'] = 'unchecked' else: result['catalog_en'] = 'unchecked' if item_specifics == True: result['item_specifics_enabled_prod1'] = 'checked' else: if cat2: item_specifics = self.pool.get('category.master').browse(cr,uid,cat2).item_specifics if item_specifics == True: result['item_specifics_enabled_prod1'] = 'checked' else: result['item_specifics_enabled_prod1'] = 'unchecked' if ids: custom_attributes = self.browse(cr,uid,ids[0]).custom_item_specifics_prod_cat_gene if custom_attributes: for each_specifics in custom_attributes: each_specifics_id = each_specifics.id ##delete from the attribute matching if each_specifics_id: delete = cr.execute('delete from custom_item_specifics where id=%s',(each_specifics_id,)) else: result['item_specifics_enabled_prod1'] = 'unchecked' if ids: custom_attributes = self.browse(cr,uid,ids[0]).custom_item_specifics_prod_cat_gene if custom_attributes: for each_specifics in custom_attributes: each_specifics_id = each_specifics.id ##delete from the attribute matching if each_specifics_id: delete = cr.execute('delete from custom_item_specifics where id=%s',(each_specifics_id,)) elif cat2: item_specifics = self.pool.get('category.master').browse(cr,uid,cat2).item_specifics catlg_enbld = self.pool.get('category.master').browse(cr,uid,cat2).catlog_enabled if catlg_enbld == True: result['catalog_en'] = 'checked' else: result['catalog_en'] = 'unchecked' if item_specifics == True: result['item_specifics_enabled_prod1'] = 'checked' else: result['item_specifics_enabled_prod1'] = 'unchecked' if ids: custom_attributes = self.browse(cr,uid,ids[0]).custom_item_specifics_prod_cat_gene if custom_attributes: for each_specifics in custom_attributes: each_specifics_id = each_specifics.id ##delete from the attribute matching if each_specifics_id: delete = cr.execute('delete from custom_item_specifics where id=%s',(each_specifics_id,)) else: result['item_specifics_enabled_prod1'] = 'unchecked' result['catalog_en'] = 'unchecked' result['product_reference_id'] = '' result['details_url'] = '' result['stock_photo_url'] = '' result['ebay_condtn'] = False domain['ebay_condtn'] = [('id', 'in', [])] if ids: custom_attributes = self.browse(cr,uid,ids[0]).custom_item_specifics_prod_cat_gene if custom_attributes: for each_specifics in custom_attributes: each_specifics_id = each_specifics.id ##delete from the attribute matching if each_specifics_id: delete = cr.execute('delete from custom_item_specifics where id=%s',(each_specifics_id,)) if len(ids): attribute_matching = self.browse(cr,uid,ids[0]).match_att_cat2 if attribute_matching: for each_attribute in attribute_matching: attribute_matching_id = each_attribute.id ##delete from the attribute matching if attribute_matching_id: delete = cr.execute('delete from attribute_matching where id=%s',(attribute_matching_id,)) return {'value':result,'domain':domain} def onchange_details_url(self,cr,uid,ids,details_url,context=None): result = {} if details_url: if ids: details_url_database = self.browse(cr,uid,ids[0]).details_url if details_url_database != details_url: result['product_refernce_id']='' result['stock_photo_url'] ='' result['details_url'] = '' else: result['product_reference_id'] = '' result['stock_photo_url'] = '' return{'value':result} _columns = { 'prods_list': fields.one2many('product.listing', 'prod_list','Shop Id',readonly = True), 'cat1': fields.many2one('category.master','Category1'), 'cat2': fields.many2one('category.master','Category2'), 'match_att_cat1': fields.one2many('attribute.matching','product_cat1_match','Matching Attribute'), 'match_att_cat2': fields.one2many('attribute.matching','product_cat2_match','Matching Attribute'), 'plcs_holds': fields.one2many('placeholder.holder', 'plc_hld','Place Holder'), 'related_template': fields.many2one('ebayerp.template'), 'start_price': fields.char('Start Price',size=64), 'reserve_price':fields.char('Reserve Price',size=64), 'buy_it_now_price':fields.char('Buy It Now Price',size=64), 'ebay_sku':fields.char('Ebay Product Sku',size=64), 'exported_to_ebay': fields.boolean('Exported To Ebay',help="Specifies to List an Product to Ebay or not"), 'catalog_en':fields.selection([('checked','Checked'),('unchecked','Unchecked')],'Item specifics Enabled'), 'custom_item_specifics_prod_cat_gene': fields.one2many('custom.item.specifics','product_cat_gen','Custom Item Specifics'), 'item_specifics_enabled_prod1':fields.selection([('checked','Checked'),('unchecked','Unchecked')],'Item specifics Enabled'), 'ebay_breadth':fields.char('Breadth',size=10), 'ebay_width':fields.char('Width',size=10), 'ebay_height':fields.char('Height',size=10), 'category_name': fields.char('CategoryName',size=64) } _defaults = { 'exported_to_ebay': lambda *a:True, 'item_specifics_enabled_prod1':'unchecked', 'catalog_en':'unchecked', 'product_reference_id':'' }
class sale_shop(osv.osv): _name = "sale.shop" _inherit = "sale.shop" def xml_format(self, message_type, merchant_string, message_data): str = """ <?xml version="1.0" encoding="utf-8"?> <AmazonEnvelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd"> <Header> <DocumentVersion>1.01</DocumentVersion> """ + merchant_string.encode("utf-8") + """ </Header> """ + message_type.encode("utf-8") + """ """ + message_data.encode("utf-8") + """ </AmazonEnvelope>""" return str def create_product(self, cr, uid, message_id, product_obj, merchant_string, instance_obj, quantity): price_string = """<Message> <MessageID>%(message_id)s</MessageID> <Price> <SKU>%(sku)s</SKU> <StandardPrice currency="USD">%(price)s</StandardPrice> </Price> </Message>""" price_string = price_string % { 'message_id': message_id, 'sku': product_obj.amazon_sku, 'price': product_obj.list_price, } price_str = """<MessageType>Price</MessageType>""" price_data = self.xml_format(price_str, merchant_string, price_string) price_submission_id = connection_obj.call(instance_obj, 'POST_PRODUCT_PRICING_DATA', price_data) print "price_submission_id", price_submission_id time.sleep(40) # if price_submission_id.get('FeedSubmissionId',False): # time.sleep(80) # submission_price_results = connection_obj.call(instance_obj, 'GetFeedSubmissionResult',price_submission_id.get('FeedSubmissionId',False)) inventory_string = """<Message><MessageID>%(message_id)s</MessageID><Inventory><SKU>%(sku)s</SKU><Quantity>%(qty)s</Quantity></Inventory></Message>""" inventory_string = inventory_string % { 'message_id': message_id, 'sku': product_obj.amazon_sku, 'qty': quantity[0] } inventory_str = """<MessageType>Inventory</MessageType>""" inventory_data = self.xml_format(inventory_str, merchant_string, inventory_string) inventory_submission_id = connection_obj.call( instance_obj, 'POST_INVENTORY_AVAILABILITY_DATA', inventory_data) time.sleep(40) print "inventory_submission_id", inventory_submission_id cr.execute( "UPDATE product_product SET amazon_prod_status='active',amazon_updated_price='%s' where id=%d" % ( product_obj.list_price, product_obj.id, )) cr.commit() return True def update_product(self, cr, uid, message_id, product_obj, merchant_string, instance_obj): price_string = """<Message> <MessageID>%(message_id)s</MessageID> <Price> <SKU>%(sku)s</SKU> <StandardPrice currency="USD">%(price)s</StandardPrice> </Price> </Message>""" price_string = price_string % { 'message_id': message_id, 'sku': product_obj.amazon_sku, 'price': product_obj.list_price, } price_str = """<MessageType>Price</MessageType>""" price_data = self.xml_format(price_str, merchant_string, price_string) price_submission_id = connection_obj.call(instance_obj, 'POST_PRODUCT_PRICING_DATA', price_data) print "price_submission_id", price_submission_id # if price_submission_id.get('FeedSubmissionId',False): # time.sleep(80) # submission_price_results = connection_obj.call(instance_obj, 'GetFeedSubmissionResult',price_submission_id.get('FeedSubmissionId',False)) cr.execute( "UPDATE product_product SET amazon_prod_status='active',amazon_updated_price='%s' where id=%d" % ( product_obj.list_price, product_obj.id, )) cr.commit() time.sleep(40) return True def import_orders_amazon(self, cr, uid, ids, context=None): instance_obj = self.browse(cr, uid, ids[0]).amazon_instance_id last_import_time = self.browse(cr, uid, ids[0]).last_amazon_order_import_date if not last_import_time: today = datetime.now() DD = timedelta(days=30) earlier = today - DD earlier_str = earlier.strftime("%Y-%m-%dT%H:%M:%S") createdAfter = earlier_str + 'Z' print "createdAfter", createdAfter createdBefore = '' else: db_import_time = time.strptime(last_import_time, "%Y-%m-%d %H:%M:%S") db_import_time = time.strftime("%Y-%m-%dT%H:%M:%S", db_import_time) createdAfter = time.strftime( "%Y-%m-%dT%H:%M:%S", time.gmtime( time.mktime( time.strptime(db_import_time, "%Y-%m-%dT%H:%M:%S")))) createdAfter = str(createdAfter) + 'Z' print "createdAfter", createdAfter make_time = datetime.utcnow() - timedelta(seconds=120) make_time_str = make_time.strftime("%Y-%m-%dT%H:%M:%S") createdBefore = make_time_str + 'Z' print "createdBefore", createdBefore # try: time.sleep(10) results = connection_obj.call(instance_obj, 'ListOrders', createdAfter, createdBefore) time.sleep(30) if results: last_dictionary = results[-1] while last_dictionary.get('NextToken', False): next_token = last_dictionary.get('NextToken', False) del results[-1] time.sleep(25) results = connection_obj.call(instance_obj, 'ListOrdersByNextToken', next_token) results = results + results last_dictionary = results[-1] if last_dictionary.get('NextToken', False) == False: break if results: orderid = self.pool.get('amazon.instance').createOrder( cr, uid, instance_obj, ids[0], results, context) cr.execute( "UPDATE sale_shop SET last_amazon_order_import_date='%s' where id=%d" % (time.strftime('%Y-%m-%d %H:%M:%S'), ids[0])) else: self.log(cr, uid, ids[0], "No More Orders to Import") return True def export_stock_levels_amazon(self, cr, uid, ids, context=None): product_obj = self.pool.get('product.product') stock_move_obj = self.pool.get('stock.move') instance_obj = self.browse(cr, uid, ids[0]).amazon_instance_id product_ids = product_obj.search( cr, uid, [('amazon_export', '=', 'True'), ('amazon_prod_status', '=', 'active')]) last_amazon_inventory_export_date = self.browse( cr, uid, ids[0]).last_amazon_inventory_export_date if last_amazon_inventory_export_date: recent_move_ids = stock_move_obj.search( cr, uid, [('date', '>', last_amazon_inventory_export_date), ('product_id', 'in', product_ids), ('state', '!=', 'draft'), ('state', '!=', 'cancel')]) else: recent_move_ids = stock_move_obj.search( cr, uid, [('product_id', 'in', product_ids)]) product_ids = [ move.product_id.id for move in stock_move_obj.browse(cr, uid, recent_move_ids) if move.product_id.state != 'obsolete' ] product_ids = [x for x in set(product_ids)] merchant_string = '' if instance_obj: merchant_string = "<MerchantIdentifier>%s</MerchantIdentifier>" % ( instance_obj.aws_merchant_id) warehouse_id = self.browse(cr, uid, ids[0]).warehouse_id.id if warehouse_id: location_id = self.pool.get('stock.warehouse').browse( cr, uid, warehouse_id).lot_input_id.id message_information = '' message_id = 1 for each_product in product_ids: product_sku = product_obj.browse(cr, uid, each_product).amazon_sku product_id_location = self._my_value(cr, uid, location_id, each_product, context={}) product_split = str(product_id_location).split('.') value = product_split[0] message_information += """<Message><MessageID>%s</MessageID><OperationType>Update</OperationType><Inventory><SKU>%s</SKU><Quantity>%s</Quantity></Inventory></Message>""" % ( message_id, product_sku, value) message_id = message_id + 1 if message_information: data = """<?xml version="1.0" encoding="utf-8"?><AmazonEnvelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd"><Header><DocumentVersion>1.01</DocumentVersion>""" + merchant_string.encode( "utf-8" ) + """</Header><MessageType>Inventory</MessageType>""" + message_information.encode( "utf-8") + """</AmazonEnvelope>""" if data: results = connection_obj.call( instance_obj, 'POST_INVENTORY_AVAILABILITY_DATA', data) print "results", results if results.get('FeedSubmissionId', False): time.sleep(70) submission_results = connection_obj.call( instance_obj, 'GetFeedSubmissionResult', results.get('FeedSubmissionId', False)) if submission_results.get('MessagesWithError', False) == '0': self.log(cr, uid, 1, "Inventory Updated Successfully") else: if submission_results.get( 'ResultDescription', False): error_message = submission_results.get( 'ResultDescription', False) error_message = str(error_message).replace( "'", " ") self.log(cr, uid, 1, error_message) self.write( cr, uid, ids[0], { 'last_amazon_inventory_export_date': time.strftime('%Y-%m-%d %H:%M:%S') }) return True def _my_value(self, cr, uid, location_id, product_id, context=None): cr.execute( 'select sum(product_qty) '\ 'from stock_move '\ 'where location_id NOT IN %s '\ 'and location_dest_id = %s '\ 'and product_id = %s '\ 'and state = %s ',tuple([(location_id,), location_id, product_id, 'done'])) wh_qty_recieved = cr.fetchone()[0] or 0.0 #this gets the value which is sold and confirmed argumentsnw = [location_id, (location_id, ), product_id, ('done', )] #this will take reservations into account cr.execute( 'select sum(product_qty) '\ 'from stock_move '\ 'where location_id = %s '\ 'and location_dest_id NOT IN %s '\ 'and product_id = %s '\ 'and state in %s ',tuple(argumentsnw)) qty_with_reserve = cr.fetchone()[0] or 0.0 qty_available = wh_qty_recieved - qty_with_reserve return qty_available def update_amazon_orders(self, cr, uid, ids, context=None): message_information = '' item_string = '' message_id = 1 saleorder_obj = self.pool.get('sale.order') saleorder_ids = [] last_amazon_update_order_export_date = self.browse( cr, uid, ids[0]).last_amazon_update_order_export_date if not last_amazon_update_order_export_date: saleorder_ids = saleorder_obj.search( cr, uid, [('state', '=', 'done'), ('shop_id', '=', ids[0]), ('amazon_order_id', '!=', False)]) else: saleorder_ids = saleorder_obj.search( cr, uid, [('write_date', '>', last_amazon_update_order_export_date), ('state', '=', 'done'), ('shop_id', '=', ids[0]), ('amazon_order_id', '!=', False)]) if saleorder_ids: for saleorder_id in saleorder_ids: picking_ids = saleorder_obj.browse(cr, uid, saleorder_id).picking_ids if picking_ids: order_id = saleorder_obj.browse( cr, uid, saleorder_id).amazon_order_id #for getting order_id tracking_id = picking_ids[ 0].carrier_tracking_ref # for getting tracking_id carrier_id = picking_ids[0].carier_id if carrier_id: carrier_code_split = carrier_id.name.split(' ') carrier_code_split_first = carrier_code_split[ 0] #for getting shipping method product_info = saleorder_obj.browse( cr, uid, saleorder_id).order_line for each_line in product_info: product_qty = each_line.product_uom_qty product_id = each_line.product_id product_qty_split = str(product_qty).split(".") product_qty_first = product_qty_split[0] product_order_item_id = product_id.product_order_item_id item_string = '''<Item><AmazonOrderItemCode>%s</AmazonOrderItemCode> <Quantity>%s</Quantity></Item>''' % ( product_order_item_id, product_qty_first) fulfillment_date = time.strftime('%Y-%m-%dT%H:%M:%S') fulfillment_date_concat = str(fulfillment_date) + '-00:00' message_information += """<Message><MessageID>%s</MessageID><OperationType>Update</OperationType><OrderFulfillment><AmazonOrderID>%s</AmazonOrderID><FulfillmentDate>%s</FulfillmentDate><FulfillmentData><CarrierName>%s</CarrierName><ShippingMethod>%s</ShippingMethod><ShipperTrackingNumber>%s</ShipperTrackingNumber></FulfillmentData>""" + item_string.encode( "utf-8") + """</OrderFulfillment></Message>""" % ( message_id, order_id, fulfillment_date_concat, carrier_code_split_first, carrier_code, tracking_id) message_id = message_id + 1 data = """<?xml version="1.0" encoding="utf-8"?><AmazonEnvelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd"><Header><DocumentVersion>1.01</DocumentVersion><MerchantIdentifier>M_SELLERON_82825133</MerchantIdentifier></Header><MessageType>OrderFulfillment</MessageType>""" + message_information.encode( "utf-8") + """</AmazonEnvelope>""" if data: results = connection_obj.call(instance_obj, 'POST_ORDER_FULFILLMENT_DATA', data) print "results", results if results.get('FeedSubmissionId', False): time.sleep(70) submission_results = connection_obj.call( instance_obj, 'GetFeedSubmissionResult', results.get('FeedSubmissionId', False)) if submission_results.get('MessagesWithError', False) == '0': self.log(cr, uid, 1, "Status Updated Successfully") else: if submission_results.get('ResultDescription', False): error_message = submission_results.get( 'ResultDescription', False) error_message = str(error_message).replace( "'", " ") self.log(cr, uid, 1, error_message) # self.write(cr,uid,ids[0],{'last_ebay_update_order_export_date':time.strftime('%Y-%m-%d %H:%M:%S')}) cr.execute( "UPDATE sale_shop SET last_ebay_update_order_export_date='%s' where id=%d" % (time.strftime('%Y-%m-%d %H:%M:%S'), ids[0])) return True def _get_amazon_exportable_product_ids(self, cr, uid, ids, name, args, context=None): res = {} product_obj = self.pool.get("product.product") last_amazon_catalog_export_date = self.browse( cr, uid, ids[0]).last_amazon_catalog_export_date for shop in self.browse(cr, uid, ids, context=context): if last_amazon_catalog_export_date: product_ids = product_obj.search( cr, uid, [('amazon_export', '=', True), ('write_date', '>', last_amazon_catalog_export_date)]) else: product_ids = product_obj.search( cr, uid, [('amazon_export', '=', True)]) res[shop.id] = product_ids return res def export_catalog_amazon(self, cr, uid, ids, context={}): instance_obj = self.browse(cr, uid, ids[0]).amazon_instance_id merchant_string = '' standard_product_string = '' category_info = '' final_condition_string = '' condition_string = '' desc = '' log_id = 0 warehouse_id = self.browse(cr, uid, ids[0]).warehouse_id.id location_id = self.pool.get('stock.warehouse').browse( cr, uid, warehouse_id).lot_stock_id.id release_date = datetime.utcnow() release_date = release_date.strftime("%Y-%m-%dT%H:%M:%S") date_string = """<LaunchDate>%s</LaunchDate> <ReleaseDate>%s</ReleaseDate>""" % (release_date, release_date) if instance_obj: merchant_string = "<MerchantIdentifier>%s</MerchantIdentifier>" % ( instance_obj.aws_merchant_id) amazon_exportable_product_ids = self.browse( cr, uid, ids[0]).amazon_exportable_product_ids message_information = '' message_id = 1 for each_product in amazon_exportable_product_ids: product_nm = each_product.name_template product_sku = each_product.amazon_sku function_call = self._my_value(cr, uid, location_id, each_product.id, context={}) quantity = str(function_call).split('.') condition = each_product.amzn_condtn condition_note = each_product.condition_note if condition: condition_string += """<ConditionType>%s</ConditionType>""" % ( condition) if condition and condition_note: condition_string += """<ConditionNote>%s</ConditionNote>""" % ( condition_note) final_condition_string = "<Condition>" + condition_string.encode( 'utf-8') + "</Condition>" title = each_product.name_template sale_description = each_product.description_sale if sale_description: desc = "<Description>%s</Description>" % (sale_description) # product_category = each_product.amazon_category amz_type = each_product.amz_type amz_type_value = each_product.amz_type_value product_asin = each_product.amazon_asin if amz_type and amz_type_value: standard_product_string = """ <StandardProductID> <Type>%s</Type> <Value>%s</Value> </StandardProductID> """ % (amz_type, amz_type_value) if not standard_product_string: category_info = """<ProductData> <CE> <ProductType> <ConsumerElectronics> <VariationData></VariationData> <Color>Color</Color> <DigitalMediaFormat>4_mm_tape</DigitalMediaFormat> </KindleAccessories> </ProductType> </CE> </ProductData>""" standard_product_string = """ <StandardProductID> <Type>ASIN</Type> <Value>%s</Value> </StandardProductID> """ % (product_asin) message_information = """<Message> <MessageID>%(message_id)s</MessageID> <Product> <SKU>%(sku)s</SKU> """ + standard_product_string.encode( 'utf-8') + """ """ + date_string.encode( 'utf-8') + """ """ + final_condition_string.encode( 'utf-8') + """ <DescriptionData> <Title>%(title)s</Title> """ + desc.encode("utf-8") + """ </DescriptionData> </Product> </Message>""" message_information = message_information % { 'sku': product_sku, 'condition': condition, 'title': title, 'message_id': message_id } product_str = """<MessageType>Product</MessageType>""" product_data = self.xml_format(product_str, merchant_string, message_information) print "data", product_data if product_data: product_submission_id = connection_obj.call( instance_obj, 'POST_PRODUCT_DATA', product_data) if product_submission_id.get('FeedSubmissionId', False): time.sleep(80) submission_results = connection_obj.call( instance_obj, 'GetFeedSubmissionResult', product_submission_id.get('FeedSubmissionId', False)) if submission_results.get('MessagesWithError', False) == '0': amazon_status = each_product.amazon_prod_status if amazon_status == 'active': if each_product.list_price != each_product.amazon_updated_price: print "price UnMatches" self.update_product( cr, uid, message_id, each_product, merchant_string, instance_obj) product_long_message = ( '%s: Updated Successfully on Amazon') % ( product_nm) self.log(cr, uid, log_id, product_long_message) log_id += 1 else: self.create_product(cr, uid, message_id, each_product, merchant_string, instance_obj, quantity) product_long_message = ( '%s: Created Successfully on Amazon') % ( product_nm) self.log(cr, uid, log_id, product_long_message) log_id += 1 #code for Updating Price### # price_string = """<Message> # <MessageID>%(message_id)s</MessageID> # <Price> # <SKU>%(sku)s</SKU> # <StandardPrice currency="USD">%(price)s</StandardPrice> # </Price> # </Message>""" # price_string = price_string % { # 'message_id':message_id, # 'sku': product_sku, # 'price':list_price, # } # price_str = """<MessageType>Price</MessageType>""" # price_data = self.xml_format(price_str,merchant_string,price_string) # price_submission_id = connection_obj.call(instance_obj, 'POST_PRODUCT_PRICING_DATA',price_data) # print"price_submission_id",price_submission_id ## if price_submission_id.get('FeedSubmissionId',False): ## time.sleep(80) ## submission_price_results = connection_obj.call(instance_obj, 'GetFeedSubmissionResult',price_submission_id.get('FeedSubmissionId',False)) # # inventory_string = """<Message><MessageID>%(message_id)s</MessageID><Inventory><SKU>%(sku)s</SKU><Quantity>%(qty)s</Quantity></Inventory></Message>""" # inventory_string = inventory_string % { # 'message_id':message_id, # 'sku': product_sku, # 'qty':quantity[0]} # inventory_str = """<MessageType>Inventory</MessageType>""" # inventory_data = self.xml_format(inventory_str,merchant_string,inventory_string) # inventory_submission_id = connection_obj.call(instance_obj, 'POST_INVENTORY_AVAILABILITY_DATA',inventory_data) # print"inventory_submission_id",inventory_submission_id # cr.execute("UPDATE product_product SET prod_status='active' where id=%d"%(each_product.id,)) # cr.commit() # if inventory_submission_id.get('FeedSubmissionId',False): # time.sleep(80) # submission_inventory_results = connection_obj.call(instance_obj, 'GetFeedSubmissionResult',inventory_submission_id.get('FeedSubmissionId',False)) else: if submission_results.get('ResultDescription', False): error_message = submission_results.get( 'ResultDescription', False) error_message = str(error_message).replace( "'", " ") cr.execute( "UPDATE product_product SET submit_feed_result='%s' where id=%d" % ( error_message, each_product.id, )) cr.commit() product_long_message = ('Error : %s:') % ( product_nm) + ' ' + error_message self.log(cr, uid, log_id, product_long_message) log_id += 1 cr.execute( "UPDATE sale_shop SET last_amazon_catalog_export_date='%s' where id=%d" % (time.strftime('%Y-%m-%d %H:%M:%S'), ids[0])) return True def export_images_amazon(self, cr, uid, ids, context={}): product_image_obj = self.pool.get('product.images') instance_obj = self.browse(cr, uid, ids[0]).amazon_instance_id product_obj = self.pool.get("product.product") product_ids = product_obj.search( cr, uid, [('amazon_export', '=', 'True'), ('amazon_prod_status', '=', 'active')]) last_amazon_image_export_date = self.browse( cr, uid, ids[0]).last_amazon_image_export_date if last_amazon_image_export_date: recent_image_ids = product_image_obj.search( cr, uid, [('write_date', '>', last_amazon_image_export_date), ('product_id', 'in', product_ids)]) else: recent_image_ids = product_image_obj.search( cr, uid, [('product_id', 'in', product_ids)]) merchant_string = '' if instance_obj: merchant_string = "<MerchantIdentifier>%s</MerchantIdentifier>" % ( instance_obj.aws_merchant_id) message_information = '' message_id = 1 for each_image_id in recent_image_ids: product_id = product_image_obj.browse(cr, uid, each_image_id).product_id product_sku = product_id.amazon_sku image_url = product_image_obj.browse( cr, uid, each_image_id).amazon_url_location message_information += """<Message><MessageID>%s</MessageID><OperationType>Update</OperationType><ProductImage><SKU>%s</SKU><ImageType>Main</ImageType><ImageLocation>%s</ImageLocation></ProductImage></Message>""" % ( message_id, product_sku, image_url) message_id = message_id + 1 if message_information: data = """<?xml version="1.0" encoding="utf-8"?><AmazonEnvelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd"><Header><DocumentVersion>1.01</DocumentVersion>""" + merchant_string.encode( "utf-8" ) + """</Header><MessageType>ProductImage</MessageType>""" + message_information.encode( "utf-8") + """</AmazonEnvelope>""" if data: results = connection_obj.call(instance_obj, 'POST_PRODUCT_IMAGE_DATA', data) print "results", results if results.get('FeedSubmissionId', False): time.sleep(80) submission_results = connection_obj.call( instance_obj, 'GetFeedSubmissionResult', results.get('FeedSubmissionId', False)) if submission_results.get('MessagesWithError', False) == '0': self.log(cr, uid, 1, 'Images Updated Successfully') else: if submission_results.get('ResultDescription', False): error_message = submission_results.get( 'ResultDescription', False) error_message = str(error_message).replace( "'", " ") self.log(cr, uid, log_id, product_long_message) cr.execute( "UPDATE sale_shop SET last_amazon_image_export_date='%s' where id=%d" % (time.strftime('%Y-%m-%d %H:%M:%S'), ids[0])) return True _columns = { 'amazon_instance_id': fields.many2one('amazon.instance', 'Instance', readonly=True), 'last_amazon_inventory_export_date': fields.datetime('Last Inventory Export Time'), 'last_amazon_catalog_export_date': fields.datetime('Last Inventory Export Time'), 'last_amazon_image_export_date': fields.datetime('Last Image Export Time'), 'last_amazon_order_import_date': fields.datetime('Last Order Import Time'), 'last_amazon_update_order_export_date': fields.datetime('Last Order Update Time'), # #TODO all the following settings are deprecated and replaced by the finer grained base.sale.payment.type settings! 'amazon_picking_policy': fields.selection( [('direct', 'Partial Delivery'), ('one', 'Complete Delivery')], 'Packing Policy', help= """If you don't have enough stock available to deliver all at once, do you accept partial shipments or not?""" ), 'amazon_order_policy': fields.selection( [ ('prepaid', 'Payment Before Delivery'), ('manual', 'Shipping & Manual Invoice'), ('postpaid', 'Invoice on Order After Delivery'), ('picking', 'Invoice from the Packing'), ], 'Shipping Policy', help= """The Shipping Policy is used to synchronise invoice and delivery operations. - The 'Pay before delivery' choice will first generate the invoice and then generate the packing order after the payment of this invoice. - The 'Shipping & Manual Invoice' will create the packing order directly and wait for the user to manually click on the 'Invoice' button to generate the draft invoice. - The 'Invoice on Order After Delivery' choice will generate the draft invoice based on sale order after all packing lists have been finished. - The 'Invoice from the packing' choice is used to create an invoice during the packing process.""" ), 'amazon_invoice_quantity': fields.selection( [('order', 'Ordered Quantities'), ('procurement', 'Shipped Quantities')], 'Invoice on', help= "The sale order will automatically create the invoice proposition (draft invoice). Ordered and delivered quantities may not be the same. You have to choose if you invoice based on ordered or shipped quantities. If the product is a service, shipped quantities means hours spent on the associated tasks." ), 'amazon_shop': fields.boolean('Amazon Shop', readonly=True), 'auto_import_amazon': fields.boolean('Auto Import'), 'partner_id': fields.many2one('res.partner', 'Customer'), 'amazon_exportable_product_ids': fields.function(_get_amazon_exportable_product_ids, method=True, type='one2many', relation="product.product", string='Exportable Products'), }
# statement_facade.write(cr, uid, [statement_id], { 'date': st_data['fecha_fin'], 'balance_start': st_data['saldo_ini'], 'balance_end_real': st_data['saldo_fin'], }, context=context) # Attach the C43 file to the current statement data = base64.encodestring( c43_wizard.file ) res = statement_facade._attach_file_to_statement(cr, uid, data, statement_id, _('Bank Statement'), _('bank-statement.txt') ) return {} _name = 'l10n.es.bank.statement.import.c43.wizard' _columns = { 'file': fields.binary('Bank Statements File', required=True, filename='file_name'), 'file_name': fields.char('Bank Statements File', size=64, readonly=True), 'reco_reference_and_amount': fields.boolean('Reconcile by reference and amount'), 'reco_vat_and_amount' : fields.boolean('Reconcile by VAT number and amount'), 'reco_amount' : fields.boolean('Reconcile by amount'), 'reco_rules' : fields.boolean('Statement Line Rules'), 'reco_payment_order': fields.boolean('Reconcile payment orders by total amount'), 'reco_max_days' : fields.integer('Max. days from statement date',help='Maximum difference in days, between the maturity date of the entry to reconcile and the bank statement entry') } l10n_es_bank_statement_import_c43_wizard() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
return{'value':result} _rec_name = 'shop_id' _columns = { # 'name' :fields.char('Name',size=64), 'shop_id' : fields.many2one('sale.shop','Ebay Shop',required=True,help="Shop on which products to be relisted"), 'rel_prod' : fields.many2many('product.product','shop_prod_rel','shop_id','prod_id','List of Expired Products'), 'schedule_time':fields.datetime('Schedule Time'), 'list_durtn' : fields.many2one('duration.time','Duration',required=True,help="Duration Of the Product on Ebay"), 'template_id': fields.many2one('ebayerp.template','Template',required=True,help="Selected Template Configuration will be applied to the Listing Products"), 'ebay_current_time':fields.datetime('Ebay Current Time'), 'type': fields.selection([('Chinese','Auction'),('FixedPriceItem','Fixed Price'),('LeadGeneration','Classified Ad')],'Type',required=True,help="Type in which Products to be listed"), 'start_price':fields.many2one('product.pricelist','Start Price',help="Selected Pricelist will be applied to the Listing Products"), 'reserve_price':fields.many2one('product.pricelist','Reserve Price',help="Selected Pricelist will be applied to the Listing Products"), 'buy_it_nw':fields.many2one('product.pricelist','Buy It Now Price',help="Selected Pricelist will be applied to the Listing Products"), 'condtn':fields.selection([('1000','New'),('1500','New other (see details)'),('2000','Manufacturer refurbished'),('2500','Seller refurbished'),('3000','Used'),('7000','For parts or not working')],'Condition'), 'inst_list_chk' : fields.boolean('Start listing immediately',help="Will Active Product Immediately on Ebay"), } _defaults = { 'type': 'Chinese', 'inst_list_chk':True, 'start_price':1, 'reserve_price':1, 'buy_it_nw':1 } # _sql_constraints = [ # ('shop_uniq_completed', 'unique(shop_id)', 'This shop is already created !'), # ] ebayerp_relist() class ebayerp_relist(ebayerp_osv.ebayerp_osv): _name = "ebayerp.relist"
res_text = '\n' for i in sorted(self.imported_records): res_text+=i+': '+str(len(self.imported_records[i]))+'\n' self.imported_records.clear() self.warning_text = [] self.write(cr, uid, self_id, {'log':warning+res_text,'state':'done'}) return _columns = { 'name':fields.char('Name', size=64), 'date': fields.date('Date', required=True), 'import_model_ids':fields.many2many('migration.import_models', 'schedule_models_rel', 'schedule_id', 'import_model_id', 'Import Models'), 'actions_ids': fields.many2many('migration.model_actions', 'schedule_actions_rel', 'schedule_id', 'action_id', 'Actions'), 'state':fields.selection([('ready','Ready'),('running','Running'),('error','Error'),('done','Done'),('stop','Stopped')], 'State'), 'log': fields.text('Log'), 'print_log':fields.boolean('Print Log to Console'), 'cron_id':fields.many2one('ir.cron', 'Scheduler', readonly=True), } _defaults = { 'date': lambda *a: time.strftime('%Y-%m-%d'), 'state': lambda *a: 'ready', } def set_start(self, cr, uid, ids, context={}): self.write(cr, uid, ids, {'state':'ready'}) cron_id = self.browse(cr, uid, ids[0], {}).cron_id.id nextcall = (now()+DateTime.RelativeDateTime(seconds=30)).strftime('%Y-%m-%d %H:%M:%S') self.pool.get('ir.cron').write(cr, uid, cron_id, {'numbercall':1, 'active':True, 'nextcall':nextcall}) return True
class customs_duty(osv.osv): ''' A list of the concepts for taxes in form_86 ''' _name = 'customs.duty' _description = '' _order = 'sequence' def name_get(self, cr, uid, ids, context): if not len(ids): return [] res = [] so_brw = self.browse(cr, uid, ids, context) for item in so_brw: res.append( (item.id, '[%s] %s - %s' % (item.code, item.ref, item.name))) return res _columns = { 'code': fields.char('Code', size=16, required=True, readonly=False), 'name': fields.char('Name', size=64, required=True, readonly=False), 'ref': fields.char('Ref', size=16, required=False, readonly=False), 'sequence': fields.integer('Sequence'), 'partner_id': fields.many2one('res.partner', 'Partner', change_default=True, ondelete='restrict'), 'account_id': fields.many2one('account.account', 'Account to pay', domain="[('type','!=','view')]", ondelete='restrict', help="This account will be used for \ expenses related to taxes"), 'vat_detail': fields.boolean('Tax detail', help="Set true if this is \ vat related tax"), 'company_id': fields.many2one('res.company', 'Company', required=True, readonly=True, ondelete='restrict'), } _defaults = { 'company_id': lambda self, cr, uid, c: self.pool.get('res.company'). _company_default_get(cr, uid, 'customs.form.config', context=c), 'vat_detail': False, } _sql_constraints = [ ('code_uniq', 'UNIQUE(code,company_id)', 'The code must be unique! (for this comany)'), ('sequence_uniq', 'UNIQUE(sequence,company_id)', 'The sequence must be unique! (for this comany)'), ]
Returns the default price unity (the first in the list). """ unity = self.get(category_id__name='Duration', _object='product.uom') if not unity: _logger.warning("It seems that there isn't a reference unity in the 'Duration' UoM category. " "Please check that the category exists, and there's a refernce unity.") return unity.id if unity else False _name = 'product.product' _inherit = 'product.product' _columns = { 'can_be_rent' : fields.boolean('Can be rented', help='Enable this if you want to rent this product.'), 'rent_price' : fields.float('Rent price', help= 'The price is expressed for the duration unity defined in the company configuration.'), 'rent_price_unity' : fields.many2one('product.uom', 'Rent Price Unity', domain=[('category_id.name', '=', 'Duration')], help='Rent duration unity in which the price is defined.'), } _defaults = { 'can_be_rent' : True, 'rent_price' : 0, 'rent_price_unity' : default_price_unity, } _constraints = [(check_rent_price, _('The Rent price must be a positive value or 0 for free service or product.'), ['rent_price']),] Product()
class scheduled_product_list_line(osv.osv): _name = "scheduled.product.list.line" _columns = { 'check_order': fields.boolean(''), 'sale_order_id': fields.many2one('psd.sales.product.order', 'Sale Order Id'), 'sale_order_line_id': fields.many2one('psd.sales.product.order.lines', 'Sale Order Line Id'), # 'product_name_id': fields.many2one('product.generic.name','Product Name'), 'product_name_id': fields.many2one('product.product', 'Product Name'), # 'sku_name_id':fields.many2one('product.product','SKU Name'), 'ordered_quantity': fields.integer('Ordered Quantity'), 'allocated_quantity': fields.integer('Allocated Quantity'), 'product_uom_id': fields.many2one('product.uom', 'UOM'), 'product_mrp': fields.float('MRP'), 'product_code': fields.char('Product Code', size=200), 'mrp_date': fields.date('Mfg Date'), 'batch_no': fields.many2one('res.batchnumber', 'Batch No'), 'product_basic_rate': fields.float('Basic Rate'), 'discount': fields.float('Disc %'), 'discounted_value': fields.float('Discounted Value'), 'discounted_price': fields.float('Discounted Price'), 'discounted_amount': fields.float(string='Disc Amt'), 'tax_id': fields.many2one('account.tax', 'Tax %'), 'tax_amount': fields.float('Tax Amt'), 'total_amount': fields.float('Total Amount'), 'extended_warranty': fields.selection([('6', '6 Months'), ('12', '12 Months'), ('18', '18 Months'), ('24', '24 Months'), ('36', '36 Months'), ('48', '48 Months'), ('60', '60 Months')], 'Extended Warranty'), 'scheduled_product_list_id': fields.many2one('scheduled.product.list', 'Scheduled Products', ondelete='cascade'), 'scheduled_delivery_list_id': fields.many2one('psd.sales.delivery.schedule', 'Delivered Products', ondelete='cascade'), 'godown': fields.many2one('res.company', string='Godown'), 'specification': fields.char('Specification', size=500), 'cgst_rate': fields.char('CSGT Rate', size=10), 'sgst_rate': fields.char('SGST Rate', size=10), 'igst_rate': fields.char('IGST Rate', size=10), 'cgst_amount': fields.float('CGST Amount'), 'sgst_amount': fields.float('SGST Amount'), 'igst_amount': fields.float('IGST Amount'), 'grand_total': fields.float('Grand Total'), }
###Function that will update the cron ###freqeuence self.pool.get('currency.rate.update').save_cron( cr, uid, {'interval_type':interval} ) compagnies = self.search(cr, uid, []) for comp in compagnies : self.write(cr, uid, comp,{'interval_type':interval}) return {} _inherit = "res.company" _columns = { ### activate the currency update 'auto_currency_up': fields.boolean('Automatical update of the currency this company'), 'services_to_use' : fields.one2many( 'currency.rate.update.service', 'company_id', 'Currency update services' ), ###predifine cron frequence 'interval_type': fields.selection( [ ('days','Day(s)'), ('weeks', 'Week(s)'), ('months', 'Month(s)') ], 'Currency update frequence', help="""changing this value will also affect other compagnies"""
class scheduled_product_list(osv.osv): _name = "scheduled.product.list" _columns = { 'select_all_orders': fields.boolean('Select all Orders'), 'scheduled_product_list_ids': fields.one2many('scheduled.product.list.line', 'scheduled_product_list_id', string='Scheduled Products'), 'godown': fields.many2one('res.company', string='Godown'), } def onchange_select_all_orders(self, cr, uid, ids, select_all_orders, scheduled_product_list_ids): v = {} order_ids = [] if select_all_orders == 1: for order_id in scheduled_product_list_ids: if order_id[0] == 0: order_id[2]['check_order'] = True order_ids.append(order_id) else: for order_id in scheduled_product_list_ids: if order_id[0] == 0: order_id[2]['check_order'] = False order_ids.append(order_id) v['scheduled_product_list_ids'] = order_ids return {'value': v} def default_get(self, cr, uid, fields, context=None): customer_line_ids = [] if context is None: context = {} res = super(scheduled_product_list, self).default_get(cr, uid, fields, context=context) picking_ids = context.get('active_ids', []) if not picking_ids or (not context.get('active_model') == 'psd.sales.product.order') \ or len(picking_ids) != 1: # Partial Picking Processing may only be done for one picking at a time return res picking_id, = picking_ids if 'scheduled_product_list_ids' in fields: picking = self.pool.get('psd.sales.product.order').browse( cr, uid, picking_id, context=context) line_rec = self.pool.get('psd.sales.product.order.lines').search( cr, uid, [('psd_sales_product_order_lines_id', '=', picking_id), ('done_products', '=', False)]) line_brw = self.pool.get('psd.sales.product.order.lines').browse( cr, uid, line_rec) moves = [self._partial_move_for(cr, uid, m) for m in line_brw] res.update(scheduled_product_list_ids=moves) godown_id = self.pool.get('res.users').browse( cr, uid, uid).company_id.parent_establishment.id res['godown'] = godown_id res['select_all_orders'] = True return res def _partial_move_for(self, cr, uid, move): partial_move = {} product_name_id = move.product_name_id.id # sku_name_id = move.sku_name_id.id ordered_quantity = move.ordered_quantity product_mrp = move.product_mrp total_amount = move.total_amount batch_no = move.batch_number.id mrp_date = move.manufacturing_date main_id = move.psd_sales_product_order_lines_id.id allocated_quantity = move.allocated_quantity extended_warranty = move.extended_warranty discount = move.discount discounted_value = move.discounted_value discounted_price = move.discounted_price discounted_amount = move.discounted_amount igst_amount = move.igst_amount cgst_amount = move.cgst_amount sgst_amount = move.sgst_amount igst_rate = move.igst_rate cgst_rate = move.cgst_rate sgst_rate = move.sgst_rate # tax_id = move.tax_id.id total_amount = move.total_amount total_amount_paid = total_amount + igst_amount + cgst_amount + sgst_amount product_basic_rate = move.product_basic_rate godown_id = self.pool.get('res.users').browse( cr, uid, uid).company_id.parent_establishment.id # if allocated_quantity == 0.0: # allocated_quantity = move.ordered_quantity # else: # allocated_quantity = move.ordered_quantity - move.allocated_quantity print cgst_amount, sgst_amount, igst_amount # bb partial_move = { 'sale_order_id': main_id, 'sale_order_line_id': move.id, 'product_name_id': product_name_id, # 'sku_name_id': sku_name_id, 'ordered_quantity': ordered_quantity, 'allocated_quantity': allocated_quantity, 'discount': discount, 'discounted_value': discounted_value, 'discounted_price': discounted_price, 'discounted_amount': discounted_amount, # 'tax_id':tax_id , 'product_basic_rate': product_basic_rate, 'product_mrp': product_mrp, 'product_uom_id': move.product_uom_id.id, 'product_code': move.product_name_id.default_code, 'mrp_date': mrp_date, 'extended_warranty': extended_warranty, 'godown': godown_id, 'specification': move.specification, 'igst_amount': igst_amount, 'cgst_amount': cgst_amount, 'sgst_amount': sgst_amount, 'igst_rate': igst_rate, 'sgst_rate': igst_rate, 'cgst_rate': igst_rate, 'grand_total': total_amount_paid, 'check_order': True } return partial_move def round_off_grand_total(self, cr, uid, ids, grand_total, context=None): roundoff_grand_total = grand_total + 0.5 s = str(roundoff_grand_total) dotStart = s.find('.') grand_total = int(s[:dotStart]) return grand_total def submit(self, cr, uid, ids, context=None): amount_list = [] taxes = {} bird_pro = False bird_pro_charge = 0.0 service_tax_value = 0.0 sb_tax_value = 0.0 kk_tax_value = 0.0 total_tax_amount = 0.0 new_total_amount = 0.0 total_service_tax = 0.0 psd_sales_delivery_schedule_obj = self.pool.get( 'psd.sales.delivery.schedule') account_tax = self.pool.get('account.tax') scheduled_product_list_line_obj = self.pool.get( 'scheduled.product.list.line') psd_sales_product_order_lines_obj = self.pool.get( 'psd.sales.product.order.lines') psd_sales_product_order_obj = self.pool.get('psd.sales.product.order') tax_line_obj = self.pool.get('tax') expected_delivery_date = context.get('expected_delivery_date') active_ids_value = context.get('sale_order_active_id') search_curr_sale_order_id = psd_sales_product_order_obj.search( cr, uid, [('id', '=', active_ids_value)])[0] browse_curr_sale_order_obj = psd_sales_product_order_obj.browse( cr, uid, search_curr_sale_order_id) total_sale_order_line_list = [] all_allocated_list = [] if browse_curr_sale_order_obj.bird_pro and browse_curr_sale_order_obj.install_maintain_charges: bird_pro = browse_curr_sale_order_obj.bird_pro bird_pro_charge = browse_curr_sale_order_obj.install_maintain_charges company_id = self.pool.get('res.company')._company_default_get( cr, uid, 'scheduled.product.list.line', context=context) todays_date = datetime.now().date() self.pool.get('psd.sales.product.order').write( cr, uid, active_ids_value, {'select_all_orders': True}) cr.commit() values_create = { 'despatcher': company_id, 'expected_delivery_date': expected_delivery_date, 'state': 'new', 'sale_order_id': active_ids_value, 'bird_pro': bird_pro, 'bird_pro_charge': bird_pro_charge, 'select': True, } o = self.browse(cr, uid, ids[0]) if not o.scheduled_product_list_ids: raise osv.except_osv( _('Warning!'), _("No product left for scheduling for this order")) for rec in o.scheduled_product_list_ids: if not rec.check_order: raise osv.except_osv( _('Warning!'), _("Please select all products to schedule this order")) values_create['godown'] = o.godown.id delivery_id = psd_sales_delivery_schedule_obj.create(cr, uid, values_create, context=context) main_id = o.id for each in o.scheduled_product_list_ids: sale_order_id = each.sale_order_id.id check_ids = scheduled_product_list_line_obj.search( cr, uid, [('scheduled_product_list_id', '=', main_id)]) search_ids = scheduled_product_list_line_obj.search( cr, uid, [('scheduled_product_list_id', '=', main_id), ('check_order', '=', True)]) if len(check_ids) == len(search_ids): psd_sales_product_order_obj.write(cr, uid, sale_order_id, {'done_products': True}) cr.commit() else: psd_sales_product_order_obj.write(cr, uid, sale_order_id, {'done_products': False}) cr.commit() if not search_ids: raise osv.except_osv( _('Warning!'), _("Please tick the check box for the products")) if search_ids: print search_ids browse_ids = scheduled_product_list_line_obj.browse( cr, uid, search_ids) for line_id in browse_ids: sale_order_id = line_id.sale_order_id.id sale_order_line_id = line_id.sale_order_line_id.id product_name_id = line_id.product_name_id.id # sku_name_id = line_id.sku_name_id.id sale_allocated_quantity = line_id.sale_order_line_id.allocated_quantity ordered_quantity = line_id.ordered_quantity allocated_quantity = line_id.allocated_quantity product_mrp = line_id.product_mrp batch_no = line_id.batch_no.id mrp_date = line_id.mrp_date product_basic_rate = line_id.product_basic_rate igst_amount = line_id.igst_amount sgst_amount = line_id.sgst_amount cgst_amount = line_id.cgst_amount print sgst_amount, igst_amount, cgst_amount # nn igst_rate = line_id.igst_rate cgst_rate = line_id.cgst_rate sgst_rate = line_id.sgst_rate total_amount = line_id.total_amount # total_amount_paid = line_id.total_amount_paid extended_warranty = line_id.extended_warranty order_line_obj = self.pool.get( 'psd.sales.product.order.lines').browse( cr, uid, sale_order_line_id) # remaining_qty = order_line_obj.ordered_quantity - order_line_obj.allocated_quantity # if remaining_qty < 0: # raise osv.except_osv(_('Warning!'),_("Allocated Quantity can not be greater than Remaining Quantity!")) values = { 'sale_order_id': sale_order_id, 'sale_order_line_id': sale_order_line_id, 'product_name_id': product_name_id, # 'sku_name_id':sku_name_id, 'ordered_quantity': ordered_quantity, 'allocated_quantity': allocated_quantity, 'product_mrp': product_mrp, 'batch_no': batch_no, 'discount': line_id.discount, 'discounted_price': line_id.discounted_price, # 'discounted_amount':discount_value, # 'tax_id':line_id.tax_id.id, # 'tax_amount':tax_amount, 'product_basic_rate': product_basic_rate, 'total_amount': total_amount, 'mrp_date': mrp_date, 'scheduled_delivery_list_id': delivery_id, 'extended_warranty': extended_warranty, 'godown': line_id.godown.id, 'specification': line_id.specification, 'igst_amount': igst_amount, 'cgst_amount': cgst_amount, 'sgst_amount': sgst_amount, 'igst_rate': igst_rate, 'sgst_rate': sgst_rate, 'cgst_rate': cgst_rate, # 'grand_total':total_amount_paid, } amount_list.append(total_amount) update_calc_data = {'total_amount': total_amount} write_id = scheduled_product_list_line_obj.write( cr, uid, line_id.id, update_calc_data) psd_id = scheduled_product_list_line_obj.create( cr, uid, values) tax_id = line_id.tax_id.id print product_name_id, allocated_quantity print sale_order_id abc = self.pool.get('psd.sales.product.order.lines').search( cr, uid, [('psd_sales_product_order_lines_id', '=', sale_order_id), ('product_name_id', '=', product_name_id)]) self.pool.get('psd.sales.product.order.lines').write( cr, uid, abc, {'done_products': True}) cr.commit() total = sum(amount_list) for sale in browse_curr_sale_order_obj.psd_sales_product_order_lines_ids: total_sale_order_line_list.append(1) if sale.allocated_quantity == sale.ordered_quantity: all_allocated_list.append(1) print len(total_sale_order_line_list), len(all_allocated_list) if len(total_sale_order_line_list) == len(all_allocated_list): psd_sales_product_order_obj.write(cr, uid, active_ids_value, {'state': 'delivery_scheduled'}) return {'type': 'ir.actions.act_window_close'}
'scale_id': fields.many2one('bag.scale', 'Escala'), 'incoming_guide': fields.char('Guia Entrante', size=32), 'case_number': fields.char('Numero Caso', size=32), 'outgoing_guide': fields.char('Guia Saliente', size=32), 'internal_notes': fields.text('Nota'), 'estimated_price': fields.float('Costo Estimado', digits=(12, 2)), 'price_buffer': fields.float('Buffer Importe', digits=(12, 2)), 'base_discount': fields.float('Descuento', digits=(4, 2)), #'prepayment': fields.function(_get_total_sena, string='Sena', store=True, readonly=True), 'prepayment': fields.float(digits=(12,2)), 'shipping_cost': fields.float('Costo Envio', digits=(12, 2)), 'action': fields.selection([('reparar', 'Reparar'), ('reemplazar', 'Reemplazar')], 'Action', required=True), 'user_id': fields.many2one('res.users', 'Usuario'), 'state_id': fields.many2one('bag.state', 'Estado', required=True), 'shelving_id': fields.many2one('bag.shelving', 'Estanteria'), 'urgent': fields.boolean('Urgente'), 'papers': fields.boolean('Papeles'), 'attention': fields.boolean('Atencion'), 'monitoring': fields.boolean('Seguimiento'), 'send': fields.boolean('Enviar'), 'send_id': fields.many2one('bag.sending', 'Envio'), 'taxi': fields.boolean('Remisero'), 'baby_carriage': fields.boolean('Coche BB'), 'date_return': fields.date('Fecha Entregado'), 'work_to_be_done': fields.one2many('bag.work_to_be_done', 'service_id', 'Trabajo a realizar'), 'quotation_notes': fields.text('Observaciones de las Tareas'), # Tarea Observacion 'work_done': fields.one2many('bag.work_done', 'service_id', 'Trabajo realizado'), 'location_id': fields.many2one('bag.location', 'Ubicacion Actual'), 'retires_location_id': fields.many2one('bag.location', 'Retira en'), 'work_made': fields.text('Nota en Reparacion'), # Trabajo Realizado 'repaired_by_id': fields.many2one('res.users', 'Reparado por'),
class account_tax_code(osv.osv): _name = "account.tax.code" _inherit = "account.tax.code" _columns = { 'python_invoice': fields.text( 'Invoice Python Code', help='Python code to apply or not the tax at invoice level'), 'applicable_invoice': fields.boolean( 'Applicable Invoice', help='Use python code to apply this tax code at invoice'), } _defaults = { 'python_invoice': '''# amount\n# base\n# fiscal_unit\n# invoice: account.invoice object or False# address: res.partner.address object or False\n# partner: res.partner object or None\n# table: base.element object or None\n\n#result = table.get_element_percent(cr,uid,'COD_TABLE','COD_ELEMENT')/100\n#result = base > fiscal_unit * 4\n\nresult = True''', 'applicable_invoice': False, } _order = 'sequence' def _applicable_invoice(self, cr, uid, tax_code_id, invoice_id, amount, base, context=None): localdict = { 'amount': amount, 'base': base, 'cr': cr, 'uid': uid, 'table': self.pool.get('base.element') } code = self.browse(cr, uid, tax_code_id, context=context) if code.applicable_invoice: invoice = self.pool.get('account.invoice').browse( cr, uid, invoice_id) fiscal_unit = 0.0 ctx = context.copy() ctx.update({'company_id': invoice.company_id.id}) fiscalyear_obj = self.pool.get('account.fiscalyear') if invoice.period_id: fiscal_unit = invoice.period_id.fiscalyear_id.fiscal_unit else: fiscalyear_ids = fiscalyear_obj.find( cr, uid, invoice.date_invoice or fields.date.context_today(self, cr, uid, context=ctx), context=ctx) fiscalyear = fiscalyear_obj.browse(cr, uid, fiscalyear_ids, context=context) fiscal_unit = fiscalyear.fiscal_unit localdict['fiscal_unit'] = fiscal_unit localdict['invoice'] = invoice localdict['address'] = invoice.address_invoice_id localdict['partner'] = invoice.partner_id exec code.python_invoice in localdict return localdict.get('result', True)
class delivery_time(osv.osv): _name = 'delivery.time' _columns = { 'sequence': fields.integer('Sequence'), 'name': fields.char('Name', size=64, required=True), #'start_hour': fields.selection(([(str(x),str(x)) for x in range(0,24)] + [('-','--')]),'Start Hour'), #'start_minute': fields.selection(([(str(x*5),str(x*5)) for x in range(0,12)] + [('-','--')]),'Start Minute'), #'end_hour': fields.selection(([(str(x),str(x)) for x in range(0,24)] + [('-','--')]),'End Hour'), #'end_minute': fields.selection(([(str(x*5),str(x*5)) for x in range(0,12)] + [('-','--')]),'End Minute'), 'start_date': fields.datetime('Delivery Time From'), 'end_date': fields.datetime('Delivery Time To'), 'active': fields.boolean('Active'), 'type': fields.selection([('dts', 'Delivery'), ('pts', 'Preparation')], 'Type', required=True, select=True), 'dts_id': fields.many2one('delivery.time', 'Linked Delivery Time', domain=[('type', '=', 'dts')]), 'slot_id': fields.many2one('delivery.time.slot', 'Time Slot'), } _defaults = { 'active': True, 'type': 'dts', } def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80): if context is None: context = {} if not args: args = [] args.extend(context.get('domain', [])) #ids = self.search(cr, user, args, limit=limit, context=context) #return self.name_get(cr, user, ids, context) return super(delivery_time, self).name_search(cr, user, name, args=args, operator=operator, context=context, limit=limit) def create_from_time(self, cr, uid, data, context=None): """ create a delivery.time by given time start_date: end_date: """ #start_date = datetime.strptime(data['start_date'], '%Y-%m-%d %H:%M:%S') #end_date = datetime.strptime(data['end_date'], '%Y-%m-%d %H:%M:%S') context_tz = context.get('tz', 'Asia/Shanghai') tz = pytz.timezone(context_tz) start = pytz.utc.localize(data['start_date']).astimezone(tz) end = pytz.utc.localize(data['end_date']).astimezone(tz) start = start.strftime('%y/%m/%d %H:%M') end = end.strftime('%H:%M') # convert start in user's timezone name = "%s~%s" % ( start, end, ) data.update({'name': name}) return self.create(cr, uid, data, context) _order = 'sequence, name DESC'
class delivery_driver(osv.osv): _name = 'delivery.driver' _columns = { 'partner_id': fields.many2one( 'res.partner', 'Partner', help='Fill this field if the driver is a outsourcing of the company' ), 'employee_id': fields.many2one( 'hr.employee', 'Employee', help='Fill this if the driver is a employee of the company'), 'name': fields.char('Name', size=64, required=True), 'carrier_id': fields.many2one('delivery.carrier', 'Carrier'), 'outsourcing': fields.boolean('Outsourcing ?'), 'route_ids': fields.one2many('delivery.route', 'driver_id', 'Delivery Routes'), 'is_driver': fields.boolean('Is Driver ?'), 'is_picker': fields.boolean('Is Picker ?'), 'active': fields.boolean('Active ?'), 'color': fields.integer('Color Index'), 'tmp_route_id': fields.many2one('delivery.route_tmp', 'Temporary Delivery Route'), } _defaults = { 'outsourcing': False, 'is_driver': True, 'active': True, } def write(self, cr, uid, ids, vals, context=None): context = context or {} if type(ids) != type([]): ids = [ids] if 'tmp_route_id' in vals and 'force_dts_id' in context: driver = self.browse(cr, uid, ids[0]) if vals['tmp_route_id']: tmp_route = self.pool.get('delivery.route_tmp').browse( cr, uid, vals['tmp_route_id']) if tmp_route.route_id: route_vals = {} if driver.is_driver and not tmp_route.route_id.driver_id: route_vals = {'driver_id': driver.id} elif not tmp_route.route_id.picker_id: route_vals = {'picker_id': driver.id} if route_vals: cr.execute( "UPDATE delivery_route SET driver_id = Null WHERE driver_id = " + str(driver.id) + " AND dts_id=" + str(tmp_route.dts_id.id) + " ") cr.execute( "UPDATE delivery_route SET picker_id = Null WHERE picker_id = " + str(driver.id) + " AND dts_id=" + str(tmp_route.dts_id.id) + " ") cr.commit() self.pool.get('delivery.route').write( cr, uid, [tmp_route.route_id.id], route_vals) else: raise osv.except_osv( _('Error'), _("You can not assign more than one Deliver and one Picker." )) else: cr.execute( "UPDATE delivery_route SET driver_id = Null WHERE driver_id = " + str(driver.id) + " AND dts_id=" + str(context['force_dts_id']) + " ") cr.execute( "UPDATE delivery_route SET picker_id = Null WHERE picker_id = " + str(driver.id) + " AND dts_id=" + str(context['force_dts_id']) + " ") cr.commit() if 'is_driver' in vals or 'is_picker' in vals: driver = self.browse(cr, uid, ids[0]) is_driver = vals.get('is_driver', driver.is_driver) is_picker = vals.get('is_picker', driver.is_picker) if is_picker and is_driver: vals.update({'color': 8}) elif is_driver and not is_picker: vals.update({'color': 6}) elif is_picker and not is_driver: vals.update({'color': 2}) else: vals.update({'color': 0}) return super(delivery_driver, self).write(cr, uid, ids, vals, context=context) def create(self, cr, uid, vals, context=None): context = context or {} if 'is_driver' in vals or 'is_picker' in vals: is_driver = vals.get('is_driver', False) is_picker = vals.get('is_picker', False) if is_picker and is_driver: vals.update({'color': 8}) elif is_driver and not is_picker: vals.update({'color': 6}) elif is_picker and not is_driver: vals.update({'color': 2}) else: vals.update({'color': 0}) return super(delivery_driver, self).create(cr, uid, vals, context=context) def search(self, cr, uid, args, offset=0, limit=None, order='name', context=None, count=False): onlyactive = True for arg in args: if len(arg) == 3 and arg[0] == 'active': onlyactive = False if onlyactive: args.append(('active', '=', True)) return super(delivery_driver, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count) def _read_group_tmp_route_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None): context = context or {} route_tmp_obj = self.pool.get('delivery.route_tmp') args = [] if 'force_dts_id' in context: args.append(('dts_id', '=', context['force_dts_id'])) route_tmp_ids = route_tmp_obj.search(cr, uid, args, context=context) result = route_tmp_obj.name_get(cr, uid, route_tmp_ids, context=context) fold = {} return result, fold _group_by_full = { 'tmp_route_id': _read_group_tmp_route_ids, }
"sale_ids": fields.many2many( "sale.order", "maintenance_module_sale_rel", "module_id", "sale_id", "Sale orders" ), "nbr_source_line": fields.integer( "Source Line of Code", help="number of source line of code of uploaded module" ), "module_zip": fields.binary("Module Zip File"), "state": fields.selection( [("draft", "Draft"), ("open", "Open"), ("failed", "Failed"), ("done", "Done"), ("cancel", "Cancel")], "State", readonly=True, ), "test_ids": fields.one2many("test", "module_id", "Tests"), "test_tech_ids": one2many_mod_advert("test", "id", "Tests"), "test_func_ids": one2many_mod_advert("test", "id", "Tests"), "tech_certificate": fields.boolean("Technicle certificate", help="tick if you want technicle certificate"), "func_certificate": fields.boolean("Functional certificate", help="tick if you want functional certificate"), "tech_user_id": fields.many2one("res.users", "Technicle User", help="User for Technicle tests"), "func_user_id": fields.many2one("res.users", "Functional User", help="User for Functional tests"), } _defaults = { "technical_certificate": lambda *a: "not_started", "functional_certificate": lambda *a: "not_started", "state": lambda *a: "draft", } def refresh(self, cr, uid): def get_version(terp): return "%s.%s" % (release.major_version, terp["version"])
class delivery_route(osv.osv): _name = 'delivery.route' def _init_name(self, cr, uid, context=None): context = context or {} dts_id = context.get('force_dts_id_kanban', False) or False if dts_id: dts_pool = self.pool.get('delivery.time') base_name = dts_pool.read(cr, uid, [dts_id], ['name'])[0]['name'].split()[0] for idx in range(1, 99): name = base_name + str(idx).rjust(2, '0') ids = self.search(cr, uid, [('name', 'ilike', name)]) or False if not ids: return name return '/' def name_get(self, cr, uid, ids, context=None): context = context or {} result = [] if isinstance(ids, int): ids = [ids] if context.get('force_dts_id_kanban', False): for record in self.browse(cr, uid, ids, context=context): name = ustr(record.name) if record.driver_id: name = ustr(record.driver_id.name) + ' ' + name[2:] result.append((record.id, name.strip())) else: for record in self.browse(cr, uid, ids, context=context): result.append((record.id, record.name.strip())) return result def create(self, cr, user, vals, context=None): if ('name' not in vals) or (vals.get('name') == '/'): seq_obj_name = 'delivery.route' # SHOULD USE ir_sequence.next_by_code() or ir_sequence.next_by_id() vals['name'] = self.pool.get('ir.sequence').get( cr, user, seq_obj_name) new_id = super(delivery_route, self).create(cr, user, vals, context) return new_id _columns = { 'name': fields.char('Reference', size=64, required=True, select=True, readonly=True, states={'draft': [('readonly', False)]}), 'date': fields.date('Date', required=False, select=True, readonly=True, states={'draft': [('readonly', False)]}), 'dts_id': fields.many2one('delivery.time', 'Delivery Time', select=True, domain=[('type', '=', 'dts')], readonly=True, states={'draft': [('readonly', False)]}), 'driver_id': fields.many2one('delivery.driver', 'Delivery Driver', required=False, domain=[('is_driver', '=', True)], readonly=True, states={'draft': [('readonly', False)]}), 'picker_id': fields.many2one('delivery.driver', 'Delivery Deliver', required=False, domain=[('is_picker', '=', True)], readonly=True, states={'draft': [('readonly', False)]}), 'state': fields.selection([('draft', 'Draft'), ('confirm', 'Confirm'), ('departure', 'Departure'), ('done', 'Done'), ('cancel', 'Cancel')], 'State', readonly=True), 'line_ids': fields.one2many('delivery.route.line', 'route_id', 'Lines', required=True, readonly=False, states={'done': [('readonly', True)]}), 'departure_date': fields.datetime('Departure Date', readonly=False, states={'done': [('readonly', True)]}), 'arrive_date': fields.datetime('Arrive Date', readonly=False, states={'done': [('readonly', True)]}), 'confirm_cs': fields.boolean('Confirmed by CS'), } _defaults = { 'state': 'draft', 'name': lambda self, cr, uid, context: self._init_name( cr, uid, context=context), 'dts_id': lambda self, cr, uid, context: context.get('force_dts_id_kanban', False ) or False, } def action_draft(self, cr, uid, ids, context=None): line_obj = self.pool.get('delivery.route.line') for route in self.browse(cr, uid, ids, context=context): for line in route.line_ids: line_obj.action_draft(cr, uid, [line.id], context=context) self.write(cr, uid, ids, {'state': 'draft'}, context=context) return True def action_confirm(self, cr, uid, ids, context=None): line_obj = self.pool.get('delivery.route.line') for route in self.browse(cr, uid, ids, context=context): for line in route.line_ids: line_obj.action_confirm(cr, uid, [line.id], context=context) self.write(cr, uid, ids, {'state': 'confirm'}, context=context) return True def action_departure(self, cr, uid, ids, context=None): line_obj = self.pool.get('delivery.route.line') for route in self.browse(cr, uid, ids, context=context): if not route.confirm_cs: raise osv.except_osv( _('Error'), _("Before departure, routes need to be confirmed by the Customer Service." )) for line in route.line_ids: line_obj.action_delivered(cr, uid, [line.id], context=context) self.write(cr, uid, ids, { 'state': 'departure', 'departure_date': time.strftime('%Y-%m-%d %H:%M:%S') }, context=context) return True def action_arrive(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'arrive'}, context=context) return True def action_done_cs(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'confirm_cs': True}, context=context) return True def action_done(self, cr, uid, ids, context=None): line_obj = self.pool.get('delivery.route.line') for route in self.browse(cr, uid, ids, context=context): for line in route.line_ids: if line.state in ('draft', 'confim', 'delivered'): raise osv.except_osv( _('Error'), _("All the lines of delivery route must be delivered or returned." )) self.write(cr, uid, ids, {'state': 'done'}, context=context) return True def action_cancel(self, cr, uid, ids, context=None): line_obj = self.pool.get('delivery.route.line') for route in self.browse(cr, uid, ids, context=context): for line in route.line_ids: line_obj.action_cancel(cr, uid, [line.id], context=context) self.write(cr, uid, ids, { 'state': 'cancel', 'confirm_cs': False }, context=context) return True def _read_group_driver_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None): context = context or {} driver_obj = self.pool.get('delivery.driver') args = [('is_driver', '=', True)] driver_ids = driver_obj.search(cr, uid, args, context=context) result = driver_obj.name_get(cr, uid, driver_ids, context=context) fold = {} return result, fold def _read_group_picker_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None): context = context or {} driver_obj = self.pool.get('delivery.driver') args = [('is_picker', '=', True)] driver_ids = driver_obj.search(cr, uid, args, context=context) result = driver_obj.name_get(cr, uid, driver_ids, context=context) fold = {} return result, fold _group_by_full = { 'driver_id': _read_group_driver_ids, 'picker_id': _read_group_picker_ids, } _order = 'date DESC, name'
'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), 'ldap_base': fields.char('LDAP base', size=64, required=True), 'user': fields.many2one('res.users', 'Model User', help="Model used for user creation"), 'create_user': fields.boolean('Create user', help="Create the user if not in database"), 'ldap_tls': fields.boolean('Use TLS', help="Request secure TLS/SSL encryption when connecting to the LDAP server. " "This option requires a server with STARTTLS enabled, " "otherwise all authentication attempts will fail."), } _defaults = { 'ldap_server': '127.0.0.1', 'ldap_server_port': 389, 'sequence': 10, 'create_user': True, } CompanyLDAP()
class delivery_route_line(osv.osv): _name = 'delivery.route.line' def _get_drivers(self, cr, uid, ids, fields, args, context=None): result = {} for route in self.browse(cr, uid, ids): res = {} if route.route_id: res['picker'] = route.route_id.picker_id and route.route_id.picker_id.name or " " res['driver'] = route.route_id.driver_id and route.route_id.driver_id.name or " " else: res['picker'] = " " res['driver'] = " " result[route.id] = res return result def _get_origin(self, cr, uid, ids, fields, args, context=None): result = {} for route in self.browse(cr, uid, ids): res = {} res['origin'] = route.picking_id.origin or route.picking_id.name or "" res['sale_order_id'] = route.picking_id.sale_id and route.picking_id.sale_id.id or False res['purchase_id'] = route.picking_id.purchase_id and route.picking_id.purchase_id.id or False res['address_id'] = route.picking_id.partner_id and route.picking_id.partner_id.id or False res['so_payment_method'] = route.picking_id.sale_id and route.picking_id.sale_id.so_payment_method or False res['picking_note'] = route.picking_id.note or " " result[route.id] = res return result def _get_box_type(self, cr, uid, ids, fields, args, context=None): res = {} for route in self.browse(cr, uid, ids): box_type = '' iced = False warm = False other = False pack_set = set([ move.product_id.deliver_in for move in route.picking_id.move_lines ]) for pack in pack_set: if pack in ['warm', 'iced', 'iced_n_warm'] and not iced: if pack in ['iced', 'iced_n_warm']: box_type += '冷, ' iced = True if pack in ['warm', 'iced_n_warm'] and not warm: box_type += '热, ' warm = True else: if not other: box_type += '正常, ' other = True if box_type: box_type = box_type[:-2] res[route.id] = box_type return res def _route_to_update_after_picking_change(self, cr, uid, ids, fields=None, arg=None, context=None): if type(ids) != type([]): ids = [ids] return self.pool.get('delivery.route.line').search( cr, uid, [('picking_id', 'in', ids)]) or [] def _route_to_update_after_parent_change(self, cr, uid, ids, fields=None, arg=None, context=None): if type(ids) != type([]): ids = [ids] return self.pool.get('delivery.route.line').search( cr, uid, [('route_id', 'in', ids)]) or [] _store_origin = { 'delivery.route.line': (lambda self, cr, uid, ids, context: ids, ['picking_id'], 10), 'stock.picking': (_route_to_update_after_picking_change, [ 'sale_id', 'purchase_id', 'origin', 'note', 'so_payment_method', 'partner_id' ], 10), } _store_drivers = { 'delivery.route.line': (lambda self, cr, uid, ids, context: ids, ['route_id'], 10), 'delivery.route': (_route_to_update_after_parent_change, ['picker_id', 'driver_id'], 10), } _columns = { 'sequence': fields.integer('Sequence'), 'route_id': fields.many2one('delivery.route', 'Delivery Route', required=False, readonly=True, states={'draft': [('readonly', False)]}, ondelete="cascade"), 'picking_id': fields.many2one('stock.picking', 'Picking', required=True, select=True, readonly=True, states={'draft': [('readonly', False)]}), 'purchase_id': fields.function(_get_origin, type='many2one', obj='purchase.order', store=_store_origin, multi="origin", string='Purchase Order'), 'sale_order_id': fields.function(_get_origin, type='many2one', obj='sale.order', store=_store_origin, multi="origin", string='Sale Order'), 'origin': fields.function(_get_origin, type='char', size=256, store=_store_origin, multi="origin", string='Origin'), 'confirm_cs': fields.related('route_id', 'confirm_cs', type='boolean', string='Confirmed by CS'), 'address_id': fields.function(_get_origin, type='many2one', relation='res.partner', multi="origin", string='Delivery Address'), 'street': fields.related('address_id', 'street', type='char', size=256, string='Street'), 'partner_phone': fields.related('address_id', 'phone', type='char', size=128, string='Partner Phone', readonly=True), 'picker': fields.function(_get_drivers, type='char', size=128, store=_store_drivers, multi="drivers", string='Clerk'), 'driver': fields.function(_get_drivers, type='char', size=128, store=_store_drivers, multi="drivers", string='Driver'), 'driver_phone': fields.related('route_id', 'driver_id', 'employee_id', 'mobile_phone', type='char', size=128, string='Driver Phone'), 'so_payment_method': fields.function(_get_origin, type='char', size=128, multi="origin", string='Payment Method'), 'picking_note': fields.function(_get_origin, type='html', multi="origin", string='DO Notes'), 'box_type': fields.function(_get_box_type, type='char', size=32, store=False, string='Box Type'), 'state': fields.selection([('draft', 'Draft'), ('confirm', 'Confirm'), ('delivered', 'In delivery'), ('received', 'Delivered'), ('returned', 'Returned'), ('cancel', 'Cancel')], 'State', readonly=True), 'visit_date': fields.datetime('Visit Date', states={ 'delivered': [('required', True)], 'received': [('readonly', True)], 'returned': [('readonly', True)], }), 'note': fields.text('Notes'), 'color': fields.integer('Color Index'), 'exceptions': fields.boolean('Received with exceptions'), 'complete_state': fields.selection([("not_planned", _("Not planned")), ("planned", _("Planned")), ("in_del", _("In delivery")), ("del_ok", _("Delivered")), ("del_ex", _("Exception")), ("del_rt", _("Returned")), ("del_rt_exp", _("No redelivery")), ("cancel", _("Cancel"))], 'Delivery State'), } _defaults = { 'state': 'draft', 'complete_state': 'not_planned', } _order = 'sequence' def _read_group_route_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None): context = context or {} route_obj = self.pool.get('delivery.route') args = [('state', '=', 'draft')] if 'force_dts_id_kanban' in context: args.append(('dts_id', '=', context['force_dts_id_kanban'])) route_ids = route_obj.search(cr, uid, args, order='name', context=context) result = route_obj.name_get(cr, uid, route_ids, context=context) fold = {} return result, fold def unlink(self, cr, uid, ids, context=None): for o in self.browse(cr, uid, ids, context=context): if o.state not in ('draft', 'cancel'): raise osv.except_osv( _('Invalid action !'), _('Cannot delete Delivery Route Line(s) which are already received, returned or delivered !' )) return super(delivery_route_line, self).unlink(cr, uid, ids, context=context) def action_draft(self, cr, uid, ids, context=None): self.write(cr, uid, ids, { 'state': 'draft', 'delivery_state': 'not_planned' }, context=context) return True def action_received_do_line(self, cr, uid, line, context=None): self.pool.get('stock.picking').write(cr, uid, [line.picking_id.id], { 'delivered': True, 'delivery_state': 'del_ok' }, context=context) self.notify_related_order(cr, uid, line, 'The Order has been <b>Delivered</b>', context) return True def action_received_exp_do_line(self, cr, uid, line, context=None): self.pool.get('stock.picking').write(cr, uid, [line.picking_id.id], { 'delivered': True, 'delivery_state': 'del_ex' }, context=context) self.notify_related_order( cr, uid, line, 'The Order has been <b>Delivered with exceptions</b>', context) return True def action_delivered_do_line(self, cr, uid, line, context=None): delivered_cpt = line.picking_id.delivered_cpt + 1 self.pool.get('stock.picking').write( cr, uid, [line.picking_id.id], { 'delivered_cpt': delivered_cpt, 'delivery_state': 'in_del' }, context=context) self.notify_related_order(cr, uid, line, 'The Order is <b>in Delivery</b>', context) return True def action_returned_do_line(self, cr, uid, line, context=None): contexet = context or {} context.update({'set_dts': False}) self.pool.get('stock.picking').write(cr, uid, [line.picking_id.id], {'delivery_state': 'del_rt'}, context=context) #self.copy(cr, uid, line.id, {'dts_id':False,'note': 'Re-delivery for ' + str(line.origin),'route_id':False,'return_reasons':[],'exceptions':False,'state':'draft','complete_state':'not_planned','visit_date':False,'color':0}, context=context) self.create(cr, uid, { 'dts_id': False, 'note': 'Re-delivery for ' + str(line.origin), 'route_id': False, 'return_reasons': [], 'exceptions': False, 'color': 0, 'picking_id': line.picking_id and line.picking_id.id, }, context=context) self.notify_related_order( cr, uid, line, 'The Order has been <b>Returned (Redelivery)</b>', context) return True def action_returned_exp_do_line(self, cr, uid, line, context=None): self.pool.get('stock.picking').write(cr, uid, [line.picking_id.id], { 'delivered': True, 'delivery_state': 'del_rt_exp' }, context=context) self.notify_related_order( cr, uid, line, 'The Order has been <b>Returned (No Redelivery)</b>', context) return True def action_delivered(self, cr, uid, ids, context=None): picking_obj = self.pool.get('stock.picking') for line in self.browse(cr, uid, ids, context=context): self.action_delivered_do_line(cr, uid, line, context=context) self.write(cr, uid, ids, { 'complete_state': 'in_del', 'state': 'delivered' }, context=context) return True def action_received(self, cr, uid, ids, context=None): for line in self.browse(cr, uid, ids, context=context): self.action_received_do_line(cr, uid, line, context=context) self.write( cr, uid, ids, { 'complete_state': 'del_ok', 'state': 'received', 'visit_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S') }, context=context) return True def action_received_exp(self, cr, uid, ids, context=None): for line in self.browse(cr, uid, ids, context=context): self.action_received_exp_do_line(cr, uid, line, context=context) self.write( cr, uid, ids, { 'complete_state': 'del_ex', 'state': 'received', 'exceptions': True, 'visit_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S') }, context=context) return True def action_returned(self, cr, uid, ids, context=None): for line in self.browse(cr, uid, ids, context=context): self.action_returned_do_line(cr, uid, line, context=context) self.write( cr, uid, ids, { 'complete_state': 'del_rt', 'state': 'returned', 'visit_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S') }, context=context) return True def action_returned_exp(self, cr, uid, ids, context=None): for line in self.browse(cr, uid, ids, context=context): self.action_returned_exp_do_line(cr, uid, line, context=context) self.write( cr, uid, ids, { 'complete_state': 'del_rt_exp', 'state': 'returned', 'exceptions': True, 'visit_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S') }, context=context) return True def action_cancel_do_line(self, cr, uid, line, context=None): delivered_cpt = line.picking_id.delivered_cpt - 1 if delivered_cpt < 0: delivered_cpt = 0 self.pool.get('stock.picking').write( cr, uid, line.picking_id.id, { 'delivered': False, 'delivered_cpt': delivered_cpt, 'delivery_state': 'not_planned' }, context=context) self.notify_related_order(cr, uid, line, 'The Delivery has been <b>Canceled</b>', context) return True def action_cancel(self, cr, uid, ids, context=None): for line in self.browse(cr, uid, ids, context=context): self.action_cancel_do_line(cr, uid, line, context=context) self.write(cr, uid, ids, { 'state': 'cancel', 'complete_state': 'cancel', 'exceptions': False }, context=context) return True def action_confirm_do_line(self, cr, uid, line, context=None): self.pool.get('stock.picking').write(cr, uid, line.picking_id.id, {'delivery_state': 'planned'}, context=context) self.notify_related_order(cr, uid, line, 'The Delivery has been <b>Planned</b>', context) return True def action_confirm(self, cr, uid, ids, context=None): for line in self.browse(cr, uid, ids, context=context): if line.picking_id.delivered: raise osv.except_osv( _('Error'), _('The picking %s (origin:%s) was delivered in other delivery route' % (line.picking_id.name, line.picking_id.origin))) # if line.picking_id.type == 'out' and line.picking_id.state not in ('done'): # raise osv.except_osv(_('Error'), _('The picking %s (origin:%s) must be in done state'%(line.picking_id.name,line.picking_id.origin))) self.action_confirm_do_line(cr, uid, line, context=context) self.write(cr, uid, ids, { 'complete_state': 'planned', 'state': 'confirm' }, context=context) return True def notify_related_order(self, cr, uid, line, delivery_state, context=None): res_id = False model = False if line.sale_order_id: res_id = line.sale_order_id.id model = 'sale.order' elif line.purchase_id: res_id = line.purchase_id.id model = 'purchase.order' if res_id and model: drivers = '' body = str(delivery_state) if line.visit_date: body += " at " + str(line.visit_date) body += "<br />" if line.route_id.name: body += "<b>Route</b>: " + str(line.route_id.name) + "<br />" if line.route_id.driver_id: drivers += str(line.route_id.driver_id.name.encode('utf-8')) if line.route_id.driver_id.employee_id and line.route_id.driver_id.employee_id.mobile_phone: drivers += " (" + str( line.route_id.driver_id.employee_id.mobile_phone) + ")" if line.route_id.picker_id: if drivers: drivers += ' & ' drivers += str(line.route_id.picker_id.name.encode('utf-8')) if drivers: body += "by: " + drivers + ")" self.pool.get('mail.message').create( cr, uid, { 'type': 'notification', 'record_name': 'Delivery Route Line', 'body': body, 'res_id': res_id, 'model': model, }) return True _group_by_full = { 'route_id': _read_group_route_ids, }
res = [] try: gd_client = google.google_login(user_obj.gmail_user, user_obj.gmail_password, type="calendar") calendars = gd_client.GetAllCalendarsFeed() for cal in calendars.entry: res.append((cal.id.text, cal.title.text)) except Exception, e: return [("failed", "Connection to google fail")] res.append(("all", "All Calendars")) return res _columns = { "create_partner": fields.selection( [("create_all", "Create partner for each contact"), ("create_address", "Import only address")], "Options" ), "customer": fields.boolean("Customer", help="Check this box to set newly created partner as Customer."), "supplier": fields.boolean("Supplier", help="Check this box to set newly created partner as Supplier."), "group_name": fields.selection( _get_group, "Group Name", help="Choose which group to import, By default it takes all." ), "calendar_name": fields.selection(_get_calendars, "Calendar Name"), } _defaults = {"create_partner": "create_all", "group_name": "all"} def import_google(self, cr, uid, ids, context=None): if context == None: context = {} if not ids: return {"type": "ir.actions.act_window_close"} obj = self.browse(cr, uid, ids, context=context)[0]
class asset_asset_report(osv.osv): _name = "asset.asset.report" _description = "Assets Analysis" _auto = False _columns = { 'name': fields.char('Year', size=16, required=False, readonly=True), 'purchase_date': fields.date('Purchase Date', readonly=True), 'depreciation_date': fields.date('Depreciation Date', readonly=True), 'asset_id': fields.many2one('account.asset.asset', string='Asset', readonly=True), 'asset_category_id': fields.many2one('account.asset.category', string='Asset category'), 'partner_id': fields.many2one('res.partner', 'Partner', readonly=True), 'state': fields.selection([('draft', 'Draft'), ('open', 'Running'), ('close', 'Close')], 'Status', readonly=True), 'depreciation_value': fields.float('Amount of Depreciation Lines', readonly=True), 'move_check': fields.boolean('Posted', readonly=True), 'nbr': fields.integer('# of Depreciation Lines', readonly=True), 'gross_value': fields.float('Gross Amount', readonly=True), 'posted_value': fields.float('Posted Amount', readonly=True), 'unposted_value': fields.float('Unposted Amount', readonly=True), 'company_id': fields.many2one('res.company', 'Company', readonly=True), } def init(self, cr): tools.drop_view_if_exists(cr, 'asset_asset_report') cr.execute(""" create or replace view asset_asset_report as ( select min(dl.id) as id, dl.name as name, to_date(dl.depreciation_date, 'YYYY-MM-DD') as depreciation_date, a.purchase_date as purchase_date, (CASE WHEN (select min(d.id) from account_asset_depreciation_line as d left join account_asset_asset as ac ON (ac.id=d.asset_id) where a.id=ac.id) = min(dl.id) THEN a.purchase_value ELSE 0 END) as gross_value, dl.amount as depreciation_value, (CASE WHEN dl.move_check THEN dl.amount ELSE 0 END) as posted_value, (CASE WHEN NOT dl.move_check THEN dl.amount ELSE 0 END) as unposted_value, dl.asset_id as asset_id, dl.move_check as move_check, a.category_id as asset_category_id, a.partner_id as partner_id, a.state as state, count(dl.*) as nbr, a.company_id as company_id from account_asset_depreciation_line dl left join account_asset_asset a on (dl.asset_id=a.id) group by dl.amount,dl.asset_id,to_date(dl.depreciation_date, 'YYYY-MM-DD'),dl.name, a.purchase_date, dl.move_check, a.state, a.category_id, a.partner_id, a.company_id, a.purchase_value, a.id, a.salvage_value )""")
'published_version': fields.char('Published Version', size=64, readonly=True), 'url': fields.char('URL', size=128, readonly=True), 'dependencies_id': fields.one2many('ir.module.module.dependency', 'module_id', 'Dependencies', readonly=True), 'web_dependencies_id': fields.one2many('ir.module.web.dependency', 'module_id', 'Web Dependencies', readonly=True), '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='State', readonly=True), 'demo': fields.boolean('Demo data'), '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'), ('Other OSI approved licence', 'Other OSI Approved Licence'), ('Other proprietary', 'Other Proprietary') ], string='License', readonly=True), 'menus_by_module': fields.function(_get_views, method=True, string='Menus', type='text', multi="meta", store=True), 'reports_by_module': fields.function(_get_views, method=True, string='Reports', type='text', multi="meta", store=True), 'views_by_module': fields.function(_get_views, method=True, string='Views', type='text', multi="meta", store=True), 'certificate' : fields.char('Quality Certificate', size=64, readonly=True), }
class crm_lead(crm_case, osv.osv): """ CRM Lead Case """ _name = "crm.lead" _description = "Lead/Opportunity" _order = "priority,date_action,id desc" _inherit = ['mail.thread', 'res.partner.address'] def _read_group_stage_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None): access_rights_uid = access_rights_uid or uid stage_obj = self.pool.get('crm.case.stage') order = stage_obj._order if read_group_order == 'stage_id desc': # lame hack to allow reverting search, should just work in the trivial case order = "%s desc" % order stage_ids = stage_obj._search( cr, uid, ['|', ('id', 'in', ids), ('case_default', '=', 1)], order=order, access_rights_uid=access_rights_uid, context=context) result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context) # restore order of the search result.sort( lambda x, y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0]))) return result _group_by_full = {'stage_id': _read_group_stage_ids} # overridden because res.partner.address has an inconvenient name_get, # especially if base_contact is installed. def name_get(self, cr, user, ids, context=None): if isinstance(ids, (int, long)): ids = [ids] return [(r['id'], tools.ustr(r[self._rec_name])) for r in self.read(cr, user, ids, [self._rec_name], context)] # overridden because if 'base_contact' is installed - their default_get() will remove # 'default_type' from context making it impossible to record an 'opportunity' def default_get(self, cr, uid, fields_list, context=None): return super(osv.osv, self).default_get(cr, uid, fields_list, context=context) def _compute_day(self, cr, uid, ids, fields, args, context=None): """ @param cr: the current row, from the database cursor, @param uid: the current user’s ID for security checks, @param ids: List of Openday’s IDs @return: difference between current date and log date @param context: A standard dictionary for contextual values """ cal_obj = self.pool.get('resource.calendar') res_obj = self.pool.get('resource.resource') res = {} for lead in self.browse(cr, uid, ids, context=context): for field in fields: res[lead.id] = {} duration = 0 ans = False if field == 'day_open': if lead.date_open: date_create = datetime.strptime( lead.create_date, "%Y-%m-%d %H:%M:%S") date_open = datetime.strptime(lead.date_open, "%Y-%m-%d %H:%M:%S") ans = date_open - date_create date_until = lead.date_open elif field == 'day_close': if lead.date_closed: date_create = datetime.strptime( lead.create_date, "%Y-%m-%d %H:%M:%S") date_close = datetime.strptime(lead.date_closed, "%Y-%m-%d %H:%M:%S") date_until = lead.date_closed ans = date_close - date_create if ans: resource_id = False if lead.user_id: resource_ids = res_obj.search( cr, uid, [('user_id', '=', lead.user_id.id)]) if len(resource_ids): resource_id = resource_ids[0] duration = float(ans.days) if lead.section_id and lead.section_id.resource_calendar_id: duration = float(ans.days) * 24 new_dates = cal_obj.interval_get( cr, uid, lead.section_id.resource_calendar_id and lead.section_id.resource_calendar_id.id or False, datetime.strptime(lead.create_date, '%Y-%m-%d %H:%M:%S'), duration, resource=resource_id) no_days = [] date_until = datetime.strptime(date_until, '%Y-%m-%d %H:%M:%S') for in_time, out_time in new_dates: if in_time.date not in no_days: no_days.append(in_time.date) if out_time > date_until: break duration = len(no_days) res[lead.id][field] = abs(int(duration)) return res def _history_search(self, cr, uid, obj, name, args, context=None): res = [] msg_obj = self.pool.get('mail.message') message_ids = msg_obj.search(cr, uid, [('email_from', '!=', False), ('subject', args[0][1], args[0][2])], context=context) lead_ids = self.search(cr, uid, [('message_ids', 'in', message_ids)], context=context) if lead_ids: return [('id', 'in', lead_ids)] else: return [('id', '=', '0')] def _get_email_subject(self, cr, uid, ids, fields, args, context=None): res = {} for obj in self.browse(cr, uid, ids, context=context): res[obj.id] = '' for msg in obj.message_ids: if msg.email_from: res[obj.id] = msg.subject break return res _columns = { # Overridden from res.partner.address: 'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', select=True, help="Optional linked partner, usually after conversion of the lead"), 'id': fields.integer('ID', readonly=True), 'name': fields.char('Name', size=64, select=1), 'active': fields.boolean('Active', required=False), 'date_action_last': fields.datetime('Last Action', readonly=1), 'date_action_next': fields.datetime('Next Action', readonly=1), 'email_from': fields.char('Email', size=128, help="E-mail address of the contact", select=1), 'section_id': fields.many2one('crm.case.section', 'Sales Team', \ select=True, help='When sending mails, the default email address is taken from the sales team.'), 'create_date': fields.datetime('Creation Date' , readonly=True), 'email_cc': fields.text('Global CC', size=252 , help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"), 'description': fields.text('Notes'), 'write_date': fields.datetime('Update Date' , readonly=True), 'categ_id': fields.many2one('crm.case.categ', 'Category', \ domain="['|',('section_id','=',section_id),('section_id','=',False), ('object_id.model', '=', 'crm.lead')]"), 'type_id': fields.many2one('crm.case.resource.type', 'Campaign', \ domain="['|',('section_id','=',section_id),('section_id','=',False)]", help="From which campaign (seminar, marketing campaign, mass mailing, ...) did this contact come from?"), 'channel_id': fields.many2one('crm.case.channel', 'Channel', help="Communication channel (mail, direct, phone, ...)"), 'contact_name': fields.char('Contact Name', size=64), 'partner_name': fields.char("Customer Name", size=64,help='The name of the future partner that will be created while converting the lead into opportunity', select=1), 'optin': fields.boolean('Opt-In', help="If opt-in is checked, this contact has accepted to receive emails."), 'optout': fields.boolean('Opt-Out', help="If opt-out is checked, this contact has refused to receive emails or unsubscribed to a campaign."), 'type':fields.selection([ ('lead','Lead'), ('opportunity','Opportunity'), ],'Type', help="Type is used to separate Leads and Opportunities"), 'priority': fields.selection(crm.AVAILABLE_PRIORITIES, 'Priority', select=True), 'date_closed': fields.datetime('Closed', readonly=True), 'stage_id': fields.many2one('crm.case.stage', 'Stage', domain="[('section_ids', '=', section_id)]"), 'user_id': fields.many2one('res.users', 'Salesman', select=1), 'referred': fields.char('Referred By', size=64), 'date_open': fields.datetime('Opened', readonly=True), 'day_open': fields.function(_compute_day, string='Days to Open', \ multi='day_open', type="float", store=True), 'day_close': fields.function(_compute_day, string='Days to Close', \ multi='day_close', type="float", store=True), 'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True, help='The state is set to \'Draft\', when a case is created.\ \nIf the case is in progress the state is set to \'Open\'.\ \nWhen the case is over, the state is set to \'Done\'.\ \nIf the case needs to be reviewed then the state is set to \'Pending\'.' ), 'message_ids': fields.one2many('mail.message', 'res_id', 'Messages', domain=[('model','=',_name)]), 'subjects': fields.function(_get_email_subject, fnct_search=_history_search, string='Subject of Email', type='char', size=64), # Only used for type opportunity 'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact', domain="[('partner_id','=',partner_id)]"), 'probability': fields.float('Probability (%)',group_operator="avg"), 'planned_revenue': fields.float('Expected Revenue'), 'ref': fields.reference('Reference', selection=crm._links_get, size=128), 'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128), 'phone': fields.char("Phone", size=64), 'date_deadline': fields.date('Expected Closing'), 'date_action': fields.date('Next Action Date', select=True), 'title_action': fields.char('Next Action', size=64), 'stage_id': fields.many2one('crm.case.stage', 'Stage', domain="[('section_ids', '=', section_id)]"), 'color': fields.integer('Color Index'), 'partner_address_name': fields.related('partner_address_id', 'name', type='char', string='Partner Contact Name', readonly=True), 'partner_address_email': fields.related('partner_address_id', 'email', type='char', string='Partner Contact Email', readonly=True), 'company_currency': fields.related('company_id', 'currency_id', 'symbol', type='char', string='Company Currency', readonly=True), 'user_email': fields.related('user_id', 'user_email', type='char', string='User Email', readonly=True), 'user_login': fields.related('user_id', 'login', type='char', string='User Login', readonly=True), } _defaults = { 'active': lambda *a: 1, 'user_id': crm_case._get_default_user, 'email_from': crm_case._get_default_email, 'state': lambda *a: 'draft', 'type': lambda *a: 'lead', 'section_id': crm_case._get_section, 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get( cr, uid, 'crm.lead', context=c), 'priority': lambda *a: crm.AVAILABLE_PRIORITIES[2][0], 'color': 0, } def onchange_partner_address_id(self, cr, uid, ids, add, email=False): """This function returns value of partner email based on Partner Address """ if not add: return {'value': {'email_from': False, 'country_id': False}} address = self.pool.get('res.partner.address').browse(cr, uid, add) return { 'value': { 'email_from': address.email, 'phone': address.phone, 'country_id': address.country_id.id } } def on_change_optin(self, cr, uid, ids, optin): return {'value': {'optin': optin, 'optout': False}} def on_change_optout(self, cr, uid, ids, optout): return {'value': {'optout': optout, 'optin': False}} def onchange_stage_id(self, cr, uid, ids, stage_id, context={}): if not stage_id: return {'value': {}} stage = self.pool.get('crm.case.stage').browse(cr, uid, stage_id, context) if not stage.on_change: return {'value': {}} return {'value': {'probability': stage.probability}} def stage_find_percent(self, cr, uid, percent, section_id): """ Return the first stage with a probability == percent """ stage_pool = self.pool.get('crm.case.stage') if section_id: ids = stage_pool.search(cr, uid, [("probability", '=', percent), ("section_ids", 'in', [section_id])]) else: ids = stage_pool.search(cr, uid, [("probability", '=', percent)]) if ids: return ids[0] return False def stage_find_lost(self, cr, uid, section_id): return self.stage_find_percent(cr, uid, 0.0, section_id) def stage_find_won(self, cr, uid, section_id): return self.stage_find_percent(cr, uid, 100.0, section_id) def case_open(self, cr, uid, ids, *args): for l in self.browse(cr, uid, ids): # When coming from draft override date and stage otherwise just set state if l.state == 'draft': if l.type == 'lead': message = _("The lead '%s' has been opened.") % l.name elif l.type == 'opportunity': message = _( "The opportunity '%s' has been opened.") % l.name else: message = _("The case '%s' has been opened.") % l.name self.log(cr, uid, l.id, message) value = {'date_open': time.strftime('%Y-%m-%d %H:%M:%S')} self.write(cr, uid, [l.id], value) if l.type == 'opportunity' and not l.stage_id: stage_id = self.stage_find(cr, uid, l.section_id.id or False, [('sequence', '>', 0)]) if stage_id: self.stage_set(cr, uid, [l.id], stage_id) res = super(crm_lead, self).case_open(cr, uid, ids, *args) return res def case_close(self, cr, uid, ids, *args): res = super(crm_lead, self).case_close(cr, uid, ids, *args) self.write(cr, uid, ids, {'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')}) for case in self.browse(cr, uid, ids): if case.type == 'lead': message = _("The lead '%s' has been closed.") % case.name else: message = _("The case '%s' has been closed.") % case.name self.log(cr, uid, case.id, message) return res
('file','File'), ('parser','Parser'), ],'Template source', select=True), 'parser_def': fields.text('Parser Definition'), 'parser_loc':fields.char('Parser location', size=128, help="Path to the parser location. Beginning of the path must be start with the module name!\nLike this: {module name}/{path to the parser.py file}"), 'parser_state':fields.selection([ ('default',_('Default')), ('def',_('Definition')), ('loc',_('Location')), ],'State of Parser', select=True), 'in_format': fields.selection(_get_in_mimetypes, 'Template Mime-type'), 'out_format':fields.many2one('report.mimetypes', 'Output Mime-type'), 'report_sxw_content': fields.function(_report_content, fnct_inv=_report_content_inv, method=True, type='binary', string='SXW content',), 'active':fields.boolean('Active', help='Disables the report if unchecked.'), 'report_wizard':fields.boolean('Report Wizard'), 'copies': fields.integer('Number of Copies'), 'fallback_false':fields.boolean('Disable Format Fallback'), 'xml_id': fields.function(_get_xml_id, type='char', size=128, string="XML ID", method=True, help="ID of the report defined in xml file"), 'extras': fields.function(_get_extras, method=True, type='char', size='256', string='Extra options'), 'deferred':fields.selection([ ('off',_('Off')), ('adaptive',_('Adaptive')), ],'Deferred', help='Deferred (aka Batch) reporting, for reporting on large amount of data.'), 'deferred_limit': fields.integer('Deferred Records Limit', help='Records limit at which you are invited to start the deferred process.'), 'replace_report_id':fields.many2one('ir.actions.report.xml', 'Replace Report'), 'wizard_id':fields.many2one('ir.actions.act_window', 'Wizard Action'),
('file','File'), ('parser','Parser'), ],'Template source', select=True), 'parser_def': fields.text('Parser Definition'), 'parser_loc':fields.char('Parser location', size=128, help="Path to the parser location. Beginning of the path must be start with the module name!\nLike this: {module name}/{path to the parser.py file}"), 'parser_state':fields.selection([ ('default',_('Default')), ('def',_('Definition')), ('loc',_('Location')), ],'State of Parser', select=True), 'in_format': fields.selection(_get_in_mimetypes, 'Template Mime-type'), 'out_format':fields.many2one('report.mimetypes', 'Output Mime-type'), 'report_sxw_content': fields.function(_report_content, fnct_inv=_report_content_inv, method=True, type='binary', string='SXW content',), 'active':fields.boolean('Active'), } def unlink(self, cr, uid, ids, context=None): #TODO: process before delete resource trans_obj = self.pool.get('ir.translation') trans_ids = trans_obj.search(cr, uid, [('type','=','report'),('res_id','in',ids)]) trans_obj.unlink(cr, uid, trans_ids) #################################### reports = self.read(cr, uid, ids, ['report_name','model']) for r in reports: ir_value_ids = self.pool.get('ir.values').search(cr, uid, [('name','=',r['report_name']), ('value','=','ir.actions.report.xml,%s' % r['id']), ('model','=',r['model']) ]) if ir_value_ids: