diff options
| author | Harry (OpenERP) <hmo@tinyerp.com> | 2011-12-14 17:59:24 +0530 |
|---|---|---|
| committer | Harry (OpenERP) <hmo@tinyerp.com> | 2011-12-14 17:59:24 +0530 |
| commit | 092f97b32b35af6a40b9d2ae70c3159da2fb235f (patch) | |
| tree | 2974d3719af9338cd0b1814da900d7e9ca8d4779 /addons/purchase_requisition | |
| parent | 593f5f571bbc49673975afc405e9345ef3457b92 (diff) | |
| parent | e36dc8c5e3ca3da1474747bae5ec87fea19b23b8 (diff) | |
[MERGE] merged with trunk-development-branch
bzr revid: hmo@tinyerp.com-20111214122924-izzibrz1yz67rt7g
Diffstat (limited to 'addons/purchase_requisition')
14 files changed, 711 insertions, 578 deletions
diff --git a/addons/purchase_requisition/__openerp__.py b/addons/purchase_requisition/__openerp__.py index d1ec2b1c260..a926b3bfb3a 100644 --- a/addons/purchase_requisition/__openerp__.py +++ b/addons/purchase_requisition/__openerp__.py @@ -18,11 +18,11 @@ # ############################################################################## { - "name" : "Purchase Requisition", + "name" : "Purchase Requisitions", "version" : "0.1", "author" : "OpenERP SA", "category" : "Purchase Management", - 'complexity': "easy", + 'complexity': "normal", "images" : ['images/purchase_requisitions.jpeg'], "website" : "http://www.openerp.com", "description": """ @@ -43,8 +43,10 @@ This new object will regroup and will allow you to easily keep track and order a "security/ir.model.access.csv","purchase_requisition_sequence.xml" ], "active": False, - "test":['test/purchase_requisition_report.yml', - 'test/purchase_requisition_test.yml', + "test":[ + 'test/purchase_requisition_demo.yml', + 'test/purchase_requisition.yml', + 'test/cancel_purchase_requisition.yml', ], "installable": True, "certificate" : "001023264099823179629", diff --git a/addons/purchase_requisition/i18n/hr.po b/addons/purchase_requisition/i18n/hr.po new file mode 100644 index 00000000000..ef664e8d8cd --- /dev/null +++ b/addons/purchase_requisition/i18n/hr.po @@ -0,0 +1,436 @@ +# Croatian translation for openobject-addons +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" +"POT-Creation-Date: 2011-01-11 11:15+0000\n" +"PO-Revision-Date: 2011-12-11 22:15+0000\n" +"Last-Translator: Tomislav Bosnjakovic <Unknown>\n" +"Language-Team: Croatian <hr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-12-12 05:17+0000\n" +"X-Generator: Launchpad (build 14458)\n" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +#: selection:purchase.requisition,state:0 +msgid "In Progress" +msgstr "U tijeku" + +#. module: purchase_requisition +#: code:addons/purchase_requisition/wizard/purchase_requisition_partner.py:44 +#, python-format +msgid "No Product in Tender" +msgstr "Nema artikla u tenderu" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Confirm" +msgstr "Potvrdi" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +#: field:purchase.requisition,user_id:0 +msgid "Responsible" +msgstr "Odgovoran" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Group By..." +msgstr "Grupiraj po..." + +#. module: purchase_requisition +#: view:purchase.requisition:0 +#: field:purchase.requisition,state:0 +msgid "State" +msgstr "Status" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +#: selection:purchase.requisition,state:0 +msgid "Draft" +msgstr "Nacrt" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Supplier" +msgstr "Dobavljač" + +#. module: purchase_requisition +#: field:purchase.requisition,exclusive:0 +msgid "Requisition Type" +msgstr "Vrsta zahtjeva" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Product Detail" +msgstr "Detalji artikla" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +#: field:purchase.requisition,date_start:0 +msgid "Requisition Date" +msgstr "Datum zahtjeva" + +#. module: purchase_requisition +#: model:ir.actions.act_window,name:purchase_requisition.action_purchase_requisition_partner +#: model:ir.actions.report.xml,name:purchase_requisition.report_purchase_requisition +#: model:ir.model,name:purchase_requisition.model_purchase_requisition +#: field:product.product,purchase_requisition:0 +#: field:purchase.order,requisition_id:0 +#: view:purchase.requisition:0 +#: field:purchase.requisition.line,requisition_id:0 +#: view:purchase.requisition.partner:0 +msgid "Purchase Requisition" +msgstr "Zahtjev za nabavom" + +#. module: purchase_requisition +#: model:ir.model,name:purchase_requisition.model_purchase_requisition_line +msgid "Purchase Requisition Line" +msgstr "Stavka zahtjeva za nabavom" + +#. module: purchase_requisition +#: model:ir.model,name:purchase_requisition.model_product_product +#: field:purchase.requisition.line,product_id:0 +msgid "Product" +msgstr "Artikl" + +#. module: purchase_requisition +#: sql_constraint:purchase.order:0 +msgid "Order Reference must be unique !" +msgstr "Oznaka naloga mora biti jedinstvena" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +#: field:purchase.requisition,description:0 +msgid "Description" +msgstr "Opis" + +#. module: purchase_requisition +#: help:product.product,purchase_requisition:0 +msgid "" +"Check this box so that requisitions generates purchase requisitions instead " +"of directly requests for quotations." +msgstr "" +"Označi ovu kučicu kako bi zahtjev generirao zahtjev za nabavom umjesto " +"direktno upit." + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Type" +msgstr "Vrsta" + +#. module: purchase_requisition +#: field:purchase.requisition,company_id:0 +#: field:purchase.requisition.line,company_id:0 +msgid "Company" +msgstr "Organizacija" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Request a Quotation" +msgstr "Upit" + +#. module: purchase_requisition +#: selection:purchase.requisition,exclusive:0 +msgid "Multiple Requisitions" +msgstr "Višestruki zahtjevi" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Approved by Supplier" +msgstr "Odobrio dobavljač" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Reset to Draft" +msgstr "Vrati u nacrt" + +#. module: purchase_requisition +#: model:ir.module.module,description:purchase_requisition.module_meta_information +msgid "" +"\n" +" This module allows you to manage your Purchase Requisition.\n" +" When a purchase order is created, you now have the opportunity to save " +"the related requisition.\n" +" This new object will regroup and will allow you to easily keep track and " +"order all your purchase orders.\n" +msgstr "" +"\n" +" Ovaj modul omogućuje upravljanje zahtjevima u nabavi.\n" +" Kad se kreira nabavni nalog, imate priliku snimiti povezani zahtjev.\n" +" Novi objekt će se pregrupirati i mogućiti vam lako praćenje i " +"naručivanje svih vaših nabavnih naloga.\n" + +#. module: purchase_requisition +#: field:purchase.requisition.partner,partner_address_id:0 +msgid "Address" +msgstr "Adresa" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Order Reference" +msgstr "Oznaka narudžbe" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Start Date" +msgstr "Početni datum" + +#. module: purchase_requisition +#: model:ir.actions.act_window,help:purchase_requisition.action_purchase_requisition +msgid "" +"A purchase requisition is the step before a request for quotation. In a " +"purchase requisition (or purchase tender), you can record the products you " +"need to buy and trigger the creation of RfQs to suppliers. After the " +"negotiation, once you have reviewed all the supplier's offers, you can " +"validate some and cancel others." +msgstr "" +"Zahtjev u nabavi je korak prije upita. U zahtjevu za nabavom (ili nabavnom " +"tenderu), možete zabilježiti sve artikle\r\n" +"koje morate kupiti i pokrenuti kreiranje upita dobavljačima. Nakon pregovora " +"nakon što se razmotrili sve ponude dobavljača možete potvrditi neke, a " +"odustati od drugih." + +#. module: purchase_requisition +#: field:purchase.requisition.line,product_qty:0 +msgid "Quantity" +msgstr "Količina" + +#. module: purchase_requisition +#: model:ir.actions.act_window,name:purchase_requisition.action_purchase_requisition +#: model:ir.ui.menu,name:purchase_requisition.menu_purchase_requisition_pro_mgt +msgid "Purchase Requisitions" +msgstr "Zahtjevi u nabavi" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "End Date" +msgstr "Završni datum" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +#: field:purchase.requisition,name:0 +msgid "Requisition Reference" +msgstr "Oznaka zahtjeva" + +#. module: purchase_requisition +#: field:purchase.requisition,line_ids:0 +msgid "Products to Purchase" +msgstr "Artikli za nabavu" + +#. module: purchase_requisition +#: field:purchase.requisition,date_end:0 +msgid "Requisition Deadline" +msgstr "Konačan rok zahtjeva" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Search Purchase Requisition" +msgstr "Pretraži zahtjeve u nabavi" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Notes" +msgstr "Bilješke" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Date Ordered" +msgstr "Datum narudžbe" + +#. module: purchase_requisition +#: help:purchase.requisition,exclusive:0 +msgid "" +"Purchase Requisition (exclusive): On the confirmation of a purchase order, " +"it cancels the remaining purchase order.\n" +"Purchase Requisition(Multiple): It allows to have multiple purchase " +"orders.On confirmation of a purchase order it does not cancel the remaining " +"orders" +msgstr "" +"Zahtjev u nabavi (ekskluzivni): Prilikom potvrde nabavnog naloga , " +"poništava preostale nabavne naloge.\n" +"Zahtjevi u nabavi(Višestruki): Omogućuje više nabavnih naloga. Prilikom " +"potvrde nabavnog naloga ne poništava preostale naloge." + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Cancel Purchase Order" +msgstr "Poništi nabavni nalog" + +#. module: purchase_requisition +#: model:ir.model,name:purchase_requisition.model_purchase_order +#: view:purchase.requisition:0 +msgid "Purchase Order" +msgstr "Nalog za nabavu" + +#. module: purchase_requisition +#: code:addons/purchase_requisition/wizard/purchase_requisition_partner.py:44 +#, python-format +msgid "Error!" +msgstr "Greška!" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +#: field:purchase.requisition.line,product_uom_id:0 +msgid "Product UoM" +msgstr "JM proizvoda" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Products" +msgstr "Artikli" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Order Date" +msgstr "Datum naloga" + +#. module: purchase_requisition +#: selection:purchase.requisition,state:0 +msgid "Cancelled" +msgstr "Poništeno" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "[" +msgstr "[" + +#. module: purchase_requisition +#: model:ir.model,name:purchase_requisition.model_purchase_requisition_partner +msgid "Purchase Requisition Partner" +msgstr "Partner za zahtjev u nabavi" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "]" +msgstr "]" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Quotation Detail" +msgstr "Detalji upita" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Purchase for Requisitions" +msgstr "Nabava za zahtjev" + +#. module: purchase_requisition +#: model:ir.actions.act_window,name:purchase_requisition.act_res_partner_2_purchase_order +msgid "Purchase orders" +msgstr "Nalozi u nabavi" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +#: view:purchase.requisition:0 +#: field:purchase.requisition,origin:0 +msgid "Origin" +msgstr "" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Reference" +msgstr "Vezna oznaka" + +#. module: purchase_requisition +#: model:ir.model,name:purchase_requisition.model_procurement_order +msgid "Procurement" +msgstr "Nabava" + +#. module: purchase_requisition +#: field:purchase.requisition,warehouse_id:0 +msgid "Warehouse" +msgstr "Skladište" + +#. module: purchase_requisition +#: field:procurement.order,requisition_id:0 +msgid "Latest Requisition" +msgstr "Zadnji zahtjev" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Quotations" +msgstr "Upiti" + +#. module: purchase_requisition +#: report:purchase.requisition:0 +msgid "Qty" +msgstr "Kol." + +#. module: purchase_requisition +#: selection:purchase.requisition,exclusive:0 +msgid "Purchase Requisition (exclusive)" +msgstr "Zahtjev u nabavi (ekskluzivan)" + +#. module: purchase_requisition +#: view:purchase.requisition.partner:0 +msgid "Create Quotation" +msgstr "Kreiraj upit" + +#. module: purchase_requisition +#: constraint:product.product:0 +msgid "Error: Invalid ean code" +msgstr "Greška: neispravan EAN kod" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +#: selection:purchase.requisition,state:0 +msgid "Done" +msgstr "Izvršeno" + +#. module: purchase_requisition +#: view:purchase.requisition.partner:0 +msgid "_Cancel" +msgstr "_Otkaži" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Confirm Purchase Order" +msgstr "Potvrdi nabavni nalog" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Cancel" +msgstr "Odustani" + +#. module: purchase_requisition +#: field:purchase.requisition.partner,partner_id:0 +msgid "Partner" +msgstr "Partner" + +#. module: purchase_requisition +#: model:ir.module.module,shortdesc:purchase_requisition.module_meta_information +msgid "Purchase - Purchase Requisition" +msgstr "Nabava - Zahtjevi u nabavi" + +#. module: purchase_requisition +#: view:purchase.requisition:0 +msgid "Unassigned" +msgstr "Nedodjeljen" + +#. module: purchase_requisition +#: view:purchase.order:0 +msgid "Requisition" +msgstr "Zahtjev" + +#. module: purchase_requisition +#: field:purchase.requisition,purchase_ids:0 +msgid "Purchase Orders" +msgstr "Nalozi u nabavi" + +#. module: purchase_requisition +#: code:addons/purchase_requisition/wizard/purchase_requisition_partner.py:90 +#, python-format +msgid "" +"You have already one %s purchase order for this partner, you must cancel " +"this purchase order to create a new quotation." +msgstr "" +"Već imate jedan %s nabavni nalog za tog partnera. Morate poništiti ovaj " +"nabavni nalog kako bi kreirali novi upit." diff --git a/addons/purchase_requisition/purchase_requisition.py b/addons/purchase_requisition/purchase_requisition.py index d619e3a82f5..cc0956b8755 100644 --- a/addons/purchase_requisition/purchase_requisition.py +++ b/addons/purchase_requisition/purchase_requisition.py @@ -19,7 +19,8 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # ############################################################################## - +from datetime import datetime +from dateutil.relativedelta import relativedelta import time import netsvc @@ -83,6 +84,89 @@ class purchase_requisition(osv.osv): self.write(cr, uid, ids, {'state':'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S')}, context=context) return True + def _planned_date(self, requisition, delay=0.0): + company = requisition.company_id + date_planned = False + if requisition.date_start: + date_planned = datetime.strptime(requisition.date_start, '%Y-%m-%d %H:%M:%S') - relativedelta(days=company.po_lead) + else: + date_planned = datetime.today() - relativedelta(days=company.po_lead) + if delay: + date_planned -= relativedelta(days=delay) + return date_planned and date_planned.strftime('%Y-%m-%d %H:%M:%S') or False + + def _seller_details(self, cr, uid, requisition_line, supplier, context=None): + product_uom = self.pool.get('product.uom') + pricelist = self.pool.get('product.pricelist') + supplier_info = self.pool.get("product.supplierinfo") + product = requisition_line.product_id + default_uom_po_id = product.uom_po_id.id + qty = product_uom._compute_qty(cr, uid, requisition_line.product_uom_id.id, requisition_line.product_qty, default_uom_po_id) + seller_delay = 0.0 + seller_price = False + seller_qty = False + for product_supplier in product.seller_ids: + if supplier.id == product_supplier.name and qty >= product_supplier.qty: + seller_delay = product_supplier.delay + seller_qty = product_supplier.qty + supplier_pricelist = supplier.property_product_pricelist_purchase or False + seller_price = pricelist.price_get(cr, uid, [supplier_pricelist.id], product.id, qty, False, {'uom': default_uom_po_id})[supplier_pricelist.id] + if seller_qty: + qty = max(qty,seller_qty) + date_planned = self._planned_date(requisition_line.requisition_id, seller_delay) + return seller_price, qty, default_uom_po_id, date_planned + + def make_purchase_order(self, cr, uid, ids, partner_id, context=None): + """ + Create New RFQ for Supplier + """ + if context is None: + context = {} + assert partner_id, 'Supplier should be specified' + purchase_order = self.pool.get('purchase.order') + purchase_order_line = self.pool.get('purchase.order.line') + res_partner = self.pool.get('res.partner') + fiscal_position = self.pool.get('account.fiscal.position') + supplier = res_partner.browse(cr, uid, partner_id, context=context) + delivery_address_id = res_partner.address_get(cr, uid, [supplier.id], ['delivery'])['delivery'] + supplier_pricelist = supplier.property_product_pricelist_purchase or False + res = {} + for requisition in self.browse(cr, uid, ids, context=context): + if supplier.id in filter(lambda x: x, [rfq.state <> 'cancel' and rfq.partner_id.id or None for rfq in requisition.purchase_ids]): + raise osv.except_osv(_('Warning'), _('You have already one %s purchase order for this partner, you must cancel this purchase order to create a new quotation.') % supp_record.state) + location_id = requisition.warehouse_id.lot_input_id.id + purchase_id = purchase_order.create(cr, uid, { + 'origin': requisition.name, + 'partner_id': supplier.id, + 'partner_address_id': delivery_address_id, + 'pricelist_id': supplier_pricelist.id, + 'location_id': location_id, + 'company_id': requisition.company_id.id, + 'fiscal_position': supplier.property_account_position and supplier.property_account_position.id or False, + 'requisition_id':requisition.id, + 'notes':requisition.description, + 'warehouse_id':requisition.warehouse_id.id , + }) + res[requisition.id] = purchase_id + for line in requisition.line_ids: + product = line.product_id + seller_price, qty, default_uom_po_id, date_planned = self._seller_details(cr, uid, line, supplier, context=context) + taxes_ids = product.supplier_taxes_id + taxes = fiscal_position.map_tax(cr, uid, supplier.property_account_position, taxes_ids) + purchase_order_line.create(cr, uid, { + 'order_id': purchase_id, + 'name': product.partner_ref, + 'product_qty': qty, + 'product_id': product.id, + 'product_uom': default_uom_po_id, + 'price_unit': seller_price, + 'date_planned': date_planned, + 'notes': product.description_purchase, + 'taxes_id': [(6, 0, taxes)], + }, context=context) + + return res + purchase_requisition() class purchase_requisition_line(osv.osv): @@ -96,7 +180,7 @@ class purchase_requisition_line(osv.osv): 'product_uom_id': fields.many2one('product.uom', 'Product UoM'), 'product_qty': fields.float('Quantity', digits_compute=dp.get_precision('Product UoM')), 'requisition_id' : fields.many2one('purchase.requisition','Purchase Requisition', ondelete='cascade'), - 'company_id': fields.many2one('res.company', 'Company', required=True), + 'company_id': fields.related('requisition_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True), } def onchange_product_id(self, cr, uid, ids, product_id,product_uom_id, context=None): @@ -133,7 +217,7 @@ class purchase_order(osv.osv): proc_obj.write(cr, uid, proc_ids, {'purchase_id': po.id}) wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, 'purchase.order', order.id, 'purchase_cancel', cr) - self.pool.get('purchase.requisition').write(cr, uid, [po.requisition_id.id], {'state':'done','date_end':time.strftime('%Y-%m-%d %H:%M:%S')}) + po.requisition_id.tender_done(context=context) return res purchase_order() diff --git a/addons/purchase_requisition/purchase_requisition_demo.xml b/addons/purchase_requisition/purchase_requisition_demo.xml index deb25fe9e14..910fc22bc63 100644 --- a/addons/purchase_requisition/purchase_requisition_demo.xml +++ b/addons/purchase_requisition/purchase_requisition_demo.xml @@ -6,23 +6,64 @@ <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="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="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="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="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="requisition1"/> + </record> + + <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">3</field> + </record> </data> diff --git a/addons/purchase_requisition/purchase_requisition_view.xml b/addons/purchase_requisition/purchase_requisition_view.xml index e0f09f6f7d6..bd47d093df0 100644 --- a/addons/purchase_requisition/purchase_requisition_view.xml +++ b/addons/purchase_requisition/purchase_requisition_view.xml @@ -174,7 +174,6 @@ <menuitem id="menu_purchase_requisition_pro_mgt" sequence="0" - groups="base.group_extended" parent="purchase.menu_procurement_management" action="action_purchase_requisition"/> diff --git a/addons/purchase_requisition/security/ir.model.access.csv b/addons/purchase_requisition/security/ir.model.access.csv index ec8c031f88b..4c6b8d8cdde 100644 --- a/addons/purchase_requisition/security/ir.model.access.csv +++ b/addons/purchase_requisition/security/ir.model.access.csv @@ -1,7 +1,7 @@ -"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" -"access_purchase_requisition","purchase.requisition","model_purchase_requisition","purchase.group_purchase_user",1,1,1,1 -"access_purchase_requisition_line_purchase_user","purchase.requisition.line","model_purchase_requisition_line","purchase.group_purchase_user",1,1,1,1 -"access_purchase_requisition_manager","purchase.requisition manager","model_purchase_requisition","purchase.group_purchase_manager",1,0,0,0 -"access_purchase_requisition_line_manager","purchase.requisition.line manager","model_purchase_requisition_line","purchase.group_purchase_manager",1,0,0,0 -"access_purchase_requisition_stock_manager","purchase.requisition","model_purchase_requisition","stock.group_stock_manager",1,0,1,0 -"access_purchase_requisition_line_stock_manager","purchase.requisition.line","model_purchase_requisition_line","stock.group_stock_manager",1,0,1,0 +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_purchase_requisition,purchase.requisition,model_purchase_requisition,purchase.group_purchase_user,1,1,1,1
+access_purchase_requisition_line_purchase_user,purchase.requisition.line,model_purchase_requisition_line,purchase.group_purchase_user,1,1,1,1
+access_purchase_requisition_manager,purchase.requisition manager,model_purchase_requisition,purchase.group_purchase_manager,1,0,0,0
+access_purchase_requisition_line_manager,purchase.requisition.line manager,model_purchase_requisition_line,purchase.group_purchase_manager,1,0,0,0
+access_purchase_requisition_stock_manager,purchase.requisition,model_purchase_requisition,stock.group_stock_manager,1,0,1,0
+access_purchase_requisition_line_stock_manager,purchase.requisition.line,model_purchase_requisition_line,stock.group_stock_manager,1,0,1,0
diff --git a/addons/purchase_requisition/security/purchase_tender.xml b/addons/purchase_requisition/security/purchase_tender.xml index af8a1330e2d..71c54b973e3 100644 --- a/addons/purchase_requisition/security/purchase_tender.xml +++ b/addons/purchase_requisition/security/purchase_tender.xml @@ -2,12 +2,20 @@ <openerp> <data noupdate="1"> + <record model="ir.module.category" id="module_category_purchase_requisition"> + <field name="name">Purchase Requisition</field> + <field name="parent_id" ref="base.module_category_purchase_management"/> + <field name="sequence">9</field> + </record> + <record id="group_purchase_requisition_user" model="res.groups"> - <field name="name">Purchase Requisition / User</field> + <field name="name">User</field> + <field name="category_id" ref="module_category_purchase_requisition"/> </record> <record id="group_purchase_requisition_manager" model="res.groups"> - <field name="name">Purchase Requisition / Manager</field> + <field name="name">Manager</field> + <field name="category_id" ref="module_category_purchase_requisition"/> <field name="implied_ids" eval="[(4, ref('group_purchase_requisition_user'))]"/> </record> diff --git a/addons/purchase_requisition/test/cancel_purchase_requisition.yml b/addons/purchase_requisition/test/cancel_purchase_requisition.yml new file mode 100644 index 00000000000..389c328a5cf --- /dev/null +++ b/addons/purchase_requisition/test/cancel_purchase_requisition.yml @@ -0,0 +1,26 @@ +- + I cancel requisition. +- + !python {model: purchase.requisition}: | + self.tender_cancel(cr, uid, [ref("requisition1")]) +- + I check requisition after cancelled. +- + !assert {model: purchase.requisition, id: requisition1}: + - state == 'cancel' +- + I reset requisition as "New". +- + !python {model: purchase.requisition}: | + self.tender_reset(cr, uid, [ref('requisition1')]) +- + I duplicate requisition. +- + !python {model: purchase.requisition}: | + self.copy(cr, uid, ref('requisition1')) +- + I delete requisition. +- + !python {model: purchase.order}: | + self.unlink(cr, uid, [ref("requisition1")]) + diff --git a/addons/purchase_requisition/test/purchase_requisition.yml b/addons/purchase_requisition/test/purchase_requisition.yml index fb5fa774fc3..a2e5b743965 100644 --- a/addons/purchase_requisition/test/purchase_requisition.yml +++ b/addons/purchase_requisition/test/purchase_requisition.yml @@ -1,189 +1,90 @@ - - - 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_requisition = self.pool.get("purchase.requisition") + 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: + seller_price, qty, default_uom_po_id, date_planned = purchase_requisition._seller_details(cr, uid, line, supplier, context=context) + assert rfq_line.product_qty == qty, "Quantity is not correspond." + assert rfq_line.product_uom.id == default_uom_po_id, "UOM is not correspond." + assert rfq_line.price_unit == seller_price, "Unit Price 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) diff --git a/addons/purchase_requisition/test/purchase_requisition_demo.yml b/addons/purchase_requisition/test/purchase_requisition_demo.yml new file mode 100755 index 00000000000..42913f3e96e --- /dev/null +++ b/addons/purchase_requisition/test/purchase_requisition_demo.yml @@ -0,0 +1,10 @@ +- + In order to test process of the purchase requisition ,I create requisition +- + !record {model: purchase.requisition, id: requisition1}: + exclusive: exclusive + line_ids: + - product_id: product.product_product_cpu1 + product_qty: 10.0 + product_uom_id: product.product_uom_unit + diff --git a/addons/purchase_requisition/test/purchase_requisition_exclusive.yml b/addons/purchase_requisition/test/purchase_requisition_exclusive.yml deleted file mode 100644 index 1ab9bca9493..00000000000 --- a/addons/purchase_requisition/test/purchase_requisition_exclusive.yml +++ /dev/null @@ -1,113 +0,0 @@ -- - 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_laptopacer1}: - categ_id: product.product_category_3 - cost_method: standard - list_price: 1000.0 - mes_type: fixed - name: Laptop ACER1 - 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 - uom_id: product.product_uom_unit - uom_po_id: product.product_uom_unit -- - Then I sell 5 Laptop ACER to the customer Agrolait, sale order TEST/TENDER/0002 -- - !record {model: sale.order, id: sale_order_testtender1}: - date_order: !eval time.strftime('%Y-%m-%d') - invoice_quantity: order - name: TEST/TENDER/0002 - order_line: - - name: Laptop ACER1 - price_unit: 1000.0 - product_uom: product.product_uom_unit - product_uom_qty: 5.0 - state: draft - 'delay': 7.0 - 'product_id': product_product_laptopacer1 - '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 sale order. -- - !workflow {model: sale.order, action: order_confirm, ref: sale_order_testtender1} -- - I launch the scheduler to compute all procurements, and planify all requisitions orders. -- - !python {model: procurement.order.compute.all}: | - proc_obj = self.pool.get('procurement.order') - proc_obj._procure_confirm(cr,uid) -- - I should find a purchase requisition with the origin 'TEST/TENDER/0002', that includes a request for - 5 Laptop ACER, and a purchase order on the default supplier for this product. -- - !python {model: purchase.requisition}: | - requisition_ids =self.search(cr, uid, [('origin','=','Laptop ACER1')]) - ids=len(requisition_ids) - assert len(requisition_ids), "Purchase requisition hasn't Created" -- - On the purchase requisition, I create a new purchase order for the supplier 'DistriPC' by clicking on - the button 'New Request for Quotation'. This opens a window to ask me the supplier and I set DistriPC . -- - I Create purchase.requisition.partner . -- - !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 for the supplier 'DistriPC'. -- - !python {model: purchase.requisition.partner}: | - req_obj = self.pool.get('purchase.requisition') - ids =req_obj.search(cr, uid, [('origin','=','Laptop ACER1')]) - 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], }) -- - I set the purchase requisition as 'Exclusive' -- - !python {model: purchase.requisition}: | - ids =self.search(cr, uid, [('origin','=','Laptop ACER1')]) - self.write(cr,uid,ids[0],{'exclusive': 'exclusive' }) -- - I confirm and validate the Request for Quotation of ASUStek. -- - !python {model: purchase.order}: | - partner_id=self.pool.get('res.partner').search(cr,uid,[('name','=','ASUStek')])[0] - req_obj = self.pool.get('purchase.requisition') - ids =req_obj.search(cr, uid, [('origin','=','Laptop ACER1')]) - purchase_id= self.search(cr, uid, [('partner_id','=',partner_id),('requisition_id','in',ids)])[0] - import netsvc - wf_service = netsvc.LocalService("workflow") - if purchase_id: - wf_service.trg_validate(uid, 'purchase.order',purchase_id,'purchase_confirm', cr) - wf_service.trg_validate(uid, 'purchase.order',purchase_id,'purchase_approve', cr) -- - I check that Request for Quotation of DistriPC is cancelled. -- - !python {model: purchase.order}: | - partner_id=self.pool.get('res.partner').search(cr,uid,[('name','=','Distrib PC')])[0] - req_obj = self.pool.get('purchase.requisition') - ids =req_obj.search(cr, uid, [('origin','=','Laptop ACER1')]) - purchase_id= self.search(cr, uid, [('partner_id','=',partner_id),('requisition_id','in',ids)])[0] - state=self.browse(cr,uid,purchase_id).state - assert (state=='cancel') diff --git a/addons/purchase_requisition/test/purchase_requisition_report.yml b/addons/purchase_requisition/test/purchase_requisition_report.yml deleted file mode 100644 index 29edea96a8a..00000000000 --- a/addons/purchase_requisition/test/purchase_requisition_report.yml +++ /dev/null @@ -1,8 +0,0 @@ -- - In order to test the PDF reports defined on Purchase Requisition, we will 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.order_purchase_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) diff --git a/addons/purchase_requisition/test/purchase_requisition_test.yml b/addons/purchase_requisition/test/purchase_requisition_test.yml deleted file mode 100755 index 403eaca04fc..00000000000 --- a/addons/purchase_requisition/test/purchase_requisition_test.yml +++ /dev/null @@ -1,166 +0,0 @@ -- - In order to test the purchase requisition flow,I start by creating a new product 'MOB1' -- - !record {model: product.product, id: product_product_mob1}: - name: MOB1 - categ_id: product.product_category_3 - cost_method: standard - mes_type: fixed - price_margin: 2.0 - procure_method: make_to_stock - property_stock_inventory: stock.location_inventory - property_stock_procurement: stock.location_procurement - property_stock_production: stock.location_production - standard_price: 2000.0 - supply_method: buy - type: product - 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 -- - I create purchase requisition for MOB1 for 1 quantity. -- - !record {model: purchase.requisition, id: purchase_requisition_te0}: - company_id: base.main_company - exclusive: multiple - line_ids: - - company_id: base.main_company - product_id: product_product_mob1 - product_qty: 10.0 - product_uom_id: product.product_uom_unit - name: TE00009 -- - Initially purchase requisition is in draft state. -- - !assert {model: purchase.requisition, id: purchase_requisition_te0}: - - state == 'draft' -- - Copy purchase requisition which is in draft state than confirm and Done it. -- - !python {model: purchase.requisition}: | - copy_id = self.copy(cr, uid, ref("purchase_requisition_te0")) - self.tender_cancel(cr, uid, [copy_id], context=None) - self.tender_reset(cr, uid, [copy_id], context=None) - self.tender_in_progress(cr, uid, [copy_id], context=None) - self.tender_done(cr, uid, [copy_id], context=None) -- - I confirm the purchase requisition for MOB1. -- - !python {model: purchase.requisition}: | - self.tender_in_progress(cr, uid, [ref("purchase_requisition_te0")]) -- - I check that the purchase requisition which was initially in the draft state has transmit to In Progress after confirm it. -- - !assert {model: purchase.requisition, id: purchase_requisition_te0}: - - state == 'in_progress' -- - In order to create a purchase order for 'Axelor', i click on the wizard 'Request a Quotation' and create record for wizard. -- - !record {model: purchase.requisition.partner, id: purchase_requisition_partner_0}: - partner_address_id: base.res_partner_address_3000 - partner_id: base.res_partner_desertic_hispafuentes -- - I click on 'Create Quotation' for creating PO. -- - !python {model: purchase.requisition.partner}: | - self.create_order(cr, uid, [ref("purchase_requisition_partner_0")], {"active_model": "purchase.requisition", - "active_ids": [ref("purchase_requisition_te0")],"active_id": ref("purchase_requisition_te0"), }) -- - I confirm the purchase order of Axelor. -- - !python {model: purchase.order}: | - purchase_id= self.search(cr, uid, [('requisition_id','=',ref("purchase_requisition_te0"))]) - import netsvc - wf_service = netsvc.LocalService("workflow") - if purchase_id: - wf_service.trg_validate(uid, 'purchase.order',purchase_id[0],'purchase_confirm', cr) - wf_service.trg_validate(uid, 'purchase.order',purchase_id[0],'purchase_approve', cr) -- - I check that Quotation of Axelor is Approved. -- - !python {model: purchase.order}: | - purchase_id= self.search(cr, uid, [('requisition_id','=',ref("purchase_requisition_te0"))])[0] - state=self.browse(cr,uid,purchase_id).state - assert (state=='approved') -- - I click on Done button -- - !python {model: purchase.requisition}: | - self.tender_done(cr, uid, [ref("purchase_requisition_te0")],) -- - I check that after click on Done button state is in done. -- - !assert {model: purchase.requisition, id: purchase_requisition_te0}: - - state == 'done' -- - In order to test the purchase requisition flow for Requisition Type is exclusive -- - I create purchase requisition for Requisition Type is exclusive -- - !record {model: purchase.requisition, id: purchase_requisition_ex1}: - company_id: base.main_company - exclusive: exclusive - line_ids: - - company_id: base.main_company - product_id: product_product_mob1 - product_qty: 10.0 - product_uom_id: product.product_uom_unit - name: TE000010 -- - I Create a First Purchase Order for the supplier 'Distrib PC'. -- - !record {model: purchase.requisition.partner, id: purchase_requisition_partner_1}: - partner_address_id: base.res_partner_address_7 - partner_id: base.res_partner_4 -- - I create Quotations For supplier 'Distrib PC'. -- - !python {model: purchase.requisition.partner}: | - self.create_order(cr, uid, [ref("purchase_requisition_partner_1")], {"active_model": "purchase.requisition", - "active_ids": [ref("purchase_requisition_ex1")],"active_id": ref("purchase_requisition_ex1"), }) -- - I Create a Second Purchase Order for the supplier ASUStek. -- - !record {model: purchase.requisition.partner, id: purchase_requisition_partner_2}: - partner_address_id: base.res_partner_address_tang - partner_id: base.res_partner_asus -- - I create Quotations For supplier 'ASUStek'. -- - !python {model: purchase.requisition.partner}: | - self.create_order(cr, uid, [ref("purchase_requisition_partner_2")], {"active_model": "purchase.requisition", - "active_ids": [ref("purchase_requisition_ex1")],"active_id": ref("purchase_requisition_ex1"), }) -- - I check that Initially purchase requisition is draft state. -- - !assert {model: purchase.requisition, id: purchase_requisition_ex1}: - - state == 'draft' -- - I confirm the Second purchase order of ASUStek, than check that Quotation is Approved. -- - !python {model: purchase.order}: | - purchase_id= self.search(cr, uid, [('partner_id','=',ref("base.res_partner_asus")),('requisition_id','=',ref("purchase_requisition_ex1"))]) - import netsvc - wf_service = netsvc.LocalService("workflow") - if purchase_id: - wf_service.trg_validate(uid, 'purchase.order',purchase_id[0],'purchase_confirm', cr) - wf_service.trg_validate(uid, 'purchase.order',purchase_id[0],'purchase_approve', cr) - state=self.browse(cr,uid,purchase_id[0]).state - assert (state=='approved') - -- - I check that Quotation of Distrib PC is cancelled. -- - !python {model: purchase.order}: | - partner_id=self.pool.get('res.partner').search(cr,uid,[('name','=','Distrib PC')])[0] - purchase_id= self.search(cr, uid, [('partner_id','=',partner_id),('requisition_id','=',ref("purchase_requisition_ex1"))])[0] - state=self.browse(cr,uid,purchase_id).state - assert (state=='cancel') -- - I check that Purchase Requisition is Done. -- - !assert {model: purchase.requisition, id: purchase_requisition_ex1}: - - state == 'done' diff --git a/addons/purchase_requisition/wizard/purchase_requisition_partner.py b/addons/purchase_requisition/wizard/purchase_requisition_partner.py index 766e0adb75a..043ed749f4b 100644 --- a/addons/purchase_requisition/wizard/purchase_requisition_partner.py +++ b/addons/purchase_requisition/wizard/purchase_requisition_partner.py @@ -20,8 +20,6 @@ ############################################################################## import time -from datetime import datetime -from dateutil.relativedelta import relativedelta from osv import fields, osv from osv.orm import browse_record, browse_null from tools.translate import _ @@ -31,7 +29,7 @@ class purchase_requisition_partner(osv.osv_memory): _description = "Purchase Requisition Partner" _columns = { 'partner_id': fields.many2one('res.partner', 'Partner', required=True,domain=[('supplier', '=', True)]), - 'partner_address_id':fields.many2one('res.partner.address', 'Address', required=True), + 'partner_address_id':fields.many2one('res.partner.address', 'Address'), } def view_init(self, cr, uid, fields_list, context=None): @@ -42,7 +40,7 @@ class purchase_requisition_partner(osv.osv_memory): tender = self.pool.get('purchase.requisition').browse(cr, uid, record_id, context=context) if not tender.line_ids: raise osv.except_osv(_('Error!'), _('No Product in Tender')) - True + return res def onchange_partner_id(self, cr, uid, ids, partner_id): if not partner_id: @@ -52,94 +50,9 @@ class purchase_requisition_partner(osv.osv_memory): return {'value':{'partner_address_id': addr['default']}} def create_order(self, cr, uid, ids, context=None): - """ - To Create a purchase orders . - - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param ids: the ID or list of IDs - @param context: A standard dictionary - @return: {} - - """ - if context is None: - context = {} - record_ids = context and context.get('active_ids', False) - if record_ids: - data = self.browse(cr, uid, ids,context=context)[0] - company = self.pool.get('res.users').browse(cr, uid, uid, context).company_id - order_obj = self.pool.get('purchase.order') - order_line_obj = self.pool.get('purchase.order.line') - partner_obj = self.pool.get('res.partner') - tender_line_obj = self.pool.get('purchase.requisition.line') - pricelist_obj = self.pool.get('product.pricelist') - prod_obj = self.pool.get('product.product') - tender_obj = self.pool.get('purchase.requisition') - acc_pos_obj = self.pool.get('account.fiscal.position') - partner_id = data.partner_id.id - supplier_data = data.partner_id - address_id = partner_obj.address_get(cr, uid, [partner_id], ['delivery'])['delivery'] - list_line=[] - purchase_order_line={} - for tender in tender_obj.browse(cr, uid, record_ids, context=context): - for supp_record in tender.purchase_ids: - if supp_record.partner_id.id == partner_id and supp_record.state <> 'cancel': - raise osv.except_osv(_('Warning'), _('You have already one %s purchase order for this partner, you must cancel this purchase order to create a new quotation.') % supp_record.state) - for line in tender.line_ids: - partner_list = sorted([(partner.sequence, partner) for partner in line.product_id.seller_ids if partner]) - partner_rec = partner_list and partner_list[0] and partner_list[0][1] or False - uom_id = line.product_id.uom_po_id and line.product_id.uom_po_id.id or False - - if tender.date_start: - newdate = datetime.strptime(tender.date_start, '%Y-%m-%d %H:%M:%S') - relativedelta(days=company.po_lead) - else: - newdate = datetime.today() - relativedelta(days=company.po_lead) - delay = partner_rec and partner_rec.delay or 0.0 - if delay: - newdate -= relativedelta(days=delay) - - partner = partner_rec and partner_rec.name or supplier_data - pricelist_id = partner.property_product_pricelist_purchase and partner.property_product_pricelist_purchase.id or False - price = pricelist_obj.price_get(cr, uid, [pricelist_id], line.product_id.id, line.product_qty, False, {'uom': uom_id})[pricelist_id] - product = prod_obj.browse(cr, uid, line.product_id.id, context=context) - location_id = self.pool.get('stock.warehouse').read(cr, uid, [tender.warehouse_id.id], ['lot_input_id'])[0]['lot_input_id'][0] - - purchase_order_line= { - 'name': product.partner_ref, - 'product_qty': line.product_qty, - 'product_id': line.product_id.id, - 'product_uom': uom_id, - 'price_unit': price, - 'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'), - 'notes': product.description_purchase, - } - taxes_ids = line.product_id.product_tmpl_id.supplier_taxes_id - taxes = acc_pos_obj.map_tax(cr, uid, partner.property_account_position, taxes_ids) - purchase_order_line.update({ - 'taxes_id': [(6,0,taxes)] - }) - list_line.append(purchase_order_line) - purchase_id = order_obj.create(cr, uid, { - 'origin': tender.purchase_ids and tender.purchase_ids[0].origin or tender.name, - 'partner_id': partner_id, - 'partner_address_id': address_id, - 'pricelist_id': pricelist_id, - 'location_id': tender.purchase_ids and tender.purchase_ids[0].location_id.id or line.product_id.product_tmpl_id.property_stock_production.id, - 'company_id': tender.company_id.id, - 'fiscal_position': partner.property_account_position and partner.property_account_position.id or False, - 'requisition_id':tender.id, - 'notes':tender.description, - 'warehouse_id':tender.warehouse_id.id and tender.warehouse_id.id , - 'location_id':location_id, - 'company_id':tender.company_id.id, - }) - order_ids=[] - for order_line in list_line: - order_line.update({ - 'order_id': purchase_id - }) - order_line_obj.create(cr,uid,order_line) + active_ids = context and context.get('active_ids', []) + data = self.browse(cr, uid, ids, context=context)[0] + self.pool.get('purchase.requisition').make_purchase_order(cr, uid, active_ids, data.partner_id.id, context=context) return {'type': 'ir.actions.act_window_close'} purchase_requisition_partner() |
