diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml index 8aae0062a33..52e0f539b80 100644 --- a/addons/mrp/mrp_view.xml +++ b/addons/mrp/mrp_view.xml @@ -746,7 +746,7 @@ - + @@ -774,7 +774,7 @@ - + diff --git a/addons/mrp/wizard/mrp_product_produce_view.xml b/addons/mrp/wizard/mrp_product_produce_view.xml index 666be7d5114..859bebc2b43 100644 --- a/addons/mrp/wizard/mrp_product_produce_view.xml +++ b/addons/mrp/wizard/mrp_product_produce_view.xml @@ -18,16 +18,16 @@ + groups="stock.group_production_lot"/> - + + groups="stock.group_production_lot"/> diff --git a/addons/mrp/wizard/stock_move_view.xml b/addons/mrp/wizard/stock_move_view.xml index ebd948633c2..86588927c57 100644 --- a/addons/mrp/wizard/stock_move_view.xml +++ b/addons/mrp/wizard/stock_move_view.xml @@ -15,7 +15,7 @@ - diff --git a/addons/mrp_repair/views/report_mrprepairorder.xml b/addons/mrp_repair/views/report_mrprepairorder.xml index 2897fee1fd9..a6d00ba5b15 100644 --- a/addons/mrp_repair/views/report_mrprepairorder.xml +++ b/addons/mrp_repair/views/report_mrprepairorder.xml @@ -30,7 +30,7 @@

Repair Order N°: - Repair Quotation N°: + Repair Quotation N°:

@@ -41,7 +41,9 @@
Lot Number - + + +
Guarantee Limit: diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py index 2ebc800ec04..e45651a30a2 100644 --- a/addons/procurement/procurement.py +++ b/addons/procurement/procurement.py @@ -64,7 +64,7 @@ class procurement_group(osv.osv): } _defaults = { 'name': lambda self, cr, uid, c: self.pool.get('ir.sequence').get(cr, uid, 'procurement.group') or '', - 'move_type': lambda self, cr, uid, c: 'one' + 'move_type': lambda self, cr, uid, c: 'direct' } class procurement_rule(osv.osv): @@ -267,7 +267,7 @@ class procurement_order(osv.osv): # # Scheduler # - def run_scheduler(self, cr, uid, use_new_cursor=False, context=None): + def run_scheduler(self, cr, uid, use_new_cursor=False, company_id = False, context=None): ''' Call the scheduler to check the procurement order. This is intented to be done for all existing companies at the same time, so we're running all the methods as SUPERUSER to avoid intercompany and access rights issues. @@ -288,8 +288,11 @@ class procurement_order(osv.osv): cr = openerp.registry(cr.dbname).cursor() # Run confirmed procurements + dom = [('state', '=', 'confirmed')] + if company_id: + dom += [('company_id', '=', company_id)] while True: - ids = self.search(cr, SUPERUSER_ID, [('state', '=', 'confirmed')], context=context) + ids = self.search(cr, SUPERUSER_ID, dom, context=context) if not ids: break self.run(cr, SUPERUSER_ID, ids, context=context) @@ -298,8 +301,11 @@ class procurement_order(osv.osv): # Check if running procurements are done offset = 0 + dom = [('state', '=', 'running')] + if company_id: + dom += [('company_id', '=', company_id)] while True: - ids = self.search(cr, SUPERUSER_ID, [('state', '=', 'running')], offset=offset, context=context) + ids = self.search(cr, SUPERUSER_ID, dom, offset=offset, context=context) if not ids: break done = self.check(cr, SUPERUSER_ID, ids, context=context) diff --git a/addons/procurement/wizard/schedulers_all.py b/addons/procurement/wizard/schedulers_all.py index 5c712b3af38..34d4758c5d5 100644 --- a/addons/procurement/wizard/schedulers_all.py +++ b/addons/procurement/wizard/schedulers_all.py @@ -37,8 +37,12 @@ class procurement_compute_all(osv.osv_memory): """ proc_obj = self.pool.get('procurement.order') #As this function is in a new thread, i need to open a new cursor, because the old one may be closed + new_cr = self.pool.cursor() - proc_obj.run_scheduler(new_cr, uid, use_new_cursor=new_cr.dbname, context=context) + user = self.pool.get('res.users').browse(new_cr, uid, uid, context=context) + comps = [x.id for x in user.company_ids] + for comp in comps: + proc_obj.run_scheduler(new_cr, uid, use_new_cursor=new_cr.dbname, company_id = comp, context=context) #close the new cursor new_cr.close() return {} diff --git a/addons/product_expiry/product_expiry.py b/addons/product_expiry/product_expiry.py index e311356dbbd..6979344bbcc 100644 --- a/addons/product_expiry/product_expiry.py +++ b/addons/product_expiry/product_expiry.py @@ -92,7 +92,7 @@ class stock_quant(osv.osv): def apply_removal_strategy(self, cr, uid, location, product, qty, domain, removal_strategy, context=None): if removal_strategy == 'fefo': - order = 'removal_date, id' + order = 'removal_date, in_date, id' return self._quants_get_order(cr, uid, location, product, qty, domain, order, context=context) return super(stock_quant, self).apply_removal_strategy(cr, uid, location, product, qty, domain, removal_strategy, context=context) diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index bfdd83e0872..09cc4c301a4 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -700,6 +700,7 @@ class purchase_order(osv.osv): 'origin': order.name, 'route_ids': order.picking_type_id.warehouse_id and [(6, 0, [x.id for x in order.picking_type_id.warehouse_id.route_ids])] or [], 'warehouse_id':order.picking_type_id.warehouse_id.id, + 'invoice_state': order.invoice_method == 'picking' and '2binvoiced' or 'none' } diff_quantity = order_line.product_qty @@ -709,9 +710,10 @@ class purchase_order(osv.osv): tmp.update({ 'product_uom_qty': min(procurement_qty, diff_quantity), 'product_uos_qty': min(procurement_qty, diff_quantity), - 'move_dest_id': procurement.move_dest_id.id, # blabla - 'group_id': procurement.group_id.id or group_id, # blabla to check ca devrait etre bon et groupé dans le meme picking qd meme + 'move_dest_id': procurement.move_dest_id.id, #move destination is same as procurement destination + 'group_id': procurement.group_id.id or group_id, #move group is same as group of procurements if it exists, otherwise take another group 'procurement_id': procurement.id, + 'invoice_state': procurement.rule_id.invoice_state or (procurement.location_id and procurement.location_id.usage == 'customer' and procurement.invoice_state) or (order.invoice_method == 'picking' and '2binvoiced') or 'none', #dropship case takes from sale }) diff_quantity -= min(procurement_qty, diff_quantity) res.append(tmp) @@ -1299,6 +1301,7 @@ class procurement_order(osv.osv): res[procurement.id] = False else: schedule_date = self._get_purchase_schedule_date(cr, uid, procurement, company, context=context) + purchase_date = self._get_purchase_order_date(cr, uid, procurement, company, schedule_date, context=context) line_vals = self._get_po_line_values_from_proc(cr, uid, procurement, partner, company, schedule_date, context=context) #look for any other draft PO for the same supplier, to attach the new line on instead of creating a new draft one available_draft_po_ids = po_obj.search(cr, uid, [ @@ -1306,6 +1309,10 @@ class procurement_order(osv.osv): ('location_id', '=', procurement.location_id.id), ('company_id', '=', procurement.company_id.id), ('dest_address_id', '=', procurement.partner_dest_id.id)], context=context) if available_draft_po_ids: po_id = available_draft_po_ids[0] + po_rec = po_obj.browse(cr, uid, po_id, context=context) + #if the product has to be ordered earlier those in the existing PO, we replace the purchase date on the order to avoid ordering it too late + if datetime.strptime(po_rec.date_order, DEFAULT_SERVER_DATE_FORMAT) > purchase_date: + po_obj.write(cr, uid, [po_id], {'date_order': purchase_date}, context=context) #look for any other PO line in the selected PO with same product and UoM to sum quantities instead of creating a new po line available_po_line_ids = po_line_obj.search(cr, uid, [('order_id', '=', po_id), ('product_id', '=', line_vals['product_id']), ('product_uom', '=', line_vals['product_uom'])], context=context) if available_po_line_ids: @@ -1318,7 +1325,6 @@ class procurement_order(osv.osv): po_line_id = po_line_obj.create(cr, SUPERUSER_ID, line_vals, context=context) linked_po_ids.append(procurement.id) else: - purchase_date = self._get_purchase_order_date(cr, uid, procurement, company, schedule_date, context=context) name = seq_obj.get(cr, uid, 'purchase.order') or _('PO: %s') % procurement.name po_vals = { 'name': name, @@ -1363,6 +1369,13 @@ class product_template(osv.Model): _name = 'product.template' _inherit = 'product.template' + def _get_buy_route(self, cr, uid, context=None): + + buy_route = self.pool.get('ir.model.data').xmlid_to_res_id(cr, uid, 'purchase.route_warehouse0_buy') + if buy_route: + return [buy_route] + return [] + def _purchase_count(self, cr, uid, ids, field_name, arg, context=None): res = dict.fromkeys(ids, 0) for template in self.browse(cr, uid, ids, context=context): @@ -1374,6 +1387,7 @@ class product_template(osv.Model): } _defaults = { 'purchase_ok': 1, + 'route_ids': _get_buy_route, } class product_product(osv.Model): @@ -1451,15 +1465,9 @@ class account_invoice_line(osv.Model): readonly=True), } -class product_product(osv.osv): - _inherit = "product.product" +class product_template(osv.osv): + _inherit = "product.template" - def _get_buy_route(self, cr, uid, context=None): - buy_route = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'purchase', 'route_warehouse0_buy')[1] - return [buy_route] - _defaults = { - 'route_ids': _get_buy_route, - } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/purchase/stock.py b/addons/purchase/stock.py index 69d970b7be6..26d2ff1002f 100644 --- a/addons/purchase/stock.py +++ b/addons/purchase/stock.py @@ -55,6 +55,33 @@ class stock_move(osv.osv): }) return super(stock_move, self).copy(cr, uid, id, default, context) + + def _create_invoice_line_from_vals(self, cr, uid, move, invoice_line_vals, context=None): + invoice_line_id = super(stock_move, self)._create_invoice_line_from_vals(cr, uid, move, invoice_line_vals, context=context) + if move.purchase_line_id: + purchase_line = move.purchase_line_id + self.pool.get('purchase.order.line').write(cr, uid, [purchase_line.id], { + 'invoice_lines': [(4, invoice_line_id)] + }, context=context) + self.pool.get('purchase.order').write(cr, uid, [purchase_line.order_id.id], { + 'invoice_ids': [(4, invoice_line_vals['invoice_id'])], + }) + return invoice_line_id + + def _get_master_data(self, cr, uid, move, company, context=None): + if move.purchase_line_id: + purchase_order = move.purchase_line_id.order_id + return purchase_order.partner_id, purchase_order.create_uid.id, purchase_order.pricelist_id.currency_id.id + return super(stock_move, self)._get_master_data(cr, uid, move, company, context=context) + + def _get_invoice_line_vals(self, cr, uid, move, partner, inv_type, context=None): + res = super(stock_move, self)._get_invoice_line_vals(cr, uid, move, partner, inv_type, context=context) + if move.purchase_line_id: + purchase_line = move.purchase_line_id + res['invoice_line_tax_id'] = [(6, 0, [x.id for x in purchase_line.taxes_id])] + res['price_unit'] = purchase_line.price_unit + return res + class stock_picking(osv.osv): _inherit = 'stock.picking' diff --git a/addons/sale_stock/sale_stock.py b/addons/sale_stock/sale_stock.py index b3bbd253392..63f6068f3c2 100644 --- a/addons/sale_stock/sale_stock.py +++ b/addons/sale_stock/sale_stock.py @@ -388,7 +388,7 @@ class stock_move(osv.osv): return super(stock_move, self).action_cancel(cr, uid, ids, context=context) def _create_invoice_line_from_vals(self, cr, uid, move, invoice_line_vals, context=None): - invoice_line_id = self.pool.get('account.invoice.line').create(cr, uid, invoice_line_vals, context=context) + invoice_line_id = super(stock_move, self)._create_invoice_line_from_vals(cr, uid, move, invoice_line_vals, context=context) if move.procurement_id and move.procurement_id.sale_line_id: sale_line = move.procurement_id.sale_line_id self.pool.get('sale.order.line').write(cr, uid, [sale_line.id], { diff --git a/addons/stock/procurement.py b/addons/stock/procurement.py index a8fc778f2e6..b8d7a03c9f2 100644 --- a/addons/stock/procurement.py +++ b/addons/stock/procurement.py @@ -261,7 +261,7 @@ class procurement_order(osv.osv): result['domain'] = "[('group_id','in',[" + ','.join(map(str, list(group_ids))) + "])]" return result - def run_scheduler(self, cr, uid, use_new_cursor=False, context=None): + def run_scheduler(self, cr, uid, use_new_cursor=False, company_id=False, context=None): ''' Call the scheduler in order to check the running procurements (super method), to check the minimum stock rules and the availability of moves. This function is intended to be run for all the companies at the same time, so @@ -286,8 +286,7 @@ class procurement_order(osv.osv): move_obj = self.pool.get('stock.move') #Minimum stock rules - company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id - self._procure_orderpoint_confirm(cr, SUPERUSER_ID, use_new_cursor=False, company_id=company.id, context=context) + self._procure_orderpoint_confirm(cr, SUPERUSER_ID, use_new_cursor=False, company_id=company_id, context=context) #Search all confirmed stock_moves and try to assign them confirmed_ids = move_obj.search(cr, uid, [('state', '=', 'confirmed')], limit=None, order='priority desc, date_expected asc', context=context) @@ -331,7 +330,7 @@ class procurement_order(osv.osv): [order_point.product_id.id], context={'location': order_point.location_id.id})[order_point.product_id.id]['virtual_available'] - def _procure_orderpoint_confirm(self, cr, uid, use_new_cursor=False, company_id=False, context=None): + def _procure_orderpoint_confirm(self, cr, uid, use_new_cursor=False, company_id = False, context=None): ''' Create procurement based on Orderpoint @@ -341,14 +340,15 @@ class procurement_order(osv.osv): if context is None: context = {} if use_new_cursor: - cr = openerp.registry(cr.dbname).db.cursor() + cr = openerp.registry(cr.dbname).cursor() orderpoint_obj = self.pool.get('stock.warehouse.orderpoint') procurement_obj = self.pool.get('procurement.order') offset = 0 ids = [1] + dom = company_id and [('company_id', '=', company_id)] or [] while ids: - ids = orderpoint_obj.search(cr, uid, [('company_id', '=', company_id)], offset=offset, limit=100) + ids = orderpoint_obj.search(cr, uid, dom, offset=offset, limit=100) for op in orderpoint_obj.browse(cr, uid, ids, context=context): prods = self._product_virtual_get(cr, uid, op) if prods is None: diff --git a/addons/stock/product.py b/addons/stock/product.py index 0cf7df5e836..1cd677706f6 100644 --- a/addons/stock/product.py +++ b/addons/stock/product.py @@ -171,13 +171,13 @@ class product_product(osv.osv): def _product_available_text(self, cr, uid, ids, field_names=None, arg=False, context=None): res = {} for product in self.browse(cr, uid, ids, context=context): - res[product.id] = str(product.qty_available) + _(" In Stock") + res[product.id] = str(product.qty_available) + _(" On Hand") return res _columns = { 'reception_count': fields.function(_stock_move_count, string="Reception", type='integer', multi='pickings'), 'delivery_count': fields.function(_stock_move_count, string="Delivery", type='integer', multi='pickings'), - 'qty_in_stock': fields.function(_product_available_text, type='char'), + 'qty_available_text': fields.function(_product_available_text, type='char'), 'qty_available': fields.function(_product_available, multi='qty_available', type='float', digits_compute=dp.get_precision('Product Unit of Measure'), string='Quantity On Hand', @@ -277,6 +277,12 @@ class product_product(osv.osv): res['fields']['qty_available']['string'] = _('Produced Qty') return res + + def action_view_routes(self, cr, uid, ids, context=None): + template_obj = self.pool.get("product.template") + templ_ids = list(set([x.product_tmpl_id.id for x in self.browse(cr, uid, ids, context=context)])) + return template_obj.action_view_routes(cr, uid, templ_ids, context=context) + class product_template(osv.osv): _name = 'product.template' _inherit = 'product.template' diff --git a/addons/stock/product_view.xml b/addons/stock/product_view.xml index 2a7ad044fbc..c3941eb1887 100644 --- a/addons/stock/product_view.xml +++ b/addons/stock/product_view.xml @@ -193,7 +193,7 @@ - + @@ -202,13 +202,13 @@