[MERGE] purchase and sale improvements & fixes
bzr revid: fp@tinyerp.com-20120920095825-3s0sq2qw7i5owyo0
This commit is contained in:
commit
b6ed28e7c1
|
@ -318,21 +318,26 @@ class purchase_order(osv.osv):
|
|||
for po in self.browse(cr, uid, ids, context=context):
|
||||
pick_ids += [picking.id for picking in po.picking_ids]
|
||||
|
||||
res = mod_obj.get_object_reference(cr, uid, 'stock', 'view_picking_in_form')
|
||||
res_id = res and res[1] or False
|
||||
|
||||
return {
|
||||
'name': _('Receptions'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'view_id': [res_id],
|
||||
'res_model': 'stock.picking',
|
||||
'context': "{'contact_display': 'partner'}",
|
||||
'type': 'ir.actions.act_window',
|
||||
'nodestroy': True,
|
||||
'target': 'current',
|
||||
'res_id': pick_ids and pick_ids[0] or False,
|
||||
}
|
||||
action_model, action_id = tuple(mod_obj.get_object_reference(cr, uid, 'stock', 'action_picking_tree4'))
|
||||
action = self.pool.get(action_model).read(cr, uid, action_id, context=context)
|
||||
ctx = eval(action['context'])
|
||||
ctx.update({
|
||||
'search_default_purchase_id': ids[0]
|
||||
})
|
||||
if pick_ids and len(pick_ids) == 1:
|
||||
form_view_ids = [view_id for view_id, view in action['views'] if view == 'form']
|
||||
view_id = form_view_ids and form_view_ids[0] or False
|
||||
action.update({
|
||||
'views': [],
|
||||
'view_mode': 'form',
|
||||
'view_id': view_id,
|
||||
'res_id': pick_ids[0]
|
||||
})
|
||||
|
||||
action.update({
|
||||
'context': ctx,
|
||||
})
|
||||
return action
|
||||
|
||||
def wkf_approve_order(self, cr, uid, ids, context=None):
|
||||
self.write(cr, uid, ids, {'state': 'approved', 'date_approve': fields.date.context_today(self,cr,uid,context=context)})
|
||||
|
@ -863,6 +868,12 @@ class purchase_order_line(osv.osv):
|
|||
supplier_delay = int(supplier_info.delay) if supplier_info else 0
|
||||
return datetime.strptime(date_order_str, DEFAULT_SERVER_DATE_FORMAT) + relativedelta(days=supplier_delay)
|
||||
|
||||
def _check_product_uom_group(self, cr, uid, context=None):
|
||||
group_uom = self.pool.get('ir.model.data').get_object(cr, uid, 'product', 'group_uom')
|
||||
res = [user for user in group_uom.users if user.id == uid]
|
||||
return len(res) and True or False
|
||||
|
||||
|
||||
def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id,
|
||||
partner_id, date_order=False, fiscal_position_id=False, date_planned=False,
|
||||
name=False, price_unit=False, context=None):
|
||||
|
@ -908,7 +919,8 @@ class purchase_order_line(osv.osv):
|
|||
uom_id = product_uom_po_id
|
||||
|
||||
if product.uom_id.category_id.id != product_uom.browse(cr, uid, uom_id, context=context).category_id.id:
|
||||
res['warning'] = {'title': _('Warning!'), 'message': _('Selected Unit of Measure does not belong to the same category as the product Unit of Measure.')}
|
||||
if self._check_product_uom_group(cr, uid, context=context):
|
||||
res['warning'] = {'title': _('Warning!'), 'message': _('Selected Unit of Measure does not belong to the same category as the product Unit of Measure.')}
|
||||
uom_id = product_uom_po_id
|
||||
|
||||
res['value'].update({'product_uom': uom_id})
|
||||
|
@ -1083,15 +1095,15 @@ class procurement_order(osv.osv):
|
|||
|
||||
procurement_order()
|
||||
|
||||
class mail_message(osv.osv):
|
||||
_name = 'mail.message'
|
||||
_inherit = 'mail.message'
|
||||
class mail_mail(osv.osv):
|
||||
_name = 'mail.mail'
|
||||
_inherit = 'mail.mail'
|
||||
|
||||
def _postprocess_sent_message(self, cr, uid, message, context=None):
|
||||
if message.model == 'purchase.order':
|
||||
def _postprocess_sent_message(self, cr, uid, mail, context=None):
|
||||
if mail.model == 'purchase.order':
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
wf_service.trg_validate(uid, 'purchase.order', message.res_id, 'send_rfq', cr)
|
||||
return super(mail_message, self)._postprocess_sent_message(cr, uid, message=message, context=context)
|
||||
wf_service.trg_validate(uid, 'purchase.order', mail.res_id, 'send_rfq', cr)
|
||||
return super(mail_mail, self)._postprocess_sent_message(cr, uid, mail=mail, context=context)
|
||||
|
||||
mail_message()
|
||||
mail_mail()
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -14,19 +14,40 @@
|
|||
<menuitem id="menu_purchase_config_purchase" name="Configuration"
|
||||
groups="group_purchase_manager"
|
||||
parent="base.menu_purchase_root" sequence="100"/>
|
||||
<menuitem
|
||||
action="product.product_pricelist_action_for_purchase" id="menu_product_pricelist_action2_purchase"
|
||||
parent="menu_purchase_config_purchase" sequence="10" groups="product.group_purchase_pricelist" />
|
||||
|
||||
<record id="purchase_pricelist_version_action" model="ir.actions.act_window">
|
||||
<field name="name">Pricelist Versions</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">product.pricelist.version</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="product.product_pricelist_version_tree_view"/>
|
||||
<field name="domain">[('pricelist_id.type','=','purchase')]</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to add a pricelist version.
|
||||
</p><p>
|
||||
There can be more than one version of a pricelist, each of
|
||||
these must be valid during a certain period of time. Some
|
||||
examples of versions: Main Prices, 2010, 2011, Summer Sales,
|
||||
etc.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_purchase_config_pricelist" name="Pricelists"
|
||||
parent="menu_purchase_config_purchase" sequence="50" groups="product.group_purchase_pricelist"/>
|
||||
|
||||
<menuitem
|
||||
action="product.product_pricelist_action" id="menu_product_pricelist_action_purhase"
|
||||
parent="menu_purchase_config_pricelist" sequence="20" groups="base.group_no_one"/>
|
||||
action="purchase_pricelist_version_action" id="menu_purchase_pricelist_version_action"
|
||||
parent="menu_purchase_config_pricelist" sequence="2" groups="product.group_purchase_pricelist"/>
|
||||
|
||||
|
||||
<menuitem
|
||||
action="product.product_pricelist_action_for_purchase" id="menu_product_pricelist_action2_purchase"
|
||||
parent="menu_purchase_config_pricelist" sequence="10" />
|
||||
|
||||
action="product.product_price_type_action" id="menu_product_pricelist_action2_purchase_type"
|
||||
parent="menu_purchase_config_pricelist" sequence="60" />
|
||||
<menuitem
|
||||
id="menu_product_in_config_purchase" name="Products"
|
||||
parent="menu_purchase_config_purchase" sequence="30" groups="base.group_no_one"/>
|
||||
|
@ -188,7 +209,7 @@
|
|||
<button name="view_picking" string="Receive Products" type="object" attrs="{'invisible': ['|', ('shipped','=',True), ('state','!=', 'approved')]}" class="oe_highlight"/>
|
||||
<button name="action_cancel_draft" states="cancel,sent,confirmed" string="Set to Draft" type="object" />
|
||||
<button name="purchase_cancel" states="draft,confirmed,sent" string="Cancel"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,approved,done" statusbar_colors='{"except_picking":"red","except_invoice":"red","confirmed":"blue"}' readonly="1"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,sent,approved,done" statusbar_colors='{"except_picking":"red","except_invoice":"red","confirmed":"blue"}' readonly="1"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
|
@ -346,7 +367,7 @@
|
|||
<field name="name">Quotations</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">purchase.order</field>
|
||||
<field name="context">{'search_default_draft': 1}</field>
|
||||
<field name="context">{}</field>
|
||||
<field name="domain">[('state','in',('draft','sent','confirmed'))]</field>
|
||||
<field name="view_mode">tree,form,graph,calendar</field>
|
||||
<field name="search_view_id" ref="view_purchase_order_filter"/>
|
||||
|
|
|
@ -145,7 +145,7 @@
|
|||
<record id="trans_router_invoice_no_order" model="workflow.transition">
|
||||
<field name="act_from" ref="act_router"/>
|
||||
<field name="act_to" ref="act_invoice_end"/>
|
||||
<field name="condition">invoice_method<>'order'</field>
|
||||
<field name="condition">invoice_method<>'order' and invoiced</field>
|
||||
</record>
|
||||
<record id="trans_except_picking_picking_done" model="workflow.transition">
|
||||
<field name="act_from" ref="act_except_picking"/>
|
||||
|
|
|
@ -46,10 +46,6 @@ class purchase_config_settings(osv.osv_memory):
|
|||
'group_purchase_delivery_address': fields.boolean("Allow a different address for incoming products and invoicings",
|
||||
implied_group='purchase.group_delivery_invoice_address',
|
||||
help="Allows you to specify different delivery and invoice addresses on a purchase order."),
|
||||
'module_purchase_analytic_plans': fields.boolean('Allow using multiple analytic accounts on the same order',
|
||||
help ="""Allows the user to maintain several analysis plans. These let you split
|
||||
lines on a purchase order between several accounts and analytic plans.
|
||||
This installs the module purchase_analytic_plans."""),
|
||||
'module_warning': fields.boolean("Alerts by products or supplier",
|
||||
help="""Allow to configure warnings on products and trigger them when a user wants to purchase a given product or a given supplier.
|
||||
Example: Product: this product is deprecated, do not purchase more than 5.
|
||||
|
@ -62,6 +58,12 @@ class purchase_config_settings(osv.osv_memory):
|
|||
help="""Purchase Requisitions are used when you want to request quotations from several suppliers for a given set of products.
|
||||
You can configure per product if you directly do a Request for Quotation
|
||||
to one supplier or if you want a purchase requisition to negotiate with several suppliers."""),
|
||||
'module_purchase_analytic_plans': fields.boolean('Use multiple analytic accounts on purchase orders',
|
||||
help ="""Allows the user to maintain several analysis plans. These let you split lines on a purchase order between several accounts and analytic plans.
|
||||
This installs the module purchase_analytic_plans."""),
|
||||
'group_analytic_account_for_purchases': fields.boolean('Analytic accounting for purchases',
|
||||
implied_group='purchase.group_analytic_accounting',
|
||||
help="Allows you to specify an analytic account on purchase orders."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -75,7 +77,8 @@ class account_config_settings(osv.osv_memory):
|
|||
_inherit = 'account.config.settings'
|
||||
_columns = {
|
||||
'module_purchase_analytic_plans': fields.boolean('Use multiple analytic accounts on orders',
|
||||
help="""This allows install module purchase_analytic_plans."""),
|
||||
help ="""Allows the user to maintain several analysis plans. These let you split lines on a purchase order between several accounts and analytic plans.
|
||||
This installs the module purchase_analytic_plans."""),
|
||||
'group_analytic_account_for_purchases': fields.boolean('Analytic accounting for purchases',
|
||||
implied_group='purchase.group_analytic_accounting',
|
||||
help="Allows you to specify an analytic account on purchase orders."),
|
||||
|
|
|
@ -74,6 +74,10 @@
|
|||
<field name="module_purchase_analytic_plans" class="oe_inline"/>
|
||||
<label for="module_purchase_analytic_plans"/>
|
||||
</div>
|
||||
<div>
|
||||
<field name="group_analytic_account_for_purchases" class="oe_inline"/>
|
||||
<label for="group_analytic_account_for_purchases"/>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
</form>
|
||||
|
|
|
@ -11,16 +11,6 @@
|
|||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="stock_picking_inherit_purchase" model="ir.ui.view">
|
||||
<field name="name">Picking list</field>
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="auto_picking" position="after">
|
||||
<field name="purchase_id" invisible="1"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="stock_picking_in_inherit_purchase" model="ir.ui.view">
|
||||
<field name="name">Incoming Picking Inherited</field>
|
||||
|
@ -36,63 +26,18 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Picking to Invoice -->
|
||||
<record id="view_picking_in_search_picking_to_invoice" model="ir.ui.view">
|
||||
<field name="name">stock.picking.in.search</field>
|
||||
<record id="view_picking_in_search_picking_inherit" model="ir.ui.view">
|
||||
<field name="name">stock.picking.in.search.inherit</field>
|
||||
<field name="model">stock.picking.in</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_in_search"/>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Picking to Invoice">
|
||||
<field name="name" string="Picking to Invoice" filter_domain="['|',('name','ilike',self),('origin','ilike',self)]"/>
|
||||
<filter icon="terp-check" name="available" string="Available" domain="[('state','=','assigned')]" help="Incoming Shipments Available"/>
|
||||
<filter icon="terp-dialog-close" name="done" string="Received" domain="[('state','=','done')]" help="Incoming Shipments already Received"/>
|
||||
<separator/>
|
||||
<filter icon="terp-accessories-archiver-minus" string="Back Orders" domain="[('backorder_id', '!=', False)]" help="Is a Back Order"/>
|
||||
<separator/>
|
||||
<filter string="To Invoice" name="to_invoice" icon="terp-dolar" domain="[('invoice_state', '=', '2binvoiced')]"/>
|
||||
<field name="stock_journal_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="purchase_id" />
|
||||
<group expand="0" string="Group By..." colspan="4" col="8">
|
||||
<filter icon="terp-stock_effects-object-colorize" name="Status" string="Status" domain="[]" context="{'group_by':'state'}"/>
|
||||
<filter string="Order Date" icon="terp-go-month" domain="[]" context="{'group_by':'date'}"/>
|
||||
<filter string="Scheduled Date" icon="terp-go-month" domain="[]" context="{'group_by':'min_date'}"/>
|
||||
<filter string="Journal" icon="terp-folder-orange" domain="[]" context="{'group_by':'stock_journal_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
<xpath expr="//field[@name='product_id']" position="before">
|
||||
<field name="purchase_id"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="act_purchase_order_2_stock_picking" model="ir.actions.act_window">
|
||||
<field name="name">Incoming Shipments</field>
|
||||
<field name="res_model">stock.picking.in</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar</field>
|
||||
<field name="domain">[('type','=','in')]</field>
|
||||
<field name="context">{'search_default_purchase_id': active_id,'default_type': 'in'}</field>
|
||||
<field name="search_view_id" ref="view_picking_in_search_picking_to_invoice"/>
|
||||
</record>
|
||||
|
||||
<record id="act_purchase_order_2_stock_picking_tree" model="ir.actions.act_window.view">
|
||||
<field eval="1" name="sequence"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="stock.view_picking_in_tree"/>
|
||||
<field name="act_window_id" ref="act_purchase_order_2_stock_picking"/>
|
||||
</record>
|
||||
|
||||
<record id="act_purchase_order_2_stock_picking_form" model="ir.actions.act_window.view">
|
||||
<field eval="2" name="sequence"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="stock.view_picking_in_form"/>
|
||||
<field name="act_window_id" ref="act_purchase_order_2_stock_picking"/>
|
||||
</record>
|
||||
|
||||
<record id="act_purchase_order_2_stock_picking_calendar" model="ir.actions.act_window.view">
|
||||
<field eval="3" name="sequence"/>
|
||||
<field name="view_mode">calendar</field>
|
||||
<field name="view_id" ref="stock.stock_picking_in_calendar"/>
|
||||
<field name="act_window_id" ref="act_purchase_order_2_stock_picking"/>
|
||||
</record>
|
||||
|
||||
<!-- is it need ? we have another method "Receive Products"-->
|
||||
<record id="purchase_order_2_stock_picking" model="ir.ui.view">
|
||||
<field name="name">Purchase Picking Inherited</field>
|
||||
<field name="model">purchase.order</field>
|
||||
|
@ -100,8 +45,8 @@
|
|||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[contains(@class, 'oe_title')]" position="before">
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<button type="action"
|
||||
name="%(act_purchase_order_2_stock_picking)d"
|
||||
<button type="object"
|
||||
name="view_picking"
|
||||
string="Incoming Shipments" states="approved"/>
|
||||
</div>
|
||||
</xpath>
|
||||
|
@ -110,13 +55,13 @@
|
|||
|
||||
<record id="action_picking_tree4_picking_to_invoice" model="ir.actions.act_window">
|
||||
<field name="name">On Incoming Shipments</field>
|
||||
<field name="res_model">stock.picking</field>
|
||||
<field name="res_model">stock.picking.in</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar</field>
|
||||
<field name="domain">[('type','=','in')]</field>
|
||||
<field name="context">{"default_type": "in", "contact_display": "partner_address", "search_default_done": 1, "search_default_to_invoice": 1}</field>
|
||||
<field name="search_view_id" ref="view_picking_in_search_picking_to_invoice"/>
|
||||
<field name="search_view_id" ref="stock.view_picking_in_search"/>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
Here you can track all the product receptions of purchase
|
||||
|
|
|
@ -771,7 +771,8 @@ class sale_order(osv.osv):
|
|||
'default_res_id': ids[0],
|
||||
'default_use_template': True,
|
||||
'default_template_id': template_id,
|
||||
})
|
||||
'mark_so_as_sent': True
|
||||
})
|
||||
return {
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
|
@ -1476,15 +1477,14 @@ class sale_order_line(osv.osv):
|
|||
|
||||
sale_order_line()
|
||||
|
||||
class mail_message(osv.osv):
|
||||
_inherit = 'mail.message'
|
||||
|
||||
def _postprocess_sent_message(self, cr, uid, message, context=None):
|
||||
if message.model == 'sale.order':
|
||||
class mail_compose_message(osv.osv):
|
||||
_inherit = 'mail.compose.message'
|
||||
def send_mail(self, cr, uid, ids, context=None):
|
||||
context = context or {}
|
||||
if context.get('mark_so_as_sent', False) and context.get('default_res_id', False):
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
wf_service.trg_validate(uid, 'sale.order', message.res_id, 'quotation_sent', cr)
|
||||
return super(mail_message, self)._postprocess_sent_message(cr, uid, message=message, context=context)
|
||||
|
||||
mail_message()
|
||||
wf_service.trg_validate(uid, 'sale.order', context.get('default_res_id', False), 'quotation_sent', cr)
|
||||
return super(mail_compose_message, self).send_mail(cr, uid, ids, context=context)
|
||||
mail_compose_message()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -673,6 +673,13 @@ class stock_picking(osv.osv):
|
|||
]
|
||||
|
||||
def action_process(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
context.update({
|
||||
'active_model': self._name,
|
||||
'active_ids': ids,
|
||||
'active_id': len(ids) and ids[0] or False
|
||||
})
|
||||
return {
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
|
|
|
@ -107,21 +107,10 @@ class stock_partial_picking(osv.osv_memory):
|
|||
picking_ids = context.get('active_ids', [])
|
||||
active_model = context.get('active_model')
|
||||
|
||||
if active_model == 'purchase.order':
|
||||
for purchase_order in self.pool.get('purchase.order').browse(cr, uid, picking_ids, context=context):
|
||||
picking_ids = [picking_id.id for picking_id in purchase_order.picking_ids]
|
||||
elif active_model == 'sale.order':
|
||||
for sale_order in self.pool.get('sale.order').browse(cr, uid, picking_ids, context=context):
|
||||
picking_ids = [picking.id for picking in sale_order.picking_ids]
|
||||
|
||||
if not picking_ids or len(picking_ids) != 1:
|
||||
# Partial Picking Processing may only be done for one picking at a time
|
||||
return res
|
||||
# The check about active_model is there in case the client mismatched the context during propagation of it
|
||||
# (already seen in previous bug where context passed was containing ir.ui.menu as active_model and the menu
|
||||
# ID as active_id). Though this should be fixed in clients now, this place is sensitive enough to ensure the
|
||||
# consistancy of the context.
|
||||
assert active_model in ('stock.picking', 'stock.picking.in', 'stock.picking.out', 'purchase.order', 'sale.order'), 'Bad context propagation'
|
||||
assert active_model in ('stock.picking', 'stock.picking.in', 'stock.picking.out'), 'Bad context propagation'
|
||||
picking_id, = picking_ids
|
||||
if 'picking_id' in fields:
|
||||
res.update(picking_id=picking_id)
|
||||
|
|
Loading…
Reference in New Issue