[MERGE]: Merge with lp:~openerp-dev/openobject-addons/ksa-addons2

bzr revid: rpa@tinyerp.com-20101207104811-ccx204cbxp2p56kh
This commit is contained in:
rpa (Open ERP) 2010-12-07 16:18:11 +05:30
commit b6e743433b
9 changed files with 102 additions and 29 deletions

View File

@ -53,11 +53,23 @@ class mrp_workcenter(osv.osv):
'costs_journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal'),
'costs_general_account_id': fields.many2one('account.account', 'General Account', domain=[('type','<>','view')]),
'resource_id': fields.many2one('resource.resource','Resource', ondelete='cascade', required=True),
'product_id': fields.many2one('product.product','Product'),
}
_defaults = {
'capacity_per_cycle': 1.0,
'resource_type': 'material',
}
def on_change_product_cost(self, cr, uid, ids, product_id, context=None):
if context is None:
context = {}
value = {}
if product_id:
cost = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
value = {'costs_hour' :cost.standard_price}
return {'value': value}
mrp_workcenter()
@ -746,7 +758,10 @@ class mrp_production(osv.osv):
'account_id': account,
'general_account_id': wc.costs_general_account_id.id,
'journal_id': wc.costs_journal_id.id,
'code': wc.code
'ref': wc.code,
'product_id': wc.product_id.id,
'unit_amount': wc.costs_hour * wc.time_cycle,
'product_uom_id': wc.product_id.uom_id.id
} )
if wc.costs_journal_id and wc.costs_general_account_id:
value = wc_line.cycle * wc.costs_cycle
@ -759,7 +774,10 @@ class mrp_production(osv.osv):
'account_id': account,
'general_account_id': wc.costs_general_account_id.id,
'journal_id': wc.costs_journal_id.id,
'code': wc.code,
'ref': wc.code,
'product_id': wc.product_id.id,
'unit_amount': wc.costs_hour * wc.time_cycle,
'product_uom_id': wc.product_id.uom_id.id
} )
return amount

View File

@ -162,12 +162,13 @@
</group>
<group col="2" colspan="2">
<separator colspan="2" string="Costing Information"/>
<field name="product_id" on_change="on_change_product_cost(product_id)"/>
<field name="costs_hour"/>
<field name="costs_hour_account_id" groups="analytic.group_analytic_accounting"/>
<field name="costs_cycle"/>
<field name="costs_cycle_account_id" groups="analytic.group_analytic_accounting"/>
<field name="costs_journal_id" groups="analytic.group_analytic_accounting"/>
<field name="costs_general_account_id" groups="analytic.group_analytic_accounting"/>
<field name="costs_journal_id" attrs="{'required':['|',('costs_hour_account_id', '=', True),('costs_cycle_account_id', '=', True)]}" groups="analytic.group_analytic_accounting"/>
<field name="costs_general_account_id" attrs="{ 'required':['|',('costs_cycle_account_id', '=', True),('costs_hour_account_id', '=', True)]}" groups="analytic.group_analytic_accounting"/>
</group>
<separator colspan="4" string="Description"/>
<field colspan="4" name="note" nolabel="1"/>
@ -650,9 +651,9 @@
<field name="product_uom" string="UOM"/>
<field name="location_id" string="Source Loc." />
<field name="state" invisible="1"/>
<button name="%(stock.action_partial_move)d"
string="Partial"
type="action" states="confirmed,assigned"
<button name="%(stock.action_partial_move)d"
string="Partial"
type="action" states="confirmed,assigned"
icon="gtk-justify-fill"/>
<button name="%(stock.move_scrap)d"
string="Scrap Products" type="action"
@ -935,9 +936,9 @@
<menuitem action="mrp_workcenter_action" id="menu_view_resource_search_mrp" parent="menu_pm_resources_config" sequence="1"/>
<menuitem action="resource.action_resource_calendar_form" id="menu_view_resource_calendar_search_mrp" parent="menu_pm_resources_config" sequence="1"/>
<menuitem action="resource.action_resource_calendar_leave_tree" id="menu_view_resource_calendar_leaves_search_mrp" parent="menu_pm_resources_config" sequence="1"/>
<!-- Planning -->
<menuitem id="menu_mrp_planning" name="Planning"
parent="base.menu_mrp_root" sequence="2"
groups="base.group_extended"/>

View File

@ -25,7 +25,7 @@ class mrp_price(osv.osv_memory):
_name = 'mrp.product_price'
_description = 'Product Price'
_columns = {
'number': fields.integer('Quantity', required=True, help="Specify quantity of products to produce or buy. Report of Cost structure will be displayed base on this qunatity."),
'number': fields.integer('Quantity', required=True, help="Specify quantity of products to produce or buy. Report of Cost structure will be displayed base on this quantity."),
}
_defaults = {
'number': 1,

View File

@ -490,6 +490,16 @@ class stock_warehouse_orderpoint(osv.osv):
_name = "stock.warehouse.orderpoint"
_description = "Minimum Inventory Rule"
def _get_draft_procurements(self, cr, uid, ids, field_name, arg, context=None):
if context is None:
context = {}
result = {}
procurement_obj = self.pool.get('procurement.order')
for orderpoint in self.browse(cr, uid, ids, context=context):
procurement_ids = procurement_obj.search(cr, uid , [('state', '=', 'draft'), ('product_id', '=', orderpoint.product_id.id), ('location_id', '=', orderpoint.location_id.id)])
result[orderpoint.id] = procurement_ids
return result
_columns = {
'name': fields.char('Name', size=32, required=True),
'active': fields.boolean('Active', help="If the active field is set to False, it will allow you to hide the orderpoint without removing it."),
@ -508,6 +518,8 @@ class stock_warehouse_orderpoint(osv.osv):
help="The procurement quantity will by rounded up to this multiple."),
'procurement_id': fields.many2one('procurement.order', 'Latest procurement', ondelete="set null"),
'company_id': fields.many2one('res.company','Company',required=True),
'procurement_draft_ids': fields.function(_get_draft_procurements, method=True, type='many2many', relation="procurement.order", \
string="Related Procurement Orders",help="Draft procurement of the product and location of that orderpoint"),
}
_defaults = {
'active': lambda *a: 1,

View File

@ -4,7 +4,7 @@
<!--
Procurement
-->
<record id="procurement_tree_view" model="ir.ui.view">
<field name="name">procurement.order.tree</field>
@ -145,7 +145,7 @@
<field name="search_view_id" ref="view_procurement_filter"/>
<field name="help">Procurement Orders represent the need for a certain quantity of products, at a given time, in a given location. Sale Orders are one typical source of Procurement Orders (but these are distinct documents). Depending on the procurement parameters and the products configuration, the procurement engine will attempt to satisfy the need by reserving products from stock, or ordering products from a supplier, or passing a manufacturing order, etc. A Procurement Exception occurs when the system cannot find a way to fulfill a procurement. Some exceptions will resolve themselves automatically, but others require manual intervention (those are identified by a specific error message)</field>
</record>
<record id="procurement_action5" model="ir.actions.act_window">
<field name="name">Procurement Exceptions</field>
<field name="type">ir.actions.act_window</field>
@ -224,6 +224,10 @@
<field name="procurement_id" readonly="1"/>
<field name="active" />
</group>
<group col="4" colspan="4" groups="base.group_extended">
<separator string="Related Procurement Orders" colspan="4" />
<field name="procurement_draft_ids" colspan="4" nolabel="1"/>
</group>
</form>
</field>
</record>
@ -238,11 +242,11 @@
<field name="help">You can define your minimum stock rules, so that OpenERP will trigger automatically the propositions of manufacturing or purchase orders according to the stock level. Once the virtual stock of a product (=stock on hand minus all confirmed orders and reservations) is bellow the minimum quantity, OpenERP will generate a procurement request in order to fullfil the stock up to the maximum quantity.</field>
</record>
<act_window
<act_window
context="{'search_default_warehouse_id': active_id}"
id="act_stock_warehouse_2_stock_warehouse_orderpoint"
name="Minimum Stock Rules"
res_model="stock.warehouse.orderpoint"
name="Minimum Stock Rules"
res_model="stock.warehouse.orderpoint"
src_model="stock.warehouse"/>
<!-- add product_uom to context to be the default value when adding new orderpoints -->

View File

@ -34,14 +34,14 @@ class procurement_order(osv.osv):
def _procure_confirm(self, cr, uid, ids=None, use_new_cursor=False, context=None):
'''
Call the scheduler to check the procurement order
@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 use_new_cursor: False or the dbname
@param context: A standard dictionary for contextual values
@return: Dictionary of values
@return: Dictionary of values
'''
if not context:
context = {}
@ -50,7 +50,7 @@ class procurement_order(osv.osv):
if use_new_cursor:
cr = pooler.get_db(use_new_cursor).cursor()
wf_service = netsvc.LocalService("workflow")
procurement_obj = self.pool.get('procurement.order')
if not ids:
ids = procurement_obj.search(cr, uid, [], order="date_planned")
@ -112,13 +112,13 @@ class procurement_order(osv.osv):
if uid:
request = self.pool.get('res.request')
summary = '''Here is the procurement scheduling report.
Start Time: %s
End Time: %s
Total Procurements processed: %d
Procurements with exceptions: %d
Skipped Procurements (scheduled date outside of scheduler range) %d
Exceptions:\n'''% (start_date, end_date, report_total, report_except, report_later)
summary += '\n'.join(report)
request.create(cr, uid,
@ -141,7 +141,7 @@ class procurement_order(osv.osv):
def create_automatic_op(self, cr, uid, context=None):
"""
Create procurement of virtual stock < 0
@param self: The object pointer
@param cr: The current row, from the database cursor,
@param uid: The current user ID for security checks
@ -191,14 +191,14 @@ class procurement_order(osv.osv):
'''
Create procurement based on Orderpoint
use_new_cursor: False or the dbname
@param self: The object pointer
@param cr: The current row, from the database cursor,
@param user_id: The current user ID for security checks
@param context: A standard dictionary for contextual values
@param param: False or the dbname
@return: Dictionary of values
"""
"""
'''
if not context:
context = {}
@ -212,27 +212,52 @@ class procurement_order(osv.osv):
report = []
offset = 0
ids = [1]
newdate = datetime.today()
if automatic:
self.create_automatic_op(cr, uid, context=context)
while ids:
ids = orderpoint_obj.search(cr, uid, [], offset=offset, limit=100)
for op in orderpoint_obj.browse(cr, uid, ids):
for op in orderpoint_obj.browse(cr, uid, ids, context=context):
if op.procurement_id.state != 'exception':
if op.procurement_id and op.procurement_id.purchase_id and op.procurement_id.purchase_id.state in ('draft', 'confirmed'):
continue
prods = location_obj._product_virtual_get(cr, uid,
op.location_id.id, [op.product_id.id],
{'uom': op.product_uom.id})[op.product_id.id]
if prods < op.product_min_qty:
qty = max(op.product_min_qty, op.product_max_qty)-prods
reste = qty % op.qty_multiple
if reste > 0:
qty += op.qty_multiple - reste
newdate = datetime.today() + relativedelta(
days = int(op.product_id.seller_delay))
if qty <= 0:
continue
if op.product_id.type not in ('consu'):
# Check draft procurement related to this order point
if op.procurement_draft_ids:
procure_qty = {}
#Compute list of draft procurement attached to Orderpoint
for pro_data in op.procurement_draft_ids:
procure_qty.update({pro_data.product_qty: pro_data.id })
procure_list = procure_qty.keys()
procure_list.sort()
procure_list.reverse()
to_generate = qty
for proc in procure_list:
if to_generate >= proc:
wf_service.trg_validate(uid, 'procurement.order', procure_qty[proc], 'button_confirm', cr)
procurement_obj.write(cr, uid, [procure_qty[proc]], {'origin': op.name}, context=context)
to_generate -= proc
if not to_generate:
break
qty = to_generate
if qty:
proc_id = procurement_obj.create(cr, uid, {
'name': op.name,
'date_planned': newdate.strftime('%Y-%m-%d'),
@ -248,7 +273,7 @@ class procurement_order(osv.osv):
wf_service.trg_validate(uid, 'procurement.order', proc_id,
'button_check', cr)
orderpoint_obj.write(cr, uid, [op.id],
{'procurement_id': proc_id})
{'procurement_id': proc_id}, context=context)
offset += len(ids)
if use_new_cursor:
cr.commit()

View File

@ -355,7 +355,8 @@ class product_template(osv.osv):
return True
_constraints = [
(_check_uos, 'Error: UOS must be in a different category than the UOM', ['uos_id']),
# According to bug: 543979
# (_check_uos, 'Error: UOS must be in a different category than the UOM', ['uos_id']),
(_check_uom, 'Error: The default UOM and the purchase UOM must be in the same category.', ['uom_id']),
]

View File

@ -1930,6 +1930,12 @@ class stock_move(osv.osv):
acc_variation = accounts.get('property_stock_variation', False)
journal_id = accounts['stock_journal']
if acc_dest == acc_variation:
raise osv.except_osv(_('Error!'), _('Can not create Journal Entry, Output Account defined on this product and Variant account on category of this product is same.'))
if acc_src == acc_variation:
raise osv.except_osv(_('Error!'), _('Can not create Journal Entry, Input Account defined on this product and Variant account on category of this product is same.'))
if not acc_src:
raise osv.except_osv(_('Error!'), _('There is no stock input account defined for this product or its category: "%s" (id: %d)') % \
(move.product_id.name, move.product_id.id,))
@ -2442,6 +2448,12 @@ class stock_inventory(osv.osv):
return self.pool.get('stock.move').create(cr, uid, move_vals)
def action_done(self, cr, uid, ids, context=None):
""" Finished the inventory
@return: True
"""
if context is None:
context = {}
move_obj = self.pool.get('stock.move')
for inv in self.browse(cr, uid, ids, context=context):
move_obj.action_done(cr, uid, [x.id for x in inv.move_ids], context=context)
@ -2449,7 +2461,7 @@ class stock_inventory(osv.osv):
return True
def action_confirm(self, cr, uid, ids, context=None):
""" Finishes the inventory and writes its finished date
""" Confirm the inventory and writes its finished date
@return: True
"""
if context is None:
@ -2460,7 +2472,7 @@ class stock_inventory(osv.osv):
product_context = dict(context, compute_child=False)
location_obj = self.pool.get('stock.location')
for inv in self.browse(cr, uid, ids):
for inv in self.browse(cr, uid, ids, context=context):
move_ids = []
for line in inv.inventory_line_id:
pid = line.product_id.id

View File

@ -64,7 +64,7 @@ class stock_split_into(osv.osv_memory):
if quantity_rest>0:
quantity_rest = move.product_qty - quantity
tracking_id = track_obj.create(cr, uid, {}, context=context)
if quantity==0.0:
if quantity == 0.0:
move_obj.write(cr, uid, [move.id], {'tracking_id': tracking_id}, context=context)
else:
default_val = {