From 9514caf309312b1ccf67a00d006eb6e41d701ec9 Mon Sep 17 00:00:00 2001 From: "uco (OpenERP)" Date: Tue, 6 Apr 2010 12:22:09 +0530 Subject: [PATCH 01/30] [ADD,REF] mrp_repair: Added docstrings in all functions. Refactored code according to pep-8 standards. Improved coding i.e. removed self.pool.get from inside the loops. bzr revid: uco@tinyerp.co.in-20100406065209-sklmtp3dffsp3uy2 --- addons/mrp_repair/mrp_repair.py | 254 ++++++++++++++++------ addons/mrp_repair/wizard/cancel_repair.py | 34 ++- addons/mrp_repair/wizard/make_invoice.py | 21 +- 3 files changed, 208 insertions(+), 101 deletions(-) diff --git a/addons/mrp_repair/mrp_repair.py b/addons/mrp_repair/mrp_repair.py index e456c3770d2..f59da6a751c 100644 --- a/addons/mrp_repair/mrp_repair.py +++ b/addons/mrp_repair/mrp_repair.py @@ -33,8 +33,18 @@ class mrp_repair(osv.osv): _description = 'Repairs Order' def _amount_untaxed(self, cr, uid, ids, field_name, arg, context): + """ 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') + cur_obj = self.pool.get('res.currency') for repair in self.browse(cr, uid, ids): res[repair.id] = 0.0 for line in repair.operations: @@ -46,35 +56,46 @@ class mrp_repair(osv.osv): return res def _amount_tax(self, cr, uid, ids, field_name, arg, context): + """ Calculates taxed amount. + @param field_name: Name of field. + @param arg: Argument + @return: Dictionary of values. + """ res = {} - cur_obj=self.pool.get('res.currency') + cur_obj = self.pool.get('res.currency') + tax_obj = self.pool.get('account.tax') for repair in self.browse(cr, uid, ids): val = 0.0 - cur=repair.pricelist_id.currency_id + cur = repair.pricelist_id.currency_id for line in repair.operations: if line.to_invoice: - for c in self.pool.get('account.tax').compute(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, repair.partner_invoice_id.id, line.product_id, repair.partner_id): - val+= c['amount'] + for c in tax_obj.compute(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, repair.partner_invoice_id.id, line.product_id, repair.partner_id): + val += c['amount'] for line in repair.fees_lines: if line.to_invoice: - for c in self.pool.get('account.tax').compute(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, repair.partner_invoice_id.id, line.product_id, repair.partner_id): - val+= c['amount'] - res[repair.id]=cur_obj.round(cr, uid, cur, val) + for c in tax_obj.compute(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, repair.partner_invoice_id.id, line.product_id, repair.partner_id): + 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): + """ 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) tax = self._amount_tax(cr, uid, ids, field_name, arg, context) - cur_obj=self.pool.get('res.currency') + cur_obj = self.pool.get('res.currency') for id in ids: - repair=self.browse(cr, uid, [id])[0] - cur=repair.pricelist_id.currency_id + repair = self.browse(cr, uid, [id])[0] + 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 _columns = { - 'name' : fields.char('Repair Reference',size=24, required=True), + '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)]"), @@ -110,12 +131,12 @@ class mrp_repair(osv.osv): 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'), + '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'), '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), + 'repaired': fields.boolean('Repaired', readonly=True), 'amount_untaxed': fields.function(_amount_untaxed, method=True, string='Untaxed Amount'), 'amount_tax': fields.function(_amount_tax, method=True, string='Taxes'), 'amount_total': fields.function(_amount_total, method=True, string='Total'), @@ -144,6 +165,10 @@ class mrp_repair(osv.osv): 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, @@ -154,6 +179,12 @@ class mrp_repair(osv.osv): } 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: @@ -179,15 +210,23 @@ class mrp_repair(osv.osv): 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': self.pool.get('product.pricelist').search(cr,uid,[('type','=','sale')])[0] + 'pricelist_id': pricelist_obj.search(cr, uid, [('type','=','sale')])[0] } } - addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['delivery', 'invoice', 'default']) - partner = self.pool.get('res.partner').browse(cr, uid, part) + 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'], @@ -197,6 +236,14 @@ class mrp_repair(osv.osv): } 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. + """ + prodlot_obj = self.pool.get('stock.production.lot') + move_obj = self.pool.get('stock.move') data = {} data['value'] = { 'location_id': False, @@ -207,8 +254,8 @@ class mrp_repair(osv.osv): if not lot: return data - lot_info = self.pool.get('stock.production.lot').browse(cr, uid, lot) - move_ids = self.pool.get('stock.move').search(cr, uid, [('prodlot_id', '=', lot)]) + lot_info = prodlot_obj.browse(cr, uid, lot) + move_ids = move_obj.search(cr, uid, [('prodlot_id', '=', lot)]) if not len(move_ids): return data @@ -219,13 +266,17 @@ class mrp_repair(osv.osv): return lst_move move_id = move_ids[0] - move = get_last_move(self.pool.get('stock.move').browse(cr, uid, move_id)) + 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') @@ -238,6 +289,11 @@ class mrp_repair(osv.osv): 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'): @@ -248,6 +304,9 @@ class mrp_repair(osv.osv): return True def action_cancel(self, cr, uid, ids, context=None): + """ Cancels repair order. + @return: True + """ ok=True mrp_line_obj = self.pool.get('mrp.repair.line') for repair in self.browse(cr, uid, ids): @@ -259,25 +318,33 @@ class mrp_repair(osv.osv): return self.action_invoice_create(cr, uid, ids) def action_invoice_create(self, cr, uid, ids, group=False, context=None): - res={} + """ 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 + 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 + 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=invoice_obj.browse(cr, uid,inv_id) + 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 ''), } - invoice_obj.write(cr, uid, [inv_id],invoice_vals,context=context) + invoice_obj.write(cr, uid, [inv_id], invoice_vals, context=context) else: a = repair.partner_id.property_account_receivable.id inv = { @@ -291,10 +358,9 @@ class mrp_repair(osv.osv): 'comment': repair.quotation_notes, 'fiscal_position': repair.partner_id.property_account_position.id } - inv_obj = self.pool.get('account.invoice') 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}) + self.write(cr, uid, repair.id, {'invoiced': True, 'invoice_id': inv_id}) for operation in repair.operations: if operation.to_invoice == True: @@ -302,29 +368,29 @@ class mrp_repair(osv.osv): name = repair.name + '-' + operation.name else: name = operation.name - invoice_line_id=self.pool.get('account.invoice.line').create(cr, uid, { + invoice_line_id = inv_line_obj.create(cr, uid, { 'invoice_id': inv_id, 'name': name, - 'origin':repair.name, + 'origin': repair.name, 'account_id': operation.product_id and operation.product_id.property_account_income and operation.product_id.property_account_income.id, - 'quantity' : operation.product_uom_qty, + '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 + '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 }) - self.pool.get('mrp.repair.line').write(cr, uid, [operation.id], {'invoiced':True,'invoice_line_id':invoice_line_id}) + 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 - invoice_fee_id=self.pool.get('account.invoice.line').create(cr, uid, { + invoice_fee_id = inv_line_obj.create(cr, uid, { 'invoice_id': inv_id, 'name': name, - 'origin':repair.name, + 'origin': repair.name, 'account_id': a, 'quantity': fee.product_uom_qty, 'invoice_line_tax_id': [(6,0,[x.id for x in fee.tax_id])], @@ -333,27 +399,39 @@ class mrp_repair(osv.osv): 'price_unit': fee.price_unit, 'price_subtotal': fee.product_uom_qty*fee.price_unit }) - self.pool.get('mrp.repair.fee').write(cr, uid, [fee.id], {'invoiced':True,'invoice_line_id':invoice_fee_id}) - res[repair.id]=inv_id + repair_fee_obj.write(cr, uid, [fee.id], {'invoiced': True, 'invoice_line_id': invoice_fee_id}) + res[repair.id] = inv_id #self.action_invoice_end(cr, uid, ids) return res def action_repair_ready(self, cr, uid, ids, context=None): - self.write(cr, uid, ids, {'state':'ready'}) + """ Writes repair order state to 'Ready' + @return: True + """ + self.write(cr, uid, ids, {'state': 'ready'}) return True def action_invoice_cancel(self, cr, uid, ids, context=None): - self.write(cr, uid, ids, {'state':'invoice_except'}) + """ Writes repair order state to 'Exception in invoice' + @return: True + """ + self.write(cr, uid, ids, {'state': 'invoice_except'}) return True def action_repair_start(self, cr, uid, ids, context=None): - self.write(cr, uid, ids, {'state':'under_repair'}) + """ Writes repair order state to 'Under Repair' + @return: True + """ + self.write(cr, uid, ids, {'state': 'under_repair'}) return True def action_invoice_end(self, cr, uid, ids, context=None): + """ Writes repair order state to 'Ready' if invoice method is Before repair. + @return: True + """ for order in self.browse(cr, uid, ids): val = {} - if (order.invoice_method=='b4repair'): + if (order.invoice_method == 'b4repair'): val['state'] = 'ready' else: #val['state'] = 'done' @@ -362,9 +440,13 @@ class mrp_repair(osv.osv): 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): val = {} - val['repaired']=True + 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'): @@ -376,15 +458,23 @@ class mrp_repair(osv.osv): return True def wkf_repair_done(self, cr, uid, ids, *args): - res=self.action_repair_done(cr,uid,ids) + res = 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') company = self.pool.get('res.users').browse(cr, uid, uid).company_id for repair in self.browse(cr, uid, ids, context=context): for move in repair.operations: - move_id = self.pool.get('stock.move').create(cr, uid, { + move_id = move_obj.create(cr, uid, { 'name': move.name, 'product_id': move.product_id.id, 'product_qty': move.product_uom_qty, @@ -395,11 +485,11 @@ class mrp_repair(osv.osv): 'tracking_id': False, 'state': 'done', }) - self.pool.get('mrp.repair.line').write(cr, uid, [move.id], {'move_id': move_id}) + repair_line_obj.write(cr, uid, [move.id], {'move_id': move_id}) if repair.deliver_bool: - pick_name = self.pool.get('ir.sequence').get(cr, uid, 'stock.picking.out') - picking = self.pool.get('stock.picking').create(cr, uid, { + pick_name = seq_obj.get(cr, uid, 'stock.picking.out') + picking = pick_obj.create(cr, uid, { 'name': pick_name, 'origin': repair.name, 'state': 'draft', @@ -409,10 +499,9 @@ class mrp_repair(osv.osv): 'invoice_state': 'none', 'type': 'out', }) - wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, 'stock.picking', picking, 'button_confirm', cr) - move_id = self.pool.get('stock.move').create(cr, uid, { + move_id = move_obj.create(cr, uid, { 'name': repair.name, 'picking_id': picking, 'product_id': repair.product_id.id, @@ -427,10 +516,10 @@ class mrp_repair(osv.osv): 'tracking_id': False, 'state': 'assigned', # FIXME done ? }) - self.write(cr, uid, [repair.id], {'state':'done', 'picking_id':picking}) + self.write(cr, uid, [repair.id], {'state': 'done', 'picking_id': picking}) res[repair.id] = picking else: - self.write(cr, uid, [repair.id], {'state':'done'}) + self.write(cr, uid, [repair.id], {'state': 'done'}) return res @@ -438,7 +527,18 @@ mrp_repair() class ProductChangeMixin(object): - def product_id_change(self, cr, uid, ids, pricelist, product, uom=False, product_uom_qty=0, partner_id=False, guarantee_limit=False): + def product_id_change(self, cr, uid, ids, pricelist, product, uom=False, + product_uom_qty=0, partner_id=False, guarantee_limit=False): + """ On change of product it sets product quantity, tax account, name, + uom of product, unit price and price subtotal. + @param pricelist: Pricelist of current record. + @param product: Changed id of product. + @param uom: UoM of current record. + @param product_uom_qty: Quantity of current record. + @param partner_id: Partner of current record. + @param guarantee_limit: Guarantee limit of current record. + @return: Dictionary of values and warning message. + """ result = {} warning = {} @@ -447,7 +547,7 @@ class ProductChangeMixin(object): result['product_uom_qty'] = product_uom_qty if product: - product_obj = self.pool.get('product.product').browse(cr, uid, product) + product_obj = self.pool.get('product.product').browse(cr, uid, product) if partner_id: partner = self.pool.get('res.partner').browse(cr, uid, partner_id) result['tax_id'] = self.pool.get('account.fiscal.position').map_tax(cr, uid, partner.property_account_position, product_obj.taxes_id) @@ -455,7 +555,7 @@ class ProductChangeMixin(object): result['name'] = product_obj.partner_ref result['product_uom'] = product_obj.uom_id and product_obj.uom_id.id or False if not pricelist: - warning={ + warning = { 'title':'No Pricelist !', 'message': 'You have to select a pricelist in the Repair form !\n' @@ -466,14 +566,14 @@ class ProductChangeMixin(object): product, product_uom_qty, partner_id, {'uom': uom,})[pricelist] if price is False: - warning={ + warning = { 'title':'No valid pricelist line found !', 'message': "Couldn't find a pricelist line matching this product and quantity.\n" "You have to change either the product, the quantity or the pricelist." } else: - result.update({'price_unit': price, 'price_subtotal' :price*product_uom_qty}) + result.update({'price_unit': price, 'price_subtotal': price*product_uom_qty}) return {'value': result, 'warning': warning} @@ -484,10 +584,15 @@ class mrp_repair_line(osv.osv, ProductChangeMixin): 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'}) + 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): + """ 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): @@ -524,10 +629,16 @@ class mrp_repair_line(osv.osv, ProductChangeMixin): } _defaults = { 'state': lambda *a: 'draft', - 'product_uom_qty':lambda *a:1, + 'product_uom_qty': lambda *a: 1, } def onchange_operation_type(self, cr, uid, ids, type, guarantee_limit): + """ 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, @@ -537,19 +648,19 @@ class mrp_repair_line(osv.osv, ProductChangeMixin): produc_id = self.pool.get('stock.location').search(cr, uid, [('name','=','Production')])[0] if type == 'add': stock_id = self.pool.get('stock.location').search(cr, uid, [('name','=','Stock')])[0] - to_invoice=False + to_invoice = False if guarantee_limit and today() > mx.DateTime.strptime(guarantee_limit, '%Y-%m-%d'): to_invoice=True return {'value': { 'to_invoice': to_invoice, 'location_id': stock_id, - 'location_dest_id' : produc_id + 'location_dest_id': produc_id } } return {'value': { 'to_invoice': False, 'location_id': produc_id, - 'location_dest_id':False + 'location_dest_id': False } } @@ -558,13 +669,20 @@ mrp_repair_line() class mrp_repair_fee(osv.osv, ProductChangeMixin): _name = 'mrp.repair.fee' _description = 'Repair Fees line' + def copy_data(self, cr, uid, id, default=None, context=None): if not default: default = {} - default.update( {'invoice_line_id':False,'invoiced':False}) + default.update({'invoice_line_id': False, 'invoiced': False}) return super(mrp_repair_fee, self).copy_data(cr, uid, id, default, context) + def _amount_line(self, cr, uid, ids, field_name, arg, context): + """ Calculates amount. + @param field_name: Name of field. + @param arg: Argument + @return: Dictionary of values. + """ res = {} - cur_obj=self.pool.get('res.currency') + cur_obj = self.pool.get('res.currency') for line in self.browse(cr, uid, ids): res[line.id] = line.to_invoice and line.price_unit * line.product_uom_qty or 0 cur = line.repair_id.pricelist_id.currency_id diff --git a/addons/mrp_repair/wizard/cancel_repair.py b/addons/mrp_repair/wizard/cancel_repair.py index 7977a8b2195..371b7ba82e3 100644 --- a/addons/mrp_repair/wizard/cancel_repair.py +++ b/addons/mrp_repair/wizard/cancel_repair.py @@ -28,17 +28,13 @@ class repair_cancel(osv.osv_memory): _description = 'Cancel Repair' def cancel_repair(self, cr, uid, ids, context): - """ - Cancels the repair - - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param ids: List of IDs selected - @param context: A standard dictionary - - @return: - + """ Cancels the repair + @param self: The object pointer. + @param cr: A database cursor + @param uid: ID of the user currently logged in + @param ids: List of IDs selected + @param context: A standard dictionary + @return: """ record_id = context and context.get('active_id', False) or False assert record_id, _('Active ID is not Found') @@ -54,16 +50,12 @@ class repair_cancel(osv.osv_memory): return {} def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): - """ - Changes the view dynamically - - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param context: A standard dictionary - - @return: New arch of view. - + """ Changes the view dynamically + @param self: The object pointer. + @param cr: A database cursor + @param uid: ID of the user currently logged in + @param context: A standard dictionary + @return: New arch of view. """ record_id = context and context.get('active_id', False) or False res = super(repair_cancel, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False) diff --git a/addons/mrp_repair/wizard/make_invoice.py b/addons/mrp_repair/wizard/make_invoice.py index 063040590e6..5619f80681d 100644 --- a/addons/mrp_repair/wizard/make_invoice.py +++ b/addons/mrp_repair/wizard/make_invoice.py @@ -31,21 +31,18 @@ class make_invoice(osv.osv_memory): } def make_invoices(self, cr, uid, ids, context): - """ - Generates invoice(s) of selected records. - - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param ids: List of IDs selected - @param context: A standard dictionary - - @return: Loads the view of new invoice(s). - + """ Generates invoice(s) of selected records. + @param self: The object pointer. + @param cr: A database cursor + @param uid: ID of the user currently logged in + @param ids: List of IDs selected + @param context: A standard dictionary + @return: Loads the view of new invoice(s). """ inv = self.browse(cr, uid, ids[0]) order_obj = self.pool.get('mrp.repair') - newinv = order_obj.action_invoice_create(cr, uid, context['active_ids'], group=inv.group,context=context) + newinv = order_obj.action_invoice_create(cr, uid, context['active_ids'], + group=inv.group,context=context) return { 'domain': [('id','in', newinv.values())], From 1b2f939266031a4b013f02cde4e30074531f82d5 Mon Sep 17 00:00:00 2001 From: "sbh (Open ERP)" Date: Tue, 6 Apr 2010 13:39:33 +0530 Subject: [PATCH 02/30] [Fix] point_of_sale : if last_picking not found it give the error message bzr revid: sbh@tinyerp.com-20100406080933-riw4saazig2pi6w3 --- addons/point_of_sale/wizard/wizard_return.py | 82 ++++++++++---------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/addons/point_of_sale/wizard/wizard_return.py b/addons/point_of_sale/wizard/wizard_return.py index 591fd00b18a..673610e8c2c 100644 --- a/addons/point_of_sale/wizard/wizard_return.py +++ b/addons/point_of_sale/wizard/wizard_return.py @@ -266,6 +266,7 @@ def _create_returns(self, cr, uid, data, context): return res def _create_returns2(self, cr, uid, data, context): + act={} pool = pooler.get_pool(cr.dbname) order_obj = pool.get('pos.order') line_obj = pool.get('pos.order.line') @@ -283,46 +284,49 @@ def _create_returns2(self, cr, uid, data, context): res=cr.fetchone() location_id=res and res[0] or None stock_dest_id = int(val.split(',')[1]) + if order_id.last_out_picking.id: + new_picking=picking_obj.copy(cr, uid, order_id.last_out_picking.id, {'name':'%s (return)' % order_id.name, + 'move_lines':[], 'state':'draft', 'type':'in', + 'type':'in', + 'date':date_cur, }) + new_order=order_obj.copy(cr,uid,order_id.id, {'name': 'Refund %s'%order_id.name, + 'lines':[], + 'statement_ids':[], + 'last_out_picking':[]}) + for line in order_id.lines: + for r in data['form'].get('returns',[]): + if line.id==r and (data['form']['return%s' %r]!=0.0): + new_move=stock_move_obj.create(cr, uid,{ + 'product_qty': data['form']['return%s' %r], + 'product_uos_qty': uom_obj._compute_qty(cr, uid,data['form']['return%s' %r] ,line.product_id.uom_id.id), + 'picking_id':new_picking, + 'product_uom':line.product_id.uom_id.id, + 'location_id':location_id, + 'product_id':line.product_id.id, + 'location_dest_id':stock_dest_id, + 'name':'%s (return)' %order_id.name, + 'date':date_cur, + 'date_planned':date_cur,}) + line_obj.copy(cr,uid,line.id,{'qty':-data['form']['return%s' %r], + 'order_id': new_order, + }) + order_obj.write(cr,uid, new_order, {'state':'done'}) + wf_service.trg_validate(uid, 'stock.picking',new_picking,'button_confirm', cr) + picking_obj.force_assign(cr, uid, [new_picking], context) + act = { + 'domain': "[('id', 'in', ["+str(new_order)+"])]", + 'name': 'Refunded Orders', + 'view_type': 'form', + 'view_mode': 'form,tree', + 'res_model': 'pos.order', + 'auto_refresh':0, + 'res_id':new_order, + 'view_id': False, + 'type': 'ir.actions.act_window' + } + else: + raise wizard.except_wizard(_('Error'), _('Last out picking No find!')) - new_picking=picking_obj.copy(cr, uid, order_id.last_out_picking.id, {'name':'%s (return)' % order_id.name, - 'move_lines':[], 'state':'draft', 'type':'in', - 'type':'in', - 'date':date_cur, }) - new_order=order_obj.copy(cr,uid,order_id.id, {'name': 'Refund %s'%order_id.name, - 'lines':[], - 'statement_ids':[], - 'last_out_picking':[]}) - for line in order_id.lines: - for r in data['form'].get('returns',[]): - if line.id==r and (data['form']['return%s' %r]!=0.0): - new_move=stock_move_obj.create(cr, uid,{ - 'product_qty': data['form']['return%s' %r], - 'product_uos_qty': uom_obj._compute_qty(cr, uid,data['form']['return%s' %r] ,line.product_id.uom_id.id), - 'picking_id':new_picking, - 'product_uom':line.product_id.uom_id.id, - 'location_id':location_id, - 'product_id':line.product_id.id, - 'location_dest_id':stock_dest_id, - 'name':'%s (return)' %order_id.name, - 'date':date_cur, - 'date_planned':date_cur,}) - line_obj.copy(cr,uid,line.id,{'qty':-data['form']['return%s' %r], - 'order_id': new_order, - }) - order_obj.write(cr,uid, new_order, {'state':'done'}) - wf_service.trg_validate(uid, 'stock.picking',new_picking,'button_confirm', cr) - picking_obj.force_assign(cr, uid, [new_picking], context) - act = { - 'domain': "[('id', 'in', ["+str(new_order)+"])]", - 'name': 'Refunded Orders', - 'view_type': 'form', - 'view_mode': 'form,tree', - 'res_model': 'pos.order', - 'auto_refresh':0, - 'res_id':new_order, - 'view_id': False, - 'type': 'ir.actions.act_window' - } return act def test(self,cr,uid,data,context={}): # import pdb; pdb.set_trace() From 719dabda77d4678b33828091733c6f059e059f91 Mon Sep 17 00:00:00 2001 From: "uco (OpenERP)" Date: Tue, 6 Apr 2010 14:27:06 +0530 Subject: [PATCH 03/30] [REF] mrp: Changes made according to pep-8 standards. Improved coding i.e. removed self.pool.get from inside the loops. bzr revid: uco@tinyerp.co.in-20100406085706-9zotp2ele4e6udss --- addons/mrp/installer.py | 10 +-- addons/mrp/mrp.py | 179 ++++++++++++++++++++------------------- addons/mrp/mrp_view.xml | 1 + addons/mrp/product.py | 34 +++----- addons/mrp/schedulers.py | 6 +- addons/mrp/stock.py | 54 +++++++----- 6 files changed, 147 insertions(+), 137 deletions(-) diff --git a/addons/mrp/installer.py b/addons/mrp/installer.py index d595860ba39..361998f50bd 100644 --- a/addons/mrp/installer.py +++ b/addons/mrp/installer.py @@ -26,23 +26,23 @@ class mrp_installer(osv.osv_memory): _columns = { # Manufacturing Resource Planning - 'stock_location':fields.boolean('Advanced Routes', + 'stock_location': fields.boolean('Advanced Routes', help="Manages product routes and paths within and between " "locations (e.g. warehouses)"), - 'mrp_jit':fields.boolean('Just In Time Scheduling', + 'mrp_jit': fields.boolean('Just In Time Scheduling', help="Enables Just In Time computation of procurement orders." "\n\nWhile it's more resource intensive than the default " "setup, the JIT computer avoids having to wait for the " "procurement scheduler to run or having to run the " "procurement scheduler manually."), - 'mrp_operations':fields.boolean('Manufacturing Operations', + 'mrp_operations': fields.boolean('Manufacturing Operations', help="Enhances production orders with readiness states as well " "as the dates of start and end of execution of the order."), - 'mrp_subproduct':fields.boolean('MRP Subproducts', + 'mrp_subproduct': fields.boolean('MRP Subproducts', help="Enables multiple product output from a single production " "order: without this, a productio order can have only one " "output product."), - 'mrp_repair':fields.boolean('Repairs', + 'mrp_repair': fields.boolean('Repairs', help="Enables warranty and repair management (and their impact " "on stocks and invoicing)."), } diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index 9ca9fee3e91..ab13dca1585 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -161,15 +161,16 @@ class mrp_bom(osv.osv): @return: Dictionary of values """ result = {} + bom_obj = self.pool.get('mrp.bom') for bom in self.browse(cr, uid, ids, context=context): result[bom.id] = map(lambda x: x.id, bom.bom_lines) if bom.bom_lines: continue ok = ((name=='child_complete_ids') and (bom.product_id.supply_method=='produce')) if bom.type=='phantom' or ok: - sids = self.pool.get('mrp.bom').search(cr, uid, [('bom_id','=',False),('product_id','=',bom.product_id.id)]) + sids = bom_obj.search(cr, uid, [('bom_id','=',False),('product_id','=',bom.product_id.id)]) if sids: - bom2 = self.pool.get('mrp.bom').browse(cr, uid, sids[0], context=context) + bom2 = bom_obj.browse(cr, uid, sids[0], context=context) result[bom.id] += map(lambda x: x.id, bom2.bom_lines) return result @@ -182,13 +183,13 @@ class mrp_bom(osv.osv): """ res = dict(map(lambda x: (x,''), ids)) for line in self.browse(cr, uid, ids): - if line.type=='phantom' and not line.bom_id: + if line.type == 'phantom' and not line.bom_id: res[line.id] = 'set' continue - if line.bom_lines or line.type=='phantom': + if line.bom_lines or line.type == 'phantom': continue - if line.product_id.supply_method=='produce': - if line.product_id.procure_method=='make_to_stock': + if line.product_id.supply_method == 'produce': + if line.product_id.procure_method == 'make_to_stock': res[line.id] = 'stock' else: res[line.id] = 'order' @@ -220,9 +221,9 @@ class mrp_bom(osv.osv): 'property_ids': fields.many2many('mrp.property', 'mrp_bom_property_rel', 'bom_id','property_id', 'Properties'), 'revision_ids': fields.one2many('mrp.bom.revision', 'bom_id', 'BoM Revisions'), 'revision_type': fields.selection([('numeric','numeric indices'),('alpha','alphabetical indices')], 'Index type'), - 'child_ids': fields.function(_child_compute,relation='mrp.bom', method=True, string="BoM Hierarchy", type='many2many'), - 'child_complete_ids': fields.function(_child_compute,relation='mrp.bom', method=True, string="BoM Hierarchy", type='many2many'), - 'company_id': fields.many2one('res.company','Company',required=True), + 'child_ids': fields.function(_child_compute, relation='mrp.bom', method=True, string="BoM Hierarchy", type='many2many'), + 'child_complete_ids': fields.function(_child_compute, relation='mrp.bom', method=True, string="BoM Hierarchy", type='many2many'), + 'company_id': fields.many2one('res.company', 'Company', required=True), 'multi_level_bom': fields.boolean('Multi-level BoM'), } @@ -262,8 +263,8 @@ class mrp_bom(osv.osv): @return: Dictionary of changed values """ if product_id: - prod=self.pool.get('product.product').browse(cr,uid,[product_id])[0] - v = {'product_uom':prod.uom_id.id} + prod = self.pool.get('product.product').browse(cr, uid, [product_id])[0] + v = {'product_uom': prod.uom_id.id} if not name: v['name'] = prod.name return {'value': v} @@ -286,8 +287,8 @@ class mrp_bom(osv.osv): prop = 0 for prop_id in bom.property_ids: if prop_id.id in properties: - prop+=1 - if (prop>max_prop) or ((max_prop==0) and not result): + prop += 1 + if (prop > max_prop) or ((max_prop == 0) and not result): result = bom.id max_prop = prop return result @@ -304,20 +305,20 @@ class mrp_bom(osv.osv): """ factor = factor / (bom.product_efficiency or 1.0) factor = rounding(factor, bom.product_rounding) - if factor'internal': + if routing_loc.usage <> 'internal': pick_type = 'out' address_id = routing_loc.address_id and routing_loc.address_id.id or False routing_loc = routing_loc.id - pick_name = seq_obj.get(cr, uid, 'stock.picking.'+pick_type) + pick_name = seq_obj.get(cr, uid, 'stock.picking.' + pick_type) picking_id = pick_obj.create(cr, uid, { 'name': pick_name, - 'origin': (production.origin or '').split(':')[0] +':'+production.name, + 'origin': (production.origin or '').split(':')[0] + ':' + production.name, 'type': pick_type, 'move_type': 'one', 'state': 'auto', @@ -867,7 +871,7 @@ class mrp_production(osv.osv): source = production.product_id.product_tmpl_id.property_stock_production.id data = { - 'name':'PROD:'+production.name, + 'name':'PROD:' + production.name, 'date_planned': production.date_planned, 'product_id': production.product_id.id, 'product_qty': production.product_qty, @@ -885,11 +889,11 @@ class mrp_production(osv.osv): self.write(cr, uid, [production.id], {'move_created_ids': [(6, 0, [res_final_id])]}) moves = [] for line in production.product_lines: - move_id=False + move_id = False newdate = production.date_planned if line.product_id.type in ('product', 'consu'): res_dest_id = move_obj.create(cr, uid, { - 'name':'PROD:'+production.name, + 'name':'PROD:' + production.name, 'date_planned': production.date_planned, 'product_id': line.product_id.id, 'product_qty': line.product_qty, @@ -904,7 +908,7 @@ class mrp_production(osv.osv): }) moves.append(res_dest_id) move_id = move_obj.create(cr, uid, { - 'name':'PROD:'+production.name, + 'name':'PROD:' + production.name, 'picking_id':picking_id, 'product_id': line.product_id.id, 'product_qty': line.product_qty, @@ -932,12 +936,10 @@ class mrp_production(osv.osv): 'move_id': move_id, 'company_id': production.company_id.id, }) - wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr) proc_ids.append(proc_id) - wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr) - self.write(cr, uid, [production.id], {'picking_id':picking_id, 'move_lines': [(6,0,moves)], 'state':'confirmed'}) + self.write(cr, uid, [production.id], {'picking_id': picking_id, 'move_lines': [(6,0,moves)], 'state':'confirmed'}) return picking_id def force_production(self, cr, uid, ids, *args): @@ -955,6 +957,7 @@ class mrp_production_workcenter_line(osv.osv): _name = 'mrp.production.workcenter.line' _description = 'Work Orders' _order = 'sequence' + _columns = { 'name': fields.char('Work Order', size=64, required=True), 'workcenter_id': fields.many2one('mrp.workcenter', 'Work Center', required=True), @@ -973,6 +976,7 @@ mrp_production_workcenter_line() class mrp_production_product_line(osv.osv): _name = 'mrp.production.product.line' _description = 'Production scheduled products' + _columns = { 'name': fields.char('Name', size=64, required=True), 'product_id': fields.many2one('product.product', 'Product', required=True), @@ -998,6 +1002,7 @@ class mrp_procurement(osv.osv): _name = "mrp.procurement" _description = "Procurement" _order = 'priority,date_planned' + _columns = { 'name': fields.char('Reason', size=64, required=True, help='Requisition name.'), 'origin': fields.char('Source Document', size=64, @@ -1038,7 +1043,7 @@ class mrp_procurement(osv.osv): ('waiting','Waiting')], 'State', required=True, help='When a procurement is created the state is set to \'Draft\'.\n If the procurement is confirmed, the state is set to \'Confirmed\'.\ \nAfter confirming the state is set to \'Running\'.\n If any exception arises in the order then the state is set to \'Exception\'.\n Once the exception is removed the state becomes \'Ready\'.\n It is in \'Waiting\'. state when the procurement is waiting for another one to finish.'), - 'note' : fields.text('Note'), + 'note': fields.text('Note'), 'company_id': fields.many2one('res.company','Company',required=True), } _defaults = { @@ -1047,7 +1052,7 @@ class mrp_procurement(osv.osv): 'date_planned': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), 'close_move': lambda *a: 0, 'procure_method': lambda *a: 'make_to_order', - 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.procurement', context=c) + 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'mrp.procurement', context=c) } def unlink(self, cr, uid, ids, context=None): @@ -1066,10 +1071,10 @@ class mrp_procurement(osv.osv): @return: Dictionary of values. """ if product_id: - w=self.pool.get('product.product').browse(cr,uid,product_id, context) + w = self.pool.get('product.product').browse(cr, uid, product_id, context) v = { - 'product_uom':w.uom_id.id, - 'product_uos':w.uos_id and w.uos_id.id or w.uom_id.id + 'product_uom': w.uom_id.id, + 'product_uos': w.uos_id and w.uos_id.id or w.uom_id.id } return {'value': v} return {} @@ -1092,7 +1097,7 @@ class mrp_procurement(osv.osv): for procurement in self.browse(cr, uid, ids, context): if procurement.move_id: ok = True - if not procurement.move_id.state=='cancel': + if not procurement.move_id.state == 'cancel': res = False return res and ok @@ -1103,7 +1108,7 @@ class mrp_procurement(osv.osv): res = True for proc in self.browse(cr, uid, ids, context): if proc.move_id: - if not proc.move_id.state=='done': + if not proc.move_id.state == 'done': res = False return res @@ -1116,7 +1121,7 @@ class mrp_procurement(osv.osv): @param proc: Current procurement. @return: Quantity or False. """ - if proc.product_id.type=='product': + if proc.product_id.type == 'product': if proc.move_id.product_uos: return proc.move_id.product_uos_qty return False @@ -1126,7 +1131,7 @@ class mrp_procurement(osv.osv): @param proc: Current procurement. @return: UoS or False. """ - if proc.product_id.type=='product': + if proc.product_id.type == 'product': if proc.move_id.product_uos: return proc.move_id.product_uos.id return False @@ -1160,7 +1165,7 @@ class mrp_procurement(osv.osv): @return: True or False """ for procurement in self.browse(cr, uid, ids, context=context): - if procurement.move_id and procurement.move_id.state=='auto': + if procurement.move_id and procurement.move_id.state == 'auto': return True return False @@ -1185,7 +1190,7 @@ class mrp_procurement(osv.osv): """ ok = True for procurement in self.browse(cr, uid, ids, context=context): - if procurement.product_id.type=='service': + if procurement.product_id.type == 'service': ok = ok and self._check_make_to_stock_service(cr, uid, procurement, context) else: ok = ok and self._check_make_to_stock_product(cr, uid, procurement, context) @@ -1198,7 +1203,7 @@ class mrp_procurement(osv.osv): res = True user = self.pool.get('res.users').browse(cr, uid, uid) for procurement in self.browse(cr, uid, ids): - if procurement.product_id.product_tmpl_id.supply_method<>'produce': + if procurement.product_id.product_tmpl_id.supply_method <> 'produce': if procurement.product_id.seller_ids: partner = procurement.product_id.seller_ids[0].name if user.company_id and user.company_id.partner_id: @@ -1220,7 +1225,7 @@ class mrp_procurement(osv.osv): user = self.pool.get('res.users').browse(cr, uid, uid) partner_obj = self.pool.get('res.partner') for procurement in self.browse(cr, uid, ids): - if procurement.product_id.product_tmpl_id.supply_method<>'buy': + if procurement.product_id.product_tmpl_id.supply_method <> 'buy': return False if not procurement.product_id.seller_ids: cr.execute('update mrp_procurement set message=%s where id=%s', (_('No supplier defined for this product !'), procurement.id)) @@ -1240,7 +1245,7 @@ class mrp_procurement(osv.osv): @return: True or False """ for record in self.browse(cr, uid, ids): - if record.move_id and record.move_id.state=='cancel': + if record.move_id and record.move_id.state == 'cancel': return True return False @@ -1255,32 +1260,32 @@ class mrp_procurement(osv.osv): if procurement.product_id.type in ('product', 'consu'): if not procurement.move_id: source = procurement.location_id.id - if procurement.procure_method=='make_to_order': + if procurement.procure_method == 'make_to_order': source = procurement.product_id.product_tmpl_id.property_stock_procurement.id id = move_obj.create(cr, uid, { - 'name': 'PROC:'+procurement.name, + 'name': 'PROC:' + procurement.name, 'location_id': source, 'location_dest_id': procurement.location_id.id, 'product_id': procurement.product_id.id, - 'product_qty':procurement.product_qty, + 'product_qty': procurement.product_qty, 'product_uom': procurement.product_uom.id, 'date_planned': procurement.date_planned, - 'state':'confirmed', + 'state': 'confirmed', 'company_id': procurement.company_id.id, }) - self.write(cr, uid, [procurement.id], {'move_id': id, 'close_move':1}) + self.write(cr, uid, [procurement.id], {'move_id': id, 'close_move': 1}) else: # TODO: check this - if procurement.procure_method=='make_to_stock' and procurement.move_id.state in ('waiting',): + if procurement.procure_method == 'make_to_stock' and procurement.move_id.state in ('waiting',): id = move_obj.write(cr, uid, [procurement.move_id.id], {'state':'confirmed'}) - self.write(cr, uid, ids, {'state':'confirmed','message':''}) + self.write(cr, uid, ids, {'state': 'confirmed', 'message': ''}) return True def action_move_assigned(self, cr, uid, ids, context={}): """ Changes procurement state to Running and writes message. @return: True """ - self.write(cr, uid, ids, {'state':'running','message':_('from stock: products assigned.')}) + self.write(cr, uid, ids, {'state': 'running', 'message': _('from stock: products assigned.')}) return True def _check_make_to_stock_service(self, cr, uid, procurement, context={}): @@ -1306,7 +1311,7 @@ class mrp_procurement(osv.osv): @return: True """ for procurement in self.browse(cr, uid, ids): - self.write(cr, uid, [procurement.id], {'state':'running'}) + self.write(cr, uid, [procurement.id], {'state': 'running'}) return True def action_produce_assign_product(self, cr, uid, ids, context={}): @@ -1346,12 +1351,12 @@ class mrp_procurement(osv.osv): 'company_id': procurement.company_id.id, }) res[procurement.id] = produce_id - self.write(cr, uid, [procurement.id], {'state':'running'}) + self.write(cr, uid, [procurement.id], {'state': 'running'}) bom_result = production_obj.action_compute(cr, uid, [produce_id], properties=[x.id for x in procurement.property_ids]) wf_service.trg_validate(uid, 'mrp.production', produce_id, 'button_confirm', cr) move_obj.write(cr, uid, [res_id], - {'location_id':procurement.location_id.id}) + {'location_id': procurement.location_id.id}) return res def action_po_assign(self, cr, uid, ids, context={}): @@ -1385,7 +1390,7 @@ class mrp_procurement(osv.osv): qty = uom_obj._compute_qty(cr, uid, procurement.product_uom.id, procurement.product_qty, uom_id) if procurement.product_id.seller_ids[0].qty: - qty=max(qty,procurement.product_id.seller_ids[0].qty) + qty = max(qty,procurement.product_id.seller_ids[0].qty) price = pricelist_obj.price_get(cr, uid, [pricelist_id], procurement.product_id.id, qty, False, {'uom': uom_id})[pricelist_id] @@ -1394,9 +1399,9 @@ class mrp_procurement(osv.osv): newdate = newdate - procurement.product_id.seller_ids[0].delay #Passing partner_id to context for purchase order line integrity of Line name - context.update({'lang':partner.lang, 'partner_id':partner_id}) + context.update({'lang': partner.lang, 'partner_id': partner_id}) - product = prod_obj.browse(cr,uid,procurement.product_id.id,context=context) + product = prod_obj.browse(cr, uid, procurement.product_id.id, context=context) line = { 'name': product.partner_ref, @@ -1406,13 +1411,13 @@ class mrp_procurement(osv.osv): 'price_unit': price, 'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'), 'move_dest_id': res_id, - 'notes':product.description_purchase, + 'notes': product.description_purchase, } taxes_ids = procurement.product_id.product_tmpl_id.supplier_taxes_id taxes = acc_pos_obj.map_tax(cr, uid, partner.property_account_position, taxes_ids) line.update({ - 'taxes_id':[(6,0,taxes)] + 'taxes_id': [(6,0,taxes)] }) purchase_id = po_obj.create(cr, uid, { 'origin': procurement.origin, @@ -1425,7 +1430,7 @@ class mrp_procurement(osv.osv): 'fiscal_position': partner.property_account_position and partner.property_account_position.id or False }) res[procurement.id] = purchase_id - self.write(cr, uid, [procurement.id], {'state':'running', 'purchase_id':purchase_id}) + self.write(cr, uid, [procurement.id], {'state': 'running', 'purchase_id': purchase_id}) return res def action_cancel(self, cr, uid, ids): @@ -1437,16 +1442,16 @@ class mrp_procurement(osv.osv): move_obj = self.pool.get('stock.move') for proc in self.browse(cr, uid, ids): if proc.close_move: - if proc.move_id.state not in ('done','cancel'): + if proc.move_id.state not in ('done', 'cancel'): todo2.append(proc.move_id.id) else: - if proc.move_id and proc.move_id.state=='waiting': + if proc.move_id and proc.move_id.state == 'waiting': todo.append(proc.move_id.id) if len(todo2): move_obj.action_cancel(cr, uid, todo2) if len(todo): - move_obj.write(cr, uid, todo, {'state':'assigned'}) - self.write(cr, uid, ids, {'state':'cancel'}) + move_obj.write(cr, uid, todo, {'state': 'assigned'}) + self.write(cr, uid, ids, {'state': 'cancel'}) wf_service = netsvc.LocalService("workflow") for id in ids: wf_service.trg_trigger(uid, 'mrp.procurement', id, cr) @@ -1461,7 +1466,7 @@ class mrp_procurement(osv.osv): """ ok = False for procurement in self.browse(cr, uid, ids): - if procurement.move_id.state=='assigned' or procurement.move_id.state=='done': + if procurement.move_id.state == 'assigned' or procurement.move_id.state == 'done': self.action_done(cr, uid, [procurement.id]) ok = True return ok @@ -1470,7 +1475,7 @@ class mrp_procurement(osv.osv): """ Changes procurement state to Ready. @return: True """ - res = self.write(cr, uid, ids, {'state':'ready'}) + res = self.write(cr, uid, ids, {'state': 'ready'}) return res def action_done(self, cr, uid, ids): @@ -1482,7 +1487,7 @@ class mrp_procurement(osv.osv): if procurement.move_id: if procurement.close_move and (procurement.move_id.state <> 'done'): move_obj.action_done(cr, uid, [procurement.move_id.id]) - res = self.write(cr, uid, ids, {'state':'done', 'date_close':time.strftime('%Y-%m-%d')}) + res = self.write(cr, uid, ids, {'state': 'done', 'date_close': time.strftime('%Y-%m-%d')}) wf_service = netsvc.LocalService("workflow") for id in ids: wf_service.trg_trigger(uid, 'mrp.procurement', id, cr) diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml index 15729a8c985..4ee689d90ff 100644 --- a/addons/mrp/mrp_view.xml +++ b/addons/mrp/mrp_view.xml @@ -867,6 +867,7 @@ + diff --git a/addons/mrp/product.py b/addons/mrp/product.py index 30e5a911dba..6a73063e591 100644 --- a/addons/mrp/product.py +++ b/addons/mrp/product.py @@ -27,13 +27,9 @@ class product_product(osv.osv): _inherit = "product.product" def get_product_accounts(self, cr, uid, product_id, context={}): - - """ - To get the stock input account, stock output account and stock journal related to product. - - @param product_id : product id - @return: dictionary which contains information regarding stock input account, stock output account and stock journal - + """ To get the stock input account, stock output account and stock journal related to product. + @param product_id: product id + @return: dictionary which contains information regarding stock input account, stock output account and stock journal """ product_obj = self.pool.get('product.product').browse(cr, uid, product_id, False) @@ -55,14 +51,10 @@ class product_product(osv.osv): return res def do_change_standard_price(self, cr, uid, ids, datas, context={}): - """ - Changes the Standard Price of Product and parent products and creates an account move accordingly. - - @param datas : dict. contain default datas like new_price, stock_output_account, stock_input_account, stock_journal - @param context: A standard dictionary - - @return: - + """ Changes the Standard Price of Product and parent products and creates an account move accordingly. + @param datas: dict. contain default datas like new_price, stock_output_account, stock_input_account, stock_journal + @param context: A standard dictionary + @return: """ #TODO : TO Check res = super(product_product, self).do_change_standard_price(cr, uid, ids, datas, context=context) @@ -73,15 +65,15 @@ class product_product(osv.osv): if bom.bom_id.bom_lines : for bom_line in bom.bom_id.bom_lines : prod_price = self.read(cr, uid, bom_line.product_id.id, ['standard_price'])['standard_price'] - price += bom_line.product_qty * prod_price + price += bom_line.product_qty * prod_price - accounts = self.get_product_accounts(cr, uid, bom.bom_id.product_id.id , context) + accounts = self.get_product_accounts(cr, uid, bom.bom_id.product_id.id, context) datas = { - 'new_price' : price, - 'stock_output_account' : accounts['stock_account_output'], - 'stock_input_account' : accounts['stock_account_input'], - 'stock_journal' : accounts['stock_journal'] + 'new_price': price, + 'stock_output_account': accounts['stock_account_output'], + 'stock_input_account': accounts['stock_account_input'], + 'stock_journal': accounts['stock_journal'] } super(product_product, self).do_change_standard_price(cr, uid, [bom.bom_id.product_id.id], datas, context) _compute_price(bom.bom_id) diff --git a/addons/mrp/schedulers.py b/addons/mrp/schedulers.py index 097f81f7529..12341ceb5a0 100644 --- a/addons/mrp/schedulers.py +++ b/addons/mrp/schedulers.py @@ -60,7 +60,7 @@ class mrp_procurement(osv.osv): cr.execute('select id from mrp_procurement where state=%s and procure_method=%s order by priority,date_planned limit 500 offset %s', ('confirmed', 'make_to_order', offset)) ids = map(lambda x: x[0], cr.fetchall()) for proc in procurement_obj.browse(cr, uid, ids): - if (maxdate.strftime('%Y-%m-%d')>=proc.date_planned): + if (maxdate.strftime('%Y-%m-%d') >= proc.date_planned): wf_service.trg_validate(uid, 'mrp.procurement', proc.id, 'button_check', cr) else: offset += 1 @@ -81,7 +81,7 @@ class mrp_procurement(osv.osv): ids = [] while True: report_ids = [] - ids = self.pool.get('mrp.procurement').search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_stock')], offset=offset) + ids = procurement_obj.search(cr, uid, [('state', '=', 'confirmed'), ('procure_method', '=', 'make_to_stock')], offset=offset) for proc in procurement_obj.browse(cr, uid, ids): if ((maxdate).strftime('%Y-%m-%d') >= proc.date_planned) : wf_service.trg_validate(uid, 'mrp.procurement', proc.id, 'button_check', cr) @@ -140,7 +140,7 @@ class mrp_procurement(osv.osv): for warehouse in warehouse_obj.browse(cr, uid, warehouse_ids, context=context): context['warehouse'] = warehouse - for product in self.pool.get('product.product').browse(cr, uid, products_id, context=context): + for product in product_obj.browse(cr, uid, products_id, context=context): if product.virtual_available >= 0.0: continue diff --git a/addons/mrp/stock.py b/addons/mrp/stock.py index d395214b87a..05f7c3c18c8 100644 --- a/addons/mrp/stock.py +++ b/addons/mrp/stock.py @@ -34,6 +34,7 @@ class stock_warehouse_orderpoint(osv.osv): """ _name = "stock.warehouse.orderpoint" _description = "Orderpoint minimum rule" + _columns = { 'name': fields.char('Name', size=32, required=True), 'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the orderpoint without removing it."), @@ -59,28 +60,31 @@ class stock_warehouse_orderpoint(osv.osv): 'qty_multiple': lambda *a: 1, 'name': lambda x,y,z,c: x.pool.get('ir.sequence').get(y,z,'mrp.warehouse.orderpoint') or '', 'product_uom': lambda sel, cr, uid, context: context.get('product_uom', False), - 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.warehouse.orderpoint', context=c) + 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'stock.warehouse.orderpoint', context=c) } + def onchange_warehouse_id(self, cr, uid, ids, warehouse_id, context={}): """ Finds location id for changed warehouse. @param warehouse_id: Changed id of warehouse. @return: Dictionary of values. """ if warehouse_id: - w=self.pool.get('stock.warehouse').browse(cr,uid,warehouse_id, context) - v = {'location_id':w.lot_stock_id.id} + w = self.pool.get('stock.warehouse').browse(cr, uid, warehouse_id, context) + v = {'location_id': w.lot_stock_id.id} return {'value': v} return {} + def onchange_product_id(self, cr, uid, ids, product_id, context={}): """ Finds UoM for changed product. @param product_id: Changed id of product. @return: Dictionary of values. """ if product_id: - prod=self.pool.get('product.product').browse(cr,uid,product_id) - v = {'product_uom':prod.uom_id.id} + prod = self.pool.get('product.product').browse(cr,uid,product_id) + v = {'product_uom': prod.uom_id.id} return {'value': v} return {} + def copy(self, cr, uid, id, default=None,context={}): if not default: default = {} @@ -88,14 +92,17 @@ class stock_warehouse_orderpoint(osv.osv): 'name': self.pool.get('ir.sequence').get(cr, uid, 'mrp.warehouse.orderpoint') or '', }) return super(stock_warehouse_orderpoint, self).copy(cr, uid, id, default, context) + stock_warehouse_orderpoint() class StockMove(osv.osv): _inherit = 'stock.move' + _columns = { 'production_id': fields.many2one('mrp.production', 'Production', select=True), 'procurements': fields.one2many('mrp.procurement', 'move_id', 'Requisitions'), } + def copy(self, cr, uid, id, default=None, context=None): default = default or {} default['procurements'] = [] @@ -106,19 +113,24 @@ class StockMove(osv.osv): @param move: Stock moves @return: True """ - if move.product_id.supply_method=='produce' and move.product_id.procure_method=='make_to_order': - bis = self.pool.get('mrp.bom').search(cr, uid, [ + bom_obj = self.pool.get('mrp.bom') + move_obj = self.pool.get('stock.move') + procurement_obj = self.pool.get('mrp.procurement') + product_obj = self.pool.get('product.product') + wf_service = netsvc.LocalService("workflow") + if move.product_id.supply_method == 'produce' and move.product_id.procure_method == 'make_to_order': + bis = bom_obj.search(cr, uid, [ ('product_id','=',move.product_id.id), ('bom_id','=',False), ('type','=','phantom')]) if bis: factor = move.product_qty - bom_point = self.pool.get('mrp.bom').browse(cr, uid, bis[0]) - res = self.pool.get('mrp.bom')._bom_explode(cr, uid, bom_point, factor, []) + bom_point = bom_obj.browse(cr, uid, bis[0]) + res = bom_obj._bom_explode(cr, uid, bom_point, factor, []) dest = move.product_id.product_tmpl_id.property_stock_production.id state = 'confirmed' - if move.state=='assigned': - state='assigned' + if move.state == 'assigned': + state = 'assigned' for line in res[0]: valdef = { 'picking_id': move.picking_id.id, @@ -135,9 +147,9 @@ class StockMove(osv.osv): 'move_history_ids2': [(6,0,[])], 'procurements': [], } - mid = self.pool.get('stock.move').copy(cr, uid, move.id, default=valdef) - prodobj = self.pool.get('product.product').browse(cr, uid, line['product_id'], context=context) - proc_id = self.pool.get('mrp.procurement').create(cr, uid, { + mid = move_obj.copy(cr, uid, move.id, default=valdef) + prodobj = product_obj.browse(cr, uid, line['product_id'], context=context) + proc_id = procurement_obj.create(cr, uid, { 'name': (move.picking_id.origin or ''), 'origin': (move.picking_id.origin or ''), 'date_planned': move.date_planned, @@ -151,21 +163,18 @@ class StockMove(osv.osv): 'move_id': mid, 'company_id': line['company_id'], }) - wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr) - self.pool.get('stock.move').write(cr, uid, [move.id], { + move_obj.write(cr, uid, [move.id], { 'location_id': move.location_dest_id.id, 'auto_validate': True, 'picking_id': False, 'location_id': dest, 'state': 'waiting' }) - for m in self.pool.get('mrp.procurement').search(cr, uid, [('move_id','=',move.id)], context): - wf_service = netsvc.LocalService("workflow") + for m in procurement_obj.search(cr, uid, [('move_id','=',move.id)], context): wf_service.trg_validate(uid, 'mrp.procurement', m, 'button_wait_done', cr) return True - def action_consume(self, cr, uid, ids, product_qty, location_id=False, context=None): """ Consumed product with specific quatity from specific source location. @param product_qty: Consumed product quantity @@ -232,8 +241,9 @@ class StockPicking(osv.osv): @param *args: Arguments @return: Picking ids. """ - for move in self.pool.get('stock.move').browse(cr, uid, picks): - self.pool.get('stock.move')._action_explode(cr, uid, move) + move_obj = self.pool.get('stock.move') + for move in move_obj.browse(cr, uid, picks): + move_obj._action_explode(cr, uid, move) return picks StockPicking() @@ -241,6 +251,7 @@ StockPicking() class spilt_in_production_lot(osv.osv_memory): _inherit = "stock.move.split" + def split(self, cr, uid, ids, move_ids, context=None): """ Splits move lines into given quantities. @param move_ids: Stock moves. @@ -255,5 +266,6 @@ class spilt_in_production_lot(osv.osv_memory): for new_move in new_moves: production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]}) return res + spilt_in_production_lot() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From e22b59ee3f4e3e10e11092100c06ce14ec752c3c Mon Sep 17 00:00:00 2001 From: "sbh (Open ERP)" Date: Tue, 6 Apr 2010 14:31:01 +0530 Subject: [PATCH 04/30] [IMP] purchase_manual: convert the purchase_line_invoice into osv_memory bzr revid: sbh@tinyerp.com-20100406090101-v8c3eien7v8k5625 --- addons/purchase_manual/__terp__.py | 3 +- .../purchase_manual/purchase_manual_view.xml | 4 +- addons/purchase_manual/wizard/__init__.py | 3 +- .../wizard/purchase_line_invoice.py | 132 ++++++++++++++ .../wizard/purchase_line_invoice_view.xml | 33 ++++ .../wizard/wizard_purchase_line_invoice.py | 162 ------------------ 6 files changed, 171 insertions(+), 166 deletions(-) create mode 100644 addons/purchase_manual/wizard/purchase_line_invoice.py create mode 100644 addons/purchase_manual/wizard/purchase_line_invoice_view.xml delete mode 100644 addons/purchase_manual/wizard/wizard_purchase_line_invoice.py diff --git a/addons/purchase_manual/__terp__.py b/addons/purchase_manual/__terp__.py index 7634af9ca7a..a0c140cbcc2 100644 --- a/addons/purchase_manual/__terp__.py +++ b/addons/purchase_manual/__terp__.py @@ -31,7 +31,8 @@ 'init_xml': [], 'update_xml': [ 'purchase_manual_view.xml', - 'purchase_manual_wizard.xml', + 'wizard/purchase_line_invoice_view.xml', + ], 'demo_xml': [], 'installable': True, diff --git a/addons/purchase_manual/purchase_manual_view.xml b/addons/purchase_manual/purchase_manual_view.xml index 4e698dcac53..7d97cca7512 100644 --- a/addons/purchase_manual/purchase_manual_view.xml +++ b/addons/purchase_manual/purchase_manual_view.xml @@ -77,7 +77,7 @@ - + Uninvoiced Purchase Order Lines @@ -99,7 +99,7 @@ - + diff --git a/addons/purchase_manual/wizard/__init__.py b/addons/purchase_manual/wizard/__init__.py index e93c28bfe14..9f53e1a75ad 100644 --- a/addons/purchase_manual/wizard/__init__.py +++ b/addons/purchase_manual/wizard/__init__.py @@ -19,4 +19,5 @@ # ############################################################################## -import wizard_purchase_line_invoice + +import purchase_line_invoice diff --git a/addons/purchase_manual/wizard/purchase_line_invoice.py b/addons/purchase_manual/wizard/purchase_line_invoice.py new file mode 100644 index 00000000000..12024df71ad --- /dev/null +++ b/addons/purchase_manual/wizard/purchase_line_invoice.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import netsvc +import ir +from osv import osv +from tools.translate import _ + +class purchase_line_invoice(osv.osv_memory): + + """ To create invoice for purchase order line""" + + _name = 'purchase.order.line_invoice' + _description = 'Purchase Order Line Make Invoice' + + def makeInvoices(self, cr, uid, ids, context): + """ + To get Purchase Order line and create Invoice + @param self: The object pointer. + @param cr: A database cursor + @param uid: ID of the user currently logged in + @param context: A standard dictionary + @return : retrun view of Invoice + """ + record_ids = context.get('active_ids',[]) + if record_ids: + res = False + invoices = {} + invoice_obj=self.pool.get('account.invoice') + purchase_line_obj=self.pool.get('purchase.order.line') + property_obj=self.pool.get('ir.property') + account_fiscal_obj=self.pool.get('account.fiscal.position') + invoice_line_obj=self.pool.get('account.invoice.line') + + def make_invoice(order, lines): + a = order.partner_id.property_account_payable.id + if order.partner_id and order.partner_id.property_payment_term.id: + pay_term = order.partner_id.property_payment_term.id + else: + pay_term = False + inv = { + 'name': order.name, + 'origin': order.name, + 'type': 'in_invoice', + 'reference': "P%dPO%d" % (order.partner_id.id, order.id), + 'account_id': a, + 'partner_id': order.partner_id.id, + 'address_invoice_id': order.partner_address_id.id, + 'address_contact_id': order.partner_address_id.id, + 'invoice_line': [(6,0,lines)], + 'currency_id' : order.pricelist_id.currency_id.id, + 'comment': order.notes, + 'payment_term': pay_term, + 'fiscal_position': order.partner_id.property_account_position.id + } + inv_id = invoice_obj.create(cr, uid, inv) + return inv_id + + for line in purchase_line_obj.browse(cr,uid,record_ids): + if (not line.invoiced) and (line.state not in ('draft','cancel')): + if not line.order_id.id in invoices: + invoices[line.order_id.id] = [] + if line.product_id: + a = line.product_id.product_tmpl_id.property_account_expense.id + if not a: + a = line.product_id.categ_id.property_account_expense_categ.id + if not a: + raise osv.except_osv(_('Error !'), + _('There is no expense account defined ' \ + 'for this product: "%s" (id:%d)') % \ + (line.product_id.name, line.product_id.id,)) + else: + a = property_obj.get(cr, uid, + 'property_account_expense_categ', 'product.category', + context=context) + fpos = line.order_id.fiscal_position or False + a = account_fiscal_obj.map_account(cr, uid, fpos, a) + inv_id = invoice_line_obj.create(cr, uid, { + 'name': line.name, + 'origin': line.order_id.name, + 'account_id': a, + 'price_unit': line.price_unit, + 'quantity': line.product_qty, + 'uos_id': line.product_uom.id, + 'product_id': line.product_id.id or False, + 'invoice_line_tax_id': [(6, 0, [x.id for x in line.taxes_id])], + 'note': line.notes, + 'account_analytic_id': line.account_analytic_id and line.account_analytic_id.id or False, + }) + cr.execute('insert into purchase_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id)) + purchase_line_obj.write(cr, uid, [line.id], {'invoiced': True}) + invoices[line.order_id.id].append((line,inv_id)) + + res = [] + for result in invoices.values(): + order = result[0][0].order_id + il = map(lambda x: x[1], result) + res.append(make_invoice(order, il)) + + return { + 'domain': "[('id','in', ["+','.join(map(str,res))+"])]", + 'name': _('Supplier Invoices'), + 'view_type': 'form', + 'view_mode': 'tree,form', + 'res_model': 'account.invoice', + 'view_id': False, + 'context': "{'type':'in_invoice'}", + 'type': 'ir.actions.act_window' + } +purchase_line_invoice() + + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/purchase_manual/wizard/purchase_line_invoice_view.xml b/addons/purchase_manual/wizard/purchase_line_invoice_view.xml new file mode 100644 index 00000000000..c5855e5d448 --- /dev/null +++ b/addons/purchase_manual/wizard/purchase_line_invoice_view.xml @@ -0,0 +1,33 @@ + + + + + + + + Control invoices + purchase.order.line_invoice + form + +
+ + +