def _check_amount(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): if obj.voucher_id: if not (abs(obj.amount) == obj.voucher_id.amount): return False return True _constraints = [(_check_amount, 'The amount of the voucher must be the same amount as the one on the statement line', ['amount']),] _columns = { 'amount_reconciled': fields.function(_amount_reconciled,string='Amount reconciled', method=True, type='float'), 'voucher_id': fields.many2one('account.voucher', 'Payment'), }
def __init__(self, cr, pool): self._columns.update(self._columns_to_add) self._fields_names.update(self._fields_names_to_add) self._actions_to_eval.setdefault(self._name,{}) self._fields_names_to_eval.setdefault(self._name,{}) self._actions_to_eval[self._name].update(self._actions) self._fields_names_to_eval[self._name].update(self._fields_names) #method to retrieve many2many fields with custom format def _get_fields_names(self, cr, uid, ids, name, args, context=None): res = {} if not isinstance(name, list): name = [name] for obj in self.browse(cr, uid, ids, context=context): #for each field_names to read, retrieve their values res[obj.id] = {} for fname in name: #many2many browse_record field to map field_ids = obj[self._fields_names_to_eval[self._name][fname]] if isinstance(field_ids, browse_null)== True : continue if not isinstance(field_ids, list): field_ids = [field_ids] val = [] for item in field_ids: val.append([item.id,item.name_get()[0][1]]) res[obj.id].update({fname:val}) return res super(OpenbaseCore,self).__init__(cr,pool) #then, add m2m openbase.tag to model # src = self._name.replace('.','_') # target = 'tag' # self._columns.update({'tags':fields.many2many('openbase.tag', '%s_%s_rel'%(src,target), src+'_id', target+'_id', 'Tags', # context={'default_model':self._name}, domain=[('model','=',self._name)])}) #add _field_names to fields definition of the model for f in self._fields_names.keys(): #force name of new field with '_names' suffix self._columns.update({f:fields.function(_get_fields_names, type='char',method=True, multi='field_names',store=False)})
class fuel_qty_line(osv.osv): """ To manage fuel quantity lines """ _name = "fuel.qty.line" _description = 'Fuel Quantity Details' def _amount_line(self, cr, uid, ids, field_name, arg, context=None): """ Finds the value of fuel in the quantity line. @param field_name: list contains name of fields that call this method @param arg: extra argument @return: Dictionary of values """ res = {} if context is None: context = {} for line in self.browse(cr, uid, ids, context=context): price = line.price_unit * line.product_qty or 0.0 res[line.id] = price return res def _spent_qty_line(self, cr, uid, ids, field_name, arg, context=None): ''' Compute the spent quantity. @return Dictionary of value ''' result = {} uom_obj = self.pool.get('product.uom') fleet_log_obj= self.pool.get('fleet.vehicle.log.fuel') for spent in self.browse(cr, uid, ids, context=context): result[spent.id] = 0 vehi_ids = fleet_log_obj.search(cr, uid, [('qty_line_id.id','=',spent.id)], context=context) for veh in fleet_log_obj.browse(cr, uid, vehi_ids, context=context): un_convert_unit = veh.product_uom.id convert_unit = spent.product_uom.id result[spent.id] += uom_obj._compute_qty(cr, uid, un_convert_unit, veh.liter, convert_unit) return result _columns = { 'vehicles_id': fields.many2one('fleet.vehicle', 'Car'), 'department_id': fields.many2one('hr.department', 'Department',), 'product_id': fields.many2one('product.product', 'Product', required=True), 'product_qty': fields.float('Quantity', required=True, digits=(16,2)), 'spent_qty':fields.function(_spent_qty_line, method=True, string='Spent Quantity'), 'product_uom': fields.many2one('product.uom', 'Product UOM', required=True), 'price_unit': fields.float('Unit Price', required=True, digits_compute=dp.get_precision('Account')), 'qty_id': fields.many2one('fuel.quantity', 'Fuel Quantity',ondelete='cascade'), 'name': fields.text('Note', size=256), 'price_subtotal': fields.function(_amount_line, method=True, string='Sub Total',digits_compute=dp.get_precision('Account')), 'month': fields.related('qty_id','month', type='selection',selection=[(str(n),str(n)) for n in range(1,13)],string ='Month',readonly=True, store=True), 'year': fields.related('qty_id','year', type='char',string ='Year',readonly=True, store=True), 'type_plan': fields.related('qty_id','type_plan', type='selection',selection=[('constant_fuel','Constant Fuel'),('mission_extra','Mission Extra')],string ='Plan type',readonly=True, store=True), 'place_id':fields.many2one('vehicle.place', 'Place',), 'company_id': fields.many2one('res.company','Company'), 'share': fields.boolean('Share'), } _defaults = { 'share': False, }
res={} for expense in self.browse(cr, uid, ids): analytic_lines = [] for line in expense.line_ids: try: if line.deferred_line_ids: analytic_lines.extend([x.id for x in line.deferred_line_ids]) except orm.except_orm, e: if e.name != 'AccessError': raise e res[expense.id] = analytic_lines return res _columns={ 'deferred_analytics_id': fields.many2one('account.analytic.plan.instance', 'Deferred Analytic Distribution'), 'deferred_line_ids': fields.function(_get_deferred_analytic_lines, type='one2many', obj='account.analytic.line', method=True, string='Analytic Lines'), } def delete_analytic_lines(self, cr, uid, ids, context=None): analytic_line_obj = self.pool.get('account.analytic.line') for expense in self.browse(cr, uid, ids): for line in expense.deferred_line_ids: line.unlink() return True def create_analytic_lines(self, cr, uid, ids, context=None): analytic_line_obj = self.pool.get('account.analytic.line') journal_obj = self.pool.get('account.journal') expense_line_obj = self.pool.get('hr.expense.line') for expense in self.browse(cr, uid, ids): journal_ids = journal_obj.search(cr, uid, [
('except_picking', 'Shipping Exception'), ('except_invoice', 'Invoice Exception'), ('done', 'Done'), ('cancel', 'Cancelled') ] _columns = { 'state' : fields.selection(STATE_SELECTION, 'State', readonly=True, help="The state of the purchase order or the quotation request. A quotation is a purchase order in a 'Draft' state. Then the order has to be confirmed by the user, the state switch to 'Confirmed'. Then the supplier must confirm the order to change the state to 'Approved'. When the purchase order is paid and received, the state becomes 'Done'. If a cancel action occurs in the invoice or in the reception of goods, the state becomes in exception.", select=True), 'budget_info_ids_po' : fields.many2many('budget.info.po', 'budget_info_rel_po', 'order_id', 'budget_info_id_po', 'Budget Line', readonly=True), 'budget_note' : fields.text('Budget Note'), 'budget_note_line_ids' : fields.one2many('budget.note.po', 'order_id', 'Budget Note History'), #######DICOUNT##################### 'amount_untaxed': fields.function(_amount_all, method=True, digits_compute= dp.get_precision('Purchase Price'), string='Untaxed Amount', store={ 'purchase.order.line': (_get_order, None, 10), 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['discount_total'], 20), }, multi="sums", help="The amount without tax"), 'amount_tax': fields.function(_amount_all, method=True, digits_compute= dp.get_precision('Purchase Price'), string='Taxes', store={ 'purchase.order.line': (_get_order, None, 10), 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['discount_total'], 20), }, multi="sums", help="The tax amount"), 'amount_total': fields.function(_amount_all, method=True, digits_compute= dp.get_precision('Purchase Price'), string='Total', store={ 'purchase.order.line': (_get_order, None, 10), 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['discount_total'], 20), }, multi="sums",help="The total amount"), 'discount_total': fields.float('Discount Total(%)', digits=(16,2)), ################################### 'approve_status': fields.function(_get_approve_status, method=True, string='To be Approve By',type= 'char', size=64),
'CompleteMenuName':menu.complete_name, 'ActionHelp':menu.action.help, 'ModuleName':data_id.module, 'XmlId':data_id.name}, context=context)) res_mod_dic['doc_on_module'].append(self.title_help(cr,uid, mnames[data_id.module],data_id.module,context=context)) except KeyError, e: self.__logger.warning( 'Data not found for reference %s[%s:%s.%s]', data_id.model, data_id.res_id, data_id.model, data_id.name, exc_info=True) pass except Exception, e: self.__logger.warning('Unknown error while browsing %s[%s]', data_id.model, data_id.res_id, exc_info=True) pass res_mod_dic['doc_on_module']=list(set(res_mod_dic['doc_on_module'])) for key, value in res.iteritems(): for k, v in res[key].iteritems() : #TODO Make Generic or with regEx #Putting title on the begining. txt = "\n".join(sorted(v[:len(v)-2])) res[key][k] = "%s\n%s" % (v.pop(len(v)-2),txt) return res _columns={ 'doc_on_module': fields.function(_get_docs, method=True, string='Documentation', type='text', multi="meta", store=False), } module()
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()
#logger.notifyChannel('bank_reference',netsvc.LOG_DEBUG,'Using finnish domestic reference as a root for RF number') #if myCompany.country_id.code in ('FI', 'RF_fi', 'fi'): # cs = 98 - int(prefix) % 97 # if cs < 10: # res = "RF0%s%s" % (cs,prefix) # else: # res = "RF%s%s" % (cs,prefix) #cs = 98 - int(prefix) % 97 #if cs < 10: # res = "RF0%s%s" % (cs,prefix) #else: # res = "RF%s%s" % (cs,prefix) #self.write(cursor, user, ids, {'finref':res}) reslist[inv.id] = res #logger.notifyChannel('bank_reference',netsvc.LOG_DEBUG,'reslist: %s' % reslist) return reslist _columns = { 'bank_reference': fields.function(_reference, method=True, type='char',store=True, string='Bank reference'), 'finref': fields.char('Finnish Reference', required=False) } #_defaults = { # 'finref': lambda self,ids: get_ref_number(self, ids), #} account_invoice()
continue output = StringIO() # call the helper: bars = ''.join([c for c in invoice.pyafipws_barcode if c.isdigit()]) if not bars: bars = "00" pyi25.GenerarImagen(bars, output, extension="PNG") # get the result and encode it for openerp binary field: images[invoice.id] = output.getvalue().encode("base64") output.close() return images # add the computed columns: _columns.update({ 'pyafipws_barcode_img': fields.function( _get_pyafipws_barcode_img, type='binary', method=True, store=False), }) electronic_invoice() class invoice_wizard(osv.osv_memory): _name = 'pyafipws.invoice.wizard' _columns = { 'journal': fields.many2one('account.journal', 'Journal'), 'cbte_nro': fields.integer('number'), 'cae': fields.char('CAE', size=14, readonly=True, ), 'cae_due': fields.char('Vencimiento CAE', size=10, readonly=True, ), 'total': fields.float('Total', readonly=True, ), 'vat': fields.float('IVA', readonly=True, ),
class account_invoice(osv.osv): _name = "account.invoice" _inherit = "account.invoice" def invoice_validate(self, cr, uid, ids, context=None): res = super(account_invoice, self).invoice_validate(cr, uid, ids, context=context) context = {} account_move_line = self.pool.get('account.move.line') for invoice in self.browse(cr, uid, ids, context=context): for ar in invoice.outstanding_ar_ids: account_move_line.write(cr, uid, ar.id, {'is_used': True}, context={}) return res def action_cancel(self, cr, uid, ids, *args): r = super(account_invoice, self).action_cancel(cr, uid, ids, *args) context = {} account_move_line = self.pool.get('account.move.line') for invoice in self.browse(cr, uid, ids, context=context): for ar in invoice.outstanding_ar_ids: account_move_line.write(cr, uid, ar.id, {'is_used': False}, context={}) return r def _outstanding_debit(self, cr, uid, ids, field, arg, context=None): results = {} for inv in self.browse(cr, uid, ids, context=context): results[inv.id] = 0.0 for ar in inv.outstanding_ar_ids: results[inv.id] += ar.debit return results def _outstanding_credit(self, cr, uid, ids, field, arg, context=None): results = {} for inv in self.browse(cr, uid, ids, context=context): results[inv.id] = 0.0 for ar in inv.outstanding_ar_ids: results[inv.id] += ar.credit return results def _net_total(self, cr, uid, ids, field, arg, context=None): results = {} # return harus berupa dictionary dengan key id session # contoh kalau 3 records: # { # 1 : 50.8, # 2 : 25.5, # 3 : 10.0 # } for inv in self.browse(cr, uid, ids, context=context): results[ inv. id] = inv.amount_total + inv.outstanding_debit - inv.outstanding_credit return results _columns = { 'outstanding_ar_ids': fields.many2many( 'account.move.line', # 'other.object.name' dengan siapa dia many2many 'invoice_aml', # 'relation object' 'invoice_id', # 'actual.object.id' in relation table 'aml_id', # 'other.object.id' in relation table 'Outstanding AR', # 'Field Name' required=False), 'outstanding_debit': fields.function(_outstanding_debit, string="Total AR Unpaid", type="float"), 'outstanding_credit': fields.function(_outstanding_credit, string="Total AR Paid", type="float"), 'net_total': fields.function(_net_total, string="Net Total", type="float") } def fill_ar(self, cr, uid, ids, context=None): aml_obj = self.pool.get('account.move.line') inv_obj = self.pool.get('account.invoice') # import pdb; pdb .set_trace() for inv in self.browse(cr, uid, ids, context=context): if inv.type == 'out_invoice': cr.execute("delete from invoice_aml where invoice_id=%d" % (inv.id)) cond = [ # ('is_used', '=', False ), '|', ('reconcile_id', '=', False), ('reconcile_partial_id', '!=', False), ('account_type', '=', 'receivable'), ('partner_id', '=', inv.partner_id.id) ] aml_ids = aml_obj.search(cr, uid, cond, context=context) if aml_ids: amls = aml_obj.browse(cr, uid, aml_ids, context=context) ar_lines = [aml.id for aml in amls] data = {'outstanding_ar_ids': [(6, 0, ar_lines)]} inv_obj.write(cr, uid, [inv.id], data, context=context) return True def create(self, cr, uid, vals, context=None): id = super(account_invoice, self).create(cr, uid, vals, context=context) inv = self.browse(cr, uid, id, context=context) if inv.type == 'out_invoice': #sales self.fill_ar(cr, uid, [id], context=context) return id
class report_xml(osv.osv): def _report_content(self, cursor, user, ids, name, arg, context=None): res = {} for report in self.browse(cursor, user, ids, context=context): data = report[name + '_data'] if not data and report[name[:-8]]: fp = None try: fp = tools.file_open(report[name[:-8]], mode='rb') data = fp.read() except: data = False finally: if fp: fp.close() res[report.id] = data return res def _report_content_inv(self, cursor, user, id, name, value, arg, context=None): self.write(cursor, user, id, {name + '_data': value}, context=context) def _report_sxw(self, cursor, user, ids, name, arg, context=None): res = {} for report in self.browse(cursor, user, ids, context=context): if report.report_rml: res[report.id] = report.report_rml.replace('.rml', '.sxw') else: res[report.id] = False return res def register_all(self, cr): """Report registration handler that may be overridden by subclasses to add their own kinds of report services. Loads all reports with no manual loaders (auto==True) and registers the appropriate services to implement them. """ opj = os.path.join cr.execute("SELECT * FROM ir_act_report_xml WHERE auto=%s ORDER BY id", (True, )) result = cr.dictfetchall() svcs = netsvc.Service._services for r in result: if svcs.has_key('report.' + r['report_name']): continue if r['report_rml'] or r['report_rml_content_data']: report_sxw('report.' + r['report_name'], r['model'], opj('addons', r['report_rml'] or '/'), header=r['header']) if r['report_xsl']: report_rml('report.' + r['report_name'], r['model'], opj('addons', r['report_xml']), r['report_xsl'] and opj('addons', r['report_xsl'])) _name = 'ir.actions.report.xml' _inherit = 'ir.actions.actions' _table = 'ir_act_report_xml' _sequence = 'ir_actions_id_seq' _order = 'name' _columns = { 'name': fields.char('Name', size=64, required=True, translate=True), 'model': fields.char('Object', size=64, required=True), 'type': fields.char('Action Type', size=32, required=True), 'report_name': fields.char('Service Name', size=64, required=True), 'usage': fields.char('Action Usage', size=32), 'report_type': fields.char( 'Report Type', size=32, required=True, help= "Report Type, e.g. pdf, html, raw, sxw, odt, html2html, mako2html, ..." ), 'groups_id': fields.many2many('res.groups', 'res_groups_report_rel', 'uid', 'gid', 'Groups'), 'multi': fields.boolean( 'On Multiple Doc.', help= "If set to true, the action will not be displayed on the right toolbar of a form view." ), 'attachment': fields.char( 'Save as Attachment Prefix', size=128, help= 'This is the filename of the attachment used to store the printing result. Keep empty to not save the printed reports. You can use a python expression with the object and time variables.' ), 'attachment_use': fields.boolean( 'Reload from Attachment', help= 'If you check this, then the second time the user prints with same attachment name, it returns the previous report.' ), 'auto': fields.boolean('Custom Python Parser'), 'header': fields.boolean('Add RML Header', help="Add or not the corporate RML header"), 'report_xsl': fields.char('XSL Path', size=256), 'report_xml': fields.char('XML Path', size=256, help=''), # Pending deprecation... to be replaced by report_file as this object will become the default report object (not so specific to RML anymore) 'report_rml': fields.char( 'Main Report File Path', size=256, help= "The path to the main report file (depending on Report Type) or NULL if the content is in another data field" ), # temporary related field as report_rml is pending deprecation - this field will replace report_rml after v6.0 'report_file': fields.related( 'report_rml', type="char", size=256, required=False, readonly=False, string='Report File', help= "The path to the main report file (depending on Report Type) or NULL if the content is in another field", store=True), 'report_sxw': fields.function(_report_sxw, type='char', string='SXW Path'), 'report_sxw_content_data': fields.binary('SXW Content'), 'report_rml_content_data': fields.binary('RML Content'), 'report_sxw_content': fields.function( _report_content, fnct_inv=_report_content_inv, type='binary', string='SXW Content', ), 'report_rml_content': fields.function(_report_content, fnct_inv=_report_content_inv, type='binary', string='RML Content'), } _defaults = { 'type': 'ir.actions.report.xml', 'multi': False, 'auto': True, 'header': True, 'report_sxw_content': False, 'report_type': 'pdf', 'attachment': False, }
class act_window(osv.osv): _name = 'ir.actions.act_window' _table = 'ir_act_window' _inherit = 'ir.actions.actions' _sequence = 'ir_actions_id_seq' _order = 'name' def _check_model(self, cr, uid, ids, context=None): for action in self.browse(cr, uid, ids, context): if not self.pool.get(action.res_model): return False if action.src_model and not self.pool.get(action.src_model): return False return True def _invalid_model_msg(self, cr, uid, ids, context=None): return _('Invalid model name in the action definition.') _constraints = [(_check_model, _invalid_model_msg, ['res_model', 'src_model'])] def _views_get_fnc(self, cr, uid, ids, name, arg, context=None): """Returns an ordered list of the specific view modes that should be enabled when displaying the result of this action, along with the ID of the specific view to use for each mode, if any were required. This function hides the logic of determining the precedence between the view_modes string, the view_ids o2m, and the view_id m2o that can be set on the action. :rtype: dict in the form { action_id: list of pairs (tuples) } :return: { action_id: [(view_id, view_mode), ...], ... }, where view_mode is one of the possible values for ir.ui.view.type and view_id is the ID of a specific view to use for this mode, or False for the default one. """ res = {} for act in self.browse(cr, uid, ids): res[act.id] = [(view.view_id.id, view.view_mode) for view in act.view_ids] view_ids_modes = [view.view_mode for view in act.view_ids] modes = act.view_mode.split(',') missing_modes = [ mode for mode in modes if mode not in view_ids_modes ] if missing_modes: if act.view_id and act.view_id.type in missing_modes: # reorder missing modes to put view_id first if present missing_modes.remove(act.view_id.type) res[act.id].append((act.view_id.id, act.view_id.type)) res[act.id].extend([(False, mode) for mode in missing_modes]) return res def _search_view(self, cr, uid, ids, name, arg, context=None): res = {} for act in self.browse(cr, uid, ids, context=context): field_get = self.pool.get(act.res_model).fields_view_get( cr, uid, act.search_view_id and act.search_view_id.id or False, 'search', context=context) res[act.id] = str(field_get) return res _columns = { 'name': fields.char('Action Name', size=64, translate=True), 'type': fields.char('Action Type', size=32, required=True), 'view_id': fields.many2one('ir.ui.view', 'View Ref.', ondelete='cascade'), 'domain': fields.char('Domain Value', size=250, help="Optional domain filtering of the destination data, as a Python expression"), 'context': fields.char('Context Value', size=250, required=True, help="Context dictionary as Python expression, empty by default (Default: {})"), 'res_id': fields.integer('Record ID', help="Database ID of record to open in form view, when ``view_mode`` is set to 'form' only"), 'res_model': fields.char('Destination Model', size=64, required=True, help="Model name of the object to open in the view window"), 'src_model': fields.char('Source Model', size=64, help="Optional model name of the objects on which this action should be visible"), 'target': fields.selection([('current','Current Window'),('new','New Window'),('inline','Inline Edit'),('inlineview','Inline View')], 'Target Window'), 'view_mode': fields.char('View Mode', size=250, required=True, help="Comma-separated list of allowed view modes, such as 'form', 'tree', 'calendar', etc. (Default: tree,form)"), 'view_type': fields.selection((('tree','Tree'),('form','Form')), string='View Type', required=True, help="View type: Tree type to use for the tree view, set to 'tree' for a hierarchical tree view, or 'form' for a regular list view"), 'usage': fields.char('Action Usage', size=32, help="Used to filter menu and home actions from the user form."), 'view_ids': fields.one2many('ir.actions.act_window.view', 'act_window_id', 'Views'), 'views': fields.function(_views_get_fnc, type='binary', string='Views', help="This function field computes the ordered list of views that should be enabled " \ "when displaying the result of an action, federating view mode, views and " \ "reference view. The result is returned as an ordered list of pairs (view_id,view_mode)."), 'limit': fields.integer('Limit', help='Default limit for the list view'), 'auto_refresh': fields.integer('Auto-Refresh', help='Add an auto-refresh on the view'), 'groups_id': fields.many2many('res.groups', 'ir_act_window_group_rel', 'act_id', 'gid', 'Groups'), 'search_view_id': fields.many2one('ir.ui.view', 'Search View Ref.'), 'filter': fields.boolean('Filter'), 'auto_search':fields.boolean('Auto Search'), 'search_view' : fields.function(_search_view, type='text', string='Search View'), 'multi': fields.boolean('Action on Multiple Doc.', help="If set to true, the action will not be displayed on the right toolbar of a form view"), } _defaults = { 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'tree,form', 'context': '{}', 'limit': 80, 'target': 'current', 'auto_refresh': 0, 'auto_search': True, 'multi': False, } def for_xml_id(self, cr, uid, module, xml_id, context=None): """ Returns the act_window object created for the provided xml_id :param module: the module the act_window originates in :param xml_id: the namespace-less id of the action (the @id attribute from the XML file) :return: A read() view of the ir.actions.act_window """ dataobj = self.pool.get('ir.model.data') data_id = dataobj._get_id(cr, SUPERUSER_ID, module, xml_id) res_id = dataobj.browse(cr, uid, data_id, context).res_id return self.read(cr, uid, res_id, [], context)
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', } product_listing() class product_listing(ebayerp_osv.ebayerp_osv): _name = 'product.listing' _inherit = 'product.listing' product_listing()
res = {} try: duration = 0 for sheet in self.browse(cr, uid, ids, context=context): for overtime in sheet.overtime_ids: duration += overtime.duration log.info("duration=%s" % duration) res[sheet.id] = duration except Exception, e: raise osv.except_osv(_('Variable Error !'), _('Variable Error: %s') % (e)) return res _columns = { 'overtime_ids': fields.one2many('hr_timesheet_sheet.sheet.overtime', 'sheet_id', 'Overtime lines', readonly=False), 'total_overtimes': fields.function(_get_total_duration, method=True, store=True, type='float', size=64, string='Total Duration', readonly=True), } __defaults = { #'source': 'manual', } hr_timesheet_sheet() class hr_timesheet_sheet_sheet_overtime(osv.osv): _name = "hr_timesheet_sheet.sheet.overtime" _description = "Overtimes" _order='date' _columns = { 'sheet_id': fields.many2one('hr_timesheet_sheet.sheet', 'Sheet', required=True, readonly=True, select="1"),
class jmdsaleorder(osv.Model): _inherit = "sale.order" def create(self, cr, uid, vals, context=None): now = datetime.now() cur_month = now.strftime("%m") cur_year = now.strftime("%y") partner_id = vals.get('partner_id') partner_object = self.pool.get("res.partner") partner_ref = "" max_id = "01" for i in partner_object.browse(cr, uid, [partner_id]): partner_ref = i.referencia #Buscando la ultima cotización del mes for j in self.browse(cr, uid, self.search(cr, uid, [(1, "=", 1)])): if j.name[-4:-2] == cur_month: try: intval = int(j.name[-2:]) intmax = int(max_id) if intval >= intmax: intmax = intval + 1 max_id = str(intmax) if intmax < 10: max_id = "0" + str(intmax) except ValueError: print("Warning wrong quotation code ") if vals.get('name', '/') == '/': vals['name'] = partner_ref + "-" + cur_year + cur_month + \ max_id or '/' return super(jmdsaleorder, self).create(cr, uid, vals, context=context) def addversion(self, cr, uid, ids, context=None): print("Im duplicating the sale order right now!!!") default = {} duplicatename = "" for i in self.browse(cr, uid, ids, context): duplicatename = i.name if duplicatename[-2:-1] == "V": versionno = int(duplicatename[-1:]) versionno = versionno + 1 duplicatename = duplicatename[:-2] + "V" + str(versionno) else: duplicatename = duplicatename + "V1" for i in self.browse( cr, uid, self.search(cr, uid, [('name', '=', duplicatename)]), context): duplicatename = duplicatename + (versionno + 1) print(("The duplicate name should be" + duplicatename)) default.update({ 'date_order': fields.date.context_today(self, cr, uid, context=context), 'state': 'draft', 'invoice_ids': [], 'date_confirm': False, 'name': duplicatename, }) self.copy(cr, uid, ids[0], default, context=None) def create_cuotas(self, cr, uid, ids, context=None): ret = {} obj_cuotas = self.pool.get("control_encuestas") for i in self.browse(cr, uid, ids, context): id_cuotas = obj_cuotas.create(cr, uid, { 'name': i.name, 'cotizacion_id': i.id }) self.write(cr, uid, [i.id], {'cuotas': id_cuotas}) return ret def request_budget(self, cr, uid, ids, context=None): ret = {} presupuesto_obj = self.pool.get("ea.presupuesto") for i in self.browse(cr, uid, ids, context): id_pres = presupuesto_obj.create(cr, uid, { 'name': i.name, 'claveproyecto': i.nombre_corto }) self.write(cr, uid, [i.id], {'budget': id_pres}) return ret def confirmar(self, cr, uid, ids, context=None): ret = {} for i in self.browse(cr, uid, ids, context): self.write(cr, uid, [i.id], {'confirmada': True}) return ret def facturar(self, cr, uid, ids, context=None): ret = {} for i in self.browse(cr, uid, ids, context): self.write(cr, uid, [i.id], {'a_facturar': True}) return ret def get_id(self, cr, uid, ids, fieldname, args, context=None): ret = {} for i in self.browse(cr, uid, ids, context): ret[i.id] = i.id return ret _columns = { 'tipo': fields.many2one("ea.tipoestudio", string="Tipo de Estudio", ondelete="set null"), 'nombre_corto': fields.char(string="Nombre Corto", size=40, translate=True), 'budget': fields.many2one("ea.presupuesto", string="Presupuesto", ondelete="set null"), 'current_id': fields.function(get_id, strgin="Id", type="integer"), 'metodologia': fields.text("Metodología"), 'objetivo': fields.text("Objetivo"), 'tipo_levantamiento': fields.char("Tipo de Levantamiento"), 'aprobada': fields.boolean("Aprobada por Control"), 'cuotas': fields.many2one("control_encuestas", string="Cuotas"), 'obj_img1': fields.binary("Imagen 1"), 'obj_img2': fields.binary("Imagen 2"), 'obj_img3': fields.binary("Imagen 3"), 'obj_img4': fields.binary("Imagen 4"), 'obj_img5': fields.binary("Imagen 5"), 'met_img1': fields.binary("Imagen 1"), 'met_name1': fields.char("Nombre Imagen 1"), 'met_img2': fields.binary("Imagen 2"), 'met_img3': fields.binary("Imagen 3"), 'met_img4': fields.binary("Imagen 4"), 'met_img5': fields.binary("Imagen 5"), 'odt': fields.many2one("ea.project_wizard", string="Orden de Trabajo"), 'creado': fields.related("odt", "creado", type="boolean", string="Proyecto Creado", readonly=True), 'resp': fields.text(string="Responsabilidades de la\ Agencia"), 'rpoy': fields.text("Responsables del Proyecto"), 'ent': fields.text("Entregables"), 'ttiempos': fields.text("Tiempos"), 'tmuestra': fields.text("Muestra"), 'tiempos': fields.one2many("ea.tiempos", 'odv', string="Tiempos"), 'muestra': fields.one2many("ea.muestra", 'odv', string="Muestra"), 'observaciones': fields.text("Observaciones"), 'director': fields.many2one("res.users", string="Director de Cuenta"), 'confirmada': fields.boolean("Confirmada"), 'a_facturar': fields.boolean("A Facturar"), 'propuesta_ids': fields.one2many("ea.propuesta", "order_id", string="Propuestas") } _defaults = { 'note': 'La cotización tiene validez de 90 días a partir de la fecha\ de elaboración. Los precios NO incluyen el 16% de I.V.A. Se facturará \ el 100% a la entrega de resultados. Cualquier cambio solicitado a la \ presente cotización, puede afectar los parámetros de costo mencionado. \ La cancelación una vez autorizado el estudio, puede incurrir en costos \ de cancelación.', 'resp': "<ol>\ <li>Elaboración del cuestionario en conjunto con el cliente.</li>\ <li>Adaptación y desarrollo del cuestionario.</li> \ <li>Trabajo de campo objetivo\ (con nuestro propio departamento de campo).</li>\ <li>Supervisión permanente.</li>\ <li>Procesamiento de la información (codificación, captura y tabulación).\ </li>\ <li>Los esquemas de codificación serán propuestos por la agencia. En caso\ de requerir los marcos de codificación previo a la entrega del reporte,\ favor de hacérmelo saber por escrito.</li>\ <li>Análisis estadísticos y mercadológicos.</li>\ <li>Elaboración del Reporte.</li>\ </ol>\ <i style='font-size: 13px;'>Nota: La agencia (Estadística Aplicada) se\ compromete a que la información obtenida en este proyecto quede a\ disposición del cliente en los siguientes medios: físicamente (durante 6\ meses) y en medios magnéticos (3 años).</i>", 'rpoy': " <p>El proyecto estará a cargo de las siguientes\ personas:<br>\ </p>\ <ol>\ <li>Diseño del Cuestionario, Planeación y Logística: Dr. Javier Alagón y\ Lucero López.</li>\ <li>Conducción del Trabajo de Campo: Sergio García.</li>\ <li>Análisis e Interpretación de Resultados: Dr. Javier Alagón y Lucero\ López.</li>\ <li>Comunicación permanente con clientes: Dr. Javier Alagón\ y Lucero López</li>\ <li>Responsable del proyecto: Lucero López.</li>\ </ol>", 'ent': '''<ol> <li>Tabulación de acuerdo con la estructura aprobada por el cliente cuando lo solicite (Por ejemplo: Excel o SPSS).</li> <li>Reporte de presentación (vía electrónica, FTP ó papel).</li> </ol> <p style='font-size:13px;'>Nota: Una vez entregados los resultados del estudio y/o llevada a cabo la presentación de los mismos, el cliente cuenta con un período de 30 días para hacer cualquier solicitud o tratamiento adicional de los datos. Cualquier requerimiento posterior a este lapso implicará su revisión en tiempo y costo.</p>''' }
class tcv_bundle(osv.osv): _name = 'tcv.bundle' _description = 'Modulo para administrar bundle' ##------------------------------------------------------------------------- ##------------------------------------------------------- _internal methods def _check_product(self, cr, uid, ids, context=None): ''' Check if the account voucher is duplicates fields to be compared: type partner_id amount journal_id reference payment_doc id (to avoid "self.id" error) returns True if not duplicated ''' res = True for item in self.browse(cr, uid, ids, context=context): product_id = item.product_id.id for line in item.line_ids: res = res and line.product_id.id == product_id return res def button_available(self, cr, uid, ids, context=None): vals = {'state': 'available'} res = self.write(cr, uid, ids, vals, context) return res def button_draft(self, cr, uid, ids, context=None): vals = {'state': 'draft'} res = self.write(cr, uid, ids, vals, context) return res ##--------------------------------------------------------- function fields def _compute_all(self, cr, uid, ids, field_name, arg, context=None): res = {} for item in self.browse(cr, uid, ids, context=context): data = {'pieces': 0, 'product_qty': 0.0} for lot in item.line_ids: data['pieces'] += 1 data['product_qty'] += lot.lot_factor res[item.id] = data return res def _compute_lot_list(self, cr, uid, ids, field_name, arg, context=None): res = {} for item in self.browse(cr, uid, ids, context=context): l = [] for line in item.line_ids: l.append(line.prod_lot_id.full_name) res[item.id] = {'lot_list': ', '.join(l)} return res _columns = { 'name': fields.char('Name', size=16, required=True, readonly=True, states={'draft': [('readonly', False)]}), 'company_id': fields.many2one('res.company', 'Company', required=True, readonly=True, states={'draft': [('readonly', False)]}, ondelete='restrict'), 'product_id': fields.many2one('product.product', 'Product', ondelete='restrict', required=True, readonly=True, states={'draft': [('readonly', False)]}), 'location_id': fields.many2one('stock.location', 'Location', readonly=False, ondelete='restrict'), 'pieces': fields.function(_compute_all, method=True, type='float', string='Pieces', multi='all', digits=0, readonly=True, states={'draft': [('readonly', False)]}), 'product_qty': fields.function(_compute_all, method=True, type='float', string='Quantity', digits_compute=dp.get_precision('Product UoM'), multi='all', readonly=True, states={'draft': [('readonly', False)]}), 'image': fields.binary("Image", help="Select image here", readonly=True, states={'draft': [('readonly', False)]}), 'weight_net': fields.float('Weight net', digits_compute=dp.get_precision('Account'), readonly=True, states={'draft': [('readonly', False)]}), 'date': fields.date('Date', required=True, readonly=True, states={'draft': [('readonly', False)]}, select=True), 'line_ids': fields.one2many('tcv.bundle.lines', 'bundle_id', 'Lots', readonly=True, states={'draft': [('readonly', False)]}), 'lot_list': fields.function(_compute_lot_list, method=True, type='char', string='lot list', size=256, store=False, multi='all', readonly=True, states={'draft': [('readonly', False)]}), 'reserved': fields.boolean('Reserved', required=True, readonly=False, states={'draft': [('readonly', False)]}), 'state': fields.selection([('draft', 'Draft'), ('available', 'Available')], string='Status', required=True, readonly=True), 'print': fields.boolean('Imprimir'), } _defaults = { 'name': lambda *a: '/', 'company_id': lambda self, cr, uid, c: self.pool.get('res.company'). _company_default_get(cr, uid, self._name, context=c), 'date': lambda *a: time.strftime('%Y-%m-%d'), 'state': lambda *a: 'draft', 'reserved': lambda *a: False, } _constraints = [(_check_product, 'Error ! Product mismatch.', ['product_id', 'parent.product_id'])] _sql_constraints = [ ('name_uniq', 'UNIQUE(name)', 'The name must be unique!'), ] ##------------------------------------------------------------------------- ##---------------------------------------------------------- public methods ##-------------------------------------------------------- buttons (object) ##------------------------------------------------------------ on_change... ##----------------------------------------------------- create write unlink def create(self, cr, uid, vals, context=None): if not vals.get('name') or vals.get('name') == '/': vals.update({ 'name': self.pool.get('ir.sequence').get(cr, uid, 'tcv.bundle') }) obj_bun = self.pool.get('tcv.bundle') if vals.get('bundle_id') and vals.get('product_id'): bun_brw = obj_bun.browse(cr, uid, vals['bundle_id'], context=context) if vals['product_id'] != bun_brw.product_id.id: raise osv.except_osv( _('Error!'), _('The bundle product and lot product must be the same.')) res = super(tcv_bundle, self).create(cr, uid, vals, context) return res def unlink(self, cr, uid, ids, context=None): for item in self.browse(cr, uid, ids, context={}): if item.state != 'draft': raise osv.except_osv( _('Error!'), _('Can\'t delete a bundle while state <> "Draft".')) elif item.reserved: raise osv.except_osv(_('Error!'), _('Can\'t delete a reserved bundle.')) res = super(tcv_bundle, self).unlink(cr, uid, ids, context) return res
class inmueble(osv.Model): _name = 'inmueble' _description = 'Inmueble gestionado por la inmobiliaria' def _check_form(self, cr, uid, ids): for clase in self.browse(cr, uid, ids): if (clase.price > 0): return True else: return False def _totalVisitas(self, cr, uid, ids, field, arg, context=None): res = {} # Recorre todas las clases y calcula el número de gymusers asociados for clase in self.browse(cr, uid, ids, context=context): res[clase.id] = len(clase.visita_ids) return res def on_change_class(self, cr, uid, ids, estado): warning = { 'title': 'Estado Incorrecto', 'message': 'El inmueble debe estar tasado' } if estado != "disponible": return {'value': {'name': 'ERROR'}, 'warning': warning} _columns = { 'id_inmueble': fields.integer('Id', size=9, required=True), 'name': fields.char('Direccion', size=60, required=True), 'postal_code': fields.integer('Codigo postal', size=5, required=True), 'price': fields.float('Precio', size=20, required=True), 'data': fields.text('Datos'), 'score': fields.float('Valoracion', size=20), 'totalvisitas': fields.function(_totalVisitas, type='integer', string='Total de visitas', store=True), 'visita_ids': fields.one2many('visita', 'inmueble_id', 'Visitas concertadas en el inmueble'), 'contrato_id': fields.many2one('contrato', 'Contrato'), 'state': fields.selection([('aceptado', 'Aceptado'), ('disponible', 'Disponible'), ('alquiladovendido', 'Alquilado o vendido')], 'Estado'), 'caracteristica_ids': fields.many2many('caracteristica', 'inmueble_caracteristica_rel', 'inmueble_id_inmueble', 'caracteristica_name', 'Caracteristicas'), 'propietario_id': fields.many2one('propietario', 'Propietario'), 'tasador_dni': fields.many2one('tasador', 'Tasador'), } _defaults = {'state': 'aceptado'} _constraints = [(_check_form, '¡ Errores en el formulario !', ['Precio'])] _sql_constraints = [('id_inmueble_uniq', 'unique (id_inmueble)', 'Id del inmueble ya registrado.')]
try: im = urllib2.urlopen(_url.encode("UTF-8")) if im.headers.maintype != "image": raise TypeError(im.headers.maintype) except Exception, e: path = os.path.join("report_aeroo", "config_pixmaps", "module_banner.png") image_file = file_data = tools.file_open(path, "rb") try: file_data = image_file.read() self._logo_image = base64.encodestring(file_data) return self._logo_image finally: image_file.close() else: self._logo_image = base64.encodestring(im.read()) return self._logo_image def _get_image_fn(self, cr, uid, ids, name, args, context=None): image = self._get_image(cr, uid, context) return dict.fromkeys(ids, image) # ok to use .fromkeys() as the image is same for all _columns = { "link": fields.char("Original developer", size=128, readonly=True), "config_logo": fields.function(_get_image_fn, string="Image", type="binary", method=True), } _defaults = {"config_logo": _get_image, "link": "http://www.alistek.com"} report_aeroo_installer()
class purchase_order(osv.osv): _name = "purchase.order" _inherit = "purchase.order" _description = "Purchase Order" def _amount_all(self, cr, uid, ids, field_name, arg, context=None): res = {} cur_obj = self.pool.get('res.currency') for order in self.browse(cr, uid, ids, context=context): res[order.id] = { 'amount_untaxed': 0.0, 'amount_tax': 0.0, 'amount_total': 0.0, 'add_disc_amt': 0.0, 'amount_net': 0.0, } val = val1 = val2 = 0.0 cur = order.pricelist_id.currency_id for line in order.order_line: val1 += line.price_subtotal line_price_unit = line.price_unit * ( 1 - (order.add_disc or 0.0) / 100.0) for c in self.pool.get('account.tax').compute_all( cr, uid, line.taxes_id, line_price_unit, line.product_qty, order.partner_address_id.id, line.product_id.id, order.partner_id)['taxes']: val += c.get('amount', 0.0) val2 = val1 * order.add_disc / 100 res[order.id]['add_disc_amt'] = cur_obj.round(cr, uid, cur, val2) res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur, val) res[order.id]['amount_untaxed'] = cur_obj.round(cr, uid, cur, val1) res[order.id]['amount_net'] = res[ order.id]['amount_untaxed'] - res[order.id]['add_disc_amt'] res[order.id]['amount_total'] = res[order.id]['amount_net'] + res[ order.id]['amount_tax'] return res _columns = { 'add_disc': fields.float('Additional Discount(%)', digits=(4, 2), states={ 'confirmed': [('readonly', True)], 'approved': [('readonly', True)], 'done': [('readonly', True)] }), 'add_disc_amt': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Sale Price'), string='Additional Disc Amt', store=True, multi='sums', help="The additional discount on untaxed amount."), 'amount_net': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Sale Price'), string='Net Amount', store=True, multi='sums', help="The amount after additional discount."), 'amount_untaxed': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Purchase Price'), string='Untaxed Amount', store=True, multi="sums", help="The amount without tax"), 'amount_tax': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Purchase Price'), string='Taxes', store=True, multi="sums", help="The tax amount"), 'amount_total': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Purchase Price'), string='Total', store=True, multi="sums", help="The total amount"), } _defaults = { 'add_disc': 0.0, } def action_invoice_create(self, cr, uid, ids, context=None): """Generates invoice for given ids of purchase orders and links that invoice ID to purchase order. :param ids: list of ids of purchase orders. :return: ID of created invoice. :rtype: int """ res = False journal_obj = self.pool.get('account.journal') inv_obj = self.pool.get('account.invoice') inv_line_obj = self.pool.get('account.invoice.line') fiscal_obj = self.pool.get('account.fiscal.position') property_obj = self.pool.get('ir.property') for order in self.browse(cr, uid, ids, context=context): pay_acc_id = order.partner_id.property_account_payable.id journal_ids = journal_obj.search( cr, uid, [('type', '=', 'purchase'), ('company_id', '=', order.company_id.id)], limit=1) if not journal_ids: raise osv.except_osv( _('Error !'), _('There is no purchase journal defined for this company: "%s" (id:%d)' ) % (order.company_id.name, order.company_id.id)) # generate invoice line correspond to PO line and link that to created invoice (inv_id) and PO line inv_lines = [] for po_line in order.order_line: if po_line.product_id: acc_id = po_line.product_id.product_tmpl_id.property_account_expense.id if not acc_id: acc_id = po_line.product_id.categ_id.property_account_expense_categ.id if not acc_id: raise osv.except_osv( _('Error !'), _('There is no expense account defined for this product: "%s" (id:%d)' ) % ( po_line.product_id.name, po_line.product_id.id, )) else: acc_id = property_obj.get( cr, uid, 'property_account_expense_categ', 'product.category').id fpos = order.fiscal_position or False acc_id = fiscal_obj.map_account(cr, uid, fpos, acc_id) inv_line_data = self._prepare_inv_line(cr, uid, acc_id, po_line, context=context) inv_line_id = inv_line_obj.create(cr, uid, inv_line_data, context=context) inv_lines.append(inv_line_id) po_line.write( { 'invoiced': True, 'invoice_lines': [(4, inv_line_id)] }, context=context) # get invoice data and create invoice inv_data = { 'name': order.partner_ref or order.name, 'reference': order.partner_ref or order.name, 'account_id': pay_acc_id, 'type': 'in_invoice', 'partner_id': order.partner_id.id, 'currency_id': order.pricelist_id.currency_id.id, 'address_invoice_id': order.partner_address_id.id, 'address_contact_id': order.partner_address_id.id, 'journal_id': len(journal_ids) and journal_ids[0] or False, 'invoice_line': [(6, 0, inv_lines)], 'origin': order.name, 'fiscal_position': order.fiscal_position.id or order.partner_id.property_account_position.id, 'payment_term': order.partner_id.property_payment_term and order.partner_id.property_payment_term.id or False, 'company_id': order.company_id.id, 'add_disc': order.add_disc or 0.0 } inv_id = inv_obj.create(cr, uid, inv_data, context=context) # compute the invoice inv_obj.button_compute(cr, uid, [inv_id], context=context, set_total=True) # Link this new invoice to related purchase order order.write({'invoice_ids': [(4, inv_id)]}, context=context) res = inv_id return res
_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""" ), ###function field that allows to know the ###mutli company currency implementation 'multi_company_currency_enable' : fields.function( _multi_curr_enable, method=True, type='boolean', string="Multi company currency", help='if this case is not check you can'+\ ' not set currency is active on two company' ), } ResCompany()
class account_analytic_account(osv.osv): _inherit = "account.analytic.account" def _ca_invoiced_calc(self, cr, uid, ids, name, arg, context=None): """Replace the original amount column by aa_amount_currency""" res = {} res_final = {} child_ids = tuple(self.search(cr, uid, [('parent_id', 'child_of', ids)], context=context)) for i in child_ids: res[i] = {} for n in [name]: res[i][n] = 0.0 if not child_ids: return res if child_ids: cr.execute("SELECT account_analytic_line.account_id, COALESCE(SUM(aa_amount_currency), 0.0) \ FROM account_analytic_line \ JOIN account_analytic_journal \ ON account_analytic_line.journal_id = account_analytic_journal.id \ WHERE account_analytic_line.account_id IN %s \ AND account_analytic_journal.type = 'sale' \ GROUP BY account_analytic_line.account_id", (child_ids,)) for account_id, sum in cr.fetchall(): res[account_id][name] = round(sum,2) data = self._compute_level_tree(cr, uid, ids, child_ids, res, [name], context=context) for i in data: res_final[i] = data[i][name] return res_final def _total_cost_calc(self, cr, uid, ids, name, arg, context=None): """Replace the original amount column by aa_amount_currency""" res = {} res_final = {} child_ids = tuple(self.search(cr, uid, [('parent_id', 'child_of', ids)], context=context)) for i in child_ids: res[i] = {} for n in [name]: res[i][n] = 0.0 if not child_ids: return res if child_ids: cr.execute("""SELECT account_analytic_line.account_id, COALESCE(SUM(aa_amount_currency), 0.0) \ FROM account_analytic_line \ JOIN account_analytic_journal \ ON account_analytic_line.journal_id = account_analytic_journal.id \ WHERE account_analytic_line.account_id IN %s \ AND amount<0 \ GROUP BY account_analytic_line.account_id""",(child_ids,)) for account_id, sum in cr.fetchall(): res[account_id][name] = round(sum,2) data = self._compute_level_tree(cr, uid, ids, child_ids, res, [name], context) for i in data: res_final[i] = data[i][name] return res_final _columns ={ 'ca_invoiced': fields.function(_ca_invoiced_calc, method=True, type='float', string='Invoiced Amount', help="Total customer invoiced amount for this account.", digits_compute=dp.get_precision('Account')), 'total_cost': fields.function(_total_cost_calc, method=True, type='float', string='Total Costs', help="Total of costs for this account. It includes real costs (from invoices) and indirect costs, like time spent on timesheets.", digits_compute=dp.get_precision('Account')), }
'host': fields.char('Host', size=64, required=True), 'port': fields.integer('Port', required=True), 'ooo_restart_cmd': fields.char('OOO restart command', size=256, \ help='Enter the shell command that will be executed to restart the LibreOffice/OpenOffice background process.'+ \ 'The command will be executed as the user of the OpenERP server process,'+ \ 'so you may need to prefix it with sudo and configure your sudoers file to have this command executed without password.'), 'state':fields.selection([ ('init','Init'), ('error','Error'), ('done','Done'), ], 'State', select=True, readonly=True), 'msg': fields.text('Message', readonly=True), 'error_details': fields.text('Error Details', readonly=True), 'link':fields.char('Installation Manual', size=128, help='Installation (Dependencies and Base system setup)', readonly=True), 'config_logo': fields.function(_get_image_fn, string='Image', type='binary', method=True), } def default_get(self, cr, uid, fields, context=None): config_obj = self.pool.get('oo.config') data = super(aeroo_config_installer, self).default_get(cr, uid, fields, context=context) ids = config_obj.search(cr, 1, [], context=context) if ids: res = config_obj.read(cr, 1, ids[0], context=context) del res['id'] data.update(res) return data def check(self, cr, uid, ids, context=None): config_obj = self.pool.get('oo.config')
class project_task(osv.Model): _inherit = "project.task" _name = "project.task" def _get_parent_category(self, cr, uid, ids, fields, args, context=None): context = context or {} res = {} for task in self.browse(cr, uid, ids): res[task.id] = task.gap_category_id and task.gap_category_id.parent_id.id or False return res def _task_to_update_after_category_change(self, cr, uid, ids, fields=None, arg=None, context=None): if type(ids) != type([]): ids = [ids] return self.pool.get('project.task').search(cr, uid, [('gap_category_id', 'in', ids)]) or [] def _get_child_tasks(self, cr, uid, ids, context=None): if type(ids) != type([]): ids = [ids] cr.execute("SELECT DISTINCT parent_id FROM project_task_parent_rel WHERE task_id in %s", (tuple(ids),)) task_ids = filter(None, map(lambda x:x[0], cr.fetchall())) or [] return task_ids def _get_child_hours(self, cr, uid, ids, field_names, args, context=None): result = {} for task in self.browse(cr, uid, ids, context=context): res = {} child_org_planned_hours = 0.0 child_planned_hours = 0.0 child_remaining_hours = 0.0 for child in task.child_ids: child_org_planned_hours += child.org_planned_hours child_planned_hours += child.planned_hours child_remaining_hours += child.remaining_hours res['child_org_planned_hours'] = child_org_planned_hours res['child_planned_hours'] = child_planned_hours res['child_remaining_hours'] = child_remaining_hours result[task.id] = res return result # def onchange_planned(self, cr, uid, ids, planned = 0.0, effective = 0.0): # return {'value':{'remaining_hours': planned - effective, 'org_planned_hours':planned}} _columns = { 'child_org_planned_hours': fields.function(_get_child_hours, string='Child Original Planned Hours', multi='child_hours', help="Computed using the sum of the child tasks Original planned hours.", store = { 'project.task': (_get_child_tasks, ['org_planned_hours','planned_hours'], 10), }), 'child_planned_hours': fields.function(_get_child_hours, string='Child Planned Hours', multi='child_hours', help="Computed using the sum of the child tasks planned hours.", store = { 'project.task': (_get_child_tasks, ['planned_hours','remaining_hours'], 10), }), 'child_remaining_hours': fields.function(_get_child_hours, string='Child Remaining Hours', multi='child_hours', help="Computed using the sum of the child tasks work done.", store = { 'project.task': (_get_child_tasks, ['planned_hours','remaining_hours'], 10), }), 'module_id': fields.many2one('openerp_module', 'Module', select=True), 'gap_category_id': fields.many2one('gap_analysis.functionality.category','Category', select=True), 'parent_category': fields.function(_get_parent_category, method=True, type='many2one', obj='gap_analysis.functionality.category', string='Parent Category', store={'project.task': (lambda self, cr, uid, ids, context: ids, ['gap_category_id'], 10), 'gap_analysis.functionality.category': (_task_to_update_after_category_change, ['parent_id'], 10),}), 'gap_line_id': fields.many2one('gap_analysis.line', 'Gap Analysis Line', select=True), 'code_gap': fields.char('Code in Gap', size=6), 'to_report': fields.boolean('Report to customer'), 'org_planned_hours': fields.float('Original Planned Hours', help='Original estimated time to do the task, usually set by the project manager when the task is in draft state.'), } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
regexStr = '^((https|http|ftp|rtsp|mms)?://)+' regex = re.compile(regexStr) print regex.match(url) return regex.match(url) def _get_image(self, cursor, user, ids, name, arg, context=None): image = {} res = self.read(cursor, user, ids, ['image_link']) image_link = res[0]['image_link'] if image_link: if not self.is_url(image_link): raise osv.except_osv('URL Error','URL should start with https|http|ftp|rtsp|mms.') req = Request(image_link) try: respose = urlopen(req) except IOError, e: if hasattr(e, 'reason'): raise osv.except_osv('URL Error','We failed to reach a server.' + 'Reason: ', e.reason) elif hasattr(e, 'code'): raise osv.except_osv('URL Error','The server couldn\'t fulfill the request.\n' + 'Error code: ', e.code) pic = base64.encodestring(respose.read()) for id in ids: image[id] = pic return image _columns = { 'image_link' : fields.char('Image Link', size=180), 'image' : fields.function(_get_image, method=True, string='Product Image', type='binary', store=False), } product_template_img()
class sale_order_line(osv.osv): _inherit = "sale.order.line" 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): res = super(sale_order_line, self).product_id_change(cr, uid, ids, pricelist, product, qty=qty, uom=uom, qty_uos=qty_uos, uos=uos, name=name, partner_id=partner_id, lang=lang, update_tax=update_tax, date_order=date_order, packaging=packaging, fiscal_position=fiscal_position, flag=flag) frm_cur = self.pool.get('res.users').browse( cr, uid, uid).company_id.currency_id.id to_cur = self.pool.get('res.partner').browse( cr, uid, partner_id).property_product_pricelist.currency_id.id if product: purchase_price = self.pool.get('product.product').browse( cr, uid, product).standard_price price = self.pool.get('res.currency').compute(cr, uid, frm_cur, to_cur, purchase_price, round=False) res['value'].update({'purchase_price': price}) return res def _product_margin(self, cr, uid, ids, field_name, arg, context=None): res = {} for line in self.browse(cr, uid, ids, context=context): res[line.id] = 0 if line.product_id: if line.purchase_price: res[line.id] = round( (line.price_unit * line.product_uos_qty * (100.0 - line.discount) / 100.0) - (line.purchase_price * line.product_uos_qty), 2) else: res[line.id] = round( (line.price_unit * line.product_uos_qty * (100.0 - line.discount) / 100.0) - (line.product_id.standard_price * line.product_uos_qty), 2) return res _columns = { 'margin': fields.function(_product_margin, method=True, string='Margin', store=True), 'purchase_price': fields.float('Cost Price', digits=(16, 2)) }
_columns = { 'name': fields.char("Name", size=128, readonly=True, required=True, select=True), 'category_id': fields.many2one('ir.module.category', 'Category', readonly=True, select=True), 'shortdesc': fields.char('Short Description', size=256, readonly=True, translate=True), 'description': fields.text("Description", readonly=True, translate=True), 'author': fields.char("Author", size=128, readonly=True), 'maintainer': fields.char('Maintainer', size=128, readonly=True), 'contributors': fields.text('Contributors', readonly=True), 'website': fields.char("Website", size=256, readonly=True), # attention: Incorrect field names !! # installed_version 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'),
class account_invoice(osv.Model): _inherit = 'account.invoice' def my_company(self, cr, uid, context=None): #TODO : Multi company... return self.pool.get('res.company').browse(cr, uid, 1) def _foreign_partner_check(self, cr, uid, ids, field, value, context=None): res = {} cc = self.my_company(cr, uid).partner_id.country_id.id for p in self.browse(cr, uid, ids): res[p. id] = p.partner_id.country_id.id and p.partner_id.country_id.id or False return res def _second_currency_value(self, cr, uid, ids, name, val, context=None): res = {} #odmah na HRK. id=30 sc = self.pool.get('res.currency').browse(cr, uid, 30) for inv in self.browse(cr, uid, ids): res[inv.id] = { 'second_rate': sc.rate, #'second_rdate':sc.date, 'second_value': inv.amount_total / sc.rate } return res _columns = { #'second_curr':fields.boolean(_foreign_partner_check, type="boolean", string="Foreign partner", method=True, store=True), 'second_curr': fields.boolean('EUR'), 'second_value': fields.function(_second_currency_value, type="float", string="Iznos u EUR", method=True, multi="2nd"), 'second_rate': fields.function(_second_currency_value, type="float", digits=(12, 6), string="Tečaj", method=True, multi="2nd"), } def button_reverse(self, cr, uid, ids, context=None): reverse = self.pool.get('invoice.reverse.calc').create( cr, uid, {'invoice_id': ids[0]}) view_ref = self.pool.get('ir.model.data').get_object_reference( cr, uid, 'account_2nd_currency', 'invoice_reverse_calc_wizard') view_id = view_ref and view_ref[1] or False, return { 'type': 'ir.actions.act_window', 'name': 'Reverse calculation', 'res_model': 'invoice.reverse.calc', 'res_id': reverse, 'view_type': 'form', 'view_mode': 'form', 'view_id': view_id, 'target': 'new', 'nodestroy': False, }
#=========================================================================== 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 account_fstr_category(osv.osv): _name = "account_fstr.category" _description = "Financial Statement template category" _order = "sequence, id" def __compute(self, cr, uid, ids, field_names, arg=None, context=None, query='', query_params=()): res = {} for category_obj in self.browse(cr, uid, ids, context=context): res.update({ category_obj.id: self.__compute_balance_for_caregory(cr, uid, category_obj, context=context) }) return res def __compute_balance_for_caregory(self, cr, uid, category_obj, context={}): result = 0 if category_obj.state == 'normal': for account_obj in category_obj.account_ids: result += account_obj.balance else: for child_category_obj in category_obj.child_id: result += self.__compute_balance_for_caregory( cr, uid, child_category_obj, context=context) return result def _get_progenitor_id(self, cr, uid, ids, field_names, arg=None, context={}): res = {} for category_obj in self.browse(cr, uid, ids, context=context): res.update({ category_obj.id: self._get_progenitor_id_in_recurse(cr, uid, category_obj, context=context) }) return res def _get_progenitor_id_in_recurse(self, cr, uid, category_obj, context={}): result = None if not (category_obj.parent_id and category_obj.parent_id.id): result = category_obj.id else: result = self._get_progenitor_id_in_recurse(cr, uid, category_obj.parent_id, context=context) return result def _get_childs(self, cr, uid, ids, context={}): return self.search(cr, uid, [('id', 'child_of', ids)], context=context) _columns = { 'name': fields.char( 'Category Title name', size=128, required=True, select=True, ), 'digits_round': fields.integer('Digits round', required=True), 'company_id': fields.many2one( 'res.company', 'Company', ondelete='set null', ), 'name_end': fields.char( 'Category End/Total name', size=128, ), 'display_total': fields.boolean('Display End/Total'), 'parent_id': fields.many2one( 'account_fstr.category', 'Parent node', ondelete='cascade', select=True, ), 'sequence': fields.integer('Sequence'), 'consolidate_total': fields.boolean( 'Consolidate total', help= "Selecting Consolidate total will print this category total as a single summed figure and will not list out each individual account" ), 'display_heading': fields.boolean('Display title'), 'bold_title': fields.boolean('Bold'), 'italic_title': fields.boolean('Italic'), 'underline_title': fields.boolean('Unnderline'), 'bold_end': fields.boolean('Bold'), 'italic_end': fields.boolean('Italic'), 'underline_end': fields.boolean('Unnderline'), 'inversed_sign': fields.boolean('Inversed sign'), 'child_id': fields.one2many( 'account_fstr.category', 'parent_id', 'Consolidated Children', select=True, ), 'account_ids': fields.many2many( 'account.account', 'account_fstr_category_account', 'account_id', 'category_id', 'Accounts', select=True, ), 'indent_title': fields.integer('Indent Title, (pt)'), 'indent_end': fields.integer('Indent End, (pt)'), 'top_spacing_title': fields.integer('Top spacing Title, (pt)'), 'top_spacing_end': fields.integer('Top spacing End, (pt)'), 'bottom_spacing_title': fields.integer('Bottom spacing Title, (pt)'), 'bottom_spacing_end': fields.integer('Bottom spacing End, (pt)'), 'state': fields.selection( [('view', 'View'), ('root', 'Root'), ('normal', 'Normal')], 'Type', select=True, ), 'balance': fields.function(__compute, digits_compute=dp.get_precision('Account'), method=True, string='Balance', store=False, type='float'), 'printable': fields.boolean( 'Printable', help="Select to allow category to display in print list"), 'progenitor_id': fields.function( _get_progenitor_id, method=True, string='Root', type='many2one', obj='account_fstr.category', store={'account_fstr.category': (_get_childs, ['parent_id'], 1)}, select=True, ), } _defaults = { 'state': 'normal', 'indent_title': 10, 'indent_end': 10, 'top_spacing_title': 0, 'digits_round': 0, } def print_template(self, cr, uid, ids, context={}): return account_fstr_wizard.account_fstr_wizard.print_template( cr, uid, ids, context={}) def _get_selected_accounts(self, cr, uid, progenitor_id, current_category_id, context={}): result = [] category_ids = self.search(cr, uid, [('progenitor_id', '=', progenitor_id)], context=context) for category_obj in self.browse(cr, uid, category_ids, context=context): if category_obj.id != current_category_id[0]: result.extend( [category.id for category in category_obj.account_ids]) return result def test_account_list(self, cr, uid, ids, progenitor_id, account_ids): warning = {} warning_account_names = [] current_account_ids = [] all_account_ids_for_template = self._get_selected_accounts( cr, uid, progenitor_id, ids) updated_account_ids = account_ids[0][2] for account_obj in self.pool.get('account.account').browse( cr, uid, updated_account_ids): if not (account_obj.id in all_account_ids_for_template): current_account_ids.append(account_obj.id) else: warning_account_names.append(account_obj.name) if warning_account_names: warning.update({ 'title': 'Alert', 'message': "Accounts %s already exist in current template" % (", ".join(warning_account_names)), }) return { 'value': { 'account_ids': current_account_ids, }, 'warning': warning } def view_exception_accounts(self, cr, uid, ids, context={}): account_list = self._get_selected_accounts(cr, uid, ids[0], ids, context=context) model_data_pool = self.pool.get('ir.model.data') model_data_ids = model_data_pool.search( cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'view_account_list')], context=context) resource_id = model_data_pool.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id'] return { 'name': "Exception Accounts", 'view_mode': 'tree,form', 'view_type': 'form', 'res_model': 'account.account', 'type': 'ir.actions.act_window', 'nodestroy': True, 'domain': [('type', '!=', 'view'), ('id', 'not in', account_list)] }
class sale_order_line(osv.osv): _inherit = "sale.order.line" def _categ_name_get(self, cr, uid, ids, prop, unknow_none, context=None): if not len(ids): return [] res = {} for line in self.browse(cr, uid, ids, context): name = line.product_id.categ_id.name res[line.id] = name return res _columns = { 'categ_id': fields.related('product_id', 'categ_id', type="many2one", relation="product.category", string='Category', readonly=True), 'categ_name': fields.function(_categ_name_get, type="char", string='Category'), 'code': fields.related('product_id', 'code', type="varchar", string='Code', readonly=True), 'product_pack_qty_helper': fields.float('Package #', digits_compute=dp.get_precision('Product UoS'), readonly=True, states={'draft': [('readonly', False)]}), } def product_pack_helper_change(self, cr, uid, ids, pack_helper_qty, content_qty, 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): _logger = logging.getLogger(__name__) qty = pack_helper_qty if packaging: qty = round(pack_helper_qty * content_qty, 0) qty_uos = round(pack_helper_qty * content_qty, 0) uos = uom res = 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) res['value']['qty'] = qty _logger.debug('FGF SO portal pack change %s', res) if res.get('warning') and res['warning'].get('message'): res['warning']['message'] = '' for line in self.browse(cr, uid, ids, context): if line.product_packaging: if res['value']['product_uom_qty'] > line.product_id.qty_available or res[ 'value'][ 'product_uom_qty'] > line.product_id.qty_available - line.product_id.outgoing_qty: pack_name = line.product_packaging.ul.name warning_msg = _("""The ordered quantity of %s %s (%s %s) is currently not available, our sales person will contact you to offer alternatives, please just save the data""") % \ (pack_helper_qty, pack_name, pack_helper_qty * content_qty, line.product_uos.name or line.product_uom.name ) res['warning']['message'] = warning_msg else: if pack_helper_qty > line.product_id.qty_available or pack_helper_qty > line.product_id.qty_available - line.product_id.outgoing_qty: pack_name = line.product_id.uom_id.name res['value']['product_uom_qty'] = qty warning_msg = _( 'The ordered quantity of %s %s is currently not available, our sales person will contact you to offer alternatives, please just save the data' ) % (pack_helper_qty, pack_name) res['warning']['message'] = warning_msg _logger.debug('FGF SO portal pack change warning delete %s', res) return res def product_id_change_portal(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): res = 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) if res.get('warning') and res['warning'].get('message'): res['warning']['message'] = '' return res
class multi_quote(osv.osv): """ class to add fields to purchase quote to check the products for more than one supplier """ _inherit = 'pur.quote' def _get_order(self, cr, uid, ids, context={}): """ To read the products of quotaion. @return: products ids """ line_ids = [line.id for line in self.pool.get('pq.products').browse(cr, uid, ids, context=context)] return line_ids def button_dummy(self, cr, uid, ids, context={}): """ Dummy function to recomputes the functional felids. @return: True """ super(multi_quote, self).button_dummy( cr, uid, ids, context=context) return True def _amount_all(self, cr, uid, ids, field_name, arg, context=None): """ Override _amount_all Function To Compute amount depend on value of the chosen field """ res = {} res = super(multi_quote, self)._amount_all( cr, uid, ids, field_name, arg,context=context) for quote in self.browse(cr, uid, ids, context=context): res[quote.id] = { 'amount_untaxed': 0.0, 'amount_tax': 0.0, 'amount_total': 0.0, } if quote.pq_pro_ids : if quote.pq_ir_ref.multi == 'multiple' : total_with_tax = total_without_taxes = 0.0 for line in quote.pq_pro_ids: if line.chosen == True : unit_price = line.price_subtotal total_without_taxes += unit_price tax_to_unit = 0.0 for tax in self.pool.get('account.tax').compute_all(cr, uid, quote.taxes_id, line.price_unit, line.product_qty)['taxes']: unit_tax= tax.get('amount', 0.0) tax_to_unit += unit_tax/line.product_qty total_with_tax += unit_tax line_tax = tax_to_unit + line.price_unit cr.execute("UPDATE pq_products SET price_unit_tax=%s, price_unit_total=%s where id = %s ", (tax_to_unit, line_tax, line.id)) res[quote.id] = { 'amount_tax':total_with_tax, 'amount_untaxed':total_without_taxes, 'amount_total':total_with_tax + total_without_taxes } else : total_with_tax = total_without_taxes = 0.0 for line in quote.pq_pro_ids: unit_price = line.price_subtotal total_without_taxes += unit_price tax_to_unit = 0.0 for tax in self.pool.get('account.tax').compute_all(cr, uid, quote.taxes_id, line.price_unit, line.product_qty)['taxes']: unit_tax= tax.get('amount', 0.0) tax_to_unit += unit_tax/line.product_qty total_with_tax += unit_tax line_tax = tax_to_unit + line.price_unit cr.execute("UPDATE pq_products SET price_unit_tax=%s, price_unit_total=%s where id = %s ", (tax_to_unit, line_tax, line.id)) res[quote.id] = { 'amount_tax':total_with_tax, 'amount_untaxed':total_without_taxes, 'amount_total':total_with_tax + total_without_taxes } return res _columns = { 'multi_purchase_total': fields.float('Total For Multi Purchase'), 'amount_untaxed': fields.function(_amount_all, method=True, string='Untaxed Amount', store={ 'pur.quote': (lambda self, cr, uid, ids, c={}: ids, ['pq_pro_ids', 'taxes_id'], 10), 'pq.products': (_get_order, ['price_unit','product_qty'], 10), }, multi="sums", help="The amount without tax"), 'amount_tax': fields.function(_amount_all, method=True, string='Taxes', store={ 'pur.quote': (lambda self, cr, uid, ids, c={}: ids, ['pq_pro_ids', 'taxes_id'], 10), 'pq.products': (_get_order, ['price_unit','product_qty'], 10), }, multi="sums", help="The tax amount"), 'amount_total': fields.function(_amount_all, method=True, string='Total', store={ 'pur.quote': (lambda self, cr, uid, ids, c={}: ids, ['pq_pro_ids', 'taxes_id'], 10), 'pq.products': (_get_order, ['price_unit','product_qty'], 10), }, multi="sums"), } def confirmed(self, cr, uid, ids, context=None): """ Inhertited to add the check of multi suppliers, product just in one quote and must select product in the quote """ # product just in one quote quote = self.browse(cr,uid,ids)[0] requisition = self.pool.get('ireq.m').browse(cr, uid, quote.pq_ir_ref.id) if requisition.multi in ['multiple']: quotations = self.pool.get('pur.quote').search(cr, uid, [('pq_ir_ref','=',requisition.id)]) for test_quote in self.pool.get('pur.quote').browse(cr, uid, quotations): name1='' name2='' if test_quote.id != quote.id : for product in quote.pq_pro_ids : if product.chosen : name1 = product.name count = 0 for quots in test_quote.pq_pro_ids : if quots.chosen and test_quote.state not in ['cancel']: name2=quots.name if name1==name2: count += 1 if count != 0: raise osv.except_osv(('Product is already chosen !'), ('The Product %s must be chosen just ones ...')%(name1,)) # must select product multi_po = requisition.multi for quotes_ in self.browse(cr, uid, ids): count=0 if multi_po in ['multiple']: for product in quotes_.pq_pro_ids : if product.chosen: count += 1 if count == 0: raise osv.except_osv(('No product is chosen !'), ('You must choose products from this quote first then confirm it or cancel it ...')) super(multi_quote, self).confirmed(cr, uid, ids) def cancel(self, cr, uid, ids, context=None): """ To modify the utomatic cancelling """ #TODO chech if this functiion is needed (when cancel the last one mack the requisition move ) super(multi_quote, self).cancel(cr, uid, ids, context) multi_po = self.browse(cr, uid, ids)[0].pq_ir_ref.multi if multi_po in ['multiple']: qoute_obj = self.browse(cr, uid, ids)[0] requisition = self.pool.get('ireq.m').browse(cr, uid, qoute_obj.pq_ir_ref.id) requisition_qoute = self.pool.get('pur.quote').search(cr, uid, [('pq_ir_ref','=', requisition.id)]) count1=0 count2=0 for qoute in self.pool.get('pur.quote').browse(cr, uid, requisition_qoute): count1 += 1 if qoute.state in ['done','cancel']: count2 += 1 if count1 == count2 : notes = self.pool.get('ireq.m').browse(cr, uid, qoute.pq_ir_ref.id).notes or '' self.pool.get('ireq.m').write(cr, uid, qoute.pq_ir_ref.id, {'state':'wait_confirmed','notes':notes}) def done(self,cr, uid, ids, context=None): ########### product just in one quote record = self.browse(cr, uid, ids)[0] req = self.pool.get('ireq.m').browse(cr, uid, record.pq_ir_ref.id) internal_products = self.pool.get('ireq.products') if not req.multi in ['multiple']: super(multi_quote, self).done(cr, uid, ids, context) else: all_qoutes = self.pool.get('pur.quote').search(cr, uid, [('pq_ir_ref','=',req.id)]) for product in self.pool.get('pur.quote').browse(cr, uid, all_qoutes): name1='' name2='' if product.id != record.id : for pro in record.pq_pro_ids : if pro.chosen : name1 = pro.name count = 0 for quots in product.pq_pro_ids : if quots.chosen and record.state not in ['cancel']: name2=quots.name if name1==name2: count += 1 if count != 0: raise osv.except_osv(('Product is already chosen !'), ('The Product %s must be chosen just ones ...')%(name1,)) self.write(cr, uid, ids, {'state':'done'}) # For updating the internal requestion products prices quote = self.browse(cr, uid, ids)[0] for product in quote.pq_pro_ids: if product.req_product: internal_products_ids = product.req_product.id else: internal_products_ids = internal_products.search(cr, uid, [('pr_rq_id', '=', quote.pq_ir_ref.id), ('product_id', '=', product.product_id.id)]) internal_products_ids = internal_products.search(cr, uid, [('pr_rq_id', '=', quote.pq_ir_ref.id), ('product_id', '=', product.product_id.id)]) internal_products.write(cr, uid, internal_products_ids, {'price_unit': product.price_unit }) multi_po=self.browse(cr,uid,ids)[0].pq_ir_ref.multi #TODO check when to close the quote state all_qoutes = self.pool.get('pur.quote').search(cr, uid, [('pq_ir_ref','=',req.id)]) count1=0 count2=0 for product in self.pool.get('pur.quote').browse(cr, uid, all_qoutes): count1 += 1 if product.state in ['done','cancel']: count2 += 1 if count1 == count2 : self.pool.get('ireq.m').write(cr, uid, product.pq_ir_ref.id, {'state':'wait_confirmed'}) return True def make_purchase_order(self,cr, uid, ids, context=None): purchase_line_obj = self.pool.get('purchase.order.line') or_id = super(multi_quote, self).make_purchase_order(cr, uid, ids, context=context) for quote in self.browse(cr, uid, ids): if quote.pq_ir_ref.multi in ['multiple']: for one_quote in quote.pq_ir_ref.q_ids: if one_quote.state == 'done': for product in one_quote.pq_pro_ids: if not product.chosen: order_line = purchase_line_obj.search(cr, uid, [('quote_product','=', product.id)]) purchase_line_obj.unlink(cr, uid, order_line) return or_id
class product_product(osv.osv): _inherit = "product.product" def _product_available(self, cr, uid, ids, field_names=None, arg=False, context=None): """ Finds the incoming and outgoing quantity of product. @return: Dictionary of values """ warehouse_obj = self.pool.get('stock.warehouse') warehouses = warehouse_obj.search(cr, uid, []) depot1 = warehouses[0] depot2 = warehouses[1] if not field_names: field_names = [] if context is None: context = {} res = {} for id in ids: res[id] = {}.fromkeys(field_names, 0.0) for f in field_names: c = context.copy() if f == 'qty_available': c.update({'states': ('done', ), 'what': ('in', 'out')}) if f == 'virtual_available': c.update({ 'states': ('confirmed', 'waiting', 'assigned', 'done'), 'what': ('in', 'out') }) if f == 'incoming_qty': c.update({ 'states': ('confirmed', 'waiting', 'assigned'), 'what': ('in', ) }) if f == 'outgoing_qty': c.update({ 'states': ('confirmed', 'waiting', 'assigned'), 'what': ('out', ) }) if f == 'stock_depot1': c.update({ 'states': ('confirmed', 'waiting', 'assigned', 'done'), 'what': ('in', 'out'), 'warehouse': depot1 }) if f == 'stock_depot2': c.update({ 'states': ('confirmed', 'waiting', 'assigned', 'done'), 'what': ('in', 'out'), 'warehouse': depot2 }) stock = self.get_product_available(cr, uid, ids, context=c) for id in ids: res[id][f] = stock.get(id, 0.0) return res _columns = { 'pub_id': fields.many2one('pub.analysis'), 'stock_depot1': fields.function(_product_available, method=True, type='float', string='Depot 1', multi='qty_available'), 'stock_depot2': fields.function(_product_available, method=True, type='float', string='Depot 2', multi='qty_available'), }
class product_product(osv.osv): _inherit = 'product.product' def onchange_categ_id(self, cr, uid, ids, categ_id, context=None): res = {'value': {}} categ_pool = self.pool.get('product.category') if categ_id: categ_obj = categ_pool.browse(cr, uid, categ_id, context=context) res['value']['type'] = categ_obj.product_type res['value']['valuation'] = categ_obj.valuation res['value']['cost_method'] = categ_obj.cost_method return res def _compute_inventory_value(self, cr, uid, ids, field_name, arg, context=None): res = {} for product in self.browse(cr, uid, ids, context=context): inventory_value = 0.0 res[product.id] = { 'iventory_value': 0.0, } res[product.id][ 'iventory_value'] = product.standard_price * product.qty_available return res def _get_product(self, cr, uid, ids, context=None): result = {} for move in self.pool.get('stock.move').browse(cr, uid, ids, context=context): if move.state == 'done': result[move.product_id.id] = True return result.keys() def _get_total_qty(self, cr, uid, ids, field_names=None, arg=False, context=None): res = {} move_pool = self.pool.get('stock.move') internal_locs = self.pool.get('stock.location').search( cr, uid, [('usage', '=', 'internal')], context=context) for product in self.browse(cr, uid, ids, context=None): res[product.id] = 0.0 outgoing_move_ids = move_pool.search( cr, uid, [('location_id', 'in', internal_locs), ('product_id', '=', product.id), ('state', '=', 'done')], context=context) outgoing_sum = 0.0 incoming_sum = 0.0 if outgoing_move_ids: for outgoing_move in move_pool.browse(cr, uid, outgoing_move_ids, context=context): outgoing_sum += outgoing_move.product_qty incoming_move_ids = move_pool.search( cr, uid, [('location_dest_id', 'in', internal_locs), ('product_id', '=', product.id), ('state', '=', 'done')], context=context) if incoming_move_ids: for incoming_move in move_pool.browse(cr, uid, incoming_move_ids, context=context): incoming_sum += incoming_move.product_qty res[product.id] = incoming_sum - outgoing_sum return res _columns = { 'certificate_ids': fields.many2many('product.certificate', 'product_cert_rel', 'product_id', 'certificate_id', 'Certificate(s)'), 'manufacturer_id': fields.many2one('res.partner', 'Manufacturer'), 'part_no': fields.char('Part Number', size=128), 'type': fields.selection( [('product', 'Stock Item'), ('consu', 'Non Stock Item'), ('service', 'Service Charges')], 'Product Type', required=True, help= "Consumable: Will not imply stock management for this product. \nStockable product: Will imply stock management for this product." ), 'multi_price_ids': fields.one2many('product.multiple.prices', 'product_id', 'Multiple Prices'), 'iventory_value': fields.function(_compute_inventory_value, digits_compute=dp.get_precision('Account'), string='Inventory Value', multi='value'), 'qty_on_hand_store': fields.function( _get_total_qty, type='float', string='Quantity On Hand', digits_compute=dp.get_precision('Product Unit of Measure'), store={ 'stock.move': (_get_product, [], 10), }) } _defaults = {'type': 'consu'} def _check_internal_number(self, cr, uid, ids, context=None): for product_obj in self.browse(cr, uid, ids, context=context): if product_obj.default_code and product_obj.type != 'product': product_ids = self.search( cr, uid, [('default_code', '=', product_obj.default_code), ('id', '!=', product_obj.id)], context=context) if product_ids: return False return True def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100): if not args: args = [] if name: ids = self.search(cr, user, [('default_code', '=', name)] + args, limit=limit, context=context) if not ids: ids = self.search(cr, user, [('part_no', '=', name)] + args, limit=limit, context=context) if not ids: ids = self.search(cr, user, [('ean13', '=', name)] + args, limit=limit, context=context) if not ids: # Do not merge the 2 next lines into one single search, SQL search performance would be abysmal # on a database with thousands of matching products, due to the huge merge+unique needed for the # OR operator (and given the fact that the 'name' lookup results come from the ir.translation table # Performing a quick memory merge of ids in Python will give much better performance ids = set() ids.update( self.search(cr, user, args + [('default_code', operator, name)], limit=limit, context=context)) ids.update( self.search(cr, user, args + [('part_no', operator, name)], limit=limit, context=context)) if not limit or len(ids) < limit: # we may underrun the limit because of dupes in the results, that's fine ids.update( self.search(cr, user, args + [('name', operator, name)], limit=(limit and (limit - len(ids)) or False), context=context)) ids = list(ids) if not ids: ptrn = re.compile('(\[(.*?)\])') res = ptrn.search(name) if res: ids = self.search( cr, user, [('default_code', '=', res.group(2))] + args, limit=limit, context=context) else: ids = self.search(cr, user, args, limit=limit, context=context) result = self.name_get(cr, user, ids, context=context) return result _constraints = [ (_check_internal_number, 'Product with same internal number already exists', ['default_code']), ]
class c2c_budget_line(osv.osv): """ camptocamp budget line. A budget version line NOT linked to an analytic account """ def filter_by_period(self, cr, uid, lines, periods_ids, context={}): """ return a list of lines amoungs those given in parameter that are linked to one of the given periods """ result = [] self._logger.debug('periods_ids `%s`', periods_ids) self._logger.debug('lines `%s`', periods_ids) if len(periods_ids) == 0: return result for l in lines: self._logger.debug('l= `%s`', l) if l.period_id.id in periods_ids: result.append(l) self._logger.debug('result `%s`', result) return result def filter_by_date(self, cr, uid, lines, date_start=None,\ date_end=None, context={}): """return a list of lines among those given in parameter \that stand between date_start and date_end """ result = [] for l in lines: if (date_start == None or l.period_id.date_start >= date_start)\ and (date_end == None or l.period_id.date_stop <= date_end): result.append(l) return result def filter_by_missing_analytic_account(self, cr, uid, lines, context={}): """return a list of lines among those given in parameter that are ot linked to a analytic account """ result = [] for l in lines: if not l.analytic_account_id: result.append(l) return result def filter_by_items(self, cr, uid, lines, items_ids, context={}): """return a list of lines among those given in parameter that are linked to one of the given items """ result = [] budget_items_obj = self.pool.get('c2c_budget.item') all_items = budget_items_obj.get_sub_items(cr, items_ids) for l in lines: if l.budget_item_id.id in all_items: result.append(l) return result def filter_by_analytic_account(self, cr, uid, lines,\ analytic_accounts_ids, context={}): """return a list of lines among those given in parameter that is linked to analytic_accounts. param analytic_accounts_ids should be a list of accounts'ids. """ result = [] aa_obj = self.pool.get('account.analytic.account') all_accounts = aa_obj.get_children_flat_list(cr, uid, analytic_accounts_ids) for l in lines: if l.analytic_account_id.id in all_accounts: result.append(l) return result def get_analytic_accounts(self, cr, uid, lines,\ company_id, context={}): """ from a bunch of lines, return all analytic accounts ids linked by those lines. Use it when you need analytic accounts in a financial approach. For a project approach, use get_project() above this is a facility to allow this module to be overridden to use projects instead of analytic accounts """ return self.get_projects(cr, uid, lines, context) def get_projects(self, cr, uid, lines, context={}): """ from a bunch of lines, return all analytic accounts ids linked by those lines this is an alias of get_analytic_accounts() called when AA are used in a project approach (contrary to a financial approach) this is a facility to allow this module to be overridden to use projects instead of analytic accounts """ result = [] for l in lines: if l.analytic_account_id and l.analytic_account_id.id not in result: result.append(l.analytic_account_id.id) return result def get_versions(self, cr, uid, lines, context={}): """ from a bunch of lines, return all budgets' versions those lines belong to """ version = [] version_ids = [] for l in lines: if l.budget_version_id and l.budget_version_id.id \ not in version_ids: version.append(l.budget_version_id) version_ids.append(l.budget_version_id.id) return version def get_periods(self, cr, uid, ids, context={}): """return periods informations used by this budget lines. (the periods are selected in the budget lines)""" periods = [] periods_ids = [] lines = self.browse(cr, uid, ids, context) for l in lines: if l.period_id.id not in periods_ids: periods.append(l.period_id) periods_ids.append(l.period_id.id) #sort periods by dates def byDateStart(first, second): if first.date_start > second.date_start: return 1 elif first.date_start < second.date_start: return -1 return 0 periods.sort(byDateStart) return periods def _get_budget_currency_amount(self, cr, uid, ids, name, arg, context={}): """ return the line's amount xchanged in the budget's currency """ res = {} #We get all values from DB objs = self.browse(cr, uid, ids) for obj in objs: budget_currency_id = obj.budget_version_id.currency_id.id #get the budget creation date in the right format t = datetime.now() budget_ref_date = t.timetuple() if obj.budget_version_id.ref_date: budget_ref_date = time.strptime(obj.budget_version_id.ref_date, "%Y-%m-%d") res[obj.id] = c2c_helper.exchange_currency(cr, obj.amount, obj.currency_id.id, budget_currency_id) return res def _get_budget_version_currency(self, cr, uid, context): """ return the default currency for this line of account. The default currency is the currency set for the budget version if it exists """ # if the budget currency is already set if 'currency_id' in context and context['currency_id'] != False: return context['currency_id'] return False _name = "c2c_budget.line" _description = "Budget Lines" _logger = logging.getLogger(_name) _columns = { 'period_id': fields.many2one('account.period', 'Period', required=True), 'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account'), 'budget_item_id': fields.many2one('c2c_budget.item', 'Budget Item', required=True), 'name': fields.char('Description', size=200), 'amount': fields.float('Amount', required=True), 'currency_id': fields.many2one('res.currency', 'Currency', required=True), 'amount_in_budget_currency': fields.function(_get_budget_currency_amount, method=True, type='float', string='In Budget\'s Currency'), 'budget_version_id': fields.many2one('c2c_budget.version', 'Budget Version', required=True), } _defaults = { 'currency_id' : lambda self, cr, uid, context :\ self._get_budget_version_currency(cr, uid, context) } _order = 'name' def _check_item_in_budget_tree(self, cr, uid, ids): _logger = logging.getLogger(__name__) """ check if the line's budget item is in the budget's structure """ lines = self.browse(cr, uid, ids) for l in lines: #get list of budget items for this budget budget_item_object = self.pool.get('c2c_budget.item') flat_items_ids = budget_item_object.get_sub_items( cr, [l.budget_version_id.budget_id.budget_item_id.id]) if l.budget_item_id.id not in flat_items_ids: _logger.debug('FGF budget_item not in structure %s' % (l.budget_item_id.id)) return False return True def _check_period(self, cr, uid, ids): """ check if the line's period overlay the budget's period """ lines = self.browse(cr, uid, ids) for l in lines: # if a line's period is entierly before \ #the budget's period or entierly after it, \ #the line's period does not overlay the budget's period if (l.period_id.date_start < l.budget_version_id.budget_id.start_date \ and l.period_id.date_stop < l.budget_version_id.budget_id.start_date) \ or (l.period_id.date_start > l.budget_version_id.budget_id.end_date \ and l.period_id.date_stop > l.budget_version_id.budget_id.end_date): return False return True def search(self, cr, user, args, offset=0, limit=None, \ order=None, context={}, count=False): """search through lines that belongs to accessible versions """ lines_ids = super(c2c_budget_line, self).search(cr, user, args, offset, limit, order, context, count) #get versions the user can see, from versions, get periods then filter lines by those periods if lines_ids: version_obj = self.pool.get('c2c_budget.version') versions_ids = version_obj.search(cr, user, [], context=context) versions = version_obj.browse(cr, user, versions_ids, context=context) periods = [] for v in versions: periods = periods + version_obj.get_periods( cr, user, v, context=context) lines = self.browse(cr, user, lines_ids, context=context) #lines = self.filter_by_period(cr, user, lines, [p.id for p in periods], context) line_ids = [] # FIXME - may be a data error in blau6 if lines: try: lines_ids = [l.id for l in lines] except: self._logger.debug('lines `%s`', lines) return lines_ids _constraints = [ (_check_period, "The line's period must overlap the budget's start or end dates", ['period_id']), (_check_item_in_budget_tree, "The line's bugdet item must belong to the budget structure\ defined in the budget", ['budget_item_id']) ]
class directdebit_communication(osv.osv): _name = 'directdebit.communication' _inherit = 'directdebit.communication' def _get_credicoop_output(self, cr, uid, ids, fields, args, context=None): r = self.generate_output(cr, uid, ids, context=context) return r def _get_credicoop_input(self, cr, uid, ids, fields, args, context=None): #import pdb; pdb.set_trace() return {} def _set_credicoop_input(self, cr, uid, ids, field_name, field_value, arg, context=None): dd_line_obj = self.pool.get('directdebit.communication.line') dd_input = field_value.decode('base64') if dd_input: dd_input = dd_input.split('\n') for line in dd_input: ml = re_be_communication_line.match(line) if ml: data = ml.groupdict() par_id = int(data['partner_id']) amount = float(data['amount']) dd_line_ids = dd_line_obj.search( cr, uid, [('id', '=', ids), ('partner_id', '=', par_id), ('amount', '=', amount)]) if len(dd_line_ids) == 1: dd_line_obj.write( cr, uid, dd_line_ids, {'response_code': data['response_code']}) _columns = { 'credicoop_output': fields.function(_get_credicoop_output, type="binary", mode="model", string="File to send to credicoop", readonly="True", store=False), 'credicoop_input': fields.function(_get_credicoop_input, fnct_inv=_set_credicoop_input, type="binary", mode="model", string="File from credicoop", store=False), } def generate_output(self, cr, uid, ids, context=None): r = {} for com in self.browse(cr, uid, ids): if com.state == 'draft': r[com.id] = None continue out = StringIO() for line in com.line_ids: ml = eb_communication_line_map(line) ol = eb_communication_line.format(**ml) out.write(ol) r[com.id] = out.getvalue().encode('base64') return r def read_input(self, cr, uid, ids, context=None): #import pdb; pdb.set_trace() return {}
except Exception,e : raise except_orm(_('Error!'), str(e)) _columns = { 'user_id': fields.many2one('res.users', 'Owner', select=1), 'group_ids': fields.many2many('res.groups', 'document_directory_group_rel', 'item_id', 'group_id', 'Groups'), 'parent_id': fields.many2one('document.directory', 'Directory', select=1), 'file_size': fields.integer('File Size', required=True), 'file_type': fields.char('Content Type', size=32), 'index_content': fields.text('Indexed Content'), 'write_date': fields.datetime('Date Modified', readonly=True), 'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True), 'create_date': fields.datetime('Date Created', readonly=True), 'create_uid': fields.many2one('res.users', 'Creator', readonly=True), 'store_method': fields.selection([('db','Database'),('fs','Filesystem'),('link','Link')], "Storing Method"), 'datas': fields.function(_data_get,method=True,fnct_inv=_data_set,string='File Content',type="binary"), 'store_fname': fields.char('Stored Filename', size=200), 'res_model': fields.char('Attached Model', size=64), #res_model 'res_id': fields.integer('Attached ID'), #res_id 'partner_id':fields.many2one('res.partner', 'Partner', select=1), 'title': fields.char('Resource Title',size=64), } _defaults = { 'user_id': lambda self,cr,uid,ctx:uid, 'file_size': lambda self,cr,uid,ctx:0, 'store_method': lambda *args: 'db' } _sql_constraints = [ ('filename_uniq', 'unique (name,parent_id,res_id,res_model)', 'The file name must be unique !') ]
class mrp_repair(osv.osv): _name = 'mrp.repair' _description = 'Repair Order' def _amount_untaxed(self, cr, uid, ids, field_name, arg, context=None): """ Calculates untaxed amount. @param self: The object pointer @param cr: The current row, from the database cursor, @param uid: The current user ID for security checks @param ids: List of selected IDs @param field_name: Name of field. @param arg: Argument @param context: A standard dictionary for contextual values @return: Dictionary of values. """ res = {} cur_obj = self.pool.get('res.currency') for repair in self.browse(cr, uid, ids, context=context): res[repair.id] = 0.0 for line in repair.operations: res[repair.id] += line.price_subtotal for line in repair.fees_lines: res[repair.id] += line.price_subtotal cur = repair.pricelist_id.currency_id res[repair.id] = cur_obj.round(cr, uid, cur, res[repair.id]) return res def _amount_tax(self, cr, uid, ids, field_name, arg, context=None): """ Calculates taxed amount. @param field_name: Name of field. @param arg: Argument @return: Dictionary of values. """ res = {} #return {}.fromkeys(ids, 0) cur_obj = self.pool.get('res.currency') tax_obj = self.pool.get('account.tax') for repair in self.browse(cr, uid, ids, context=context): val = 0.0 cur = repair.pricelist_id.currency_id for line in repair.operations: #manage prices with tax included use compute_all instead of compute if line.to_invoice: tax_calculate = tax_obj.compute_all( cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, repair.partner_invoice_id.id, line.product_id, repair.partner_id) for c in tax_calculate['taxes']: val += c['amount'] for line in repair.fees_lines: if line.to_invoice: tax_calculate = tax_obj.compute_all( cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, repair.partner_invoice_id.id, line.product_id, repair.partner_id) for c in tax_calculate['taxes']: val += c['amount'] res[repair.id] = cur_obj.round(cr, uid, cur, val) return res def _amount_total(self, cr, uid, ids, field_name, arg, context=None): """ Calculates total amount. @param field_name: Name of field. @param arg: Argument @return: Dictionary of values. """ res = {} untax = self._amount_untaxed(cr, uid, ids, field_name, arg, context=context) tax = self._amount_tax(cr, uid, ids, field_name, arg, context=context) cur_obj = self.pool.get('res.currency') for id in ids: repair = self.browse(cr, uid, id, context=context) cur = repair.pricelist_id.currency_id res[id] = cur_obj.round(cr, uid, cur, untax.get(id, 0.0) + tax.get(id, 0.0)) return res def _get_default_address(self, cr, uid, ids, field_name, arg, context=None): res = {} partner_obj = self.pool.get('res.partner') for data in self.browse(cr, uid, ids, context=context): adr_id = False if data.partner_id: adr_id = partner_obj.address_get(cr, uid, [data.partner_id.id], ['default'])['default'] res[data.id] = adr_id return res def _get_lines(self, cr, uid, ids, context=None): result = {} for line in self.pool.get('mrp.repair.line').browse(cr, uid, ids, context=context): result[line.repair_id.id] = True return result.keys() _columns = { 'name': fields.char('Repair Reference', size=24, required=True), 'product_id': fields.many2one('product.product', string='Product to Repair', required=True, readonly=True, states={'draft': [('readonly', False)]}), 'partner_id': fields.many2one( 'res.partner', 'Partner', select=True, help= 'This field allow you to choose the parner that will be invoiced and delivered' ), 'address_id': fields.many2one('res.partner.address', 'Delivery Address', domain="[('partner_id','=',partner_id)]"), 'default_address_id': fields.function(_get_default_address, type="many2one", relation="res.partner.address"), 'prodlot_id': fields.many2one('stock.production.lot', 'Lot Number', select=True, domain="[('product_id','=',product_id)]"), 'state': fields.selection( [('draft', 'Quotation'), ('confirmed', 'Confirmed'), ('ready', 'Ready to Repair'), ('under_repair', 'Under Repair'), ('2binvoiced', 'To be Invoiced'), ('invoice_except', 'Invoice Exception'), ('done', 'Done'), ('cancel', 'Cancel')], 'State', readonly=True, help= ' * The \'Draft\' state is used when a user is encoding a new and unconfirmed repair order. \ \n* The \'Confirmed\' state is used when a user confirms the repair order. \ \n* The \'Ready to Repair\' state is used to start to repairing, user can start repairing only after repair order is confirmed. \ \n* The \'To be Invoiced\' state is used to generate the invoice before or after repairing done. \ \n* The \'Done\' state is set when repairing is completed.\ \n* The \'Cancelled\' state is used when user cancel repair order.' ), 'location_id': fields.many2one('stock.location', 'Current Location', select=True, readonly=True, states={'draft': [('readonly', False)]}), 'location_dest_id': fields.many2one('stock.location', 'Delivery Location', readonly=True, states={'draft': [('readonly', False)]}), 'move_id': fields.many2one('stock.move', 'Move', required=True, domain="[('product_id','=',product_id)]", readonly=True, states={'draft': [('readonly', False)]}), 'guarantee_limit': fields.date( 'Guarantee limit', help= "The guarantee limit is computed as: last move date + warranty defined on selected product. If the current date is below the guarantee limit, each operation and fee you will add will be set as 'not to invoiced' by default. Note that you can change manually afterwards." ), 'operations': fields.one2many('mrp.repair.line', 'repair_id', 'Operation Lines', readonly=True, states={'draft': [('readonly', False)]}), 'pricelist_id': fields.many2one( 'product.pricelist', 'Pricelist', help='The pricelist comes from the selected partner, by default.'), 'partner_invoice_id': fields.many2one('res.partner.address', 'Invoicing Address', domain="[('partner_id','=',partner_id)]"), 'invoice_method': fields.selection( [("none", "No Invoice"), ("b4repair", "Before Repair"), ("after_repair", "After Repair")], "Invoice Method", select=True, required=True, states={'draft': [('readonly', False)]}, readonly=True, help= 'This field allow you to change the workflow of the repair order. If value selected is different from \'No Invoice\', it also allow you to select the pricelist and invoicing address.' ), 'invoice_id': fields.many2one('account.invoice', 'Invoice', readonly=True), 'picking_id': fields.many2one('stock.picking', 'Picking', readonly=True), 'fees_lines': fields.one2many('mrp.repair.fee', 'repair_id', 'Fees Lines', readonly=True, states={'draft': [('readonly', False)]}), 'internal_notes': fields.text('Internal Notes'), 'quotation_notes': fields.text('Quotation Notes'), 'company_id': fields.many2one('res.company', 'Company'), 'deliver_bool': fields.boolean( 'Deliver', help= "Check this box if you want to manage the delivery once the product is repaired. If cheked, it will create a picking with selected product. Note that you can select the locations in the Info tab, if you have the extended view." ), 'invoiced': fields.boolean('Invoiced', readonly=True), 'repaired': fields.boolean('Repaired', readonly=True), 'amount_untaxed': fields.function(_amount_untaxed, string='Untaxed Amount', store={ 'mrp.repair': (lambda self, cr, uid, ids, c={}: ids, ['operations'], 10), 'mrp.repair.line': (_get_lines, [ 'price_unit', 'price_subtotal', 'product_id', 'tax_id', 'product_uom_qty', 'product_uom' ], 10), }), 'amount_tax': fields.function(_amount_tax, string='Taxes', store={ 'mrp.repair': (lambda self, cr, uid, ids, c={}: ids, ['operations'], 10), 'mrp.repair.line': (_get_lines, [ 'price_unit', 'price_subtotal', 'product_id', 'tax_id', 'product_uom_qty', 'product_uom' ], 10), }), 'amount_total': fields.function(_amount_total, string='Total', store={ 'mrp.repair': (lambda self, cr, uid, ids, c={}: ids, ['operations'], 10), 'mrp.repair.line': (_get_lines, [ 'price_unit', 'price_subtotal', 'product_id', 'tax_id', 'product_uom_qty', 'product_uom' ], 10), }), } _defaults = { 'state': lambda *a: 'draft', 'deliver_bool': lambda *a: True, 'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get( cr, uid, 'mrp.repair'), 'invoice_method': lambda *a: 'none', 'company_id': lambda self, cr, uid, context: self.pool.get('res.company'). _company_default_get(cr, uid, 'mrp.repair', context=context), 'pricelist_id': lambda self, cr, uid, context: self.pool.get( 'product.pricelist').search(cr, uid, [('type', '=', 'sale')])[0] } def copy(self, cr, uid, id, default=None, context=None): if not default: default = {} default.update({ 'state': 'draft', 'repaired': False, 'invoiced': False, 'invoice_id': False, 'picking_id': False, 'name': self.pool.get('ir.sequence').get(cr, uid, 'mrp.repair'), }) return super(mrp_repair, self).copy(cr, uid, id, default, context) def onchange_product_id(self, cr, uid, ids, product_id=None): """ On change of product sets some values. @param product_id: Changed product @return: Dictionary of values. """ return { 'value': { 'prodlot_id': False, 'move_id': False, 'guarantee_limit': False, 'location_id': False, 'location_dest_id': False, } } def onchange_move_id(self, cr, uid, ids, prod_id=False, move_id=False): """ On change of move id sets values of guarantee limit, source location, destination location, partner and partner address. @param prod_id: Id of product in current record. @param move_id: Changed move. @return: Dictionary of values. """ data = {} data['value'] = {} if not prod_id: return data if move_id: move = self.pool.get('stock.move').browse(cr, uid, move_id) product = self.pool.get('product.product').browse(cr, uid, prod_id) limit = datetime.strptime(move.date_expected, '%Y-%m-%d %H:%M:%S') + relativedelta( months=int(product.warranty)) data['value']['guarantee_limit'] = limit.strftime('%Y-%m-%d') data['value']['location_id'] = move.location_dest_id.id data['value']['location_dest_id'] = move.location_dest_id.id if move.address_id: data['value'][ 'partner_id'] = move.address_id.partner_id and move.address_id.partner_id.id else: data['value']['partner_id'] = False data['value'][ 'address_id'] = move.address_id and move.address_id.id d = self.onchange_partner_id(cr, uid, ids, data['value']['partner_id'], data['value']['address_id']) data['value'].update(d['value']) return data def button_dummy(self, cr, uid, ids, context=None): return True def onchange_partner_id(self, cr, uid, ids, part, address_id): """ On change of partner sets the values of partner address, partner invoice address and pricelist. @param part: Changed id of partner. @param address_id: Address id from current record. @return: Dictionary of values. """ part_obj = self.pool.get('res.partner') pricelist_obj = self.pool.get('product.pricelist') if not part: return { 'value': { 'address_id': False, 'partner_invoice_id': False, 'pricelist_id': pricelist_obj.search(cr, uid, [('type', '=', 'sale')])[0] } } addr = part_obj.address_get(cr, uid, [part], ['delivery', 'invoice', 'default']) partner = part_obj.browse(cr, uid, part) pricelist = partner.property_product_pricelist and partner.property_product_pricelist.id or False return { 'value': { 'address_id': address_id or addr['delivery'], 'partner_invoice_id': addr['invoice'], 'pricelist_id': pricelist } } def onchange_lot_id(self, cr, uid, ids, lot, product_id): """ On change of production lot sets the values of source location, destination location, move and guarantee limit. @param lot: Changed id of production lot. @param product_id: Product id from current record. @return: Dictionary of values. """ move_obj = self.pool.get('stock.move') data = {} data['value'] = { 'location_id': False, 'location_dest_id': False, 'move_id': False, 'guarantee_limit': False } if not lot: return data move_ids = move_obj.search(cr, uid, [('prodlot_id', '=', lot)]) if not len(move_ids): return data def get_last_move(lst_move): while lst_move.move_dest_id and lst_move.move_dest_id.state == 'done': lst_move = lst_move.move_dest_id return lst_move move_id = move_ids[0] move = get_last_move(move_obj.browse(cr, uid, move_id)) data['value']['move_id'] = move.id d = self.onchange_move_id(cr, uid, ids, product_id, move.id) data['value'].update(d['value']) return data def action_cancel_draft(self, cr, uid, ids, *args): """ Cancels repair order when it is in 'Draft' state. @param *arg: Arguments @return: True """ if not len(ids): return False mrp_line_obj = self.pool.get('mrp.repair.line') for repair in self.browse(cr, uid, ids): mrp_line_obj.write(cr, uid, [l.id for l in repair.operations], {'state': 'draft'}) self.write(cr, uid, ids, {'state': 'draft'}) wf_service = netsvc.LocalService("workflow") for id in ids: wf_service.trg_create(uid, 'mrp.repair', id, cr) return True def action_confirm(self, cr, uid, ids, *args): """ Repair order state is set to 'To be invoiced' when invoice method is 'Before repair' else state becomes 'Confirmed'. @param *arg: Arguments @return: True """ mrp_line_obj = self.pool.get('mrp.repair.line') for o in self.browse(cr, uid, ids): if (o.invoice_method == 'b4repair'): self.write(cr, uid, [o.id], {'state': '2binvoiced'}) else: self.write(cr, uid, [o.id], {'state': 'confirmed'}) if not o.operations: raise osv.except_osv( _('Error !'), _('You cannot confirm a repair order which has no line.' )) for line in o.operations: if line.product_id.track_production and not line.prodlot_id: raise osv.except_osv( _('Warning'), _("Production lot is required for opration line with product '%s'" ) % (line.product_id.name)) mrp_line_obj.write(cr, uid, [l.id for l in o.operations], {'state': 'confirmed'}) return True def action_cancel(self, cr, uid, ids, context=None): """ Cancels repair order. @return: True """ mrp_line_obj = self.pool.get('mrp.repair.line') for repair in self.browse(cr, uid, ids, context=context): mrp_line_obj.write(cr, uid, [l.id for l in repair.operations], {'state': 'cancel'}, context=context) self.write(cr, uid, ids, {'state': 'cancel'}) return True def wkf_invoice_create(self, cr, uid, ids, *args): return self.action_invoice_create(cr, uid, ids) def action_invoice_create(self, cr, uid, ids, group=False, context=None): """ Creates invoice(s) for repair order. @param group: It is set to true when group invoice is to be generated. @return: Invoice Ids. """ res = {} invoices_group = {} inv_line_obj = self.pool.get('account.invoice.line') inv_obj = self.pool.get('account.invoice') repair_line_obj = self.pool.get('mrp.repair.line') repair_fee_obj = self.pool.get('mrp.repair.fee') for repair in self.browse(cr, uid, ids, context=context): res[repair.id] = False if repair.state in ('draft', 'cancel') or repair.invoice_id: continue if not (repair.partner_id.id and repair.partner_invoice_id.id): raise osv.except_osv( _('No partner !'), _('You have to select a Partner Invoice Address in the repair form !' )) comment = repair.quotation_notes if (repair.invoice_method != 'none'): if group and repair.partner_invoice_id.id in invoices_group: inv_id = invoices_group[repair.partner_invoice_id.id] invoice = inv_obj.browse(cr, uid, inv_id) invoice_vals = { 'name': invoice.name + ', ' + repair.name, 'origin': invoice.origin + ', ' + repair.name, 'comment': (comment and (invoice.comment and invoice.comment + "\n" + comment or comment)) or (invoice.comment and invoice.comment or ''), } inv_obj.write(cr, uid, [inv_id], invoice_vals, context=context) else: if not repair.partner_id.property_account_receivable: raise osv.except_osv( _('Error !'), _('No account defined for partner "%s".') % repair.partner_id.name) account_id = repair.partner_id.property_account_receivable.id inv = { 'name': repair.name, 'origin': repair.name, 'type': 'out_invoice', 'account_id': account_id, 'partner_id': repair.partner_id.id, 'address_invoice_id': repair.address_id.id, 'currency_id': repair.pricelist_id.currency_id.id, 'comment': repair.quotation_notes, 'fiscal_position': repair.partner_id.property_account_position.id } inv_id = inv_obj.create(cr, uid, inv) invoices_group[repair.partner_invoice_id.id] = inv_id self.write(cr, uid, repair.id, { 'invoiced': True, 'invoice_id': inv_id }) for operation in repair.operations: if operation.to_invoice == True: if group: name = repair.name + '-' + operation.name else: name = operation.name if operation.product_id.property_account_income: account_id = operation.product_id.property_account_income.id elif operation.product_id.categ_id.property_account_income_categ: account_id = operation.product_id.categ_id.property_account_income_categ.id else: raise osv.except_osv( _('Error !'), _('No account defined for product "%s".') % operation.product_id.name) invoice_line_id = inv_line_obj.create( cr, uid, { 'invoice_id': inv_id, 'name': name, 'origin': repair.name, 'account_id': account_id, 'quantity': operation.product_uom_qty, 'invoice_line_tax_id': [ (6, 0, [x.id for x in operation.tax_id]) ], 'uos_id': operation.product_uom.id, 'price_unit': operation.price_unit, 'price_subtotal': operation.product_uom_qty * operation.price_unit, 'product_id': operation.product_id and operation.product_id.id or False }) repair_line_obj.write( cr, uid, [operation.id], { 'invoiced': True, 'invoice_line_id': invoice_line_id }) for fee in repair.fees_lines: if fee.to_invoice == True: if group: name = repair.name + '-' + fee.name else: name = fee.name if not fee.product_id: raise osv.except_osv( _('Warning !'), _('No product defined on Fees!')) if fee.product_id.property_account_income: account_id = fee.product_id.property_account_income.id elif fee.product_id.categ_id.property_account_income_categ: account_id = fee.product_id.categ_id.property_account_income_categ.id else: raise osv.except_osv( _('Error !'), _('No account defined for product "%s".') % fee.product_id.name) invoice_fee_id = inv_line_obj.create( cr, uid, { 'invoice_id': inv_id, 'name': name, 'origin': repair.name, 'account_id': account_id, 'quantity': fee.product_uom_qty, 'invoice_line_tax_id': [(6, 0, [x.id for x in fee.tax_id])], 'uos_id': fee.product_uom.id, 'product_id': fee.product_id and fee.product_id.id or False, 'price_unit': fee.price_unit, 'price_subtotal': fee.product_uom_qty * fee.price_unit }) repair_fee_obj.write(cr, uid, [fee.id], { 'invoiced': True, 'invoice_line_id': invoice_fee_id }) res[repair.id] = inv_id return res def action_repair_ready(self, cr, uid, ids, context=None): """ Writes repair order state to 'Ready' @return: True """ for repair in self.browse(cr, uid, ids, context=context): self.pool.get('mrp.repair.line').write( cr, uid, [l.id for l in repair.operations], {'state': 'confirmed'}, context=context) self.write(cr, uid, [repair.id], {'state': 'ready'}) return True def action_repair_start(self, cr, uid, ids, context=None): """ Writes repair order state to 'Under Repair' @return: True """ repair_line = self.pool.get('mrp.repair.line') for repair in self.browse(cr, uid, ids, context=context): repair_line.write(cr, uid, [l.id for l in repair.operations], {'state': 'confirmed'}, context=context) repair.write({'state': 'under_repair'}) return True def action_repair_end(self, cr, uid, ids, context=None): """ Writes repair order state to 'To be invoiced' if invoice method is After repair else state is set to 'Ready'. @return: True """ for order in self.browse(cr, uid, ids, context=context): val = {} val['repaired'] = True if (not order.invoiced and order.invoice_method == 'after_repair'): val['state'] = '2binvoiced' elif (not order.invoiced and order.invoice_method == 'b4repair'): val['state'] = 'ready' else: pass self.write(cr, uid, [order.id], val) return True def wkf_repair_done(self, cr, uid, ids, *args): self.action_repair_done(cr, uid, ids) return True def action_repair_done(self, cr, uid, ids, context=None): """ Creates stock move and picking for repair order. @return: Picking ids. """ res = {} move_obj = self.pool.get('stock.move') wf_service = netsvc.LocalService("workflow") repair_line_obj = self.pool.get('mrp.repair.line') seq_obj = self.pool.get('ir.sequence') pick_obj = self.pool.get('stock.picking') for repair in self.browse(cr, uid, ids, context=context): for move in repair.operations: move_id = move_obj.create( cr, uid, { 'name': move.name, 'product_id': move.product_id.id, 'product_qty': move.product_uom_qty, 'product_uom': move.product_uom.id, 'address_id': repair.address_id and repair.address_id.id or False, 'location_id': move.location_id.id, 'location_dest_id': move.location_dest_id.id, 'tracking_id': False, 'prodlot_id': move.prodlot_id and move.prodlot_id.id or False, 'state': 'done', }) repair_line_obj.write(cr, uid, [move.id], { 'move_id': move_id, 'state': 'done' }, context=context) if repair.deliver_bool: pick_name = seq_obj.get(cr, uid, 'stock.picking.out') picking = pick_obj.create( cr, uid, { 'name': pick_name, 'origin': repair.name, 'state': 'draft', 'move_type': 'one', 'address_id': repair.address_id and repair.address_id.id or False, 'note': repair.internal_notes, 'invoice_state': 'none', 'type': 'out', }) move_id = move_obj.create( cr, uid, { 'name': repair.name, 'picking_id': picking, 'product_id': repair.product_id.id, 'product_qty': move.product_uom_qty or 1.0, 'product_uom': repair.product_id.uom_id.id, 'prodlot_id': repair.prodlot_id and repair.prodlot_id.id or False, 'address_id': repair.address_id and repair.address_id.id or False, 'location_id': repair.location_id.id, 'location_dest_id': repair.location_dest_id.id, 'tracking_id': False, 'state': 'assigned', }) wf_service.trg_validate(uid, 'stock.picking', picking, 'button_confirm', cr) self.write(cr, uid, [repair.id], { 'state': 'done', 'picking_id': picking }) res[repair.id] = picking else: self.write(cr, uid, [repair.id], {'state': 'done'}) return res
'tml_source':fields.selection([ ('database','Database'), ('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'), } 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))
class mrp_repair_line(osv.osv, ProductChangeMixin): _name = 'mrp.repair.line' _description = 'Repair Line' def copy_data(self, cr, uid, id, default=None, context=None): if not default: default = {} default.update({ 'invoice_line_id': False, 'move_id': False, 'invoiced': False, 'state': 'draft' }) return super(mrp_repair_line, self).copy_data(cr, uid, id, default, context) def _amount_line(self, cr, uid, ids, field_name, arg, context=None): """ Calculates amount. @param field_name: Name of field. @param arg: Argument @return: Dictionary of values. """ res = {} cur_obj = self.pool.get('res.currency') for line in self.browse(cr, uid, ids, context=context): res[line. id] = line.to_invoice and line.price_unit * line.product_uom_qty or 0 cur = line.repair_id.pricelist_id.currency_id res[line.id] = cur_obj.round(cr, uid, cur, res[line.id]) return res _columns = { 'name': fields.char('Description', size=64, required=True), 'repair_id': fields.many2one('mrp.repair', 'Repair Order Reference', ondelete='cascade', select=True), 'type': fields.selection([('add', 'Add'), ('remove', 'Remove')], 'Type', required=True), 'to_invoice': fields.boolean('To Invoice'), 'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], required=True), 'invoiced': fields.boolean('Invoiced', readonly=True), 'price_unit': fields.float('Unit Price', required=True, digits_compute=dp.get_precision('Sale Price')), 'price_subtotal': fields.function(_amount_line, string='Subtotal', digits_compute=dp.get_precision('Sale Price')), 'tax_id': fields.many2many('account.tax', 'repair_operation_line_tax', 'repair_operation_line_id', 'tax_id', 'Taxes'), 'product_uom_qty': fields.float('Quantity (UoM)', digits=(16, 2), required=True), 'product_uom': fields.many2one('product.uom', 'Product UoM', required=True), 'prodlot_id': fields.many2one('stock.production.lot', 'Lot Number', domain="[('product_id','=',product_id)]"), 'invoice_line_id': fields.many2one('account.invoice.line', 'Invoice Line', readonly=True), 'location_id': fields.many2one('stock.location', 'Source Location', required=True, select=True), 'location_dest_id': fields.many2one('stock.location', 'Dest. Location', required=True, select=True), 'move_id': fields.many2one('stock.move', 'Inventory Move', readonly=True), 'state': fields.selection( [('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancel', 'Canceled')], 'State', required=True, readonly=True, help= ' * The \'Draft\' state is set automatically as draft when repair order in draft state. \ \n* The \'Confirmed\' state is set automatically as confirm when repair order in confirm state. \ \n* The \'Done\' state is set automatically when repair order is completed.\ \n* The \'Cancelled\' state is set automatically when user cancel repair order.' ), } _defaults = { 'state': lambda *a: 'draft', 'product_uom_qty': lambda *a: 1, } def onchange_operation_type(self, cr, uid, ids, type, guarantee_limit, company_id=False, context=None): """ On change of operation type it sets source location, destination location and to invoice field. @param product: Changed operation type. @param guarantee_limit: Guarantee limit of current record. @return: Dictionary of values. """ if not type: return {'value': {'location_id': False, 'location_dest_id': False}} warehouse_obj = self.pool.get('stock.warehouse') location_id = self.pool.get('stock.location').search( cr, uid, [('usage', '=', 'production')], context=context) location_id = location_id and location_id[0] or False if type == 'add': # TOCHECK: Find stock location for user's company warehouse or # repair order's company's warehouse (company_id field is added in fix of lp:831583) args = company_id and [('company_id', '=', company_id)] or [] warehouse_ids = warehouse_obj.search(cr, uid, args, context=context) stock_id = False if warehouse_ids: stock_id = warehouse_obj.browse( cr, uid, warehouse_ids[0], context=context).lot_stock_id.id to_invoice = (guarantee_limit and datetime.strptime( guarantee_limit, '%Y-%m-%d') < datetime.now()) return { 'value': { 'to_invoice': to_invoice, 'location_id': stock_id, 'location_dest_id': location_id } } return { 'value': { 'to_invoice': False, 'location_id': location_id, 'location_dest_id': False } }
_columns = { 'name':fields.char('Instance Name', size=64, required=True, select=True), 'identifier':fields.char('Identifier', size=64, readonly=True, select=True), 'hardware_id' : fields.char('Hardware Identifier', size=128, select=True), 'parent_id':fields.many2one('sync.server.entity', 'Parent Instance', ondelete='cascade'), 'group_ids':fields.many2many('sync.server.entity_group', 'sync_entity_group_rel', 'entity_id', 'group_id', string="Groups"), 'state' : fields.selection([('pending', 'Pending'), ('validated', 'Validated'), ('invalidated', 'Invalidated'), ('updated', 'Updated')], 'State'), 'email':fields.char('Contact Email', size=512), 'user_id': fields.many2one('res.users', 'User', ondelete='restrict', required=True), #just in case, since the many2one exist it has no cost in database 'children_ids' : fields.one2many('sync.server.entity', 'parent_id', 'Children Instances'), 'update_token' : fields.char('Update security token', size=256), 'activity' : fields.function(_get_activity, type='char', string="Activity", method=True, multi="_get_act"), 'last_dateactivity': fields.function(_get_activity, type='datetime', string="Date of last activity", method=True, multi="_get_act"), #'last_activity' : fields.datetime("Date of last activity", readonly=True), 'parent_left' : fields.integer("Left Parent", select=1), 'parent_right' : fields.integer("Right Parent", select=1), 'msg_ids_tmp':fields.text('List of temporary ids of message to be pulled'), 'version': fields.integer('version'), 'last_sequence': fields.integer('Last update sequence pulled', readonly=True), } _defaults = { 'version': lambda *a: 0, 'last_sequence': lambda *a: 0, }
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,
return False return True def _valid_get(self, cr, uid, ids, field_name, arg, context=None): res = {} for contract in self.browse(cr, uid, ids, context=context): res[contract.id] = ("unvalid", "valid")[contract.date_stop >= time.strftime('%Y-%m-%d')] return res _columns = { 'name' : fields.char('Contract ID', size=256, required=True, readonly=True), 'password' : fields.char('Password', size=64, invisible=True, required=True, readonly=True), 'date_start' : fields.date('Starting Date', readonly=True), 'date_stop' : fields.date('Ending Date', readonly=True), 'module_ids' : fields.many2many('maintenance.contract.module', 'maintenance_contract_module_rel', 'contract_id', 'module_id', 'Covered Modules', readonly=True), 'state' : fields.function(_valid_get, method=True, string="State", type="selection", selection=[('valid', 'Valid'),('unvalid', 'Unvalid')], readonly=True), 'kind' : fields.selection([('full', 'Full'),('partial', 'Partial')], 'Kind', required=True, readonly=True), } _defaults = { 'password' : lambda obj,cr,uid,context={} : '', } _sql_constraints = [ ('uniq_name', 'unique(name)', "Your maintenance contract is already subscribed in the system !") ] maintenance_contract() class maintenance_contract_wizard(osv.osv_memory): _name = 'maintenance.contract.wizard'
class taobao_shop(osv.osv, TaobaoMixin): _name = "taobao.shop" _description = "Taobao Shop" def _get_taobao_shop_url(self, cr, uid, ids, field_name, arg, context=None): res = {} for shop in self.browse(cr, uid, ids, context=context): res[shop.id] = 'http://shop%s.taobao.com' % shop.taobao_shop_sid return res _columns = { 'name': fields.char(u'店铺名字', size=256), 'sale_shop_id': fields.many2one('sale.shop', 'Sale Shop', required=True, select=True), 'taobao_shop_sid': fields.char(u'店铺编号', size=64), 'taobao_shop_url': fields.function(_get_taobao_shop_url, type='char', string=u'店铺地址'), 'taobao_nick': fields.char(u'卖家昵称', size=64), 'taobao_user_id': fields.char(u'卖家数字ID', size=64), 'taobao_app_key': fields.char('App Key', size=256, unique=True), 'taobao_app_secret': fields.char('App Secret', size=256), 'taobao_session_key': fields.char('Session Key', size=256), #taobao shop 'enable_taobao_stream': fields.boolean(u'接收淘宝主动通知消息'), } _sql_constraints = [('taobao_app_key_uniq', 'unique(taobao_app_key)', 'Taobao Shop App Key must be unique!')] _defaults = { 'enable_taobao_stream': True, } def create(self, cr, user, vals, context=None): try: top = TOP(vals['taobao_app_key'], vals['taobao_app_secret'], vals['taobao_session_key']) top('taobao.increment.customer.permit') tb_user = top('taobao.user.seller.get', fields=['user_id', 'nick']).user tb_shop = top('taobao.shop.get', nick=tb_user.nick, fields=['sid', 'nick']).shop vals['taobao_shop_sid'] = tb_shop.sid vals['taobao_user_id'] = tb_user.user_id vals['taobao_nick'] = tb_user.nick if not vals.get('name', False): vals['name'] = tb_user.nick return super(taobao_shop, self).create(cr, user, vals, context=context) except: raise def write(self, cr, user, ids, vals, context=None): try: shop = self._get(cr, user, ids=ids) if not 'taobao_app_key' in vals.keys(): vals['taobao_app_key'] = shop.taobao_app_key if not 'taobao_app_secret' in vals.keys(): vals['taobao_app_secret'] = shop.taobao_app_secret if not 'taobao_session_key' in vals.keys(): vals['taobao_session_key'] = shop.taobao_session_key top = TOP(vals['taobao_app_key'], vals['taobao_app_secret'], vals['taobao_session_key']) top('taobao.increment.customer.permit') tb_user = top('taobao.user.get', fields=['user_id', 'nick']).user tb_shop = top('taobao.shop.get', nick=tb_user.nick, fields=['sid', 'nick']).shop vals['taobao_shop_sid'] = tb_shop.sid vals['taobao_user_id'] = tb_user.user_id vals['taobao_nick'] = tb_user.nick return super(taobao_shop, self).write(cr, user, ids, vals, context) except: raise def __init__(self, pool, cr): super(taobao_shop, self).__init__(pool, cr) #pycurl两个函数不是线程安全。所以在主线程中进行一次的初始化和清除 import pycurl pycurl.global_init(pycurl.GLOBAL_DEFAULT) pycurl.global_cleanup() def _start_worker_thread(self, cr, uid): """ 启动 taobao worker 线程 """ for i in range(int(config.get('taobao_worker_thread_limit', 4))): thread_name = 'taobao_worker_%s' % str(i) thread_exits = False for thread in threading.enumerate(): if thread.getName() == thread_name: thread_exits = True break if not thread_exits: from taobao_base import mq_server t = threading.Thread(target=mq_server, args=[], name=thread_name) t.setDaemon(True) t.start() time.sleep(50 / 1000) def _create_stream_thread(self, cr, uid, thread_name, shop): """ 创建链接 taobao stream 线程 """ #创建stream线程 stream_thread_exits = False for thread in threading.enumerate(): if thread.getName() == thread_name: stream_thread_exits = True break if not stream_thread_exits: # check last discard_info global CHECK_DISCARD_THREAD_START if not CHECK_DISCARD_THREAD_START.get(shop.taobao_app_key, False): threading.Thread(target=self._check_discard_info, args=[cr.dbname, uid, shop.taobao_app_key]).start() CHECK_DISCARD_THREAD_START[shop.taobao_app_key] = True #start taobao stream stream_id = ''.join([ config['xmlrpc_interface'] or '0.0.0.0', ':', str(config['xmlrpc_port']), '/', thread_name ]) t = threading.Thread(target=TOP(shop.taobao_app_key, shop.taobao_app_secret, shop.taobao_session_key).stream, args=[ cr.dbname, uid, stream_id, shop.taobao_user_id, shop.taobao_nick ], name=thread_name) t.setDaemon(True) t.start() def _start_stream_thread(self, cr, uid, shops): if not config.get('taobao_stream_service', True): return for shop in shops: if shop.taobao_app_key and shop.enable_taobao_stream: for i in range(int(config.get('taobao_stream_thread_limit', 1))): shop_thread_name = 'taobao_app_' + shop.taobao_app_key + str( i) self._create_stream_thread(cr, uid, shop_thread_name, shop) def _check_discard_info(self, dbname, uid, app_key): try: pool = openerp.pooler.get_pool(dbname) cr = pool.db.cursor() tb_packet_obj = pool.get('taobao.packet') packet_ids = tb_packet_obj.search( cr, uid, [('taobao_app_key', '=', app_key)], limit=1) if packet_ids: begin_str = tb_packet_obj.perm_read( cr, uid, packet_ids)[0].get('create_date').split('.')[0] begin = datetime.datetime.strptime( begin_str, '%Y-%m-%d %H:%M:%S') + datetime.timedelta( hours=8) - datetime.timedelta(minutes=1) end = datetime.datetime.utcnow() + datetime.timedelta(hours=8) job = { "taobao_app_key": app_key, "packet": { "msg": { "begin": int(time.mktime(begin.timetuple()) * 1000), "end": int(time.mktime(end.timetuple()) * 1000) }, "code": 203 } } TaobaoMsgRouter(dbname, uid, app_key, job) except: import traceback exc = traceback.format_exc() _logger.error(exc) finally: cr.close() def stream(self, cr, uid, ids=False, context=None): if not ids: ids = self.search(cr, uid, []) if context is None: context = {} shops = self.browse(cr, uid, ids, context=context) if shops: self._start_worker_thread(cr, uid) # 启动worker 进程 self._start_stream_thread(cr, uid, shops)
'print':lambda self,cr,uid,record, groups_code: record.state in ('draft','open'), 'cancel':lambda self,cr,uid,record, groups_code: record.state == 'draft', 'delete':lambda self,cr,uid,record, groups_code: record.state == 'draft', 'replan': lambda self,cr,uid,record, groups_code: record.state == 'done', 'normal_mode_finished': lambda self,cr,uid,record, groups_code: self._task_survey_rights(cr, uid, record, groups_code) and record.state == 'open', 'normal_mode_unfinished': lambda self,cr,uid,record, groups_code: self._task_survey_rights(cr, uid, record, groups_code) and record.state == 'open', 'light_mode_finished': lambda self,cr,uid,record, groups_code: self._task_survey_rights(cr, uid, record, groups_code) and record.state == 'draft', 'light_mode_unfinished': lambda self,cr,uid,record, groups_code: self._task_survey_rights(cr, uid, record, groups_code) and record.state == 'draft', 'modify': lambda self,cr,uid,record, groups_code: True, } _columns = { 'active':fields.function(_get_active, method=True,type='boolean', store=False), 'ask_id': fields.many2one('openstc.ask', 'Demande', ondelete='set null', select="1"), 'project_id': fields.many2one('project.project', 'Intervention', ondelete='set null'), 'equipment_ids':fields.many2many('openstc.equipment', 'openstc_equipment_task_rel', 'task_id', 'equipment_id', 'Equipments'), 'consumable_ids':fields.many2many('openbase.consumable', 'openbase_consumable_task_rel', 'task_id', 'consumable_id', 'Fournitures'), 'parent_id': fields.many2one('project.task', 'Parent Task'), 'intervention_assignement_id':fields.many2one('openstc.intervention.assignement', 'Assignement'), 'absent_type_id':fields.many2one('openstc.absent.type', 'Type d''abscence'), 'category_id':fields.many2one('openstc.task.category', 'Category'), 'state': fields.selection([('absent', 'Absent'),('draft', 'New'),('open', 'In Progress'),('pending', 'Pending'), ('done', 'Done'), ('cancelled', 'Cancelled')], 'State', readonly=True, required=True, help='If the task is created the state is \'Draft\'.\n If the task is started, the state becomes \'In Progress\'.\n If review is needed the task is in \'Pending\' state.\ \n If the task is over, the states is set to \'Done\'.'), 'team_id': fields.many2one('openstc.team', 'Team'), 'km': fields.integer('Km', select=1), 'oil_qtity': fields.float('oil quantity', select=1),
class account_invoice(osv.osv): _inherit = 'account.invoice' def _amount_residual_ref(self, cr, uid, ids, name, args, context=None): res = {} for invoice in self.browse(cr, uid, ids, context=context): residual = invoice.residual if invoice.type in ('in_refund', 'out_refund'): res[invoice.id] = residual * -1 else: res[invoice.id] = residual return res def _amount_untaxed_ref(self, cr, uid, ids, name, args, context=None): res = {} for invoice in self.browse(cr, uid, ids, context=context): untaxed = invoice.amount_untaxed if invoice.type in ('in_refund', 'out_refund'): res[invoice.id] = untaxed * -1 else: res[invoice.id] = untaxed return res def _amount_all_ref(self, cr, uid, ids, name, args, context=None): res = {} for invoice in self.browse(cr, uid, ids, context=context): amount = invoice.amount_total if invoice.type in ('in_refund', 'out_refund'): res[invoice.id] = amount * -1 else: res[invoice.id] = amount return res def _amount_tax_ref(self, cr, uid, ids, name, args, context=None): res = {} for invoice in self.browse(cr, uid, ids, context=context): tax = invoice.amount_tax if invoice.type in ('in_refund', 'out_refund'): res[invoice.id] = tax * -1 else: res[invoice.id] = tax return res _columns= { 'residual_ref':fields.function(_amount_residual_ref, method=True, digits_compute=dp.get_precision('Account'), string='Residual',store=False), 'amount_untaxed_ref':fields.function(_amount_untaxed_ref, method=True, digits_compute=dp.get_precision('Account'), string='Untaxed',store=False), 'amount_total_ref':fields.function(_amount_all_ref, method=True, digits_compute=dp.get_precision('Account'), string='Total', store=False), 'amount_tax_ref':fields.function(_amount_tax_ref, method=True, digits_compute=dp.get_precision('Account'), string='Tax', store=False), 'origin': fields.char('Source Document', size=500, help="Reference of the document that produced this invoice.", readonly=True, states={'draft':[('readonly',False)]}), } def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False): res = {} journal = False if context.has_key('journal_type'): journal = context['journal_type'] if isinstance(journal,(str, unicode)): journal=[journal] if len(journal) == 1: res = super(account_invoice, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu) else: journal_obj = self.pool.get('account.journal') if context is None: context = {} if context.get('active_model', '') in ['res.partner'] and context.get('active_ids', False) and context['active_ids']: partner = self.pool.get(context['active_model']).read(cr, uid, context['active_ids'], ['supplier','customer'])[0] if not view_type: view_id = self.pool.get('ir.ui.view').search(cr, uid, [('name', '=', 'account.invoice.tree')]) view_type = 'tree' if view_type == 'form': if partner['supplier'] and not partner['customer']: view_id = self.pool.get('ir.ui.view').search(cr,uid,[('name', '=', 'account.invoice.supplier.form')]) else: view_id = self.pool.get('ir.ui.view').search(cr,uid,[('name', '=', 'account.invoice.form')]) if view_id and isinstance(view_id, (list, tuple)): view_id = view_id[0] res = super(account_invoice,self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu) type = context.get('journal_type', 'sale') for field in res['fields']: if field == 'journal_id': journal_select = journal_obj._name_search(cr, uid, '', [('type', 'in', type)], context=context, limit=None, name_get_uid=1) res['fields'][field]['selection'] = journal_select if view_type == 'tree': doc = etree.XML(res['arch']) nodes = doc.xpath("//field[@name='partner_id']") partner_string = _('Customer') if context.get('type', 'out_invoice') in ('in_invoice', 'in_refund'): partner_string = _('Supplier') for node in nodes: node.set('string', partner_string) res['arch'] = etree.tostring(doc) else: res = super(account_invoice, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu) return res
), "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", ), "page_count": fields.char( "Page Count",
class drawing_order(osv.osv): _name = "drawing.order" _inherit = ['mail.thread'] _description = "Drawing Order" _order = 'id desc' _columns = { 'name': fields.char('Name', size=64, required=True,readonly=True, states={'draft':[('readonly',False)],'rejected':[('readonly',False)]}), 'note': fields.text('Description', required=False), 'sale_product_ids': fields.many2many('sale.product','drawing_order_id_rel','drawing_order_id','id_id', string="MFG IDs",readonly=True, states={'draft':[('readonly',False)],'rejected':[('readonly',False)]}), 'order_lines': fields.one2many('drawing.order.line','order_id','Drawing Order Lines',readonly=True, states={'draft':[('readonly',False)],'rejected':[('readonly',False)]}), 'state': fields.selection([('draft','Draft'),('ready','Ready'),('confirmed','Confirmed'),('approved','Approved'),('rejected','Rejected'),('cancel','Cancelled')], 'Status', track_visibility='onchange', required=True), 'reject_message': fields.text('Rejection Message', track_visibility='onchange'), 'create_uid': fields.many2one('res.users','Creator',readonly=True), 'create_date': fields.datetime('Creation Date', readonly=True), # 'date_finished': fields.datetime('Finished Date', readonly=True), 'company_id': fields.many2one('res.company', 'Company', readonly=True), 'product_id': fields.related('order_lines','product_id', type='many2one', relation='product.product', string='Product'), 'main_part_id': fields.many2one('product.product','Main Product',readonly=True, states={'draft':[('readonly',False)],'rejected':[('readonly',False)]}), 'bom_file_name': fields.char('BOM File Name', size=64), 'bom_file': fields.function(utils.field_get_file, fnct_inv=utils.field_set_file, string="BOM File", type="binary", multi="_get_file",), } _defaults = { 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'drawing.order', context=c), 'state': 'draft', } _order = 'id desc' def _set_state(self,cr,uid,ids,state,context=None): self.write(cr,uid,ids,{'state':state},context=context) line_ids = [] for order in self.browse(cr,uid,ids,context=context): for line in order.order_lines: if not line.state == 'done': line_ids.append(line.id) self.pool.get('drawing.order.line').write(cr,uid,line_ids,{'state':state}) def _check_done_lines(self,cr,uid,ids,context=None): # for wo in self.browse(cr,uid,ids,context=context): # for line in wo.wo_cnc_lines: # if line.state == 'done': # raise osv.except_osv(_('Invalid Action!'), _('Action was blocked, there are done work order lines!')) return True def _email_notify(self, cr, uid, ids, action_name, group_params, context=None): for order in self.browse(cr, uid, ids, context=context): for group_param in group_params: email_group_id = self.pool.get('ir.config_parameter').get_param(cr, uid, group_param, context=context) if email_group_id: email_subject = 'Drawing reminder: %s %s'%(order.name,action_name) mfg_id_names = ','.join([mfg_id.name for mfg_id in order.sale_product_ids]) #[(id1,name1),(id2,name2),...(idn,namen)] main_part_name = '' if order.main_part_id: main_part_name = self.pool.get('product.product').name_get(cr, uid, [order.main_part_id.id], context=context)[0][1] email_body = '%s %s %s, MFG IDs:%s'%(order.name,main_part_name, action_name,mfg_id_names) email_from = self.pool.get("res.users").read(cr, uid, uid, ['email'],context=context)['email'] utils.email_send_group(cr, uid, email_from, None,email_subject,email_body, email_group_id, context=context) def action_ready(self, cr, uid, ids, context=None): #set the ready state self._set_state(cr, uid, ids, 'ready',context) #send email to the user group that can confirm self._email_notify(cr, uid, ids, 'need your confirmation', ['mrp_cnc_wo_group_confirm'],context) return True def action_confirm(self, cr, uid, ids, context=None): for order in self.browse(cr, uid, ids, context=context): #must have cnc lines if not order.order_lines: raise osv.except_osv(_('Error!'), _('Please add lines for order [%s]%s')%(order.id, order.name)) for line in order.order_lines: if not line.drawing_file_name: raise osv.except_osv(_('Invalid Action!'), _('The line''s "Drawing PDF" file is required!')) #set state to done self._set_state(cr, uid, ids, 'confirmed',context) #send email to the user group that can approve self._email_notify(cr, uid, ids, 'need your approval', ['mrp_cnc_wo_group_approve'],context) return True def action_cancel(self, cr, uid, ids, context=None): self._check_done_lines(cr,uid,ids,context) #set the cancel state self._set_state(cr, uid, ids, 'cancel',context) return True def action_draft(self, cr, uid, ids, context=None): #set the cancel state self._set_state(cr, uid, ids, 'draft',context) return True def action_approve(self, cr, uid, ids, context=None): #set the cancel state self._set_state(cr, uid, ids, 'approved',context) #send email to the user group that can CNC done self._email_notify(cr, uid, ids, 'was approved', ['mrp_cnc_wo_group_cnc_mgr'],context) return True def action_reject_callback(self, cr, uid, ids, message, context=None): #set the draft state self._set_state(cr, uid, ids, 'rejected',context) self.write(cr,uid,ids,{'reject_message':message}) #send email to the user for the rejection message email_from = self.pool.get("res.users").read(cr, uid, uid, ['email'],context=context)['email'] for order in self.browse(cr, uid, ids, context=context): if order.create_uid.email: email_content = 'CNC reminder: %s was rejected'%(order.name) utils.email_send_group(cr, uid, email_from, order.create_uid.email,email_content,email_content, context = context) return True def action_reject(self, cr, uid, ids, context=None): ctx = dict(context) ctx.update({'confirm_title':'Confirm rejection message', 'src_model':'drawing.order', "model_callback":'action_reject_callback',}) return self.pool.get('confirm.message').open(cr, uid, ids, ctx) def unlink(self, cr, uid, ids, context=None): orders = self.read(cr, uid, ids, ['state'], context=context) for s in orders: if s['state'] not in ['draft','cancel']: raise osv.except_osv(_('Invalid Action!'), _('Only the orders in draft or cancel state can be delete.')) self._check_done_lines(cr,uid,ids,context) return super(drawing_order, self).unlink(cr, uid, ids, context=context) def copy(self, cr, uid, id, default=None, context=None): if not default: default = {} old_data = self.read(cr,uid,id,['name'],context=context) default.update({ 'name': '%s (copy)'%old_data['name'], 'mfg_task_id': None, 'sale_product_ids': None, 'reject_message':None, }) return super(drawing_order, self).copy(cr, uid, id, default, context) def print_pdf(self, cr, uid, ids, context): order_line_ids = [] for id in ids: order = self.read(cr, uid, id, ['name','order_lines'],context=context) if len(ids) == 1: context['order_name'] = order['name'] order_line_ids += order['order_lines'] return self.pool.get('drawing.order.line').print_pdf(cr, uid, order_line_ids, context=context)
m.update(module.name) cert_num = int(m.hexdigest(), 16) oldcertif = obj_module.search(cr, uid, [("certificate", "=", cert_num)]) if oldcertif: raise osv.except_osv(_("Error !"), _("Certificate code Already Exists.")) else: obj_module.write(cr, uid, module.id, {"certificate": cert_num}) return True _name = "maintenance.maintenance.module" _description = "maintenance modules" _columns = { "name": fields.char("Name", size=128, required=True, readonly=False), "version": fields.char("Versions", size=64, readonly=False), "certificate": fields.char("Certificate Code", size=42, required=False, readonly=False), "path": fields.function(_get_module_path, method=True, string="Path", type="char", size=512, readonly=True), "technical_certificate": fields.selection( [("not_started", "Not Started"), ("failed", "Failed"), ("succeeded", "Succeeded"), ("skipped", "Skipped")], "Technical Certification", ), "functional_certificate": fields.selection( [("not_started", "Not Started"), ("failed", "Failed"), ("succeeded", "Succeeded"), ("skipped", "Skipped")], "Functional Certification", ), "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"),
class drawing_order_line(osv.osv): _name = "drawing.order.line" _description = "Drawing Order Line" _rec_name = "drawing_file_name" _columns = { 'order_id': fields.many2one('drawing.order','Drawing Order'), 'product_id': fields.many2one('product.product','Sub Product'), 'drawing_file_name': fields.char('Drawing PDF Name', size=64), 'drawing_file': fields.function(utils.field_get_file, fnct_inv=utils.field_set_file, string="Drawing PDF", type="binary", multi="_get_file",), 'step_ids': fields.many2many('drawing.step', string='Working Steps'), 'company_id': fields.related('order_id','company_id',type='many2one',relation='res.company',string='Company'), 'create_uid': fields.many2one('res.users','Creator',readonly=True), 'create_date': fields.datetime('Creation Date', readonly=True), 'state': fields.selection([('draft','Draft'),('ready','Ready'),('confirmed','Confirmed'),('approved','Approved'),('rejected','Rejected'),('cancel','Cancelled')], 'Status', required=True, readonly=True), #order fields to show in the drawing files view 'sale_product_ids': fields.related('order_id','sale_product_ids',type='many2many',relation='sale.product',rel='drawing_order_id_rel',id1='drawing_order_id',id2='id_id', string="MFG IDs",readonly=True, states={'draft':[('readonly',False)],'rejected':[('readonly',False)]}), 'main_part_id': fields.related('order_id','main_part_id',type='many2one',relation='product.product',string='Main Product'), } _defaults = { 'state': 'draft', } def _format_file_name(self, file_name): file_reserved_char = ('/','\\','<','>','*','?') new_file_name = file_name for char in file_reserved_char: new_file_name = new_file_name.replace(char, '-') return new_file_name def print_pdf(self, cr, uid, ids, context): attachment_obj = self.pool.get('ir.attachment') output = PdfFileWriter() page_cnt = 0 order = self.browse(cr, uid, ids[0], context=context) lines = self.browse(cr, uid, ids, context=context) for line in lines: if line.drawing_file_name and line.drawing_file_name.lower().endswith('.pdf'): file_ids = attachment_obj.search( cr, uid, [('name', '=', 'drawing_file'), ('res_id', '=', line.id), ('res_model', '=', 'drawing.order.line')]) if file_ids: attach_file = attachment_obj.file_get(cr, uid, file_ids[0],context=context) input = PdfFileReader(attach_file) for page in input.pages: output.addPage(page) page_cnt += 1 if page_cnt > 0: full_path_temp = attachment_obj.full_path(cr, uid, 'temp') # file_name = self._format_file_name(order.name) file_name = "Drawing" if context.get('order_name'): file_name = '%s-%s'%(file_name, self._format_file_name(context.get('order_name'))) full_file_name = '%s/%s.pdf'%(full_path_temp, file_name,) outputStream = file(full_file_name, "wb") output.write(outputStream) outputStream.close() filedata = open(full_file_name,'rb').read().encode('base64') os.remove(full_file_name) return self.pool.get('file.down').download_data(cr, uid, "%s.pdf"%(file_name,), filedata, context) else: raise osv.except_osv(_("Error!"),'No PDF files were found!') return False def unlink(self, cr, uid, ids, context=None): #delete the attachments for id in ids: utils.field_set_file(self, cr, uid, id, 'drawing_file', None, {'unlink':True}, context=None) resu = super(drawing_order_line, self).unlink(cr, uid, ids, context=context) return resu def _check_file_name(self,cr,uid,ids,context=None): for record in self.browse(cr, uid, ids, context=context): same_file_name_ids = self.search(cr, uid, [('order_id','=',record.order_id.id),('id','!=',record.id),('drawing_file_name','=',record.drawing_file_name)],context=context) if same_file_name_ids: raise osv.except_osv(_('Error'), _('Dwaring file "%s" is duplicated under same order!')% (record.file_name,)) return True _constraints = [ (_check_file_name, 'Drawing file name is duplicated under same order!', ['file_name']) ] def copy_data(self, cr, uid, id, default=None, context=None): if not default: default = {} line_data = self.browse(cr,uid,id,context=context) default.update({ 'drawing_file':line_data.drawing_file }) return super(drawing_order_line, self).copy_data(cr, uid, id, default, context)
class autobus(osv.Model): def _check_asientos(self, cr, uid, ids): # Los servicios tienen que tener almenos 0.1 KM para poder registrarse bus = self.browse(cr, uid, ids[0], context=None) if bus.numAsientos <= 11: return False return True def _numero_servicios(self, cr, uid, ids, field, args, context=None): servicios = 0 for autobus in self.browse(cr, uid, ids, context=context): servicios = len(autobus.servicio_id) return servicios def onchange_consumo(self, cr, uid, ids, consum, context=None): consumoMinimo = 1.00 if consum < consumoMinimo: res = {'value': {'consumo': consumoMinimo}} elif consum > consumoMinimo: res = {'value': {'consumo': consum}} return res _name = 'autobus' _description = 'Informacion sobre autobus' _columns = { 'name': fields.char('Matricula', size=8, required=True, readonly=False), 'numAsientos': fields.integer('Numero de Plazas', required=True), 'modelo': fields.char('Modelo de Autobus', size=32, required=False, readonly=False), 'consumo': fields.float('Consumo (L/Km)', required=True), 'revisado': fields.boolean( 'Necesita Revision'), #Cada mes este atributo pasara a FALSE 'mantenimiento_id': fields.one2many("mantenimiento", "matricula_id", "Mantenimientos"), 'servicio_id': fields.one2many("servicio", "matricula_id", "Servicios"), 'numServicios': fields.function(_numero_servicios, type='integer', string="Número de Servicios", store=True) } _constraints = [ (_check_asientos, 'El numero de asientos no pueden ser negativos', ['numAsientos']) ] _sql_constraints = [ ('matricula_uniq', 'unique (name)', 'Ya existe un autobus con esa matricula'), ]
class purchase(osv.osv): """ Modify purchase order to fit foreign purchase order """ def _calculate_bills_amount(self, cr, uid, ids): """ To calculate bills total amouunt @return: True """ for purchase in self.browse(cr, uid, ids): bill_amount_sum = 0.0 for bills in purchase.purchase_bills: bill_amount_sum += bills.bill_amount self.write(cr, uid, purchase.id, { 'bills_amoun_total': bill_amount_sum, }) return True def _amount_all(self, cr, uid, ids, field_name, arg, context=None): """ Functional field function to calculate the amount_total,amount_untaxed, amount_tax and written_total of purchase order to add exstra amount to the purchase order. @return: Dictionary of fields value """ res = super(purchase, self)._amount_all(cr, uid, ids, field_name, arg, context) for order in self.browse(cr, uid, ids, context=context): freight_all = 0.0 packing_all = 0.0 for line in order.order_line: freight_all += line.price_unit_freight * line.product_qty packing_all += line.price_unit_packing * line.product_qty self.write(cr, uid, order.id, { 'freight': (freight_all), 'packing': (packing_all) }) res[order.id]['amount_total'] = res[ order.id]['amount_untaxed'] + res[order.id]['amount_tax'] + ( freight_all) + (packing_all) currency_format = order.company_id.currency_format total = res[order.id]['amount_total'] if currency_format == 'ar': res[order.id]['written_total'] = amount_to_text_ar( total, currency_format, order.currency_id['units_name'], order.currency_id['cents_name']) else: res[order.id]['written_total'] = amount_to_text_ar(total) return res def _get_order(self, cr, uid, ids, context=None): """ Override to calling the function from purchase order object. @return: super _get_order method """ line = self.pool.get('purchase.order') return super(purchase, line)._get_order(cr, uid, ids, context) DELIVERY_SELECTION = [ ('air_freight', 'Air Freight'), ('sea_freight', 'Sea Freight'), ('land_freight', 'Land Freight'), ('free_zone', 'Free Zone'), ] TYPE_SELECTION = [ ('internal', 'Internal Purchase'), ('foreign', 'Foreign Purchase'), ] _inherit = 'purchase.order' _columns = { 'account_voucher_ids': fields.many2many('account.voucher', 'purchase_order_voucher', 'purchase_id', 'voucher_id', 'Account voucher'), 'purchase_bills': fields.one2many('purchase.bills', 'purchase_id', 'Other Cost'), 'bills_amoun_total': fields.float('Billing Total amount', digits=(16, 2)), 'purchase_type': fields.selection(TYPE_SELECTION, 'Purchase Type', select=True), 'final_invoice_no': fields.integer('Final Invoice No', size=64, states={'done': [('readonly', True)]}), 'final_invoice_date': fields.date('Final Invoice Date', states={'done': [('readonly', True)]}), 'delivery_method': fields.selection(DELIVERY_SELECTION, 'Method of dispatch', select=True, required=False, states={'done': [('readonly', True)]}), 'freight': fields.float('Freight', digits=(16, 2)), 'packing': fields.float('Packing', digits=(16, 2)), 'written_total': fields.function(_amount_all, method=True, string='written Total', type='char', size=128, store={ 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line', 'taxes_id'], 10), 'purchase.order.line': (_get_order, None, 10), }, multi="sums", help="The total written amount"), 'amount_untaxed': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Purchase Price'), string='Untaxed Amount', store={ 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line', 'taxes_id'], 10), 'purchase.order.line': (_get_order, None, 10), }, multi="sums", help="The amount without tax"), 'amount_tax': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Purchase Price'), string='Taxes', store={ 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line', 'taxes_id'], 10), 'purchase.order.line': (_get_order, None, 10), }, multi="sums", help="The tax amount"), 'amount_total': fields.function(_amount_all, method=True, digits_compute=dp.get_precision('Purchase Price'), string='Total', store={ 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line', 'taxes_id'], 10), 'purchase.order.line': (_get_order, None, 10), }, multi="sums", help="The total amount"), } _defaults = { 'bills_amoun_total': 0.0, 'freight': 0.0, 'packing': 0.0, 'purchase_type': 'internal', } def wkf_sign_order(self, cr, uid, ids, context=None): """ Workflow function override to create voucher with the extra cost prices. @return: True """ company_obj = self.pool.get('res.users').browse(cr, uid, uid).company_id for po in self.browse(cr, uid, ids, context=context): if not po.location_id: raise osv.except_osv( _('NO Stock Location !'), _('Please chose stock location then make Confirmation.')) self.write(cr, uid, ids, { 'state': 'sign', }) voucher_obj = self.pool.get('account.voucher') voucher_line_obj = self.pool.get('account.voucher.line') purchase_obj = self.pool.get('purchase.order').browse(cr, uid, ids) if not company_obj: company_obj = purchase_obj.company_id list = [] for purchase in purchase_obj: if purchase.purchase_bills: for bill in purchase.purchase_bills: journal = bill.type.property_type_journal account = bill.type.property_type_account voucher_id = voucher_obj.create( cr, uid, { 'amount': bill.bill_amount, 'type': 'purchase', 'date': time.strftime('%Y-%m-%d'), 'partner_id': bill.partner_id.id, 'journal_id': journal.id, 'reference': purchase.name, 'reference': purchase.name, }) list.append(voucher_id) vocher_line_id = voucher_line_obj.create( cr, uid, { 'amount': bill.bill_amount, 'voucher_id': voucher_id, 'account_id': account.id, 'type': 'dr', 'name': bill.description, }) self.write(cr, uid, ids, {'account_voucher_ids': [(6, 0, list)]}) purchase._calculate_bills_amount() self.write(cr, uid, ids, { 'state': 'sign', }) return True def wkf_confirm_order(self, cr, uid, ids, context=None): """ Workflow function override to force calculate the extra price amount. @return: super wkf_confirm_order method """ #for purchases in self.browse(cr, uid, ids): #purchases._calculate_bills_amount() #for line in purchases.order_line: #line._calculate_extra_amount(purchases) return super(purchase, self).wkf_confirm_order(cr, uid, ids, context) def create_supplier_invoive(self, cr, uid, ids, context=None): """ Function For create Invoice From Button add check whether it created before. @return: True """ order_obj = self.browse(cr, uid, ids)[0] invoice_obj = self.pool.get('account.invoice') invoice_line_obj = self.pool.get('account.invoice.line') invoice_record = invoice_obj.search(cr, uid, [('origin', '=', order_obj.name)]) if invoice_record: raise osv.except_osv( _('Duplicated Invoices !'), _('You are Already Create Invoice for this order before.')) invoice_id = super(purchase, self).action_invoice_create(cr, uid, ids, context) self.write(cr, uid, ids, {'invoice_method': 'manual'}) return True def action_invoice_create(self, cr, uid, ids, context=None): """ Override to add invoice lines to manage freight and packing prices. @return: invoice id """ invoice_obj = self.pool.get('account.invoice') invoice_line_obj = self.pool.get('account.invoice.line') invoice_id = super(purchase, self).action_invoice_create(cr, uid, ids, context) for order in self.browse(cr, uid, ids): company_obj = order.company_id invoice_obj.write(cr, uid, invoice_id, {'currency_id': order.currency_id.id}) line_id = invoice_line_obj.search( cr, uid, [('invoice_id', '=', invoice_id)], limit=1) account_id = invoice_line_obj.browse(cr, uid, line_id)[0].account_id.id if order.freight > 0.0: invoice_line_id = invoice_line_obj.create( cr, uid, { 'name': 'Freight', 'origin': order.name, 'invoice_id': invoice_id, 'uos_id': 0, 'product_id': 0, 'account_id': account_id, 'price_unit': order.freight, 'discount': 0, 'quantity': 1, 'invoice_line_tax_id': 0, 'account_analytic_id': 0, }) if order.packing > 0.0: invoice_line_id = invoice_line_obj.create( cr, uid, { 'name': 'Packing', 'origin': order.name, 'invoice_id': invoice_id, 'uos_id': 0, 'product_id': 0, 'account_id': account_id, 'price_unit': order.packing, 'discount': 0, 'quantity': 1, 'invoice_line_tax_id': 0, 'account_analytic_id': 0, }) if order.purchase_type == 'foreign': account_from_company = company_obj.purchase_foreign_account journal_id = company_obj.purchase_foreign_journal if not account_from_company: raise osv.except_osv( _('NO Account !'), _('no account defined for purchase foreign.')) if not journal_id: raise osv.except_osv( _('NO Journal !'), _('no journal defined for purchase foreign.')) invoice = invoice_obj.browse(cr, uid, invoice_id) invoice_obj.write(cr, uid, invoice_id, {'journal_id': journal_id.id}) for line in invoice.invoice_line: invoice_line_obj.write( cr, uid, line.id, {'account_id': account_from_company.id}) #print"invoice_id %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%",invoice_id return invoice_id def action_picking_create(self, cr, uid, ids, *args): """ Override to read account of purchase foreign from the company, and add foreign purchase price to picking. @return: picking id """ res = {} picking_obj = self.pool.get('stock.picking') picking_id = super(purchase, self).action_picking_create(cr, uid, ids, *args) move_obj = self.pool.get('stock.move') currency_obj = self.pool.get('res.currency') for purchase_obj in self.browse(cr, uid, ids): company_obj = purchase_obj.company_id if purchase_obj.purchase_type == 'foreign': account_from_company = company_obj.purchase_foreign_account if not account_from_company: raise osv.except_osv( _('NO Account !'), _('no account defined for purchase foreign.')) else: res = { 'account_id': account_from_company.id or False, 'company_id': company_obj.id, } picking_obj.write(cr, uid, picking_id, res) move = {} total_amount = 0.0 for order_line in purchase_obj.order_line: stock_move_obj = move_obj.search( cr, uid, [('purchase_line_id', '=', order_line.id)]) total_amount = order_line.price_unit_freight + order_line.price_unit_packing + order_line.price_unit new_price = currency_obj.compute( cr, uid, order_line.order_id.currency_id.id, order_line.order_id.company_id.currency_id.id, total_amount, purchase_obj.date_order) price = new_price if purchase_obj.purchase_type == 'internal': price = order_line.price_unit + order_line.price_unit_freight + order_line.price_unit_packing + order_line.price_unit_tax move = { 'price_unit': price, } move_obj.write(cr, uid, stock_move_obj, move) return picking_id
result[rec.id] = rec.mode and rec.mode.type.name or "" return result def _name_get(self, cr, uid, ids, field_name, arg, context=None): result = {} for rec in self.browse(cr, uid, ids, context): result[rec.id] = rec.reference return result _columns = { "type": fields.selection( [("payable", "Payable"), ("receivable", "Receivable")], "Type", readonly=True, select=True ), # invisible field to filter payment order lines by payment type "payment_type_name": fields.function( _payment_type_name_get, method=True, type="char", size=64, string="Payment type name" ), # The field name is necessary to add attachement documents to payment orders "name": fields.function(_name_get, method=True, type="char", size=64, string="Name"), "create_account_moves": fields.selection( [("bank-statement", "Bank Statement"), ("direct-payment", "Direct Payment")], "Create Account Moves", required=True, states={"done": [("readonly", True)]}, help='Indicates when account moves should be created for order payment lines. "Bank Statement" ' 'will wait until user introduces those payments in bank a bank statement. "Direct Payment" ' "will mark all payment lines as payied once the order is done.", ), "period_id": fields.many2one("account.period", "Period", states={"done": [("readonly", True)]}), } _defaults = {
class oebase_event_category(osv.osv): _name = 'oebase.event.category' def name_get(self, cr, uid, ids, context=None): """Return the category's display name, including their direct parent by default. :param dict context: the ``event_category_display`` key can be used to select the short version of the category (without the direct parent), when set to ``'short'``. The default is the long version.""" if context is None: context = {} if context.get('event_category_display') == 'short': return super(oebase_event_category, self).name_get(cr, uid, ids, context=context) if isinstance(ids, (int, long)): ids = [ids] 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_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] if not context: context = {} if name: name = name.split(' / ')[-1] ids = self.search(cr, uid, [('name', operator, name)] + args, limit=limit, context=context) else: ids = self.search(cr, uid, args, limit=limit, context=context) return self.name_get(cr, uid, ids, context) 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) _columns = { 'name': fields.char('Event Category', required=True, size=64, translate=True), 'parent_id': fields.many2one('oebase.event.category', 'Parent Category', select=True, ondelete='restrict'), 'description': fields.text(string='Description'), 'notes': fields.text(string='Notes'), 'complete_name': fields.function(_name_get_fnc, type="char", string='Event Category', store=True), 'child_ids': fields.one2many('oebase.event.category', 'parent_id', 'Child Categories'), 'active': fields.boolean( 'Active', help= "If unchecked, it will allow you to hide the category without removing it." ), 'parent_left': fields.integer('Left parent', select=True), 'parent_right': fields.integer('Right parent', select=True), 'event_ids': fields.many2many('oebase.event', 'oebase_event_category_rel', 'category_id', 'event_id', 'Events'), } _constraints = [ (osv.osv._check_recursion, 'Error! You can not create recursive categories.', ['parent_id']) ] _defaults = { 'active': 1, } _parent_store = True _parent_order = 'name' _order = 'parent_left'
res = phonenumbers.format_number(phonenumbers.parse(partner.get(fromfield), None), phonenumbers.PhoneNumberFormat.E164) except Exception, e: _logger.error("Cannot reformat the phone number '%s' to E.164 format. Error message: %s" % (partner.get(fromfield), e)) _logger.error("You should fix this number and run the wizard 'Reformat all phone numbers' from the menu Settings > Configuration > Asterisk") # If I raise an exception here, it won't be possible to install # the module on a DB with bad phone numbers #raise osv.except_osv(_('Error :'), _("Cannot reformat the phone number '%s' to E.164 format. Error message: %s" % (partner.get(fromfield), e))) res = False result[partner['id']][tofield] = res #print "RESULT _format_phonenumber_to_e164", result return result _columns = { 'phone_e164': fields.function(_format_phonenumber_to_e164, type='char', size=64, string='Phone in E.164 format', readonly=True, multi="e164", store={ 'res.partner': (lambda self, cr, uid, ids, c={}: ids, ['phone'], 10), }), 'mobile_e164': fields.function(_format_phonenumber_to_e164, type='char', size=64, string='Mobile in E.164 format', readonly=True, multi="e164", store={ 'res.partner': (lambda self, cr, uid, ids, c={}: ids, ['mobile'], 10), }), 'fax_e164': fields.function(_format_phonenumber_to_e164, type='char', size=64, string='Fax in E.164 format', readonly=True, multi="e164", store={ 'res.partner': (lambda self, cr, uid, ids, c={}: ids, ['fax'], 10), }), } def _reformat_phonenumbers(self, cr, uid, vals, context=None): """Reformat phone numbers in international format i.e. +33141981242""" phonefields = ['phone', 'fax', 'mobile'] if any([vals.get(field) for field in phonefields]): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) # country_id on res.company is a fields.function that looks at
class fuel_plan(osv.osv): """ To manage fuel plan and its operations """ _name = "fuel.plan" _order = "name desc" STATE_SELECTION = [ ('draft', 'Draft'), ('confirmed', 'Waiting Review and Accreditation'), #('approve', 'Service Section Manager Approved'), ('done', 'Done'), ('cancel', 'Cancel')] def _cost_total(self, cr, uid, ids, field_name, arg, context={}): """ Functional field function Finds the total cost of fuel plan. @param field_name: list contains name of fields that call this method @param arg: extra arguments @return: Dictionary of cost values """ res = {} for fuel_plan in self.browse(cr, uid, ids, context=context): val = 0.0 for qty in fuel_plan.quantity_ids: val += qty.total_amount res[fuel_plan.id] = val return res def _fuel_total(self, cr, uid, ids,field_name, arg, context={}): """ Finds the total quantity of gasoline and petrol. @param field_name: list contains name of fields that call this method @param arg: extra arguments @return: Dictionary of fuel total values """ res={} for fuel_order in self.browse(cr, uid, ids, context=context): res[fuel_order.id] = {'gasoline_total': 0.0, 'diesal_total': 0.0, 'electric_total': 0.0, 'hybrid_total': 0.0} gasoline_total = 0.0 diesal_total = 0.0 hybrid_total = 0.0 electric_total = 0.0 for line in fuel_order.quantity_ids: gasoline_total += line.fuel_qty if (line.fuel_type=='gasoline') else 0 diesal_total += line.fuel_qty if (line.fuel_type=='diesel') else 0 electric_total += line.fuel_qty if (line.fuel_type=='electric') else 0 hybrid_total += line.fuel_qty if (line.fuel_type=='hybrid') else 0 res[fuel_order.id]['gasoline_total'] = gasoline_total res[fuel_order.id]['diesal_total'] = diesal_total res[fuel_order.id]['electric_total'] = electric_total res[fuel_order.id]['hybrid_total'] = hybrid_total return res _columns = { 'name': fields.char('Reference', size=64, required=False, select=True, readonly=True, help="Unique Number for Fuel Plan, Computed Automatically When Fuel Plan Order Create"), 'date' : fields.date('Date',required=True, readonly=True,), 'month': fields.selection([(str(n),str(n)) for n in range(1,13)],'Month', readonly=True, select=True,), 'year': fields.char('Year', size=64,readonly=True), 'quantity_ids':fields.one2many('fuel.quantity', 'plan_id' , 'Department Fuel', states={'draft':[('readonly',True)],'confirmed':[('readonly',True)],'approve':[('readonly',True)]}), 'state': fields.selection(STATE_SELECTION,'State', readonly=True, select=True,), 'company_id': fields.many2one('res.company', 'Company', required=True, readonly=True, states={'draft':[('readonly',True)],'confirmed':[('readonly',True)],'approve':[('readonly',True)]}), 'department_id': fields.many2one('hr.department', 'Department',readonly=True), 'cost': fields.function(_cost_total, method=True, digits_compute=dp.get_precision('Account'), string='Cost', states={'draft':[('readonly',True)],'confirmed':[('readonly',True)],'approve':[('readonly',True)]}), 'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}), 'voucher_no': fields.many2one('account.voucher', 'Voucher Number',readonly=True,), 'gasoline_total': fields.function(_fuel_total, method=True, digits=(16,2), string='Total Gasoline', multi='total_fuel', states={'draft':[('readonly',True)],'confirmed':[('readonly',True)],'approve':[('readonly',True)]}), 'diesal_total': fields.function(_fuel_total, method=True, digits=(16,2), string='Total Diesal', multi='total_fuel', states={'draft':[('readonly',True)],'confirmed':[('readonly',True)],'approve':[('readonly',True)]}), 'electric_total': fields.function(_fuel_total, method=True, digits=(16,2), string='Total Electric', multi='total_fuel', states={'draft':[('readonly',True)],'confirmed':[('readonly',True)],'approve':[('readonly',True)]}), 'hybrid_total': fields.function(_fuel_total, method=True, digits=(16,2), string='Total Hybrid', multi='total_fuel', states={'draft':[('readonly',True)],'confirmed':[('readonly',True)],'approve':[('readonly',True)]}), 'notes': fields.text('Notes', size=512), 'type_plan': fields.selection([('constant_fuel','Constant Fuel'),('mission_extra','Mission Extra')],'Plan Type', size=512,states={'draft':[('readonly',True)],'cancel':[('readonly',True)],'confirmed':[('readonly',True)],'approve':[('readonly',True)]}), 'payment_method': fields.selection([('voucher', 'Voucher'),('enrich', 'Enrich')],'Payment', states={'done':[('readonly',True)],'draft':[('readonly',True)],'confirmed':[('readonly',True)]}, select=True), 'enrich_id':fields.many2one('payment.enrich','Enrich'), 'cost_subtype_id': fields.many2one('fleet.service.type', 'Type',help='Cost type purchased with this cost'), 'place_id':fields.many2one('vehicle.place', 'Place',), } _sql_constraints = [ ('name_uniq', 'unique(name)', _('Fuel Plan Order Reference Must Be Unique!')), ] _defaults = { 'name': lambda self, cr, uid, context: '/', 'state': 'draft', 'payment_method':'enrich', 'date': lambda *a: time.strftime('%Y-%m-%d'), 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'fuel.plan', context=c), } def create(self, cr, uid, vals, context=None): """ Create new entry sequence for every new fuel plan Record. @param vals: record to be created @return: return a result that create a new record in the database """ if ('name' not in vals) or (vals.get('name')=='/'): vals['name'] = self.pool.get('ir.sequence').get(cr, uid, 'fuel.plan') return super(fuel_plan, self).create(cr, uid, vals, context) def plan_cancel(self, cr, uid, ids, context=None): """ change state of fuel plan order from any state To cancel. @return: Boolean True """ return self.write(cr, uid, ids, {'state':'cancel'},context=context) def approve(self, cr, uid, ids, context=None): """ change state of fuel plan order To approve. @return: Boolean True """ return self.write(cr, uid, ids, {'state':'approve'},context=context) def confirmed(self, cr, uid, ids, context=None): """ change state of fuel plan order To confirmed. @return: Boolean True """ return self.write(cr, uid, ids, {'state':'confirmed'},context=context) def action_cancel_draft(self, cr, uid, ids,context=None): """ Return fuel plan state to draft. @return: Boolean True or false """ return self.write(cr, uid, ids, {'state':'draft'},context=context) def copy(self, cr, uid, id, default=None, context=None): """ Duplicate the fuel plan record and generate sequence to the new record. @param default: dict that contains some fields default value and used in the copy method @return: Id of the new record """ if default is None: default = {} default.update({'state':'draft', 'voucher_no':False, 'enrich_id':False, 'date':datetime.datetime.now().strftime ("%m/%d/%Y")}) if ('name' not in default): default['name'] = self.pool.get('ir.sequence').get(cr, uid, 'fuel.plan') return super(fuel_plan, self).copy(cr, uid, id, default, context) def unlink(self, cr, uid, ids, context=None): """ Delete the fuel plan record if record in draft state. @return: super unlink method """ if self.search(cr, uid,[('id','in',ids),('state','!=','draft')],context=context): raise osv.except_osv(_('Invalid Action Error'), _('In Order To Delete Fuel Plan Order(s), It Must Be In Draft State!')) return super(fuel_plan, self).unlink(cr, uid, ids, context=context) def create_voucher(self,cr,uid,ids,context=None): """ create a financial voucher for Fuel plan. @return: Boolean True """ voucher_obj = self.pool.get('account.voucher') affairs_account_obj = self.pool.get('admin_affairs.account') for plan in self.browse(cr, uid, ids, context=context): affairs_account_ids = affairs_account_obj.search(cr, uid, [('model_id','=','fuel.plan'), ('service_id','=',plan.cost_subtype_id.id)], context=context) if not affairs_account_ids: raise osv.except_osv(_('Configuration Error'), _("There Is No Configuration For Fuel Plan Accounting!")) affairs_account = affairs_account_obj.browse(cr, uid, affairs_account_ids[0], context=context) voucher_id = voucher_obj.create(cr, uid, { 'amount':plan.cost, 'journal_id':affairs_account.journal_id.id , 'type': 'purchase', 'date': time.strftime('%Y-%m-%d'), 'partner_id': plan.partner_id.id, 'department_id': plan.department_id.id, 'state': 'draft', 'notes': plan.notes, 'narration': _('Fuel Plan No: ')+plan.name, 'line_dr_ids': [(0,0,{ "account_analytic_id":(affairs_account.analytic_id and affairs_account.analytic_id.id) or (plan.department_id and (plan.department_id.analytic_account_id and plan.department_id.analytic_account_id.id) or False), 'account_id': affairs_account.account_id.id, 'amount':plan.cost, 'type':'dr', 'name': plan.name, })] }, context=context) self.write(cr, uid, plan.id,{'state': 'done','voucher_no':voucher_id},context=context) copy_attachments(self,cr,uid,[plan.id],'fuel.plan',voucher_id,'account.voucher', context) return True def done(self, cr, uid, ids, context={}): """ Finish the fuel plan order and create two picking, one for fixed fuel and another for extra fuel. @return: Boolean True """ '''payment_enrich_lines_obj = self.pool.get('payment.enrich.lines') for fuel_plan in self.browse(cr, uid, ids,context): if not fuel_plan.quantity_ids: raise osv.except_osv(_('ValidateError'), _('In Order To Complete Fuel Plan Order You need To Enter Fuel Quantities!')) if fuel_plan.payment_method == 'enrich': details = 'Fixed Fuel Plan No:'+fuel_plan.name payment_enrich_lines_obj.create(cr, uid, { 'enrich_id':fuel_plan.enrich_id.id, 'cost': fuel_plan.cost, 'date':time.strftime('%Y-%m-%d'), 'state':'draft', 'name':details, 'department_id':fuel_plan.department_id.id, 'model_id':'fuel.plan', }, context=context) copy_attachments(self,cr,uid,[fuel_plan.id],'fuel.plan',fuel_plan.enrich_id.id,'payment.enrich', context) elif fuel_plan.payment_method == 'voucher': self.create_voucher(cr,uid,ids,context)''' return self.write(cr, uid, ids, {'state':'done'}, context=context)
'tml_source':fields.selection([ ('database','Database'), ('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'),
_description = "CMS Placeholder" _rec_name = "slot_id" _order = "slot_id" SHORT_BODY_LENGTH = 100 def _get_short_body(self, cr, uid, ids, field_name, arg, context=None): res = {} for r in self.browse(cr, uid, ids, context=context): if not r.body: res[r.id] = r.body try: strip_body = html.fromstring(r.body).text_content().strip() except Exception, exc: strip_body = "NOT VALID HTML_TEXT" short_body = strip_body[: self.SHORT_BODY_LENGTH] if len(strip_body) > self.SHORT_BODY_LENGTH: short_body += "..." res[r.id] = short_body return res _columns = { "slot_id": fields.many2one("cms.slot", "Slot", required=True, select=1), "body": fields.text("Body"), "title_id": fields.many2one("cms.title"), "short_body": fields.function(_get_short_body, method=True, string="Short Body", type="char"), } cms_placeholder()