diff options
| author | Fabien Pinckaers <fp@tinyerp.com> | 2012-09-20 11:58:25 +0200 |
|---|---|---|
| committer | Fabien Pinckaers <fp@tinyerp.com> | 2012-09-20 11:58:25 +0200 |
| commit | b6ed28e7c1e5ceb1ddf308de7389a95a331acb7f (patch) | |
| tree | 7c76f42ec66c44edc025b4761e86b4c7d6e06ef7 | |
| parent | aceff3a48bc91ffaacad17ad1fdce43181a9c562 (diff) | |
| parent | 14a1819fa79ecc1c05709a26e19f5a610c761351 (diff) | |
[MERGE] purchase and sale improvements & fixes
bzr revid: fp@tinyerp.com-20120920095825-3s0sq2qw7i5owyo0
| -rw-r--r-- | addons/purchase/purchase.py | 60 | ||||
| -rw-r--r-- | addons/purchase/purchase_view.xml | 35 | ||||
| -rw-r--r-- | addons/purchase/purchase_workflow.xml | 2 | ||||
| -rw-r--r-- | addons/purchase/res_config.py | 13 | ||||
| -rw-r--r-- | addons/purchase/res_config_view.xml | 4 | ||||
| -rw-r--r-- | addons/purchase/stock_view.xml | 77 | ||||
| -rw-r--r-- | addons/sale/sale.py | 20 | ||||
| -rw-r--r-- | addons/stock/stock.py | 7 | ||||
| -rw-r--r-- | addons/stock/wizard/stock_partial_picking.py | 13 |
9 files changed, 106 insertions, 125 deletions
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index e982930d69e..955d55b3825 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -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: diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml index 796fd1351a9..759c0561631 100644 --- a/addons/purchase/purchase_view.xml +++ b/addons/purchase/purchase_view.xml @@ -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"/> diff --git a/addons/purchase/purchase_workflow.xml b/addons/purchase/purchase_workflow.xml index 00fb5517568..212ce304e07 100644 --- a/addons/purchase/purchase_workflow.xml +++ b/addons/purchase/purchase_workflow.xml @@ -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"/> diff --git a/addons/purchase/res_config.py b/addons/purchase/res_config.py index bf7512a8666..19b059d4d5b 100644 --- a/addons/purchase/res_config.py +++ b/addons/purchase/res_config.py @@ -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."), diff --git a/addons/purchase/res_config_view.xml b/addons/purchase/res_config_view.xml index 6453752a638..f659d7b437f 100644 --- a/addons/purchase/res_config_view.xml +++ b/addons/purchase/res_config_view.xml @@ -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> diff --git a/addons/purchase/stock_view.xml b/addons/purchase/stock_view.xml index 21c52b4d2ec..d248ef66160 100644 --- a/addons/purchase/stock_view.xml +++ b/addons/purchase/stock_view.xml @@ -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 diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 0d4bda344a5..067f842165e 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -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: diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 041950df281..30bd70b9728 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -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', diff --git a/addons/stock/wizard/stock_partial_picking.py b/addons/stock/wizard/stock_partial_picking.py index 68e053b9e22..2cf0a743faa 100644 --- a/addons/stock/wizard/stock_partial_picking.py +++ b/addons/stock/wizard/stock_partial_picking.py @@ -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) |
