class pant_form(osv.osv): _name = 'pant.form' _columns = { 'name': fields.char('Nombre', size=300, required=True), 'html': fields.html('Html Body', required=True), }
class PR(osv.osv): _name = 'pr' _columns = { 'name': fields.char('Ref No', required=True), 'tanggal': fields.date('Date', required=True), 'duedate': fields.date('Due Date'), # 'salesman_id':fields.many2one('res.users','Sales Person',required=True), 'salesman_id': fields.many2one('res.users', "Sales Person", required=True), 'customer_id': fields.many2one('res.partner', 'Customer', domain=[('customer', '=', True)], required=True), 'ref_pr': fields.char('No PR', required=True, select=True), 'location': fields.selection([('ws', 'Work Shop'), ('site', 'Site')], ' Location Of Work', required=True), 'notes': fields.html('Terms and Conditions'), 'state': fields.selection([ ('draft', 'Draft'), ('confirm', 'Confirm'), ('done', 'Done'), ], 'Status'), } def create(self, cr, uid, vals, context=None): vals['name'] = self.pool.get('ir.sequence').get(cr, uid, 'pr') return super(PR, self).create(cr, uid, vals, context=context) def submit(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'confirm'}) def setdraft(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'draft'}) def confirm(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'done'}) _defaults = { 'name': '/', 'tanggal': time.strftime('%Y-%m-%d'), 'state': 'draft' }
class sale_order(osv.osv): def _amount_untaxed_pset(self, cr, uid, ids, field_name, arg, context=None): res = {} if context is None: context = {} for order in self.browse(cr, uid, ids, context=context): amount = order.amount_untaxed / (order.number_of_set == 0 and 1 or order.number_of_set) res[order.id] = amount return res def _search_mrp_created(self, cr, uid, obj, name, args, domain=None, context=None): if not len(args): return [] for arg in args: if arg[1] == '=': if not arg[2]: ids = self.search(cr, uid, [('ref_mo_ids', '=', False)], context=context) else: ids = self.search(cr, uid, [('ref_mo_ids', '<>', False)], context=context) else: return [] return [('id', 'in', [id for id in ids])] def _mrp_created(self, cr, uid, ids, name, arg, context=None): res = dict.fromkeys(ids, False) for order in self.browse(cr, uid, ids, context=context): if order.ref_mo_ids: res[order.id] = True return res _inherit = "sale.order" _columns = { 'header_msg': fields.html('Header Message', readonly=False), 'doc_version': fields.integer('Version', required=True, readonly=True, states={'draft': [('readonly', False)]}), 'ref_quote_no': fields.char('Ref Quotate Number', size=64, readonly=True), 'number_of_set': fields.integer('Number of Sets', readonly=True, states={'draft': [('readonly', False)]}), 'amount_untaxed_pset': fields.function(_amount_untaxed_pset, digits_compute=dp.get_precision('Account'), string='Untaxed Amount/Set'), 'ref_attention_name': fields.char('Attention', size=128, readonly=False), 'ref_project_name': fields.char('Ref Project Name', size=128, readonly=False), 'is_international': fields.boolean( 'International', change_default=True, help='This check book will have affect on Document Sequence Number' ), 'add_disc_amt_ex': fields.float('Additional Discount Amt (Ex)', digits=(4, 2), readonly=True, states={'draft': [('readonly', False)]}), 'note2': fields.text('Note'), 'ref_mo_ids': fields.one2many('mrp.production', 'order_id', 'Reference MO', readonly=True), 'mrp_created': fields.function( _mrp_created, string='MO Created', type='boolean', fnct_search=_search_mrp_created, help="It indicates that sale order has at least one MO."), 'tag_no': fields.text('TAG No.'), } _defaults = { 'doc_version': 1, 'number_of_set': 1, } def action_button_confirm(self, cr, uid, ids, context=None): assert len( ids ) == 1, 'This option should only be used for a single id at a time.' self.write( cr, uid, ids, { 'ref_quote_no': self.browse(cr, uid, ids[0]).name, 'date_order': time.strftime("%Y-%m-%d") }) order = self.browse(cr, uid, ids[0]) if order.is_international: new_name = self.pool.get('ir.sequence').get( cr, uid, 'confirmed.sale.order.inter') else: new_name = self.pool.get('ir.sequence').get( cr, uid, 'confirmed.sale.order') self.write(cr, uid, ids, {'name': new_name}) super(sale_order, self).action_button_confirm(cr, uid, ids, context=context) def copy(self, cr, uid, id, default=None, context=None): if context is None: context = {} if default is None: default = {} default.update({'ref_mo_ids': []}) context.update({'is_copied': True}) return super(sale_order, self).copy(cr, uid, id, default, context) def create(self, cr, uid, vals, context=None): # On creation, set number_of_set to 1. This will set number_of_set field visible. if not context.get('is_copied', False): vals.update({'number_of_set': 1}) is_international = vals.get('is_international', False) if is_international: new_name = self.pool.get('ir.sequence').get( cr, uid, 'sale.order.inter') vals['name'] = new_name return super(sale_order, self).create(cr, uid, vals, context=context) def write(self, cr, uid, ids, vals, context=None): res = super(sale_order, self).write(cr, uid, ids, vals, context=context) # if % = 0 and add_disc_amt_ex > 0, recalculate using add_disc_amt_ex if not isinstance(ids, types.ListType): # Make it a list ids = [ids] if not vals.get('add_disc') and vals.get('add_disc_amt_ex'): amount_untaxed = self.read(cr, uid, ids, ['amount_untaxed'])[0]['amount_untaxed'] if amount_untaxed: add_disc = (vals.get('add_disc_amt_ex') / amount_untaxed) * 100 vals['add_disc'] = add_disc res = super(sale_order, self).write(cr, uid, ids, vals, context=context) # else just set add_disc_amt_ex = add_disc_amt else: for id in ids: value = self.read(cr, uid, [id], ['add_disc_amt']) super(sale_order, self).write( cr, uid, [value[0]['id']], {'add_disc_amt_ex': value[0]['add_disc_amt']}) return res def onchange_number_of_set(self, cr, uid, ids, number_of_set, context=None): if context is None: context = {} number_of_set = number_of_set < 1 and 1 or number_of_set self.recompute_order_lines(cr, uid, ids, number_of_set, context=context) return {'value': {'number_of_set': number_of_set}} def recompute_order_lines(self, cr, uid, ids, number_of_set, context=None): if context is None: context = {} # res = { # 'value': {'order_line': [] }, # } if len(ids) > 0: line_pool = self.pool.get('sale.order.line') order = self.browse(cr, uid, ids[0], context=context) for line in order.order_line: line_pool.write( cr, uid, [line.id], { 'product_uom_qty': line.product_uom_qty_pset * number_of_set, 'number_of_set': number_of_set }) return True def _prepare_order_picking(self, cr, uid, order, context=None): res = super(sale_order, self)._prepare_order_picking(cr, uid, order, context=context) res.update({ 'ref_order_id': order.id, 'ref_project_name': order.ref_project_name }) return res
class account_expense(osv.Model): _inherit = 'account.expense' _columns = { 'amount_planed': fields.float('Planed Amount', digits_compute=dp.get_precision('Account'), readonly=True, states={'draft': [('readonly', False)]}, help="Planed incomes to receive"), 'date_end': fields.date('Date End', readonly=True, states={'draft': [('readonly', False)]}), 'description': fields.html('Description', readonly=True, states={'draft': [('readonly', False)]}), 'property_bank_journal_id': fields.property( 'account.journal', type='many2one', view_load=True, relation='account.journal', string='Bank Journal', readonly=True, states={'draft': [('readonly', False)]}, help="Default bank journal to make the automated cash transfers"), } def action_pre_approve(self, cr, uid, ids, context=None): for expense in self.browse(cr, uid, ids, context=context): if not expense.invoice_ids: raise osv.except_osv( _('User Error!'), _('You must register almost one invoice on invoices tab')) return super(account_expense, self).action_pre_approve(cr, uid, ids, context=context) def action_approve(self, cr, uid, ids, context=None): for expense in self.browse(cr, uid, ids, context=context): if expense.type == 'expenditure' and not self.pool.get( 'res.currency').is_zero(cr, uid, expense.currency_id, expense.amount_balance): raise osv.except_osv( _('User Error!'), _('Te balance amount must be zero (current balance:%d)') % (expense.amount_balance)) return super(account_expense, self).action_approve(cr, uid, ids, context=context) def action_generate_transfer(self, cr, uid, ids, context=None): context = context or {} transfer_obj = self.pool.get('account.transfer') for expense in self.browse(cr, uid, ids, context=context): amount = expense.amount_planed + expense.amount_transfer if amount <= 0.01: continue src_journal = expense.property_bank_journal_id dst_journal = expense.journal_id dst_partner_id = expense.partner_id.id value = transfer_obj.onchange_journal(cr, uid, ids, src_journal.id, dst_journal.id, time.strftime('%Y-%m-%d'), 1.0, amount)['value'] value.update( transfer_obj.onchange_amount(cr, uid, ids, 'dst_amount', 0.0, amount, value['exchange_rate'])['value']) transfer_obj.create(cr, uid, { 'company_id': expense.company_id.id, 'type': 'expense', 'origin': expense.name, 'src_journal_id': src_journal.id, 'src_amount': value['src_amount'], 'dst_journal_id': dst_journal.id, 'dst_partner_id': dst_partner_id, 'dst_amount': amount, 'exchange_rate': value['exchange_rate'], 'expense_id': expense.id, }, context=context) return super(account_expense, self).action_generate_transfer(cr, uid, ids, context=context)
class modelo_de_ejemplo(orm.Model): # Definimos el nombre de nuestro modelo. Recordamos que por convención # vamos a llamarlo con el "nombre del modulo"."nombre del modelo" _name = 'mi_modulo.modelo_de_ejemplo' # Determinamos el campo por el cuál queremos que se ordenen los registros # de nuestro modelo. _order = "name desc" # Por defecto OpenERP muestra el campo name en los campos relacionales, en # caso de que queramos que OpenERP muestre otro campo se lo indicaríamos # con el atributo _rec_name # _rec_name = "otro_name" # Definimos las columnas (propiedades) de nuestro objeto (modelo). _columns = { # Definimos un campo de nombre "name" el tipo es texto, de tamaño # máximo 5 carácteres, y al cuál especificamos a OpenERP que tiene que # mostrar como label el string "Nombre", por lo que en la interfaz # veremos un label "Nombre" seguido de un input text. 'name': fields.char(string="Name", size=5, change_default=True), 'create_date': fields.date('Creation date', readonly=True), 'create_uid': fields.many2one('res.users', 'Create User', readonly=True), 'write_date': fields.datetime('Date Modified', readonly=True), 'write_uid': fields.many2one('res.users', 'Last Modification User', readonly=True), # Indicamos otro campo de texto. 'otro_name': fields.char(string="Otro Nombre", help="Este campo es para ...\n" "Esta es otra línea", translate=True), # Boolean 'active': fields.boolean("Activo"), # Integer 'valor_a': fields.integer('Valor A', required=True), 'valor_b': fields.integer('Valor B', required=True, deprecated="Utiliza el valor_a"), 'valor_c': fields.integer('Valor C', readonly=True, states={ 'draft': [('readonly', False)], 'selled': [('invisible', True)], }), # Float 'float_a': fields.float('Float A', digits=(3, 2)), 'float_b': fields.float('Float B', digits=(1, 5)), # Text && HTML 'notes': fields.text('Notas del usuario', required=True), 'notes_ui': fields.html("Notas para el cliente", required=True), # Fechas 'date_start': fields.date('Fecha inicio'), 'date_end': fields.date('Fecha fin', readonly=True), # Fechas y horas 'datetime_start': fields.datetime('Fecha y hora inicio'), 'datetime_end': fields.datetime('Fecha y hora fin'), # Fichero, imagen, doc... 'file': fields.binary('Upload a file'), 'image': fields.binary('Upload your image', filters="*.png,*.jpg"), # Selection - Incluímos el special field "state" 'state': fields.selection([ ('draft', 'Borrador'), ('confirmed', 'Confirmado'), ('selled', 'Vendido'), ('cancelled', 'Cancelado'), ], string="States") } def create(self, cr, uid, vals, context=None): """ Aprovechamos para ver una de las formas de documentar los métodos en python. Al definir este método extendemos del create del ORM, por lo que podemos modificar el valor de los parámetros, o realizar cualquier tipo de gestión antes/después de crear el registro. :param cr: Cursor de la base de datos. :param uid: Id del usuario que ejecuta el método, para las comprobaciones de seguridad :param dict vals: Valores a guardar en el registro que vamos a crear. :param context: información común del usuario. Puede contener valores como el idioma del usuario, y la hora de este. """ # Definimos un breakpoint # pdb.set_trace() if vals['datetime_start'] and vals['datetime_end']: self.check_datetime(vals['datetime_start'], vals['datetime_end']) # El método create devuelve el id del registro recien creado. record_id = super(modelo_de_ejemplo, self).create(cr, uid, vals, context=context) # Realizamos acciones después de crear el registro. # Devolvemos el id del registro. return record_id def write(self, cr, uid, ids, vals, context=None): """ Sobreescribimos el método del ORM write. Este método se ejecutará cuando se modifique un valor de un registro. :param list ids: Lista de ids de los registros a modificarse. Todos estos registros comparten las mismas modificaciones dadas por vals. :param dict vals: Diccionario con key-> field , value-> valor a modificar, para los registros. :rtype: bool :return: Siempre devuelve True. """ _logger.info("ids = %r" % (ids)) _logger.error("vals = %r" % (vals)) _logger.warning("context = %r" % (context)) if 'datetime_start' in vals and 'datetime_end' in vals: if vals['datetime_start'] and vals['datetime_end']: self.check_datetime(vals['datetime_start'], vals['datetime_end']) return super(modelo_de_ejemplo, self).write(cr, uid, ids, vals, context=context) def _get_default_name(self, cr, uid, context=None, *args): return 'AAAAA' def _get_default_date_end(self, cr, uid, context=None, *args): today = datetime.datetime.now().date() end_date = today + datetime.timedelta(days=5) return end_date.strftime(DEF_DATE) # Definimos los valores por defecto de los fields anteriormente declarados. _defaults = { # Podemos definir el valor directamente, on invocando un método. # 'name': 'AAAAA' # 'name': lambda *a: 'AAAAA', 'name': _get_default_name, 'state': 'draft', 'active': lambda *a: True, 'date_start': fields.date.today(), 'date_end': _get_default_date_end, } def check_datetime(self, datetime_start, datetime_end, context=None): """ Comprobamos la lógica de fechas... """ # 1ro comprobamos que el field datetime_start venga inicializado. if datetime_start > datetime_end: raise openerp.exceptions.AccessError( "Las fechas de 'inicio' no pueden ser posteriores " "a las fechas 'fin'") return True