<field eval="[(4, ref('group_purchase_requisition_user'))]" name="groups_id"/>
</record>
++ <record id="product.product_product_hdd3" model="product.product">
++ <field name="purchase_requisition" eval="True"/>
++ </record>
++
<!--Resource: purchase.requisition-->
-- <record id="order_purchase_requisition1" model="purchase.requisition">
++ <record id="requisition1" model="purchase.requisition">
<field name="user_id" model="res.users"/>
- <field name="exclusive">multiple</field>
+ <field name="exclusive">exclusive</field>
<field name="date_start" eval="time.strftime('%Y/%m/%d %H:%M:%S')"/>
<field name="warehouse_id" ref="stock.stock_warehouse_shop0"/>
</record>
-- <!--Resource: purchase.requisition.line-->
-
- <record id="line_purchase_requisition1" model="purchase.requisition.line">
- <field name="requisition_id" ref="order_purchase_requisition1"/>
- <field name="product_id" ref="product.product_product_pc3"/>
- <field name="product_uom_id" model="product.uom" search="[]"/>
++ <record id="requisition_line1" model="purchase.requisition.line">
++ <field name="name">[HDD3] HDD Seagate 7200.8 160GB</field>
++ <field name="requisition_id" ref="requisition1"/>
++ <field name="product_id" ref="product.product_product_hdd3"/>
++ <field name="product_uom_id" ref="product.product_uom_unit"/>
+ <field name="product_qty">5</field>
+ </record>
+
+ <!--Resource: purchase.order-->
- <record id="line_purchase_requisition1" model="purchase.requisition.line">
- <field name="requisition_id" ref="order_purchase_requisition1"/>
- <field name="product_id" ref="product.product_product_pc3"/>
- <field name="product_uom_id" model="product.uom" search="[]"/>
- <record id="requisition_order1" model="purchase.order">
++ <record id="rfq1" model="purchase.order">
+ <field name="location_id" ref="stock.stock_location_stock"/>
+ <field name="pricelist_id" ref="purchase.list0"/>
+ <field name="partner_id" ref="base.res_partner_4"/>
+ <field name="partner_address_id" ref="base.res_partner_address_7"/>
- <field name="requisition_id" ref="order_purchase_requisition1"/>
++ <field name="requisition_id" ref="requisition1"/>
++ </record>
++
++ <record id="rfq1_line" model="purchase.order.line">
++ <field name="order_id" ref="rfq1"/>
++ <field name="name">[HDD3] HDD Seagate 7200.8 160GB</field>
++ <field name="date_planned" eval="time.strftime('%Y/%m/10')"/>
++ <field name="product_id" ref="product.product_product_hdd3"/>
++ <field name="product_uom" ref="product.product_uom_unit"/>
++ <field name="price_unit">60</field>
+ <field name="product_qty">5</field>
</record>
+
- <record id="requisition_order2" model="purchase.order">
++ <record id="rfq2" model="purchase.order">
+ <field name="location_id" ref="stock.stock_location_stock"/>
+ <field name="pricelist_id" ref="purchase.list0"/>
+ <field name="partner_id" ref="base.res_partner_vickingdirect0"/>
+ <field name="partner_address_id" ref="base.res_partner_address_brussels0"/>
- <field name="requisition_id" ref="order_purchase_requisition1"/>
++ <field name="requisition_id" ref="requisition1"/>
+ </record>
+
- <!--Resource: purchase.order.line-->
-
- <record id="line9_purchase" model="purchase.order.line">
- <field name="order_id" ref="requisition_order1"/>
- <field name="date_planned" eval="time.strftime('%Y/%m/%d')"/>
- <field name="name">[CPU1] Processor AMD Athlon XP 1800+</field>
- <field name="product_id" ref="product.product_product_cpu1"/>
- <field name="product_uom" ref="product.product_uom_unit"/>
- <field name="price_unit">60</field>
- <field name="product_qty">3</field>
- </record>
-
- <record id="line10_purchase" model="purchase.order.line">
- <field name="order_id" ref="requisition_order2"/>
- <field name="date_planned" eval="time.strftime('%Y/%m/%d')"/>
- <field name="name">[CPU3] Processor AMD Athlon XP 2200+</field>
- <field name="product_id" ref="product.product_product_cpu3"/>
++ <record id="rfq2_line" model="purchase.order.line">
++ <field name="order_id" ref="rfq2"/>
++ <field name="name">[HDD3] HDD Seagate 7200.8 160GB</field>
++ <field name="date_planned" eval="time.strftime('%Y/%m/15')"/>
++ <field name="product_id" ref="product.product_product_hdd3"/>
+ <field name="product_uom" ref="product.product_uom_unit"/>
+ <field name="price_unit">50</field>
- <field name="product_qty">13</field>
++ <field name="product_qty">3</field>
+ </record>
</data>
--- /dev/null
-
+-
- In order to test the purchase requisition module, I will do a sale order -> purchase_requisition ->
- purchase flow and I will buy the required products at two different suppliers.
- -
- I start by creating a new product 'Laptop ACER', which is purchased at Asustek, in MTO,
- with the generation of purchase requisitions.
- -
- !record {model: product.product, id: product_product_laptopacer0}:
- categ_id: product.product_category_3
- cost_method: standard
- mes_type: fixed
- name: Laptop ACER
- procure_method: make_to_order
- purchase_requisition: 1
- seller_ids:
- - delay: 1
- name: base.res_partner_asus
- qty: 5.0
- min_qty: 1.0
- supply_method: buy
- type: product
++ I create the procurement order and run that procurement.
++-
++ !python {model: make.procurement}: |
++ context.update({'active_model':'product.product', 'active_ids': [ref('product.product_product_hdd3')], 'active_id': ref('product.product_product_hdd3')})
++-
++ !record {model: make.procurement, id: procurement_product_hdd3}:
++ product_id: product.product_product_hdd3
++ qty: 15
+ uom_id: product.product_uom_unit
- uom_po_id: product.product_uom_unit
- volume: 0.0
- warranty: 0.0
- weight: 0.0
- weight_net: 0.0
- list_price: 100.0
- -
- Then I sell 5 Laptop ACER to the customer Agrolait, sale order TEST/TENDER/0001.
- -
- !record {model: sale.order, id: sale_order_testtender0}:
- date_order: !eval time.strftime('%Y-%m-%d')
- invoice_quantity: order
- name: TEST/TENDER/0001
- order_line:
- - name: Laptop ACER
- price_unit: 100.0
- product_uom: product.product_uom_unit
- product_uom_qty: 5.0
- state: draft
- delay: 7.0
- product_id: product_product_laptopacer0
- product_uos_qty: 5.0
- th_weight: 0.0
- type: make_to_order
- order_policy: manual
- partner_id: base.res_partner_agrolait
- partner_invoice_id: base.res_partner_address_8
- partner_order_id: base.res_partner_address_8
- partner_shipping_id: base.res_partner_address_8
- picking_policy: direct
- pricelist_id: product.list0
- shop_id: sale.shop
- -
- I confirm the sale order.
- -
- !workflow {model: sale.order, action: order_confirm, ref: sale_order_testtender0}
- -
- I launch the scheduler to compute all procurements, and specify all requisitions orders.
- -
- !python {model: procurement.order.compute.all}: |
- proc_obj = self.pool.get('procurement.order')
- proc_obj._procure_confirm(cr,uid)
- -
- On the purchase requisition, I create a new purchase order for the supplier 'DistriPC' by clicking on
- the button 'New RfQ'. This opens a window to ask me the supplier and I set DistriPC .
- -
- !record {model: purchase.requisition.partner, id: purchase_requisition_partner_0}:
- partner_address_id: base.res_partner_address_7
- partner_id: base.res_partner_4
- -
- I create a new purchase order.
++ warehouse_id: stock.stock_warehouse_shop0
+-
- !python {model: purchase.requisition.partner}: |
- req_obj = self.pool.get('purchase.requisition')
- ids =req_obj.search(cr, uid, [('origin','=','Laptop ACER')])
- self.create_order(cr, uid, [ref("purchase_requisition_partner_0")], {"lang":
- 'en_US', "active_model": "purchase.requisition", "tz": False, "record_id":
- 1, "active_ids": ids, "active_id": ids[0], })
-
++ !python {model: make.procurement}: |
++ self.make_procurement(cr, uid, [ref('procurement_product_hdd3')], context)
+-
- I check that I have two purchase orders on the purchase requisition.
++ I run the scheduler.
+-
- !python {model: purchase.order}: |
- from tools.translate import _
- order_ids =self.search(cr, uid, [('origin','=','TEST/TENDER/0001')])
- ids=len(order_ids)
- assert(ids == 2), _('Purchase Order not Created')
-
++ !python {model: procurement.order}: |
++ self.run_scheduler(cr, uid)
++-
++ I check requisition details which created after run procurement.
+-
- I set the purchase requisition as 'Not Exclusive'.
++ !python {model: procurement.order}: |
++ procurement_ids = self.search(cr, uid, [('requisition_id','!=', False)])
++ for procurement in self.browse(cr, uid, procurement_ids, context=context):
++ requisition = procurement.requisition_id
++ assert requisition.date_end == procurement.date_planned, "End date is not correspond."
++ assert len(requisition.line_ids) == 1, "Requisition Lines should be one."
++ line = requisition.line_ids[0]
++ assert line.product_id.id == procurement.product_id.id, "Product is not correspond."
++ assert line.product_uom_id.id == procurement.product_uom.id, "UOM is not correspond."
++ assert line.product_qty == procurement.product_qty, "Quantity is not correspond."
+-
- !python {model: purchase.requisition}: |
- ids =self.search(cr, uid, [('origin','=','Laptop ACER')])
- self.write(cr,uid,ids[0],{'exclusive': 'multiple' })
++ I open another requisition.
+-
- I change the quantities so that the purchase order for DistriPC includes 3 pieces and the
- purchase order for Asustek includes 2 pieces.
++ !python {model: purchase.requisition}: |
++ self.tender_in_progress(cr, uid, [ref("requisition1")], context=context)
++-
++ Supplier send one RFQ so I create requisition request of that supplier.
++-
++ !python {model: purchase.requisition.partner}: |
++ context.update({"active_model": "purchase.requisition","active_ids": [ref("requisition1")],"active_id": ref("requisition1")})
++-
++ !record {model: purchase.requisition.partner, id: requisition_partner_0}:
++ partner_id: base.res_partner_desertic_hispafuentes
++-
++ !python {model: purchase.requisition.partner}: |
++ self.create_order(cr, uid, [ref("requisition_partner_0")], context=context)
++-
++ I check that the RFQ details which created for supplier.
+-
+ !python {model: purchase.order}: |
- line_obj=self.pool.get('purchase.order.line')
- partner_obj=self.pool.get('res.partner')
- requistion_obj=self.pool.get('purchase.requisition')
- requistion_ids =requistion_obj.search(cr, uid, [('origin','=','Laptop ACER')])
- partner_id1=partner_obj.search(cr,uid,[('name','=','ASUStek')])[0]
- partner_id2=partner_obj.search(cr,uid,[('name','=','Distrib PC')])[0]
- purchase_id1= self.search(cr, uid, [('partner_id','=',partner_id1),('requisition_id','in',requistion_ids)])
- purchase_id2= self.search(cr, uid, [('partner_id','=',partner_id2),('requisition_id','in',requistion_ids)])
- order_line1=self.browse(cr, uid, purchase_id1, context)[0].order_line[0].id
- order_line2=self.browse(cr, uid, purchase_id2, context)[0].order_line[0].id
- line_obj.write(cr, uid, order_line1, {'product_qty':2})
- line_obj.write(cr, uid, order_line2, {'product_qty':3})
- -
- I confirm and validate both purchase orders.
++ purchase_ids = self.search(cr, uid, [('requisition_id','=',ref("requisition1"))])
++ assert purchase_ids, "RFQ is not created."
++ rfq = self.browse(cr, uid, purchase_ids[0], context=context)
++ requisition = rfq.requisition_id
++ supplier = rfq.partner_id
++ assert supplier.id == ref('base.res_partner_desertic_hispafuentes'), "RFQ Partner is not correspond."
++ assert len(rfq.order_line) == len(requisition.line_ids), "Lines are not correspond."
++ for rfq_line in rfq.order_line:
++ for line in requisition.line_ids:
++ if rfq_line.product_id.id == line.product_id.id:
++ product = line.product_id
++ uom_id = line.product_uom_id.id or False
++ assert rfq_line.product_qty == line.product_qty, "Quantity is not correspond."
++ assert rfq_line.product_uom.id == uom_id, "UOM is not correspond."
++-
++ I confirmed RFQ which has best price.
+-
+ !python {model: purchase.order}: |
- order_ids= self.search(cr, uid, [])
- import netsvc
- wf_service = netsvc.LocalService("workflow")
- for id in order_ids:
- wf_service.trg_validate(uid, 'purchase.order',id,'purchase_confirm', cr)
- wf_service.trg_validate(uid, 'purchase.order',id,'purchase_approve', cr)
- -
- I check that the delivery order of the customer is in state 'Waiting Goods'.
- -
- !python {model: stock.picking }: |
- from tools.translate import _
- picking_id = self.search(cr, uid, [('origin','=','TEST/TENDER/0001')])
- if picking_id:
- pick=self.browse(cr,uid,picking_id[0])
- assert (pick.state =='confirmed'),_('Picking is not in confirm state.')
- assert (pick.move_lines[0].state == 'waiting'), _('Stock Move is not Waiting state.')
++ import netsvc
++ wf_service = netsvc.LocalService("workflow")
++ purchase = self.browse(cr, uid, ref('rfq2'), context=context)
++ wf_service.trg_validate(uid, 'purchase.order', purchase.id, 'purchase_confirm', cr)
+
+-
- I receive the order of the supplier Asustek from the Incoming Products menu.
- -
- !python {model: stock.picking }: |
- import time
- partner_obj=self.pool.get('res.partner')
- order_obj=self.pool.get('purchase.order')
- partner_id=partner_obj.search(cr,uid,[('name','=','ASUStek')])[0]
- picking_id = self.search(cr, uid, [('address_id.partner_id','=',partner_id),('type','=','in')])
- if picking_id:
- pick=self.browse(cr,uid,picking_id[0])
- move =pick.move_lines[0]
- partial_datas = {
- 'partner_id': pick.address_id.partner_id.id,
- 'address_id': pick.address_id.id,
- 'delivery_date' : time.strftime('%Y-%m-%d'),
- }
- partial_datas['move%s'%(move.id)]= {
- 'product_id': move.product_id.id,
- 'product_qty': move.product_qty,
- 'product_uom': move.product_uom.id,
- }
- self.do_partial(cr, uid, picking_id,partial_datas)
- -
- I receive the order of the supplier DistriPC from the Incoming Shipments menu.
- -
- !python {model: stock.picking }: |
- import time
- partner_id=self.pool.get('res.partner').search(cr,uid,[('name','=','Distrib PC')])[0]
- picking_id = self.search(cr, uid, [('address_id.partner_id','=',partner_id),('type','=','in')])
- if picking_id:
- pick=self.browse(cr,uid,picking_id[0])
- move =pick.move_lines[0]
- partial_datas = {
- 'partner_id':pick.address_id.partner_id.id,
- 'address_id': pick.address_id.id,
- 'delivery_date' : time.strftime('%Y-%m-%d'),
- }
- partial_datas['move%s'%(move.id)]= {
- 'product_id': move.product_id.id,
- 'product_qty': move.product_qty,
- 'product_uom': move.product_uom.id,
- }
- self.do_partial(cr, uid, picking_id,partial_datas)
- -
- I check that the delivery order of the customer is in the state Available.
- -
- !python {model: stock.picking }: |
- from tools.translate import _
- picking_id = self.search(cr, uid, [('origin','=','TEST/TENDER/0001'),('type','=','out')])
- if picking_id:
- pick=self.browse(cr,uid,picking_id[0])
- assert(pick.state == 'assigned'), _('Picking is not in available state')
-
++ I check status of requisition after confirmed best RFQ.
++-
++ !python {model: purchase.requisition}: |
++ requisition = self.browse(cr, uid, ref('requisition1'), context=context)
++ requisition.state == 'done', "Requisition should be closed."
++-
++ I print a Requisition report
++-
++ !python {model: purchase.requisition}: |
++ import netsvc, tools, os
++ (data, format) = netsvc.LocalService('report.purchase.requisition').create(cr, uid, [ref('purchase_requisition.requisition1')], {}, {})
++ if tools.config['test_report_directory']:
++ file(os.path.join(tools.config['test_report_directory'], 'purchase_requisition-purchase_requisition_report.'+format), 'wb+').write(data)