Odoo Help

Welcome!

This community is for beginners and experts willing to share their Odoo knowledge. It's not a forum to discuss ideas, but a knowledge base of questions and their answers.

2

How to fill purchase.order.line with sale.order.line? [Closed]

By
Anabela Damas
on 4/5/13, 8:27 AM 6,056 views

The Question has been closed

by
Sudhir Arya (SA)
on 04/18/2013 05:00:01

Hi, I've created a module that creates a relation one2many between Purchase Order and Sales Order. So in Purchase order we can choose a Sales Order that is the origin to this Purchase Order, like this:

In mymodule.py

class purchase_order(osv.osv):
    _inherit = 'purchase.order'
    _name = 'purchase.order'
    _columns = {
       'asd_pquotation_id': fields.many2one('sale.order','Sale Quotation', domain=[('state','in',('draft','sent'))]),
    }
    _defaults = {
        'asd_pquotation_id': lambda self, cr, uid, context: context.get('asd_pquotation_id', False),
    }
purchase_order()

class sale_order(osv.osv):
    _inherit = "sale.order"
    _name = "sale.order"
    _columns = {
        'asd_squotation': fields.one2many('purchase.order','asd_pquotation_id', 'Purchase Quotation'),
    }
sale_order()

In mymodule_view.xml

<record id="purchase_order_form_change" model="ir.ui.view">
        <field name="name">purchase.order.form.change</field>
        <field name="model">purchase.order</field>
        <field name="inherit_id" ref="purchase.purchase_order_form"/>
        <field name="arch" type="xml">
            <xpath expr="/form/sheet/group/group/field[@name='company_id']" position="after">
        <field name="asd_pquotation_id"/>
    </xpath>
    </field>
</record>

The result is like this: image description

But now I wanted to by selecting the sale quotation (in red) to fill in the purchase.order.line (in green) with the information from sale.order.line. I've tried this code, but I've an error:

In the file mymodule.py I added this function:

class purchase_order(osv.osv):

    _inherit = 'purchase.order'
    _name = 'purchase.order'
    STATE_SELECTION = [
        ('draft', 'Draft PO'),
        ('sent', 'RFQ Sent'),
        ('received', 'RFQ Received'),
        ('confirmed', 'Waiting Approval'),
        ('approved', 'Purchase Order'),
        ('except_picking', 'Shipping Exception'),
        ('except_invoice', 'Invoice Exception'),
        ('done', 'Done'),
        ('cancel', 'Cancelled')
    ]
    _columns = {
       'state': fields.selection(STATE_SELECTION, 'Status', readonly=True, help="The status of the purchase order or the quotation request. A quotation is a purchase order in a 'Draft' status. Then the order has to be confirmed by the user, the status switch to 'Confirmed'. Then the supplier must confirm the order to change the status to 'Approved'. When the purchase order is paid and received, the status becomes 'Done'. If a cancel action occurs in the invoice or in the reception of goods, the status becomes in exception.", select=True),
       'vi_coa': fields.boolean('COA', help="Check this box if you received and attach the COA"),
       'vi_msds': fields.boolean('MSDS', help="Check this box if you received and attach the MSDS"),
       'asd_pquotation_id': fields.many2one('sale.order','Sale Quotation', domain=[('state','in',('draft','sent'))]),
    }
    _defaults = {
        'asd_pquotation_id': lambda self, cr, uid, context: context.get('asd_pquotation_id', False),
    }

    def onchange_sales_order(self, cr, uid, ids, asd_pquotation_id, partner_id, pricelist_id):
        domain = []
        value = []
        if asd_pquotation_id:
            so = self.pool.get('sale.order').browse(cr,uid,asd_pquotation_id)
            for sol in so.order_line:
                vals = self.pool.get('purchase.order.line').onchange_product_id(cr, uid, ids, pricelist_id, sol.product_id.id, sol.product_uom_qty, sol.product_uom.id, partner_id)
                vals['value'].update({
                    'product_id': sol.product_id.id,
                    })
                value.append(vals['value'])
                domain.append(vals['domain'])
        return {'value': {'order_line': value}, 'domain': {'order_line': domain}}
purchase_order()

and in the view:

<record id="purchase_order_form_change" model="ir.ui.view">
    <field name="name">purchase.order.form.change</field>
    <field name="model">purchase.order</field>
    <field name="inherit_id" ref="purchase.purchase_order_form"/>
    <field name="arch" type="xml">
    <button name="wkf_send_rfq" states="draft" position="before">
        <button name="wkf_send_rfq" states="received" string="Send by EMail" type="object" context="{'send_rfq':True}"/>
            <button name="print_quotation" string="Print" type="object" states="received" groups="base.group_user"/>            
    </button>
    <button name="purchase_confirm" states="sent" position="replace">
        <button name="purchase_confirm" states="sent" string="Confirm Order"/>
        <button name="purchase_confirm" states="received" string="Confirm Order" class="oe_highlight"/>
        <button name="purchase_received" states="sent" string="Received PQ" class="oe_highlight"/>
        <button name="purchase_cancel" states="received" string="Cancel"/>
    </button>
    <field name="state" position="replace">
        <field name="state" widget="statusbar" statusbar_visible="draft,sent,received,approved,done" statusbar_colors='{"except_picking":"red","except_invoice":"red","confirmed":"blue"}' readonly="1"/>
    </field>
    <div class="oe_title" position="replace">
        <div class="oe_title">
        <h1>
        <label string="Request for Quotation " attrs="{'invisible': [('state','not in',('draft','sent','received'))]}"/>
        <label string="Purchase Order " attrs="{'invisible': [('state','in',('draft','sent','received'))]}"/>
        <field name="name" class="oe_inline" readonly="1"/>
        </h1>
        </div>
    </div>
    <field name="product_id" position="before">
            <field name="state" invisible="1" />
    </field>
    <field name="price_unit" position="replace">
            <field name="price_unit" attrs="{'invisible': [('state','in',('draft','sent'))]}"/>
    </field>
    <field name="taxes_id" position="replace">
            <field name="taxes_id" attrs="{'invisible': [('state','in',('draft','sent'))]}" widget="many2many_tags" domain="[('parent_id','=',False),('type_tax_use','!=','sale')]"/>
    </field>
    <field name="price_subtotal" position="replace">
            <field name="price_subtotal" attrs="{'invisible': [('state','in',('draft','sent'))]}"/>
    </field>
    <group class="oe_subtotal_footer oe_right" position="replace">
        <group class="oe_subtotal_footer oe_right" attrs="{'invisible': [('state','in',('draft','sent'))]}">
        <field name="amount_untaxed" widget="monetary" options="{'currency_field': 'currency_id'}"/>
        <field name="amount_tax" widget="monetary" options="{'currency_field': 'currency_id'}"/>
        <div class="oe_subtotal_footer_separator oe_inline">
            <label for="amount_total"/>
            <button name="button_dummy"
            states="draft" string="(update)" type="object" class="oe_edit_only oe_link"/>
        </div>
        <field name="amount_total" nolabel="1" class="oe_subtotal_footer_separator" widget="monetary" options="{'currency_field': 'currency_id'}"/>
        </group>
    </group>

    <xpath expr="/form/sheet/group/group/field[@name='company_id']" position="after">
        <field name="asd_pquotation_id" on_change="onchange_sales_order(asd_pquotation_id,partner_id,pricelist_id)"/>
    </xpath>

    <notebook>
        <page string="Documents" attrs="{'invisible': [('state','in',('draft','sent'))]}">
        <group string="Received Documents">
            <field name="vi_coa"/>
            <field name="vi_msds"/>
        </group>
            </page>
    </notebook>
    </field>
</record>

When I try to save I get this error:

Integrity Error

The operation cannot be completed, probably due to the following:
- deletion: you may be trying to delete a record while other records still reference it
- creation/update: a mandatory field is not correctly set

[object with reference: state - state]

openerp.sql_db: bad query: insert into "purchase_order_line" (id,"product_id","product_uom","date_planned","order_id","price_unit","company_id","name","state","product_qty","account_analytic_id","invoiced",create_uid,create_date,write_uid,write_date) values (4,2,1,'2013-04-09 00:00:00',4,'0.00',NULL,'Folic Acid',NULL,'1.000',NULL,'False',1,(now() at time zone 'UTC'),1,(now() at time zone 'UTC'))
Traceback (most recent call last):
  File "/opt/openerp-7.0/openerp/sql_db.py", line 227, in execute
    res = self._obj.execute(query, params)
IntegrityError: null value in column "state" violates not-null constraint

I if I change any line of purchase order line, all the buttons stays disabled.

Someone know how can I do what I want? I've already check this : http://doc.openerp.com/trunk/developers/server/06_misc_on_change_tips/ http://doc.openerp.com/v6.0/developer/2_6_views_events/events/events.html but this doesn't help me...

why don't you use MTO on products that does what you intend to do?

Fabien Pinckaers (fp)
on 4/9/13, 4:19 AM

What is MTO ? Is this Make to order? Where can I read something about how is this treated in openerp?

What I need is when I someone ask me for a product, I'll try to find the cheapest supplier. And for that I need that PO e SO have some connection. For example, what I need is in the SO have some list of PO and then I'll choose the cheapest. Something like the module purchase_requisition, but this module have too much bugs.

Versão Integral, Anabela Damas
on 4/9/13, 7:30 AM
3

Sudhir Arya (SA)

--Sudhir Arya (SA)--
10150
| 6 8 8
Ahmedabad, India
--Sudhir Arya (SA)--

Working as an OpenERP/Odoo developer and a Team Leader 

Top 5 Odoo contributor On Stackoverflow

LinkedIn

Blog

Stackoverflow

Sudhir Arya (SA)
On 4/5/13, 9:00 AM

order_id = so.order_line will give you list of ids of sale.order.line. (like this [1,2,3]).

When you browse sale.order.line like this: sol = self.pool.get('sale.order.line').browse(cr,uid,order_id) will give you list of browse records of sale.order.line. So you cannot use sol.product_id. You have to use loop to access lines.

This is the reason you are facing this error.

Try this:

Add on_change in your field:

<field name="asd_pquotation_id" on_change="onchange_purchase_order(asd_pquotation_id,partner_id,pricelist_id)"/>

def onchange_sales_order(self, cr, uid, id, asd_pquotation_id, partner_id, pricelist_id):
    domain = []
    value = []
    if asd_pquotation_id:
        so = self.pool.get('sale.order').browse(cr,uid,asd_pquotation_id)
        for sol in so.order_line:
            vals = self.pool.get('purchase.order.line').onchange_product_id(cr, uid, ids, pricelist_id, sol.product_id.id, sol.product_uom_qty, sol.product_uom.id, partner_id)
            vals['value'].update({
              'product_id': sol.product_id.id,
            })
            value.append(vals['value'])
            domain.append(vals['domain'])
    return {'value': {'order_line': value}, 'domain': {'order_line': domain}}

Add state in _defaults to set default value because you have overwritten state field:

_defaults = {
    'state': 'draft',
    'asd_pquotation_id': lambda self, cr, uid, context: context.get('asd_pquotation_id', False),
}

Thank you.

Thanks alot for your help!

Versão Integral, Anabela Damas
on 4/8/13, 12:45 PM

In _defaults add state. That is why you are facing this error. _defaults = {'state': 'draft'}. Try this I am sure you won't see this error again.

Sudhir Arya (SA)
on 4/9/13, 9:10 AM

Sorry, same error again .... I'll try now without my new state...

Versão Integral, Anabela Damas
on 4/9/13, 10:59 AM

I really don't know what to do more ..., new BD, I've commented everything that I've done to create the new state... And I can't rid of the error "Integrity Error"

Versão Integral, Anabela Damas
on 4/9/13, 11:30 AM

The state was missing here:
for sol in so.order_line: vals = self.pool.get('purchase.order.line').onchange_product_id(cr, uid, ids, pricelist_id, sol.product_id.id, sol.product_uom_qty, sol.product_uom.id, partner_id) vals['value'].update({ 'product_id': sol.product_id.id, 'state':'draft', 'move_ids':[], 'invoiced':0, 'invoice_lines':[] })

Thanks again for your help.

Versão Integral, Anabela Damas
on 4/9/13, 3:10 PM

About This Community

This community is for professionals and enthusiasts of our products and services. Read Guidelines

Question tools

1 follower(s)

Stats

Asked: 4/5/13, 8:27 AM
Seen: 6056 times
Last updated: 4/21/16, 4:22 AM