From 7608df909638b725682db88969787ea09433dfea Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Thu, 20 Oct 2011 11:52:48 +0530 Subject: [PATCH 02/66] [Move]purchase_requisition: Move purchase_requisition.yml in to process folder bzr revid: dbr@tinyerp.com-20111020062248-tg7pkrdvh026jvzm --- .../test/{ => process}/purchase_requisition.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename addons/purchase_requisition/test/{ => process}/purchase_requisition.yml (100%) diff --git a/addons/purchase_requisition/test/purchase_requisition.yml b/addons/purchase_requisition/test/process/purchase_requisition.yml similarity index 100% rename from addons/purchase_requisition/test/purchase_requisition.yml rename to addons/purchase_requisition/test/process/purchase_requisition.yml From 29c0a92ac50eff2e7eb9f374aba0206e0f4dd43e Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Fri, 21 Oct 2011 17:59:41 +0530 Subject: [PATCH 03/66] [IMP]purchase_requisition: try to improve the code on the bases of data bzr revid: dbr@tinyerp.com-20111021122941-dlro6heqzpmwitub --- addons/purchase/purchase_demo.xml | 16 +- addons/purchase_requisition/__openerp__.py | 4 +- .../purchase_requisition_view.xml | 4 +- .../test/process/purchase_requisition.yml | 207 +++--------------- 4 files changed, 45 insertions(+), 186 deletions(-) diff --git a/addons/purchase/purchase_demo.xml b/addons/purchase/purchase_demo.xml index 6aa98f8cf6c..958a1557b4e 100644 --- a/addons/purchase/purchase_demo.xml +++ b/addons/purchase/purchase_demo.xml @@ -161,9 +161,19 @@ 10 - + + [HDD3] HDD Seagate 7200.8 80GB + + + 70 + 10 + + + + + [HDD2] HDD Seagate 7200.8 120GB @@ -172,7 +182,7 @@ - + [RAM] DDR 256MB PC400 @@ -182,7 +192,7 @@ - + [RAM512] DDR 512MB PC400 diff --git a/addons/purchase_requisition/__openerp__.py b/addons/purchase_requisition/__openerp__.py index d1ec2b1c260..ebdb598c081 100644 --- a/addons/purchase_requisition/__openerp__.py +++ b/addons/purchase_requisition/__openerp__.py @@ -43,8 +43,8 @@ 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_report.yml', + 'test/process/purchase_requisition.yml', ], "installable": True, "certificate" : "001023264099823179629", diff --git a/addons/purchase_requisition/purchase_requisition_view.xml b/addons/purchase_requisition/purchase_requisition_view.xml index 06ee94c3941..3b0cfeb7f77 100644 --- a/addons/purchase_requisition/purchase_requisition_view.xml +++ b/addons/purchase_requisition/purchase_requisition_view.xml @@ -21,7 +21,7 @@ purchase.order - + @@ -34,7 +34,7 @@ purchase.order - + diff --git a/addons/purchase_requisition/test/process/purchase_requisition.yml b/addons/purchase_requisition/test/process/purchase_requisition.yml index fb5fa774fc3..df6d4089e54 100644 --- a/addons/purchase_requisition/test/process/purchase_requisition.yml +++ b/addons/purchase_requisition/test/process/purchase_requisition.yml @@ -1,189 +1,38 @@ - - - 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. + In order to test the purchase requisition module, I have to add a boolean field in product, + If I checked it then it's requisition create. - - I start by creating a new product 'Laptop ACER', which is purchased at Asustek, in MTO, - with the generation of purchase requisitions. + I start by Checking the product, Product must have requisition field checked. + and Product supply method is buy and the procure method is make to order. - - !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 - 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 + !record {model: product.product, id: product.product_product_hdd3}: + supply_method: 'buy' + purchase_requisition: True - - Then I sell 5 Laptop ACER to the customer Agrolait, sale order TEST/TENDER/0001. + I create the procurement order. - - !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 + !python {model: make.procurement}: | + import time + product = self.pool.get('product.product').browse(cr, uid,[ref('product.product_product_hdd3')]) + #product_uom = product.product_uom + fields = { + 'qty': 5.0, + 'product_id': product, + #'uom_id': product_uom, + #'warehouse_id': stock.warehouse0, + 'date_planned': time.strftime('%Y-%m-%d') + } + a = self.default_get(cr, uid, fields, context) + req_id = self.make_procurement(cr, uid, [ref('product.product_product_hdd3')], context) - - 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. -- - !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], }) - -- - I check that I have two purchase orders on the purchase requisition. -- - !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') - -- - I set the purchase requisition as 'Not Exclusive'. -- - !python {model: purchase.requisition}: | - ids =self.search(cr, uid, [('origin','=','Laptop ACER')]) - self.write(cr,uid,ids[0],{'exclusive': 'multiple' }) -- - I change the quantities so that the purchase order for DistriPC includes 3 pieces and the - purchase order for Asustek includes 2 pieces. + I create the procurement order from the selected purchase order. - !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}) + req_id = self.pool.get('procurement.order').action_po_assign(cr, uid, [ref('purchase.order_purchase6')], context) + self.wkf_confirm_order(cr, uid, [req_id], context) - - I confirm and validate both purchase orders. + I create the purchase requisition for the selected product. - - !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.') - -- - 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') - + !python {model: purchase.requisition}: | + self.browse(cr, uid, [context.get('requisition_id')], context) + From 86caf711dd971f063d090f4810f2b26e8756068a Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Mon, 31 Oct 2011 14:18:58 +0530 Subject: [PATCH 04/66] [IMP]puchase_requisition:Improve the test case for create procurement order from product bzr revid: dbr@tinyerp.com-20111031084858-e26x17iufxwbzrtu --- .../test/process/purchase_requisition.yml | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/addons/purchase_requisition/test/process/purchase_requisition.yml b/addons/purchase_requisition/test/process/purchase_requisition.yml index df6d4089e54..b3c1aeb0982 100644 --- a/addons/purchase_requisition/test/process/purchase_requisition.yml +++ b/addons/purchase_requisition/test/process/purchase_requisition.yml @@ -9,21 +9,25 @@ supply_method: 'buy' purchase_requisition: True - - I create the procurement order. + I create the procurement order for the product. - - !python {model: make.procurement}: | + !python {model: product.product}: | import time - product = self.pool.get('product.product').browse(cr, uid,[ref('product.product_product_hdd3')]) - #product_uom = product.product_uom - fields = { - 'qty': 5.0, - 'product_id': product, - #'uom_id': product_uom, - #'warehouse_id': stock.warehouse0, - 'date_planned': time.strftime('%Y-%m-%d') - } - a = self.default_get(cr, uid, fields, context) - req_id = self.make_procurement(cr, uid, [ref('product.product_product_hdd3')], context) + procurement = self.pool.get('make.procurement') + product = self.browse(cr, uid,[ref('product.product_product_hdd3')]) + context = {'active_model': 'product.product','active_ids': [product[0].id],'active_id': product[0].id} + default_data = procurement.default_get(cr, uid, ['uom_id', 'warehouse_id', 'date_planned', 'product_id', 'qty'], context) + vals = {'uom_id': product[0].uom_id.id,'warehouse_id': ref('stock.stock_warehouse_shop0'),'qty': default_data.get('qty'),'date_planned': default_data.get('date_planned')} + ids = procurement.create(cr, uid, vals, context) + req_id = procurement.make_procurement(cr, uid, [ids], context) + proc_order = self.pool.get('procurement.order') + order = proc_order.browse(cr, uid, [req_id.get('res_id')]) + assert order[0].state == "confirmed", "Procurement Order should be in Confirmed state" + assert order[0].product_id == product[0],"Product is not correspond in procurement order" + assert order[0].product_qty == default_data.get('qty'),"Product's quantity is not correspond in procurement order" + assert order[0].product_uom == product[0].uom_id,"Product's UOM is not correspond in procurement order" + + - I create the procurement order from the selected purchase order. - From adc05bc4d6559cdd52482f3e435f0a9d6191ef6c Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Mon, 31 Oct 2011 15:27:40 +0530 Subject: [PATCH 05/66] [IMP]puchase_requisition: Improve code for create requisition bzr revid: dbr@tinyerp.com-20111031095740-t42sdppozvhwhfqs --- .../test/process/purchase_requisition.yml | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/addons/purchase_requisition/test/process/purchase_requisition.yml b/addons/purchase_requisition/test/process/purchase_requisition.yml index b3c1aeb0982..42c66f308d4 100644 --- a/addons/purchase_requisition/test/process/purchase_requisition.yml +++ b/addons/purchase_requisition/test/process/purchase_requisition.yml @@ -9,34 +9,34 @@ supply_method: 'buy' purchase_requisition: True - - I create the procurement order for the product. + I create the procurement order for the product and after run the procurement create purchase requisition. - !python {model: product.product}: | import time - procurement = self.pool.get('make.procurement') - product = self.browse(cr, uid,[ref('product.product_product_hdd3')]) - context = {'active_model': 'product.product','active_ids': [product[0].id],'active_id': product[0].id} - default_data = procurement.default_get(cr, uid, ['uom_id', 'warehouse_id', 'date_planned', 'product_id', 'qty'], context) - vals = {'uom_id': product[0].uom_id.id,'warehouse_id': ref('stock.stock_warehouse_shop0'),'qty': default_data.get('qty'),'date_planned': default_data.get('date_planned')} - ids = procurement.create(cr, uid, vals, context) - req_id = procurement.make_procurement(cr, uid, [ids], context) + import netsvc + mk_proc = self.pool.get('make.procurement') proc_order = self.pool.get('procurement.order') + pur_req = self.pool.get('purchase.requisition') + context = {'active_model': 'product.product','active_ids': [ref('product.product_product_hdd3')],'active_id': ref('product.product_product_hdd3')} + default_data = mk_proc.default_get(cr, uid, ['uom_id', 'warehouse_id', 'date_planned', 'product_id', 'qty'], context) + vals = {'uom_id': ref('product.product_uom_unit'),'warehouse_id': ref('stock.stock_warehouse_shop0'),'qty': default_data.get('qty'),'date_planned': default_data.get('date_planned')} + ids = mk_proc.create(cr, uid, vals, context) + req_id = mk_proc.make_procurement(cr, uid, [ids], context) order = proc_order.browse(cr, uid, [req_id.get('res_id')]) assert order[0].state == "confirmed", "Procurement Order should be in Confirmed state" - assert order[0].product_id == product[0],"Product is not correspond in procurement order" + assert order[0].product_id.id == ref('product.product_product_hdd3'),"Product is not correspond in procurement order" assert order[0].product_qty == default_data.get('qty'),"Product's quantity is not correspond in procurement order" - assert order[0].product_uom == product[0].uom_id,"Product's UOM is not correspond in procurement order" - - -- - I create the procurement order from the selected purchase order. -- - !python {model: purchase.order}: | - req_id = self.pool.get('procurement.order').action_po_assign(cr, uid, [ref('purchase.order_purchase6')], context) - self.wkf_confirm_order(cr, uid, [req_id], context) -- - I create the purchase requisition for the selected product. -- - !python {model: purchase.requisition}: | - self.browse(cr, uid, [context.get('requisition_id')], context) - + assert order[0].product_uom.id == ref('product.product_uom_unit'),"Product's UOM is not correspond in procurement order" + wf_service = netsvc.LocalService("workflow") + for proc in order: + wf_service.trg_validate(uid, 'procurement.order',proc.id,'button_check', cr) + proc_ids = proc_order.search(cr, uid, [('id','=',req_id.get('res_id')),('state','in',['running'])]) + proc_id = proc_order.browse(cr, uid, proc_ids) + assert proc_id[0].state == 'running',"Product's UOM is not correspond in procurement order" + if proc_id[0].requisition_id: + pur_req_rec = pur_req.browse(cr, uid, [proc_id[0].requisition_id.id]) + assert pur_req_rec[0].state == 'draft',"Product's UOM is not correspond in procurement order" + for record in pur_req_rec[0].line_ids: + assert record.product_id.id == ref('product.product_product_hdd3'),"Product's UOM is not correspond in procurement order" + assert record.product_qty == default_data.get('qty'),"Product's UOM is not correspond in procurement order" + assert record.product_uom_id.id == ref('product.product_uom_unit'),"Product's UOM is not correspond in procurement order" From a8ee7baa2d95261435d266798cee2196bde4d617 Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Mon, 31 Oct 2011 17:22:25 +0530 Subject: [PATCH 06/66] [IMP,ADD,MOVE]puchase_requisition: Improve the code in purchase_requisition.yml file Create new ui folder Move purchase_requisition_exclusive.yml to onchange_events.yml Improve code for onchange_events.yml bzr revid: dbr@tinyerp.com-20111031115225-1yy9jsz3iee2gmlw --- addons/purchase_requisition/__openerp__.py | 3 +- .../test/process/purchase_requisition.yml | 21 ++-- .../test/purchase_requisition_exclusive.yml | 113 ------------------ .../test/ui/onchange_events.yml | 23 ++++ 4 files changed, 38 insertions(+), 122 deletions(-) delete mode 100644 addons/purchase_requisition/test/purchase_requisition_exclusive.yml create mode 100644 addons/purchase_requisition/test/ui/onchange_events.yml diff --git a/addons/purchase_requisition/__openerp__.py b/addons/purchase_requisition/__openerp__.py index ebdb598c081..e655a574e42 100644 --- a/addons/purchase_requisition/__openerp__.py +++ b/addons/purchase_requisition/__openerp__.py @@ -43,8 +43,9 @@ 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":[ 'test/process/purchase_requisition.yml', + 'test/ui/onchange_events.yml', ], "installable": True, "certificate" : "001023264099823179629", diff --git a/addons/purchase_requisition/test/process/purchase_requisition.yml b/addons/purchase_requisition/test/process/purchase_requisition.yml index 42c66f308d4..3be7e2a9ea9 100644 --- a/addons/purchase_requisition/test/process/purchase_requisition.yml +++ b/addons/purchase_requisition/test/process/purchase_requisition.yml @@ -1,6 +1,6 @@ - - In order to test the purchase requisition module, I have to add a boolean field in product, - If I checked it then it's requisition create. + In order to test the purchase requisition module, I have to checked a boolean field 'purchase requisition' in product, + If I checked it then it's requisition will be create. - I start by Checking the product, Product must have requisition field checked. and Product supply method is buy and the procure method is make to order. @@ -9,7 +9,7 @@ supply_method: 'buy' purchase_requisition: True - - I create the procurement order for the product and after run the procurement create purchase requisition. + I create the procurement order for the product and after run that procurement for create purchase requisition. - !python {model: product.product}: | import time @@ -17,6 +17,7 @@ mk_proc = self.pool.get('make.procurement') proc_order = self.pool.get('procurement.order') pur_req = self.pool.get('purchase.requisition') + pur_order = self.pool.get('purchase.order') context = {'active_model': 'product.product','active_ids': [ref('product.product_product_hdd3')],'active_id': ref('product.product_product_hdd3')} default_data = mk_proc.default_get(cr, uid, ['uom_id', 'warehouse_id', 'date_planned', 'product_id', 'qty'], context) vals = {'uom_id': ref('product.product_uom_unit'),'warehouse_id': ref('stock.stock_warehouse_shop0'),'qty': default_data.get('qty'),'date_planned': default_data.get('date_planned')} @@ -32,11 +33,15 @@ wf_service.trg_validate(uid, 'procurement.order',proc.id,'button_check', cr) proc_ids = proc_order.search(cr, uid, [('id','=',req_id.get('res_id')),('state','in',['running'])]) proc_id = proc_order.browse(cr, uid, proc_ids) - assert proc_id[0].state == 'running',"Product's UOM is not correspond in procurement order" + assert proc_id[0].state == 'running',"Generated Procurement should be in Running state" if proc_id[0].requisition_id: + po_id = pur_order.search(cr, uid, [('requisition_id','=',proc_id[0].requisition_id.id)]) + po_req = pur_order.browse(cr, uid, po_id)[0].requisition_id pur_req_rec = pur_req.browse(cr, uid, [proc_id[0].requisition_id.id]) - assert pur_req_rec[0].state == 'draft',"Product's UOM is not correspond in procurement order" + assert po_req == proc_id[0].requisition_id,"Created Requisition is not properly linked in purchase order" + assert pur_req_rec[0].state == 'draft',"Created Requisition should be in draft state" for record in pur_req_rec[0].line_ids: - assert record.product_id.id == ref('product.product_product_hdd3'),"Product's UOM is not correspond in procurement order" - assert record.product_qty == default_data.get('qty'),"Product's UOM is not correspond in procurement order" - assert record.product_uom_id.id == ref('product.product_uom_unit'),"Product's UOM is not correspond in procurement order" + assert record.product_id.id == ref('product.product_product_hdd3'),"Requisition Product is not correspond" + assert record.product_qty == default_data.get('qty'),"Requisition Product's quantity is not correspond" + assert record.product_uom_id.id == ref('product.product_uom_unit'),"Requisition Product's UOM is not correspond" + 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/ui/onchange_events.yml b/addons/purchase_requisition/test/ui/onchange_events.yml new file mode 100644 index 00000000000..683edbc6aeb --- /dev/null +++ b/addons/purchase_requisition/test/ui/onchange_events.yml @@ -0,0 +1,23 @@ +- + In order to test the onchange events of purchase requisition. +- + I call onchange event to change the product of purchase requisition line. +- + !python {model: purchase.requisition.line}: | + self.onchange_product_id(cr, uid, [ref('order_purchase_requisition1')],ref('product.product_product_hdd2'), ref('product.product_uom_unit')) +- + I change state of requisition in "In progress". +- + !python {model: purchase.requisition}: | + self.tender_in_progress(cr, uid, ref('order_purchase_requisition1')) +- + I change state of requisition as "done". +- + !python {model: purchase.requisition}: | + self.tender_done(cr, uid, ref('order_purchase_requisition1')) +- + I reset the state of requisition as "New". +- + !python {model: purchase.requisition}: | + self.tender_reset(cr, uid, ref('order_purchase_requisition1')) + From b13ddc11a75f70a4a7dad313d13de68a5eb76e73 Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Mon, 31 Oct 2011 18:11:05 +0530 Subject: [PATCH 07/66] [ADD,MOVE,IMP]purchase_requisition: [ADD]cancel_purchase_requisition.yml [ADD]duplicate_requisition.yml [MOVE]purchase_requisition_test.yml => test/ui/delete_requisition.yml [IMP]delete_requisition.yml [IMP]set the propare sequence in __openerp__.py bzr revid: dbr@tinyerp.com-20111031124105-x0rp6cg5e98lsjrp --- addons/purchase_requisition/__openerp__.py | 3 + .../process/cancel_purchase_requisition.yml | 8 + .../test/purchase_requisition_test.yml | 166 ------------------ .../test/ui/delete_requisition.yml | 27 +++ .../test/ui/duplicate_requisition.yml | 8 + .../{ => ui}/purchase_requisition_report.yml | 0 6 files changed, 46 insertions(+), 166 deletions(-) create mode 100644 addons/purchase_requisition/test/process/cancel_purchase_requisition.yml delete mode 100755 addons/purchase_requisition/test/purchase_requisition_test.yml create mode 100755 addons/purchase_requisition/test/ui/delete_requisition.yml create mode 100644 addons/purchase_requisition/test/ui/duplicate_requisition.yml rename addons/purchase_requisition/test/{ => ui}/purchase_requisition_report.yml (100%) diff --git a/addons/purchase_requisition/__openerp__.py b/addons/purchase_requisition/__openerp__.py index e655a574e42..bbe2551a14e 100644 --- a/addons/purchase_requisition/__openerp__.py +++ b/addons/purchase_requisition/__openerp__.py @@ -45,7 +45,10 @@ This new object will regroup and will allow you to easily keep track and order a "active": False, "test":[ 'test/process/purchase_requisition.yml', + 'test/process/cancel_purchase_requisition.yml', 'test/ui/onchange_events.yml', + 'test/ui/purchase_requisition_report.yml', + 'test/ui/delete_requisition.yml', ], "installable": True, "certificate" : "001023264099823179629", diff --git a/addons/purchase_requisition/test/process/cancel_purchase_requisition.yml b/addons/purchase_requisition/test/process/cancel_purchase_requisition.yml new file mode 100644 index 00000000000..cb85b32d044 --- /dev/null +++ b/addons/purchase_requisition/test/process/cancel_purchase_requisition.yml @@ -0,0 +1,8 @@ +- + In order to test the cancel purchase requisition order. +- + I try to cancel purchase requisition order. +- + !python {model: purchase.requisition}: | + self.tender_cancel(cr, uid, [ref("order_purchase_requisition1")]) + 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/test/ui/delete_requisition.yml b/addons/purchase_requisition/test/ui/delete_requisition.yml new file mode 100755 index 00000000000..f3ca08674f4 --- /dev/null +++ b/addons/purchase_requisition/test/ui/delete_requisition.yml @@ -0,0 +1,27 @@ +- + In order to test the duplicate order and check duplicate details. +- + I duplicate order. +- + !python {model: purchase.requisition}: | + context.update({'active_id':ref('order_purchase_requisition1')}) + self.copy(cr, uid, ref('order_purchase_requisition1'), context) +- + In order to test to delete process on purchase requisition order. +- + I delete draft purchase requisition order. +- + !python {model: purchase.order}: | + self.unlink(cr, uid, [ref("order_purchase_requisition1")]) +- + Now I try to cancel purchase requisition order. +- + !python {model: purchase.requisition}: | + self.tender_cancel(cr, uid, [ref("order_purchase_requisition1")]) +- + I delete cancelled purchase requisition order. +- + !python {model: purchase.order}: | + self.unlink(cr, uid, [ref("order_purchase_requisition1")]) + + diff --git a/addons/purchase_requisition/test/ui/duplicate_requisition.yml b/addons/purchase_requisition/test/ui/duplicate_requisition.yml new file mode 100644 index 00000000000..742500d865d --- /dev/null +++ b/addons/purchase_requisition/test/ui/duplicate_requisition.yml @@ -0,0 +1,8 @@ +- + In order to test the duplicate order and check duplicate details. +- + I duplicate order. +- + !python {model: purchase.requisition}: | + context.update({'active_id':ref('order_purchase_requisition1')}) + self.copy(cr, uid, ref('order_purchase_requisition1'), context) diff --git a/addons/purchase_requisition/test/purchase_requisition_report.yml b/addons/purchase_requisition/test/ui/purchase_requisition_report.yml similarity index 100% rename from addons/purchase_requisition/test/purchase_requisition_report.yml rename to addons/purchase_requisition/test/ui/purchase_requisition_report.yml From a8b7872502ce9f73ebf4741d3d51152b1ffa19f7 Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Mon, 31 Oct 2011 18:17:28 +0530 Subject: [PATCH 08/66] [IMP]purchase_requisition: remove the extra code bzr revid: dbr@tinyerp.com-20111031124728-pmrrp4bq5h1iwps5 --- .../purchase_requisition/test/ui/delete_requisition.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/addons/purchase_requisition/test/ui/delete_requisition.yml b/addons/purchase_requisition/test/ui/delete_requisition.yml index f3ca08674f4..c077784a73e 100755 --- a/addons/purchase_requisition/test/ui/delete_requisition.yml +++ b/addons/purchase_requisition/test/ui/delete_requisition.yml @@ -1,11 +1,3 @@ -- - In order to test the duplicate order and check duplicate details. -- - I duplicate order. -- - !python {model: purchase.requisition}: | - context.update({'active_id':ref('order_purchase_requisition1')}) - self.copy(cr, uid, ref('order_purchase_requisition1'), context) - In order to test to delete process on purchase requisition order. - From f45e2468bc96a191d82fc1b081e8388c531af1e0 Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Wed, 2 Nov 2011 13:05:52 +0530 Subject: [PATCH 09/66] [ADD,IMP] purchase_requisition: [ADD]Add New file for define the main flow of exclusive requisition "purchase_requisition_exclusive.yml" [IMP]Improve the demo data for exclisive code improvement [IMP]Add one new file in __openerp__.py bzr revid: dbr@tinyerp.com-20111102073552-yruxrxuvb9qji3pg --- addons/purchase_requisition/__openerp__.py | 1 + .../purchase_requisition_demo.xml | 42 ++++++++++++++++++- .../purchase_requisition_exclusive.yml | 38 +++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml diff --git a/addons/purchase_requisition/__openerp__.py b/addons/purchase_requisition/__openerp__.py index bbe2551a14e..bf21d7f3232 100644 --- a/addons/purchase_requisition/__openerp__.py +++ b/addons/purchase_requisition/__openerp__.py @@ -45,6 +45,7 @@ This new object will regroup and will allow you to easily keep track and order a "active": False, "test":[ 'test/process/purchase_requisition.yml', + 'test/process/purchase_requisition_exclusive.yml', 'test/process/cancel_purchase_requisition.yml', 'test/ui/onchange_events.yml', 'test/ui/purchase_requisition_report.yml', diff --git a/addons/purchase_requisition/purchase_requisition_demo.xml b/addons/purchase_requisition/purchase_requisition_demo.xml index deb25fe9e14..728d5fbdffd 100644 --- a/addons/purchase_requisition/purchase_requisition_demo.xml +++ b/addons/purchase_requisition/purchase_requisition_demo.xml @@ -10,7 +10,7 @@ - multiple + exclusive @@ -24,6 +24,46 @@ 5 + + + + + + + + + + + + + + + + + + + + + + + + [CPU1] Processor AMD Athlon XP 1800+ + + + 60 + 3 + + + + + + [CPU3] Processor AMD Athlon XP 2200+ + + + 50 + 13 + + diff --git a/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml b/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml new file mode 100644 index 00000000000..d3bb3a5e97e --- /dev/null +++ b/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml @@ -0,0 +1,38 @@ +- + Create two PO on based of one tender, + than confirm any one PO the second PO automatically goes in to cancel state. + order_purchase_requisition1 +- + In order to test the exclusive type requisition, I have to create two differ purchase order in one requisition [Tender] +- + I start by Checking the product, Product must have requisition field checked. +- + !record {model: product.product, id: product.product_product_cpu1}: + purchase_requisition: True +- + Checking requisition field for another product. +- + !record {model: product.product, id: product.product_product_cpu3}: + purchase_requisition: True +- + Now check that purchase order's product must have requisition field checked. +- + !python {model: purchase.order}: | + import netsvc + wf_service = netsvc.LocalService("workflow") + pur_order = self.pool.get('purchase.order') + ids = pur_order.search(cr, uid, [('requisition_id','=',ref('order_purchase_requisition1'))]) + po_id = pur_order.browse(cr, uid, ids) + for po in po_id: + for line in po.order_line: + if line.product_id.purchase_requisition == False: + assert line.product_id.purchase_requisition == True, "Purchase Order's product must have requisition field checked" + po_confirm = po_id[0].id + wf_service.trg_validate(uid, 'purchase.order',po_confirm,'purchase_confirm', cr) + assert po_id[0].state == 'approved',"After confirm a purchase order it should be in confirm state" + assert po_id[1].state == 'cancel',"After confirmed a purchase order form the this requisition the second purchase order should be automatically goes in to cancelled state" + + + + + From e90122bb113a6404df6a9efa11c0b5648146f84f Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Wed, 2 Nov 2011 13:08:20 +0530 Subject: [PATCH 10/66] [IMP]purchase_requisition: Remove extra statements bzr revid: dbr@tinyerp.com-20111102073820-kn5zvxgsxpkjmi7i --- .../test/process/purchase_requisition_exclusive.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml b/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml index d3bb3a5e97e..d68c12c6366 100644 --- a/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml +++ b/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml @@ -1,7 +1,3 @@ -- - Create two PO on based of one tender, - than confirm any one PO the second PO automatically goes in to cancel state. - order_purchase_requisition1 - In order to test the exclusive type requisition, I have to create two differ purchase order in one requisition [Tender] - From 85d601efb3333b5d4c0a2c9e841ed3b7930d09e1 Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Wed, 2 Nov 2011 15:58:09 +0530 Subject: [PATCH 11/66] [ADD,IMP] purchase_requisition: [ADD]purchase_requisition/test/ui/requisiton2request_quotation.yml [IMP]add new file in __openerp__.py [IMP]Improve code of onchange_events.yml bzr revid: dbr@tinyerp.com-20111102102809-c3cjgz7a331sdawr --- addons/purchase_requisition/__openerp__.py | 3 ++- .../purchase_requisition_exclusive.yml | 4 ---- .../test/ui/onchange_events.yml | 7 +++++- .../test/ui/requisiton2request_quotation.yml | 23 +++++++++++++++++++ 4 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 addons/purchase_requisition/test/ui/requisiton2request_quotation.yml diff --git a/addons/purchase_requisition/__openerp__.py b/addons/purchase_requisition/__openerp__.py index bf21d7f3232..426e8a770fc 100644 --- a/addons/purchase_requisition/__openerp__.py +++ b/addons/purchase_requisition/__openerp__.py @@ -45,7 +45,8 @@ This new object will regroup and will allow you to easily keep track and order a "active": False, "test":[ 'test/process/purchase_requisition.yml', - 'test/process/purchase_requisition_exclusive.yml', + 'test/process/purchase_requisition_exclusive.yml', + 'test/ui/requisiton2request_quotation.yml', 'test/process/cancel_purchase_requisition.yml', 'test/ui/onchange_events.yml', 'test/ui/purchase_requisition_report.yml', diff --git a/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml b/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml index d68c12c6366..8a9116de0d3 100644 --- a/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml +++ b/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml @@ -28,7 +28,3 @@ assert po_id[0].state == 'approved',"After confirm a purchase order it should be in confirm state" assert po_id[1].state == 'cancel',"After confirmed a purchase order form the this requisition the second purchase order should be automatically goes in to cancelled state" - - - - diff --git a/addons/purchase_requisition/test/ui/onchange_events.yml b/addons/purchase_requisition/test/ui/onchange_events.yml index 683edbc6aeb..901c50ca1c9 100644 --- a/addons/purchase_requisition/test/ui/onchange_events.yml +++ b/addons/purchase_requisition/test/ui/onchange_events.yml @@ -20,4 +20,9 @@ - !python {model: purchase.requisition}: | self.tender_reset(cr, uid, ref('order_purchase_requisition1')) - +- + I call onchange event to change the partner of purchase requisition. +- + !python {model: purchase.requisition.partner}: | + self.onchange_partner_id(cr, uid, ref('order_purchase_requisition1'), ref('base.res_partner_desertic_hispafuentes')) + diff --git a/addons/purchase_requisition/test/ui/requisiton2request_quotation.yml b/addons/purchase_requisition/test/ui/requisiton2request_quotation.yml new file mode 100644 index 00000000000..6c0ce5eee0a --- /dev/null +++ b/addons/purchase_requisition/test/ui/requisiton2request_quotation.yml @@ -0,0 +1,23 @@ +- + In order to create a Quotatoion, I click on the wizard 'Request a Quotation' and create record from 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("order_purchase_requisition1")],"active_id": ref("order_purchase_requisition1"), }) +- + I check that the purchase order is created. +- + !python {model: purchase.order}: | + purchase_ids= self.search(cr, uid, [('requisition_id','=',ref("order_purchase_requisition1"))]) + assert purchase_ids, "Purchase Order is not created from this wizard" + rfq = self.browse(cr, uid, purchase_ids[0]) + assert rfq.state == 'draft',"Purchase Order should be in draft state" + assert rfq.partner_address_id.id == ref('base.res_partner_address_3000'),"Purchase Order Partner address is not correspond" + assert rfq.partner_id.id == ref('base.res_partner_desertic_hispafuentes'),"Purchase Order Partner is not correspond" + From 7b800b5f03c9e1bd86884979b60cb5f7348af6bd Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Wed, 2 Nov 2011 16:15:31 +0530 Subject: [PATCH 12/66] [IMP] purchase_requisition: Improve the code for cancel_purchase_requisition.yml file bzr revid: dbr@tinyerp.com-20111102104531-itiutuktds163710 --- .../process/cancel_purchase_requisition.yml | 61 ++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/addons/purchase_requisition/test/process/cancel_purchase_requisition.yml b/addons/purchase_requisition/test/process/cancel_purchase_requisition.yml index cb85b32d044..eeae4689fbc 100644 --- a/addons/purchase_requisition/test/process/cancel_purchase_requisition.yml +++ b/addons/purchase_requisition/test/process/cancel_purchase_requisition.yml @@ -5,4 +5,63 @@ - !python {model: purchase.requisition}: | self.tender_cancel(cr, uid, [ref("order_purchase_requisition1")]) - +- + I check that purchase requisition order is cancelled. +- + !assert {model: purchase.requisition, id: order_purchase_requisition1}: + - state == 'cancel' +- + I change state of requisition in "In progress". +- + !python {model: purchase.requisition}: | + self.tender_in_progress(cr, uid, ref('order_purchase_requisition1')) +- + I check that purchase requisition order is "In progress". +- + !assert {model: purchase.requisition, id: order_purchase_requisition1}: + - state == 'in_progress' +- + I try to cancel "In progress" purchase requisition order. +- + !python {model: purchase.requisition}: | + self.tender_cancel(cr, uid, [ref("order_purchase_requisition1")]) +- + I check that purchase requisition order is cancelled. +- + !assert {model: purchase.requisition, id: order_purchase_requisition1}: + - state == 'cancel' +- + I reset the state of requisition as "New". +- + !python {model: purchase.requisition}: | + self.tender_reset(cr, uid, ref('order_purchase_requisition1')) +- + I check that purchase requisition order is New. +- + !assert {model: purchase.requisition, id: order_purchase_requisition1}: + - state == 'draft' +- + I change state of requisition as "done". +- + !python {model: purchase.requisition}: | + self.tender_done(cr, uid, ref('order_purchase_requisition1')) +- + I check that purchase requisition order is Done. +- + !assert {model: purchase.requisition, id: order_purchase_requisition1}: + - state == 'done' +- + I try to cancel 'Done' purchase requisition order. +- + !python {model: purchase.requisition}: | + self.tender_cancel(cr, uid, [ref("order_purchase_requisition1")]) +- + I check that purchase requisition order is cancelled. +- + !assert {model: purchase.requisition, id: order_purchase_requisition1}: + - state == 'cancel' +- + I reset the state of requisition as "New". +- + !python {model: purchase.requisition}: | + self.tender_reset(cr, uid, ref('order_purchase_requisition1')) From 2ab51f3af900577a214d60a8b336168c1bc246e9 Mon Sep 17 00:00:00 2001 From: "Jagdish Panchal (Open ERP)" Date: Fri, 18 Nov 2011 18:24:30 +0530 Subject: [PATCH 13/66] [IMP] improve test case of recruitment process bzr revid: jap@tinyerp.com-20111118125430-l02i4orxr2z940s3 --- addons/hr_recruitment/__openerp__.py | 4 +- .../test/recruitment_process.yml | 65 ++ addons/hr_recruitment/test/resume.eml | 839 ++++++++++++++++++ .../test/test_hr_recruitment.yml | 139 --- .../wizard/hr_recruitment_phonecall.py | 2 +- 5 files changed, 908 insertions(+), 141 deletions(-) create mode 100644 addons/hr_recruitment/test/recruitment_process.yml create mode 100644 addons/hr_recruitment/test/resume.eml delete mode 100644 addons/hr_recruitment/test/test_hr_recruitment.yml diff --git a/addons/hr_recruitment/__openerp__.py b/addons/hr_recruitment/__openerp__.py index b728609c53d..bff574de94b 100644 --- a/addons/hr_recruitment/__openerp__.py +++ b/addons/hr_recruitment/__openerp__.py @@ -56,7 +56,9 @@ system to store and search in your CV base. 'demo_xml': [ 'hr_recruitment_demo.xml', ], - 'test':['test/test_hr_recruitment.yml'], + 'test':[ + 'test/recruitment_process.yml', + ], 'installable': True, 'active': False, 'certificate' : '001073437025460275621', diff --git a/addons/hr_recruitment/test/recruitment_process.yml b/addons/hr_recruitment/test/recruitment_process.yml new file mode 100644 index 00000000000..64e8ab687a8 --- /dev/null +++ b/addons/hr_recruitment/test/recruitment_process.yml @@ -0,0 +1,65 @@ +- + In Order to test process of Recruitment, +- + Applicant interested in job position. so He send resume by email. +- + !python {model: mail.thread}: | + import addons + request_file = open(addons.get_module_resource('hr_recruitment','test', 'resume.eml'),'rb') + request_message = request_file.read() + self.message_process(cr, uid, 'hr.applicant', request_message) +- + After getting the mail, I check details of new applicant. +- + !python {model: hr.applicant}: | + applicant_ids = self.search(cr, uid, [('email_from','=', 'Mr. Richard Anderson ')]) + assert applicant_ids, "Applicant is not created after getting the mail" + applicant = self.browse(cr, uid, applicant_ids[0], context=context) + assert applicant.name == "Application for the post of Jr.application Programmer", "Subject does not match" + assert applicant.state == "draft" +- + I assign the Job position to the applicant +- + !python {model: hr.applicant}: | + self.write(cr, uid, [ref('hr_case_programmer')], {'job_id':ref('hr.job_jr_appli')}) +- + I open applicant for the Recruitment +- + + !python {model: hr.applicant}: | + self.case_open(cr, uid, [ref("hr_case_programmer")]) +- + I start communication with applicant, first schedule phonecall. +- + !python {model: hr.recruitment.job2phonecall}: | + self.make_phonecall(cr, uid, [ref('hr_case_programmer')]) +- + I schedule meeting with applicant for interview. +- + !python {model: hr.applicant}: | + self.action_makeMeeting(cr, uid, [ref('hr_case_programmer')]) +- + Applicant fillup the answer of the interview quetion. +- + !python {model: survey.question.wiz}: | + ctx = context.copy() + ctx.update({'active_model': 'hr.applicant', 'active_id': ref("hr_case_programmer"), 'active_ids': [ref("hr_case_programmer")], 'survey_id': ref("survey_job_0")}) + self.fields_view_get(cr, uid, ref("survey.view_survey_question_message"),"form", context=ctx) + vals = self.default_get(cr, uid , [], context=ctx) + self.create(cr, uid, vals, context=ctx) + self.action_new_page(cr, uid, [ref("survey_job_0")], context=ctx) +- + I print Applicant fill up the interview quetion +- + !python {model: hr.applicant}: | + self.action_print_survey(cr, uid, [ref('hr_case_programmer')]) +- + On a successful meeting with the applicant, I hired employee. +- + !python {model: hr.applicant}: | + self.case_close(cr, uid, [ref('hr_case_programmer')]) +- + I check that applicant is "Hired". +- + !assert {model: hr.applicant, id: hr_case_programmer}: + - state == 'done' \ No newline at end of file diff --git a/addons/hr_recruitment/test/resume.eml b/addons/hr_recruitment/test/resume.eml new file mode 100644 index 00000000000..9529873a49c --- /dev/null +++ b/addons/hr_recruitment/test/resume.eml @@ -0,0 +1,839 @@ +Return-Path: +X-Original-To: hr@mycompany.com +Delivered-To: hr@mycompany.com +Received: by mail1.mycompany.com (Postfix, from userid 10002) + id 7047CBFC94; Fri, 18 Nov 2011 10:28:16 +0100 (CET) +X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail1.mycompany.com +X-Spam-Level: +X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, + HTML_MESSAGE autolearn=ham version=3.3.1 +Received: from nm12-vm2.bullet.mail.ne1.yahoo.com (nm12-vm2.bullet.mail.ne1.yahoo.com [98.138.91.88]) + by mail1.mycompany.com (Postfix) with SMTP id 0D04ABF53A + for ; Fri, 18 Nov 2011 10:27:50 +0100 (CET) +Received: from [98.138.90.50] by nm12.bullet.mail.ne1.yahoo.com with NNFMP; 18 Nov 2011 09:26:49 -0000 +Received: from [98.138.226.126] by tm3.bullet.mail.ne1.yahoo.com with NNFMP; 18 Nov 2011 09:26:49 -0000 +Received: from [127.0.0.1] by smtp205.mail.ne1.yahoo.com with NNFMP; 18 Nov 2011 09:26:49 -0000 +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.in; s=s1024; t=1321608409; bh=GGVn24b6ZH8Ojn91evBkrwuNFmAsLAPy4OeUvOqjgig=; h=X-Yahoo-Newman-Id:X-Yahoo-Newman-Property:X-YMail-OSG:X-Yahoo-SMTP:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type; b=DFCOdjskDmdbkzvuxTqFWJOUHsT0nITWiQe5782VeyTrhymhIzNhwzdRq4wfTrzLu03rJhHadZTX0uweNCf0Jpr4OpEQevZa3aVPw44NNmhFeT2tjs9m3kNWyPnz5Nk1Yv8tiTRFSdssPfZAhwz8UXLCBFowa8DRnY2ZFIsATRE= +X-Yahoo-Newman-Id: 644435.12111.bm@smtp205.mail.ne1.yahoo.com +X-Yahoo-Newman-Property: ymail-3 +X-YMail-OSG: 09Al2uQVM1n5JcQepgua6wQsww7jiatAHXaSsMjP5Qvk9Ba + c65j0.ETzyjVh0vpjphFK3XqPtX0n17z9cUCfUhUDDXLUmUSFoZ.NjoiJ_mQ + vwd4S7.I4ObFZm5jgA0ML0cfTRAy_0msUfO3NKsh9LgBdUXztbVOwrTGQhzD + nu2v3TskGG9ZtRTiqM_Iad2qmMqveFdqUz5xBnwYYgBuLWRR7EUmU1qyOgss + LL33J2t9EOCUn2Kc9XQbSkPBBR7BYlIatTF.AAxLdsuOW6ovTGO.HM5ap0qo + LLM1_BE.EOvXdW38ZC_hHcrM4xYaYSR7c0WaOQsR8EZeXk_Vhio7HHUrdxZl + 1oZz7YWK9Q04M023JJoM4v6IrThy3BNepluEFFcavkyOnCw-- +X-Yahoo-SMTP: oNtzSBqswBAqJIGYOgyGesyleENrhUEtEgBkQ053 +Received: from [192.168.1.30] (jagdish.n_panchal@180.211.100.2 with plain) + by smtp205.mail.ne1.yahoo.com with SMTP; 18 Nov 2011 01:26:47 -0800 PST +Message-ID: <4EC624C7.6020000@yahoo.in> +Date: Fri, 18 Nov 2011 14:56:31 +0530 +From: Richard Anderson +User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110424 Thunderbird/3.1.10 +MIME-Version: 1.0 +To: hr@mycompany.com +Subject: Application for the post of Jr.application Programmer. +Content-Type: multipart/mixed; + boundary="------------010903010402010104090709" + +This is a multi-part message in MIME format. +--------------010903010402010104090709 +Content-Type: multipart/alternative; + boundary="------------010004020303010906010104" + + +--------------010004020303010906010104 +Content-Type: text/plain; charset=ISO-8859-1; format=flowed +Content-Transfer-Encoding: 7bit + +Hello Sir, + + I am**Richard Anderson completed MCA from Mac Technological +university, i send my resume for the your company job position, i +attached my resume here + +Thank you +Richard Anderson + +--------------010004020303010906010104 +Content-Type: text/html; charset=ISO-8859-1 +Content-Transfer-Encoding: 7bit + + + + + + + + + Hello Sir,
+
+  I am Richard Anderson completed MCA from Mac Technological + university, i send my resume for the your company job position, i + attached my resume here
+
+ Thank you
+ Richard Anderson + + + +--------------010004020303010906010104-- + +--------------010903010402010104090709 +Content-Type: application/msword; + name="resume.doc" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="resume.doc" + +0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAOwADAP7/CQAGAAAAAAAAAAAAAAABAAAASwAAAAAA +AAAAEAAAAgAAAAEAAAD+////AAAAAAAAAAD///////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +///////////////////////////////////9//////////7///9KAAAABQAAAAYAAAAHAAAA +CAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUA +AAD+////FwAAABgAAAAZAAAAGgAAABsAAAAcAAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAA +IwAAACQAAAAlAAAAJgAAACcAAAAoAAAA/v///yoAAAArAAAALAAAAC0AAAAuAAAALwAAADAA +AAAxAAAAMgAAADMAAAA0AAAANQAAADYAAAA3AAAAOAAAADkAAAA6AAAAOwAAADwAAAA9AAAA +PgAAAD8AAABAAAAAQQAAAEIAAABDAAAARAAAAEUAAABGAAAARwAAAEgAAABJAAAA/v////7/ +//9MAAAATQAAAP7///////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////1IA +bwBvAHQAIABFAG4AdAByAHkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAWAAUA////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAA/v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////8AAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP// +/////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7///8AAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAA////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA/v///wAAAAAAAAAAAQAAAP7////+////BAAAAAUAAAAGAAAABwAAAP7/ +//8JAAAA/v////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////8BAP7/ +AwoAAP////8GCQIAAAAAAMAAAAAAAABGGAAAAE1pY3Jvc29mdCBXb3JkLURva3VtZW50AAoA +AABNU1dvcmREb2MAEAAAAFdvcmQuRG9jdW1lbnQuOAD0ObJxAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAEAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/wAAAQACAAAAAAAAAAAAAAAAAAAAAAABAAAA +4IWf8vlPaBCrkQgAKyez2TAAAADsAAAACgAAAAEAAABYAAAAAgAAAGAAAAAEAAAAeAAAAAcA +AACUAAAACAAAAKQAAAAJAAAAsAAAAAoAAAC8AAAACwAAAMgAAAAMAAAA1AAAAA0AAADgAAAA +AgAAAOn9AAAeAAAAEAAAAENhbmRpZGF0ZXMgTmFtZQAeAAAAFAAAAHNhZ2FyIHAgc3VyeWF3 +YW5zaGkAHgAAAAcAAABOb3JtYWwAAB4AAAAEAAAAc2FpAB4AAAAEAAAAMTY5AEAAAAAAyPid +CgAAAEAAAAAAAAAAAAAAAEAAAAAAnpj/jovLAUAAAAAA1LJ/lhzMAQAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAZwAKAAEAWwAPAAIAAAAAAAAAYAAAEPH/AgBgAAAA +BgBOAG8AcgBtAGEAbAAAABEAAAADJABhJAAxJAEqJAFBJAAALwBCKgBPSgAAUUoAAENKFABt +SAkEc0gJBFBKAABuSAQIXkoAAGFKFABfSAEEdEgBBABcAAEQAQACAFwAAAAJAEgAZQBhAGQA +aQBuAGcAIAAxAAAAJwABAAMkA2EkAw3GBQABOAQAXoQAAF2EoAVghAAAE6RkABSkZAAGJAEA +DwBPSgIAUUoCAENKEgA1CAEAPgACEAEAAgA+AAAACQBIAGUAYQBkAGkAbgBnACAAMgAAAA0A +AgATpGQAFKRkAAYkAQAMAE9KAgBRSgIAQ0oSADoAAxABAAIAOgAAAAkASABlAGEAZABpAG4A +ZwAgADMAAAAFAAMABiQBAA8AT0oCAFFKAgBDShIANQgBAFYABBABAAIAVgAAAAkASABlAGEA +ZABpAG4AZwAgADQAAAAfAAQAEmRoAQEADcYFAAFoAQBehGgBXYQAAGCEmP4GJAEAEgBPSgIA +UUoCAENKEgA1CAFcCAEyAAUQAQBiBTIAAAAJAEgAZQBhAGQAaQBuAGcAIAA1AAAACgAFABOk +ZAAUpGQAAwA1CAEAUAAGEAEAAgBQAAAACQBIAGUAYQBkAGkAbgBnACAANgAAABkABgANxgUA +ATgEAF6EAABdhKAFYIQAAAYkAQASAE9KAgBRSgIAQ0oSAD4qAVwIAWAABxABAAIAYAAAAAkA +SABlAGEAZABpAG4AZwAgADcAAAAwAAcAQCYGCiYGC0YBAAomBgtGAQAxJAANxgUAARwBADck +AF6EHAFdhAAAYITk/gYkAQwAT0oCAFFKAgBDShIASAAIEAEAAgBIAAAACQBIAGUAYQBkAGkA +bgBnACAAOAAAABcACAAxJAA3JABehBwBXYQAAGCE5P4GJAEADABPSgIAUUoCAENKEgAAAEIA +QUDy/6EAQgAAABkAQQBiAHMAYQB0AHoALQBTAHQAYQBuAGQAYQByAGQAcwBjAGgAcgBpAGYA +dABhAHIAdAAAAAAAAAAAAAAAAABCAP4f8v/xAEIAAAAZAEEAYgBzAGEAdAB6AC0AUwB0AGEA +bgBkAGEAcgBkAHMAYwBoAHIAaQBmAHQAYQByAHQAAAAAAEgA/h/y/wEBSAAAABwAVwBXAC0A +QQBiAHMAYQB0AHoALQBTAHQAYQBuAGQAYQByAGQAcwBjAGgAcgBpAGYAdABhAHIAdAAAAAAA +SgD+H/L/EQFKAAAAHQBXAFcALQBBAGIAcwBhAHQAegAtAFMAdABhAG4AZABhAHIAZABzAGMA +aAByAGkAZgB0AGEAcgB0ADEAAAAAAEwA/h/y/yEBTAAAAB4AVwBXAC0AQQBiAHMAYQB0AHoA +LQBTAHQAYQBuAGQAYQByAGQAcwBjAGgAcgBpAGYAdABhAHIAdAAxADEAAAAAAE4A/h/y/zEB +TgAAAB8AVwBXAC0AQQBiAHMAYQB0AHoALQBTAHQAYQBuAGQAYQByAGQAcwBjAGgAcgBpAGYA +dABhAHIAdAAxADEAMQAAAAAAUAD+H/L/QQFQAAAAIABXAFcALQBBAGIAcwBhAHQAegAtAFMA +dABhAG4AZABhAHIAZABzAGMAaAByAGkAZgB0AGEAcgB0ADEAMQAxADEAAAAAAFIA/h/y/1EB +UgAAACEAVwBXAC0AQQBiAHMAYQB0AHoALQBTAHQAYQBuAGQAYQByAGQAcwBjAGgAcgBpAGYA +dABhAHIAdAAxADEAMQAxADEAAAAAAFQA/h/y/2EBVAAAACIAVwBXAC0AQQBiAHMAYQB0AHoA +LQBTAHQAYQBuAGQAYQByAGQAcwBjAGgAcgBpAGYAdABhAHIAdAAxADEAMQAxADEAMQAAAAAA +KgD+H/L/cQEqAAAACQBXAFcAOABOAHUAbQAyAHoAMAAAAAgAT0oBAFFKAQAuAP4f8v+BAS4A +AAAJAFcAVwA4AE4AdQBtADIAegAxAAAADABPSgcAUUoHAF5KBwAqAP4f8v+RASoAAAAJAFcA +VwA4AE4AdQBtADIAegAzAAAACABPSgEAUUoBADYA/h/y/6EBNgAAAAkAVwBXADgATgB1AG0A +MwB6ADAAAAATAE9KAABRSgAANQgBUEoAAF5KAAAAKgD+H/L/sQEqAAAACQBXAFcAOABOAHUA +bQAzAHoAMQAAAAgAT0oHAFFKBwAqAP4f8v/BASoAAAAJAFcAVwA4AE4AdQBtADMAegAyAAAA +CABPSggAUUoIACoA/h/y/9EBKgAAAAkAVwBXADgATgB1AG0ANAB6ADAAAAAIAE9KCABRSggA +LgD+H/L/4QEuAAAACQBXAFcAOABOAHUAbQA0AHoAMQAAAAwAT0oHAFFKBwBeSgcAKgD+H/L/ +8QEqAAAACQBXAFcAOABOAHUAbQA0AHoAMwAAAAgAT0oBAFFKAQA8AP4f8v8BAjwAAAAWAEQA +ZQBmAGEAdQBsAHQAIABQAGEAcgBhAGcAcgBhAHAAaAAgAEYAbwBuAHQAAAAAACoA/h/y/xEC +KgAAAAkAVwBXADgATgB1AG0AMQB6ADAAAAAIAE9KAABRSgAAKgD+H/L/IQIqAAAACQBXAFcA +OABOAHUAbQAzAHoAMwAAAAgAT0oBAFFKAQAqAP4f8v8xAioAAAAJAFcAVwA4AE4AdQBtADUA +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 +NRaQAQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFMAeQBtAGIAbwBsAAAA +MyaQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEAcgBpAGEAbAAAAEcW +kAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUAGkAbQBlAHMAIABOAGUA +dwAgAFIAbwBtAGEAbgAAADUmkAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AABUAGEAaABvAG0AYQAAAD8WkAECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AABXAGkAbgBnAGQAaQBuAGcAcwAgADIAAAA3JpABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAVgBlAHIAZABhAG4AYQAAAD80kAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAABDAG8AdQByAGkAZQByACAATgBlAHcAAAA7BpABAgAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVwBpAG4AZwBkAGkAbgBnAHMAAABTJpABgBAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATABpAGIAZQByAGEAdABpAG8AbgAgAFMA +YQBuAHMAAABBAHIAaQBhAGwAAAA/BpABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAARABlAGoAYQBWAHUAIABTAGEAbgBzAAAASSaQAYAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAEEAcgBpAGEAbAAgAFUAbgBpAGMAbwBkAGUAIABNAFMAAABCAAQA +AQiNGAAA0AIAAGgBAAAAAHPC62bU3fWmAAAAAAEAAAAAAMkAAAASBgAAAgA/AAAABACDkD8A +AADJAAAAEgYAAAIAPwAAAD8AAAAAAAAAJwMA8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAIAAAAAAAAAAAAAAAAAAPAQAN/f//0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +gAAAAAAAAAAAAAAA//8SAAAAAAAAAA8AQwBhAG4AZABpAGQAYQB0AGUAcwAgAE4AYQBtAGUA +AAAAAAAAEwBzAGEAZwBhAHIAIABwACAAcwB1AHIAeQBhAHcAYQBuAHMAaABpAAMAcwBhAGkA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAJ4EAABEAGQA7gAjAQAAAAAAAAAAAAAAAAAAAACHAKUA6APoAwAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAADwAE8GYAAACyBArwCAAAAAEEAAAACgAAswAL8EIAAACBAAAA +AACCAAAAAACDAAAAAACEAAAAAAAEQQEAAAAGAQAAAAA/AQAAAACBAf///wCDAQAAAAC/ARAA +EAD/AQAACAAAABDwBAAAAAAAAIBiAAfw5AMAAAYGnRZ3tgAAAAB7OGUgEgIAEAAAwAMAAAEA +AAAAAAAAAAAAAABuHvC4AwAAnRZ3tgAAAAB7OGUgEgIAEP+JUE5HDQoaCgAAAA1JSERSAAAA +CQAAAAsIAwAAAJqHVykAAAMAUExURQAAAPf39/////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////88f9h0AAAADdFJOU///ANfKDUEA +AAABYktHRACIBR1IAAAADGNtUFBKQ21wMDcxMgAAAANIAHO8AAAALklEQVQYV22MQQoAAAjC +rP8/Ol10K8IJiuo7tbChbMtiRIMkMeT7m9B4e5RP2B4eJACOUomEagAAAABJRU5ErkJgggAA +ngQAAEQAZADuACMBAAAAAAAAAAAAAAAAAAAAAIcApQDoA+gDAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAPAATwZgAAALIECvAIAAAAAQQAAAAKAACzAAvwQgAAAIEAAAAAAIIA +AAAAAIMAAAAAAIQAAAAAAARBAQAAAAYBAAAAAD8BAAAAAIEB////AIMBAAAAAL8BEAAQAP8B +AAAIAAAAEPAEAAAAAAAAgGIAB/DkAwAABgadFne2AAAAAHs4ZSASAgAQAADAAwAAAQAAAAAA +AAAAAAAAAG4e8LgDAACdFne2AAAAAHs4ZSASAgAQ/4lQTkcNChoKAAAADUlIRFIAAAAJAAAA +CwgDAAAAmodXKQAAAwBQTFRFAAAA9/f3//////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +////////////////////////////////////////zx/2HQAAAAN0Uk5T//8A18oNQQAAAAFi +S0dEAIgFHUgAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAAuSURBVBhXbYxBCgAACMKs/z86 +XXQrwgmK6ju1sKFsy2JEgyQx5Pub0Hh7lE/YHh4kAI5SiYRqAAAAAElFTkSuQmCCAACeBAAA +RABkAO4AIwEAAAAAAAAAAAAAAAAAAAAAhwClAOgD6AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAA8ABPBmAAAAsgQK8AgAAAABBAAAAAoAALMAC/BCAAAAgQAAAAAAggAAAAAA +gwAAAAAAhAAAAAAABEEBAAAABgEAAAAAPwEAAAAAgQH///8AgwEAAAAAvwEQABAA/wEAAAgA +AAAQ8AQAAAAAAACAYgAH8OQDAAAGBp0Wd7YAAAAAezhlIBICABAAAMADAAABAAAAAAAAAAAA +AAAAbh7wuAMAAJ0Wd7YAAAAAezhlIBICABD/iVBORw0KGgoAAAANSUhEUgAAAAkAAAALCAMA +AACah1cpAAADAFBMVEUAAAD39/f///////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +///////////////////////////////////PH/YdAAAAA3RSTlP//wDXyg1BAAAAAWJLR0QA +iAUdSAAAAAxjbVBQSkNtcDA3MTIAAAADSABzvAAAAC5JREFUGFdtjEEKAAAIwqz/PzpddCvC +CYrqO7WwoWzLYkSDJDHk+5vQeHuUT9geHiQAjlKJhGoAAAAASUVORK5CYIIAAJ4EAABEAGQA +7gAjAQAAAAAAAAAAAAAAAAAAAACHAKUA6APoAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAADwAE8GYAAACyBArwCAAAAAEEAAAACgAAswAL8EIAAACBAAAAAACCAAAAAACDAAAA +AACEAAAAAAAEQQEAAAAGAQAAAAA/AQAAAACBAf///wCDAQAAAAC/ARAAEAD/AQAACAAAABDw +BAAAAAAAAIBiAAfw5AMAAAYGnRZ3tgAAAAB7OGUgEgIAEAAAwAMAAAEAAAAAAAAAAAAAAABu +HvC4AwAAnRZ3tgAAAAB7OGUgEgIAEP+JUE5HDQoaCgAAAA1JSERSAAAACQAAAAsIAwAAAJqH +VykAAAMAUExURQAAAPf39/////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +/////////////////////////////88f9h0AAAADdFJOU///ANfKDUEAAAABYktHRACIBR1I +AAAADGNtUFBKQ21wMDcxMgAAAANIAHO8AAAALklEQVQYV22MQQoAAAjCrP8/Ol10K8IJiuo7 +tbChbMtiRIMkMeT7m9B4e5RP2B4eJACOUomEagAAAABJRU5ErkJgggAAngQAAEQAZADuACMB +AAAAAAAAAAAAAAAAAAAAAIcApQDoA+gDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAPAATwZgAAALIECvAIAAAAAQQAAAAKAACzAAvwQgAAAIEAAAAAAIIAAAAAAIMAAAAAAIQA +AAAAAARBAQAAAAYBAAAAAD8BAAAAAIEB////AIMBAAAAAL8BEAAQAP8BAAAIAAAAEPAEAAAA +AAAAgGIAB/DkAwAABgadFne2AAAAAHs4ZSASAgAQAADAAwAAAQAAAAAAAAAAAAAAAG4e8LgD +AACdFne2AAAAAHs4ZSASAgAQ/4lQTkcNChoKAAAADUlIRFIAAAAJAAAACwgDAAAAmodXKQAA +AwBQTFRFAAAA9/f3//////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +////////////////////////zx/2HQAAAAN0Uk5T//8A18oNQQAAAAFiS0dEAIgFHUgAAAAM +Y21QUEpDbXAwNzEyAAAAA0gAc7wAAAAuSURBVBhXbYxBCgAACMKs/z86XXQrwgmK6ju1sKFs +y2JEgyQx5Pub0Hh7lE/YHh4kAI5SiYRqAAAAAElFTkSuQmCCAACeBAAARABkAO4AIwEAAAAA +AAAAAAAAAAAAAAAAhwClAOgD6AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8A +BPBmAAAAsgQK8AgAAAABBAAAAAoAALMAC/BCAAAAgQAAAAAAggAAAAAAgwAAAAAAhAAAAAAA +BEEBAAAABgEAAAAAPwEAAAAAgQH///8AgwEAAAAAvwEQABAA/wEAAAgAAAAQ8AQAAAAAAACA +YgAH8OQDAAAGBp0Wd7YAAAAAezhlIBICABAAAMADAAABAAAAAAAAAAAAAAAAbh7wuAMAAJ0W +d7YAAAAAezhlIBICABD/iVBORw0KGgoAAAANSUhEUgAAAAkAAAALCAMAAACah1cpAAADAFBM +VEUAAAD39/f///////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +///////////////////PH/YdAAAAA3RSTlP//wDXyg1BAAAAAWJLR0QAiAUdSAAAAAxjbVBQ +SkNtcDA3MTIAAAADSABzvAAAAC5JREFUGFdtjEEKAAAIwqz/PzpddCvCCYrqO7WwoWzLYkSD +JDHk+5vQeHuUT9geHiQAjlKJhGoAAAAASUVORK5CYIIAAJ4EAABEAGQA7gAjAQAAAAAAAAAA +AAAAAAAAAACHAKUA6APoAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwAE8GYA +AACyBArwCAAAAAEEAAAACgAAswAL8EIAAACBAAAAAACCAAAAAACDAAAAAACEAAAAAAAEQQEA +AAAGAQAAAAA/AQAAAACBAf///wCDAQAAAAC/ARAAEAD/AQAACAAAABDwBAAAAAAAAIBiAAfw +5AMAAAYGnRZ3tgAAAAB7OGUgEgIAEAAAwAMAAAEAAAAAAAAAAAAAAABuHvC4AwAAnRZ3tgAA +AAB7OGUgEgIAEP+JUE5HDQoaCgAAAA1JSERSAAAACQAAAAsIAwAAAJqHVykAAAMAUExURQAA +APf39/////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +/////////////88f9h0AAAADdFJOU///ANfKDUEAAAABYktHRACIBR1IAAAADGNtUFBKQ21w +MDcxMgAAAANIAHO8AAAALklEQVQYV22MQQoAAAjCrP8/Ol10K8IJiuo7tbChbMtiRIMkMeT7 +m9B4e5RP2B4eJACOUomEagAAAABJRU5ErkJgggAAngQAAEQAZADuACMBAAAAAAAAAAAAAAAA +AAAAAIcApQDoA+gDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAATwZgAAALIE +CvAIAAAAAQQAAAAKAACzAAvwQgAAAIEAAAAAAIIAAAAAAIMAAAAAAIQAAAAAAARBAQAAAAYB +AAAAAD8BAAAAAIEB////AIMBAAAAAL8BEAAQAP8BAAAIAAAAEPAEAAAAAAAAgGIAB/DkAwAA +BgadFne2AAAAAHs4ZSASAgAQAADAAwAAAQAAAAAAAAAAAAAAAG4e8LgDAACdFne2AAAAAHs4 +ZSASAgAQ/4lQTkcNChoKAAAADUlIRFIAAAAJAAAACwgDAAAAmodXKQAAAwBQTFRFAAAA9/f3 +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +////////zx/2HQAAAAN0Uk5T//8A18oNQQAAAAFiS0dEAIgFHUgAAAAMY21QUEpDbXAwNzEy +AAAAA0gAc7wAAAAuSURBVBhXbYxBCgAACMKs/z86XXQrwgmK6ju1sKFsy2JEgyQx5Pub0Hh7 +lE/YHh4kAI5SiYRqAAAAAElFTkSuQmCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAA7KUBAU0gCQQAAAgSvwAAAAAAADAAAAAAAAgAAAAVAAAOAENhb2xhbjgw +AAAAAAAAAAAAAAAAAAAAAAAACQQWAJxBAAAAAAAAAAAAAHIFAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA0BAAAAAAAA//8PAAsAAAAEAAAA//8PAA8AAAARAAAA//8PAAAAAAAAAAAAAAAAAAAA +AACIAAAAAACIFQAAAAAAAIgVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANgV +AAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADsFQAANAAAACAWAAAkAAAA +RBYAAIwAAAAAAAAAAAAAACYdAAAGAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAOUaAAAmAAAACxsAAAwAAAAXGwAACAAAAAMdAAACAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALCAAAGICAACOIgAAdAAAABEd +AAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +aRoAAHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQFgAAmQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAACIFQAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHxsAAB4A +AADjHAAAGAAAAMAVAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+xwAAAgAAAAAAAAAAAAAAAUdAAAMAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAIA2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAgACAAIAAgACAAIAAgACAAIAAgACAAQwBVAFIAUgBJAEMAVQBMAFUATQAgAFYA +SQBUAEEARQANAAgADQBSAGkAYwBoAGEAcgBkACAAQQBuAGQAZQByAHMAbwBuACAACwAxADIA +MwA0ACwAIABXAGUAcwB0ACAANgA3ACAAUwB0AHIAZQBlAHQALAAgAAsAQwBhAHIAbABpAHMA +bABlACwAIABNAEEAIAAwADEANwA0ADEALAAgAAsAKAAxADIAMwApAC0ANAA1ADYAIAA3ADgA +OQAwAC4ADQAIAAsAAQAgAEMAYQByAGUAZQByACAATwBiAGoAZQBjAHQAaQB2AGUADQANAEQA +ZQBzAGkAcgBlACAAYQAgAGMAaABhAGwAbABlAG4AZwBpAG4AZwAgAHAAbwBzAGkAdABpAG8A +bgAgAGkAbgAgAHQAaABlACAAYQByAGUAYQAgAG8AZgAgAFMAbwBmAHQAdwBhAHIAZQAgAGQA +ZQB2AGUAbABvAHAAbQBlAG4AdAAsACAAdwBoAGkAYwBoACAAdwBpAGwAbAAgAHUAdABpAGwA +aQB6AGUAIABtAHkAIABpAG4AdABlAHIAZABpAHMAYwBpAHAAbABpAG4AYQByAHkALAAgAHQA +ZQBjAGgAbgBpAGMAYQBsACwAIABhAG4AZAAgAHMAbwBmAHQAdwBhAHIAZQAgAGQAZQB2AGUA +bABvAHAAbQBlAG4AdAAgAGwAaQBmAGUAIABjAHkAYwBsAGUAIABzAGsAaQBsAGwAcwAgAGkA +bgAgAGEAIABwAHIAbwBkAHUAYwB0AGkAdgBlACwAIABlAG4AdABoAHUAcwBpAGEAcwB0AGkA +YwAgAGEAbgBkACAAaQBuACAAYQAgAHQAZQBhAG0ALQBvAHIAaQBlAG4AdABlAGQAIABlAG4A +dgBpAHIAbwBuAG0AZQBuAHQALgANAA0AAQAgAEUAZAB1AGMAYQB0AGkAbwBuAGEAbAAgAFMA +dQBtAG0AYQByAHkADQBQ8CAAQwBvAG0AcABsAGUAdABlAGQAIABNAGEAcwB0AGUAcgBzACAA +aQBuACAAQwBvAG0AcAB1AHQAZQByACAAYQBwAHAAbABpAGMAYQB0AGkAbwBuACAAKABNAC4A +QwAuAEEAKQAgAHcAaQB0AGgAIAA2ADMALgA3ADEAJQAgAA0AAQAgAFQAZQBjAGgAbgBpAGMA +YQBsACAASwBuAG8AdwBsAGUAZABnAGUAIABTAHUAbQBtAGEAcgB5AA0ACAANAAEAIAAgAEQA +ZQB0AGEAaQBsAGUAZAAgAEUAZAB1AGMAYQB0AGkAbwBuAGEAbAAgAEEAYwBhAGQAZQBtAGkA +YwAgAEMAcgBlAGQAZQBuAHQAaQBhAGwAcwANAEUAeABhAG0AaQBuAGEAdABpAG8AbgAHAEIA +bwBhAHIAZAAvAFUAbgBpAHYAZQByAHMAaQB0AHkABwBQAGEAcwBzAGkAbgBnACAAWQBlAGEA +cgAHAFAAZQByAGMAZQBuAHQAYQBnAGUABwAHAAgATQAuAEMALgBBACAABwAHACAAIAAgACAA +IAAgACAAIAAgACAAUwBlAG0AZQBzAHQAZQByACAAVgBJAAcAQwBhAHIAbABpAHMAbABlACAA +VQBuAGkAdgBlAHIAcwBpAHQAeQAHADIAMAAxADEABwA2ADMALgA3ADEABwAHACAAIAAgACAA +IAAgACAAIAAgACAAUwBlAG0AZQBzAHQAZQByACAAVgAHAEMAYQByAGwAaQBzAGwAZQAgAFUA +bgBpAHYAZQByAHMAaQB0AHkABwAyADAAMQAwAAcANgA3AC4AMQA3AAcABwAgACAAIAAgACAA +IAAgACAAIAAgAFMAZQBtAGUAcwB0AGUAcgAgAEkAVgAHAEMAYQByAGwAaQBzAGwAZQAgAFUA +bgBpAHYAZQByAHMAaQB0AHkABwAyADAAMQAwAAcANgAyAC4AOAAwAAcABwAgACAAIAAgACAA +IAAgACAAIAAgAFMAZQBtAGUAcwB0AGUAcgAgAEkASQBJAAcAQwBhAHIAbABpAHMAbABlACAA +VQBuAGkAdgBlAHIAcwBpAHQAeQAHADIAMAAxADAABwA2ADIALgAyADUABwAHACAAIAAgACAA +IAAgACAAIAAgACAAUwBlAG0AZQBzAHQAZQByACAASQBJAAcAQwBhAHIAbABpAHMAbABlACAA +VQBuAGkAdgBlAHIAcwBpAHQAeQAHADIAMAAwADkABwA2ADUALgA3ADUABwAHACAAIAAgACAA +IAAgACAAIAAgACAAUwBlAG0AZQBzAHQAZQByACAASQAHAEMAYQByAGwAaQBzAGwAZQAgAFUA +bgBpAHYAZQByAHMAaQB0AHkABwAyADAAMAA5AAcANgAzAC4AMwAzAAcABwAHAAcABwAHAAcA +BwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcAAQAgAFMAdQBiAGoAZQBjAHQAIAAgAEYA +YQBtAGkAbABpAGEAcgBpAHQAeQA6AA0AUPAgAEQAYQB0AGEAYgBhAHMAZQAgAE0AYQBuAGEA +ZwBlAG0AZQBuAHQAIABDAG8AbgBjAGUAcAB0AHMADQBQ8CAATwBiAGoAZQBjAHQAIABPAHIA +aQBlAG4AdABlAGQAIABQAHIAbwBnAHIAYQBtAG0AaQBuAGcAIABDAG8AbgBjAGUAcAB0AA0A +UPAgAFMAeQBzAHQAZQBtACAAQQBuAGEAbAB5AHMAaQBzACAAYQBuAGQAIABEAGUAcwBpAGcA +bgANAFDwIABzAG8AZgB0AHcAYQByAGUAIABFAG4AZwBpAG4AZQBlAHIAaQBuAGcAIAANAFDw +IABPAHAAZQByAGEAdABpAG4AZwAgAFMAeQBzAHQAZQBtACAAQwBvAG4AYwBlAHAAdAANAFDw +IABVAG4AaQB4ACAAUwBoAGUAbABsACAAUAByAG8AZwByAGEAbQBtAGkAbgBnAA0AAQAgAEEA +cgBlAGEAIABvAGYAIABJAG4AdABlAHIAZQBzAHQAOgANAFDwIABTAG8AZgB0AHcAYQByAGUA +IABkAGUAdgBlAGwAbwBwAG0AZQBuAHQAIAAgAHUAcwBpAG4AZwAgAEoAYQB2AGEALwAuAE4A +ZQB0ACAAdABlAGMAaABuAG8AbABvAGcAaQBlAHMADQBQ8CAATABlAGEAcgBuAGkAbgBnACAA +bgBlAHcAIAB0AGUAYwBoAG4AbwBsAG8AZwBpAGUAcwAuAA0AAQAgAFAAZQByAHMAbwBuAGEA +bAAgAEQAZQB0AGEAaQBsAHMADQBOAGEAbQBlADoAIAAgAAkACQBSAGkAYwBoAGEAcgBkACAA +QQBuAGQAZQByAHMAbwBuAA0AQwB1AHIAcgBlAG4AdAAgAEEAZABkAHIAZQBzAHMACQAxADIA +MwA0ACwAIABXAGUAcwB0ACAANgA3ACAAUwB0AHIAZQBlAHQALAAgAAsAQwBhAHIAbABpAHMA +bABlACwAIABNAEEAIAAwADEANwA0ADEALAAgAAsAKAAxADIAMwApAC0ANAA1ADYAIAA3ADgA +OQAwAC4ADQBEAGEAdABlACAAbwBmACAAQgBpAHIAdABoADoAIAAJADEAcwB0ACAAagB1AG4A +ZQANAEcAZQBuAGQAZQByADoAIAAJAAkATQBhAGwAZQAJAA0ADQABAA0ATABhAG4AZwB1AGEA +ZwBlAHMAIABLAG4AbwB3AG4AIAAHAEMALAAgAEMAKwArACwASgBBAFYAQQAsACAALgBOAEUA +VAAgADMALgA1ACwAIABBAFMAUAAuAE4ARQBUACAAMwAuADUALABWAEIAIAAyADAAMAA4ACwA +cAB5AHQAaABvAG4ABwAHAEQAQgBNAFMALwBSAEQAQgBNAFMAIAAHAE8AUgBBAEMATABFACwA +TQBTACAAQQBjAGMAZQBzAHMALAAgAFMAUQBMACwAIABQAG8AcwB0AGcAcgBlAHMAcwAgAFMA +UQBMAAcABwBXAGUAYgAgAFQAZQBjAGgAbgBvAGwAbwBnAHkABwBIAFQATQBMACwASgBBAFYA +QQAgAFMAYwByAGkAcAB0AAcABwBPAHAAZQByAGEAdABpAG4AZwAgAFMAeQBzAHQAZQBtAAcA +VwBpAG4AZABvAHcAcwAgACgAOQA4AC8AMgAwADAANwAvAFgAUAAgAC8AVgBJAFMAVABBACwA +NwApACwAdQBiAHUAbgB0AHUABwAHAE8AdABoAGUAcgAHAE4AZQB0AHcAbwByAGsAIABQAHIA +bwBnAHIAYQBtAG0AaQBuAGcAIABpAG4AIABKAGEAdgBhACwAIABVAG4AaQB4ACAAUwBoAGUA +bABsACAAUAByAG8AZwByAGEAbQBtAGkAbgBnAAcABwAgAA0ADQANAA0AAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAWCAAAOAgAADoIAAA8CAAAXAgAANgI +AADaCAAA3AgAAN4IAADgCAAAAgkAAAQJAADMCgAAzgoAANAKAADSCgAA+goAAPwKAAD+CgAA +EgsAAGALAABiCwAAbAsAAHwLAAB+CwAAgAsAALgLAAC6CwAAvAsAAL4LAADACwAAwgsAAPn5 +9Ovh2PTMv7bMANisn7aVjoeHf3h4eGu2YfQAVLZhAAAAABlVCAEDauANAAAwSlAAXkoEAE9K +BABRSgQAEj4qATUIAV5KBABPSgQAUUoEAAAZVQgBA2pACQAAMEpQAF5KBABPSgQAUUoEAAxe +SgQAT0oEAFFKBAAADzUIAV5KBABPSgQAUUoEAAxDShIAT0oCAFFKAgAADENKEgBPSgUAUUoF +AAATMEpQAD4qAV5KBABPSgQAUUoEABlVCAEDaqAEAAAwSlAAXkoEAE9KBABRSgQAEkNKEgA+ +KgE1CAFPSgIAUUoCAAAQMEpQAF5KBABPSgQAUUoEAAAZVQgBA2oAAAAAMEpQAF5KBABPSgQA +UUoEABcwSlAAQ0oUAD4qAV5KBABPSgQAUUoEABBDShQAXkoEAE9KBABRSgQAABNDShQANQgB +XkoEAE9KBABRSgQAEENKFABtSAAEc0gABG5IAAQACQNqAAAAAFUIAQxDShYAT0oCAFFKAgAg +wgsAABYMAAAuDAAAUAwAAGoMAACADAAAggwAAIQMAACGDAAAkgwAAKgMAADADAAA0AwAAOgM +AADyDAAA/gwAABQNAAAqDQAAOg0AAFINAABcDQAAaA0AAH4NAACWDQAApg0AAL4NAADIDQAA +1A0AAOoNAAAEDgAAFA4AACwOAAA2DgAAQg4AAFgOAABwDgAAgA4AAJgOAACiDgAArg4AAMQO +AADaDgAA6g4AAAIPAAAMDwAAGA8AABwPAAAeDwAAIA8AACIPAAAmDwAAKA8AACoPAAAsDwAA +MA8AADIPAAA0DwAANg8AADoPAAA8DwAAPg8AAEAPAABCDwAARA8AAEYPAAD27Ozs7ADn39/Y +2M/Y2NjY2M/Y2NjY2M/Y2MnY2M/Y2MnY2M/Y2MnY2M/Y2Mnf2NjYvdjY2N/Y2Njf2NjYALCn +AAAAAAAAAAAAABAwSlAAXkoEAE9KBABRSgQAABlVCAEDaoASAAAwSlAAXkoEAE9KBABRSgQA +FkNKEgA1CAFhShIAXAgBT0oGAFFKBgAAC1wIAU9KBgBRSgYAEENKFABeSgQAT0oEAFFKBAAA +DF5KBABPSgQAUUoEAAAPNQgBXkoEAE9KBABRSgQACQNqAAAAAFUIARNDShIANQgBXkoEAE9K +BABRSgQAEj4qATUIAV5KBABPSgQAUUoEAEBGDwAAbg8AAHIPAAB0DwAAdg8AALAPAACyDwAA +tA8AAPwPAAD+DwAAABAAADYQAAA4EAAAOhAAAGYQAABoEAAAahAAAJwQAACeEAAAoBAAAM4Q +AADQEAAA0hAAAPYQAAD4EAAA+hAAAGARAABiEQAAZBEAAJoRAACcEQAAnhEAAMARAADMEQAA +0hEAAPQRAAASEgAAFBIAAIwSAACqEgAArhIAALISAAC+EgAA0hIAANoSAADeEgAA4BIAAPLm +4dra4dra4dra4dra4dra4drazcS64dra4drarcS6pdqbpZaNpdqF2qXapQAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9IKgFeSgQAT0oEAFFKBAAQQ0oUAF5KBABPSgQAUUoE +AAAIT0oGAFFKBgAAE0NKFAA1CAFeSgQAT0oEAFFKBAAPNQgBXkoEAE9KBABRSgQAGVUIAQNq +wBsAADBKUABeSgQAT0oEAFFKBAASQ0oSAD4qATUIAU9KAgBRSgIAABAwSlAAXkoEAE9KBABR +SgQAABlVCAEDaiAXAAAwSlAAXkoEAE9KBABRSgQADF5KBABPSgQAUUoEAAAIT0oFAFFKBQAA +F0NKEgA1CAFeSgIAYUoSAE9KAgBRSgIAGkNKEgA+KgE1CAFeSgIAYUoSAE9KAgBRSgIALuAS +AADiEgAAAhMAAAYTAABqEwAAhBMAAM4TAADuEwAAEBQAADQUAAB+FAAAjBQAAPQUAAD+FAAA +8eri3erd193q3eLdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALXAgB +T0oGAFFKBgAIT0oGAFFKBgAAD15KBABcCAFPSgQAUUoEAAxeSgQAT0oEAFFKBAAAHFUIAQNq +YCAAADBKUABeSgQAPAgBT0oEAFFKBAANAAgAADgIAAA8CAAA2AgAAAIJAAAECQAAzAoAAM4K +AAD6CgAAfAsAALgLAAC8CwAAFgwAAC4MAABQDAAA9wAAAAAAAAAAAAAAAPIAAAAAAAAAAAAA +AADkAAAAAAAAAAAAAAAA1QAAAAAAAAAAAAAAAMYAAAAAAAAAAAAAAAC3AAAAAAAAAAAAAAAA +sgAAAAAAAAAAAAAAAK0AAAAAAAAAAAAAAACoAAAAAAAAAAAAAAAAowAAAAAAAAAAAAAAAJ4A +AAAAAAAAAAAAAACZAAAAAAAAAAAAAAAAiwAAAAAAAAAAAAAAAH0AAAAAAAAAAAAAAAAAAAAA +AAAAAAANAAAWJAFJZgEAAAASZGgBAQADJAFhJAFHJAAADQAAFiQBSWYBAAAAEmRoAQEAAyQB +YSQBRyQAAAQAABJkaAEBAAAEAAASZGgBAQAABAAAEmRoAQEAAAQAABJkaAEBAAAEAAASZGgB +AQAABAAAEmRoAQEAAA5aAAMkA2EkA16EAABdhNACYIQAABOkAAAUpAAAAA5aAAMkA2EkA16E +AABdhNACYIQAABOkAAAUpAAAAA5aAAMkA2EkA16EAABdhKAFYIQAABOkAAAUpAAADlYAAyQB +YSQBDcYIAAJwCEALAAATpAAAFKQAAAAEXgADJANhJAMAB14AXoSAFl2EAABghNACAA5QDAAA +agwAAIAMAACCDAAAkgwAAPEAAAAAAAAAAAAAAADjAAAAAAAAAAAAAAAAZgAAAAAAAAAAAAAA +AFsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAKAAAWJAFJZgEAAAASZGgBAQBHJAAAfAAAFiQBFyQBSWYBAAAA +CNZcAARi/8ILeBlyH8IkgAAAAAQBAQAEAQEABAEBAAAAAACAAAAABAEBAAQBAQAEAQEAAAAA +AIAAAAAEAQEABAEBAAQBAQAAAAAAgAAAAAQBAQAEAQEABAEBAAQBAQAJ1ggAAQABAAEAARLW +KAAAAP/l5eUAAAAAAAD/5eXlAAAAAAAA/+Xl5QAAAAAAAP/l5eUAAABw1igAAAD/5eXlAAAA +AAAA/+Xl5QAAAAAAAP/l5eUAAAAAAAD/5eXlAAAANNYGAAEBAwAANNYGAAECA2wANNYGAAEE +AwAANNYGAAEIA2wAAzQAZjQAAA0AABYkAUlmAQAAABJkaAEBAAMkAWEkAUckAAANAAAWJAFJ +ZgEAAAASZGgBAQADJAFhJAFHJAAABJIMAACUDAAAwAwAAOgMAADyDAAA/gwAAMQAAAAAAAAA +AAAAAAC5AAAAAAAAAAAAAAAArgAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAACSAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQAAFiQBSWYB +AAAAEmRoAQEAAyQBYSQBRyQAAA0AABYkAUlmAQAAABJkaAEBAAMkAWEkAUckAAAKAAAWJAFJ +ZgEAAAASZGgBAQBHJAAACgAAFiQBSWYBAAAAEmRoAQEARyQAADoAABYkARckAUlmAQAAAAjW +GgABYv/CJIAAAAAEAQEABAEBAAQBAQAEAQEACdYCAAAS1goAAAD/AAAA/wAAcNYKAAAA/wAA +AP8AADTWBgABAQMAADTWBgABAgNsADTWBgABBAMAADTWBgABCANsAAM0AGY0AAAF/gwAAAAN +AAAqDQAAUg0AAFwNAABoDQAAggAAAAAAAAAAAAAAAHcAAAAAAAAAAAAAAABsAAAAAAAAAAAA +AAAAXgAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAAAWJAFJ +ZgEAAAASZGgBAQADJAFhJAFHJAAADQAAFiQBSWYBAAAAEmRoAQEAAyQBYSQBRyQAAAoAABYk +AUlmAQAAABJkaAEBAEckAAAKAAAWJAFJZgEAAAASZGgBAQBHJAAAfAAAFiQBFyQBSWYBAAAA +CNZcAARi/8IL0hlyH8IkgAAAAAQBAQAEAQEABAEBAAAAAACAAAAABAEBAAQBAQAEAQEAAAAA +AIAAAAAEAQEABAEBAAQBAQAAAAAAgAAAAAQBAQAEAQEABAEBAAQBAQAJ1ggAAAAAAAAAABLW +KAAAAP8AAAD/AAAAAAD/AAAA/wAAAAAA/wAAAP8AAAAAAP8AAAD/AABw1igAAAD/AAAA/wAA +AAAA/wAAAP8AAAAAAP8AAAD/AAAAAAD/AAAA/wAANNYGAAEBAwAANNYGAAECA2wANNYGAAEE +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 +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSAG8AbwB0ACAARQBuAHQAcgB5AAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgAFAP////////// +AQAAAAYJAgAAAAAAwAAAAAAAAEYAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAACAAgAAAAAAAAEA +QwBvAG0AcABPAGIAagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAASAAIAAgAAAAUAAAD/////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAGoAAAAAAAAAAQBPAGwAZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAgD/////AwAAAP////8AAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAFAAAAAAAAAAxAFQAYQBiAGwAZQAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgACAAQA +AAD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAACIwAA +AAAAAEQAYQB0AGEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAKAAIA////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAFgAAAP4kAAAAAAAABQBTAHUAbQBtAGEAcgB5AEkAbgBmAG8AcgBtAGEA +dABpAG8AbgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAgAGAAAACAAAAP////8AAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAHAEAAAAAAABXAG8AcgBkAEQA +bwBjAHUAbQBlAG4AdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +GgACAAcAAAD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkA +AACcQQAAAAAAAE8AYgBqAGUAYwB0AFAAbwBvAGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAWAAEA////////////////AAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAA/v///wAAAAAAAAAABQBEAG8AYwB1AG0AZQBuAHQAUwB1AG0A +bQBhAHIAeQBJAG4AZgBvAHIAbQBhAHQAaQBvAG4AAAAAAAAAAAAAADgAAgD///////////// +//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAdAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAP///////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAP7///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////AAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///// +//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+////AAAAAAAA +AAA= +--------------010903010402010104090709-- diff --git a/addons/hr_recruitment/test/test_hr_recruitment.yml b/addons/hr_recruitment/test/test_hr_recruitment.yml deleted file mode 100644 index b797353bde2..00000000000 --- a/addons/hr_recruitment/test/test_hr_recruitment.yml +++ /dev/null @@ -1,139 +0,0 @@ -- - In order to test hr_recruitment module for OpenERP, I will create applicants form, Manages job positions and the recruitment process. -- - - I create a department. -- - !record {model: hr.department, id: hr_department_rd0}: - manager_id: base.user_root - name: 'R & D ' - -- - I create new Job Position. -- - !record {model: hr.job, id: hr_job_jea0}: - department_id: 'hr_department_rd0' - description: 'Position of Jr. Application Engineer' - expected_employees: 5 - name: 'JAE ' -- - I create a recruitment stage "Initial Jobs Demand". -- - !record {model: hr.recruitment.stage, id: hr_recrutiment_stage_first0}: - name: 'Initial Jobs Demand' - sequence: 1 -- - I create an applicant. -- - !record {model: hr.applicant, id: hr_applicant_fresher0}: - availability: 0.0 - department_id: hr.dep_it - name: Fresher - partner_address_id: base.res_partner_address_tang - partner_id: base.res_partner_asus - partner_name: Marion Jones - partner_phone: '1111112223' - response: 0.0 - job_id: hr.job_jr_developers - salary_expected: 0.0 - salary_proposed: 0.0 - stage_id: hr_recrutiment_stage_first0 - type_id: hr_recruitment.degree_licenced - -- - I check that applicant is on "draft" state. -- - !assert {model: hr.applicant, id: hr_applicant_fresher0}: - - state == 'draft' - -- - I change the state by click on "In Progress" button. -- - !python {model: hr.applicant}: | - self.case_open(cr, uid, [ref("hr_applicant_fresher0")], {"active_ids": [ref("hr_recruitment.menu_crm_case_categ0_act_job")], - }) -- - I change the stages by clicking on stage next and stage previous buttons. -- - !python {model: hr.applicant}: | - self.stage_next(cr, uid, [ref('hr_applicant_fresher0')], None) - self.stage_previous(cr, uid, [ref('hr_applicant_fresher0')], None) -- - I create a new case category. -- - !record {model: crm.case.categ, id: crm_case_categ_employee0}: - name: 'Employee' - -- - I schedule a phonecall for this applicant by click on "Schedule a Phone Call" button. -- - !record {model: hr.recruitment.job2phonecall, id: hr_recruitment_forinterview0}: - user_id: base.user_root - deadline: !eval time.strftime('%Y-%m-%d 11:51:00') - note: 'For interview.' - category_id: 'crm_case_categ_employee0' - -- - I click on "Schedule phonecall" button of this wizard. -- - !python {model: hr.recruitment.job2phonecall}: | - self.make_phonecall(cr, uid, [ref('hr_recruitment_forinterview0')], {'active_ids': [ref('hr_applicant_fresher0')]}) - -- - I schedule meeting for interview of this applicant by click on "Schedule Meeting" button. -- - !python {model: hr.applicant}: | - self.action_makeMeeting(cr, uid, [ref('hr_recruitment_forinterview0')]) -- - I create an entry for the meeting with the applicant. -- - !record {model: crm.meeting, id: crm_meeting_fresher0}: - alarm_id: base_calendar.alarm1 - count: 0.0 - date: !eval "(datetime.now() + timedelta(1)).strftime('%Y-%m-%d 00:00:00')" - date_deadline: !eval "(datetime.now() + timedelta(1)).strftime('%Y-%m-%d 08:00:00')" - day: 0.0 - duration: 8.0 - name: Fresher - opportunity_id: crm.crm_case_construstazunits0 - partner_address_id: base.res_partner_address_tang - partner_id: base.res_partner_asus - recurrent_uid: 0.0 - rrule_type: none - state: open - user_id: base.user_root -- - I print the survery filled up by the applicant. -- - !python {model: hr.applicant}: | - self.action_print_survey(cr, uid, [ref('hr_applicant_fresher0')], None) -- - I assign the position to the applicant and its relevant department. -- - !python {model: hr.applicant}: | - res = self.onchange_job(cr, uid, [ref('hr_applicant_fresher0')], ref('hr.job_jr_developers'), None) - values = dict([('job_id', ref('hr.job_jr_developers'))] + res['value'].items()) - res1 = self.onchange_department_id(cr, uid, [ref('hr_applicant_fresher0')], ref('hr.dep_it'), None) - values.update(dict([('department_id', ref('hr.dep_it'))] + res1['value'].items())) - self.write(cr, uid, [ref('hr_applicant_fresher0')], values, None) -- - On a successful meeting with the applicant, I hired employee by click on "Hired" button. -- - !python {model: hired.employee}: | - self.case_close(cr, uid, [], context={'active_ids': [ref('hr_applicant_fresher0')]}) -- - I check that applicant state is "Hired". -- - !assert {model: hr.applicant, id: hr_applicant_fresher0}: - - state == 'done' -- - I create partner for the hired applicant for accounting purpose. -- - !record {model: hr.recruitment.partner.create, id: hr_recruitment_partner_create0}: - close: False -- - I click on Create Partner button to create a partner for applicant. -- - !python {model: hr.recruitment.partner.create}: | - self.make_order(cr, uid, [ref('hr_recruitment_partner_create0')], context={'active_ids': [ref('hr_applicant_fresher0')]}) - diff --git a/addons/hr_recruitment/wizard/hr_recruitment_phonecall.py b/addons/hr_recruitment/wizard/hr_recruitment_phonecall.py index cd9cbea52f7..0f7d30b215a 100644 --- a/addons/hr_recruitment/wizard/hr_recruitment_phonecall.py +++ b/addons/hr_recruitment/wizard/hr_recruitment_phonecall.py @@ -88,7 +88,7 @@ class job2phonecall(osv.osv_memory): id2 = data_obj.browse(cr, uid, id2, context=context).res_id if id3: id3 = data_obj.browse(cr, uid, id3, context=context).res_id - + new_phonecall_id = [] for job in job_case_obj.browse(cr, uid, context.get('active_ids', []), context=context): #TODO: Take other info from job new_phonecall_id = phonecall_case_obj.create(cr, uid, { From e27eeae8506e9c6b4baa4c3e6388f798d5472c10 Mon Sep 17 00:00:00 2001 From: "Hemendra Paregi (Open ERP)" Date: Tue, 22 Nov 2011 12:40:20 +0530 Subject: [PATCH 14/66] [IMP]project_gtd: clean yml file bzr revid: hpa@tinyerp.com-20111122071020-0uwauqbta5k6pigu --- addons/project_gtd/__openerp__.py | 3 ++- addons/project_gtd/test/timebox.yml | 42 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 addons/project_gtd/test/timebox.yml diff --git a/addons/project_gtd/__openerp__.py b/addons/project_gtd/__openerp__.py index 761b2b44708..42ac8513f37 100644 --- a/addons/project_gtd/__openerp__.py +++ b/addons/project_gtd/__openerp__.py @@ -57,7 +57,8 @@ performing those tasks. ], 'demo_xml': ['project_gtd_demo.xml'], 'test':[ - 'test/gtd_test.yml' + #'test/gtd_test.yml', + 'test/timebox.yml' ], 'installable': True, 'active': False, diff --git a/addons/project_gtd/test/timebox.yml b/addons/project_gtd/test/timebox.yml new file mode 100644 index 00000000000..7379f5857cf --- /dev/null +++ b/addons/project_gtd/test/timebox.yml @@ -0,0 +1,42 @@ +- + In order to set Daily tasks into Weekly Timebox, I create plan for that +- + !record {model: project.timebox.fill.plan, id: plan_id}: + task_ids: [project.project_task_10] + timebox_id: timebox_daily + timebox_to_id: timebox_weekly +- + I run plan to set Daily tasks into Weekly Timebox +- + !python {model: project.timebox.fill.plan}: | + self.process(cr, uid, [ref("plan_id")]) +- + I check Weekly Timebox of task after set Timebox +- + !assert {model: project.task, id: project.project_task_10, string: Task should be set to weekly timebox}: + - timebox_id.id == ref("timebox_weekly") +- + I Empty the Daily Timebox +- + !python {model: project.timebox.empty}: | + self._empty(cr, uid, {"active_model": "project.gtd.timebox", + "active_ids":[ref("timebox_daily")], + "active_id": ref("timebox_daily"), + }) +- + I check task 'Develop time management module' is no more in Daily Timebox +- + !assert {model: project.task, id: project.project_task_10 , string: Task is not in Daily Timebox}: + - timebox_id.id != ref("timebox_daily") +- + I set Previous Timebox on task +- + !python {model: project.task}: | + self.prev_timebox(cr, uid, [ref("project.project_task_10")], + {'active_ids': [ref("project.project_task_1")],}) +- + I set Next Timebox on task +- + !python {model: project.task}: | + self.next_timebox(cr, uid, [ref("project.project_task_10")], + {'active_ids': [ref("project.project_task_1")],}) From 4b072366b2d0b1be4bb6fb429a19105e057295ed Mon Sep 17 00:00:00 2001 From: "Hemendra Paregi (Open ERP)" Date: Mon, 28 Nov 2011 10:50:04 +0530 Subject: [PATCH 15/66] [IMP]project_gtd: improvement in yml bzr revid: hpa@tinyerp.com-20111128052004-cv0w7uty6d99cehh --- addons/project_gtd/__openerp__.py | 3 +- addons/project_gtd/test/gtd_test.yml | 78 ------------------- .../test/{timebox.yml => task_timebox.yml} | 0 3 files changed, 1 insertion(+), 80 deletions(-) delete mode 100644 addons/project_gtd/test/gtd_test.yml rename addons/project_gtd/test/{timebox.yml => task_timebox.yml} (100%) diff --git a/addons/project_gtd/__openerp__.py b/addons/project_gtd/__openerp__.py index 42ac8513f37..82e3f4fcb39 100644 --- a/addons/project_gtd/__openerp__.py +++ b/addons/project_gtd/__openerp__.py @@ -57,8 +57,7 @@ performing those tasks. ], 'demo_xml': ['project_gtd_demo.xml'], 'test':[ - #'test/gtd_test.yml', - 'test/timebox.yml' + 'test/task_timebox.yml' ], 'installable': True, 'active': False, diff --git a/addons/project_gtd/test/gtd_test.yml b/addons/project_gtd/test/gtd_test.yml deleted file mode 100644 index 0583bc7e8e0..00000000000 --- a/addons/project_gtd/test/gtd_test.yml +++ /dev/null @@ -1,78 +0,0 @@ -- - Create a task 'Develop time management module' with weekly timebox -- - !record {model: project.task, id: project_task_developtimemanagementmodule0}: - name: Develop time management module - planned_hours: 15.0 - project_id: project.project_project_22 - remaining_hours: 15.0 - state: draft - timebox_id: project_gtd.timebox_weekly - - -- - Open the task -- - !python {model: project.task}: | - self.do_open(cr, uid, [ref("project_task_developtimemanagementmodule0")], {"lang": - "en_US", "project_id": False, "tz": False, "active_model": "ir.ui.menu", - "department_id": False, "section_id": False, "search_default_project_id": - False, "search_default_user_id": 1, "search_default_current": 1, "active_ids": - [ref("project.menu_action_view_task")], "active_id": ref("project.menu_action_view_task"), - }) - -- - Create time box for next week -- - !record {model: project.gtd.timebox, id: project_gtd_timebox_nextweek0}: - name: Next Week - sequence: 0.0 - -- - Create time box for tomorrow -- - !record {model: project.gtd.timebox, id: project_gtd_timebox_tomorrow1}: - name: Tomorrow - sequence: 0.0 - -- - Planify the task from weekly timebox to tomorrow timebox -- - !record {model: project.timebox.fill.plan, id: project_timebox_fill_plan_0}: - task_ids: - - project_task_developtimemanagementmodule0 - timebox_id: project_gtd.timebox_weekly - timebox_to_id: project_gtd_timebox_tomorrow1 - - -- - Set the task to tomorrow timebox -- - !python {model: project.timebox.fill.plan}: | - self.process(cr, uid, [ref("project_timebox_fill_plan_0")], {"lang": "en_US", - "project_id": False, "tz": False, "active_model": "project.gtd.timebox", - "department_id": False, "section_id": False, "record_id": 1, "active_ids": - [ref("project_gtd.timebox_daily")], "active_id": ref("project_gtd.timebox_daily"), - }) - -- - Check if task set to tomorrow timebox -- - !assert {model: project.task, id: project_task_developtimemanagementmodule0, string: Task set to tomorrow timebox}: - - timebox_id.id == ref("project_gtd_timebox_tomorrow1") - -- - Empty Timebox for tomorrow -- - !python {model: project.timebox.empty}: | - self._empty(cr, uid, {"lang": "en_US", - "project_id": False, "tz": False, "active_model": "project.gtd.timebox", - "department_id": False, "section_id": False, "record_id": 1, "active_ids": - [ref("project_gtd_timebox_tomorrow1")], "active_id": ref("project_gtd_timebox_tomorrow1"), - }) - -- - Check task 'Develop time management module' is no more in tomorrow timebox -- - !assert {model: project.task, id: project_task_developtimemanagementmodule0, string: Task is not in tomorrow timebox}: - - timebox_id.id != ref("project_gtd_timebox_tomorrow1") diff --git a/addons/project_gtd/test/timebox.yml b/addons/project_gtd/test/task_timebox.yml similarity index 100% rename from addons/project_gtd/test/timebox.yml rename to addons/project_gtd/test/task_timebox.yml From 14dd6ec79008c48eb61c8eb15c30d803ef07d757 Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Mon, 28 Nov 2011 11:39:21 +0530 Subject: [PATCH 16/66] [FIX] hr_recruitment: remove non-exits fields in demo file bzr revid: hmo@tinyerp.com-20111128060921-4v61dzokconpnzl0 --- addons/hr_recruitment/hr_recruitment_demo.xml | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/addons/hr_recruitment/hr_recruitment_demo.xml b/addons/hr_recruitment/hr_recruitment_demo.xml index 0fc2c94f034..f3790f3a43f 100644 --- a/addons/hr_recruitment/hr_recruitment_demo.xml +++ b/addons/hr_recruitment/hr_recruitment_demo.xml @@ -4,22 +4,17 @@ - - - - - @@ -33,44 +28,32 @@ - - - - - - - - - - - - @@ -78,36 +61,28 @@ - - - - - - - - @@ -121,14 +96,10 @@ - - - - @@ -141,14 +112,10 @@ - - - - @@ -157,18 +124,14 @@ - - - - From c7363ab6a2fe17b2df3486ec251d16f5a628d607 Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Mon, 28 Nov 2011 11:43:07 +0530 Subject: [PATCH 17/66] [IMP]purchase_requisition: Improve the test case's statements bzr revid: dbr@tinyerp.com-20111128061307-8c7452lyvsin0qcn --- .../test/process/cancel_purchase_requisition.yml | 14 ++++++++++---- .../test/process/purchase_requisition.yml | 9 +++------ .../process/purchase_requisition_exclusive.yml | 12 ++++++++---- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/addons/purchase_requisition/test/process/cancel_purchase_requisition.yml b/addons/purchase_requisition/test/process/cancel_purchase_requisition.yml index eeae4689fbc..b065dfcff08 100644 --- a/addons/purchase_requisition/test/process/cancel_purchase_requisition.yml +++ b/addons/purchase_requisition/test/process/cancel_purchase_requisition.yml @@ -1,7 +1,7 @@ - - In order to test the cancel purchase requisition order. + In order to test the cancel flow of purchase requisition order. - - I try to cancel purchase requisition order. + I cancel the "New" purchase requisition order. - !python {model: purchase.requisition}: | self.tender_cancel(cr, uid, [ref("order_purchase_requisition1")]) @@ -10,6 +10,11 @@ - !assert {model: purchase.requisition, id: order_purchase_requisition1}: - state == 'cancel' +- + I reset the state of requisition as "New". +- + !python {model: purchase.requisition}: | + self.tender_reset(cr, uid, ref('order_purchase_requisition1')) - I change state of requisition in "In progress". - @@ -51,7 +56,7 @@ !assert {model: purchase.requisition, id: order_purchase_requisition1}: - state == 'done' - - I try to cancel 'Done' purchase requisition order. + I try to cancel "Done" purchase requisition order. - !python {model: purchase.requisition}: | self.tender_cancel(cr, uid, [ref("order_purchase_requisition1")]) @@ -64,4 +69,5 @@ I reset the state of requisition as "New". - !python {model: purchase.requisition}: | - self.tender_reset(cr, uid, ref('order_purchase_requisition1')) + self.tender_reset(cr, uid, ref('order_purchase_requisition1')) + diff --git a/addons/purchase_requisition/test/process/purchase_requisition.yml b/addons/purchase_requisition/test/process/purchase_requisition.yml index 3be7e2a9ea9..d1c6fe8eb84 100644 --- a/addons/purchase_requisition/test/process/purchase_requisition.yml +++ b/addons/purchase_requisition/test/process/purchase_requisition.yml @@ -1,18 +1,15 @@ - - In order to test the purchase requisition module, I have to checked a boolean field 'purchase requisition' in product, - If I checked it then it's requisition will be create. + In order to test the purchase requisition module, I have to checked product's boolean field 'purchase requisition'. - I start by Checking the product, Product must have requisition field checked. - and Product supply method is buy and the procure method is make to order. - !record {model: product.product, id: product.product_product_hdd3}: - supply_method: 'buy' purchase_requisition: True - - I create the procurement order for the product and after run that procurement for create purchase requisition. + I create the product's procurement order and run that procurement. + After Run the procurement I check created purchase requisition [Tender]. - !python {model: product.product}: | - import time import netsvc mk_proc = self.pool.get('make.procurement') proc_order = self.pool.get('procurement.order') diff --git a/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml b/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml index 8a9116de0d3..e5f7f61a5fd 100644 --- a/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml +++ b/addons/purchase_requisition/test/process/purchase_requisition_exclusive.yml @@ -1,17 +1,21 @@ - - In order to test the exclusive type requisition, I have to create two differ purchase order in one requisition [Tender] + In order to test the exclusive type requisition, I have to create two differ purchase order of one requisition [Tender] - - I start by Checking the product, Product must have requisition field checked. + I select purchase requisition of '[CPU1] Processor AMD Athlon XP 1800+' and '[CPU3] Processor AMD Athlon XP 2200+'. + So, those products must have requisition field checked. +- + I start by Checking requisition field for '[CPU1] Processor AMD Athlon XP 1800+' product. - !record {model: product.product, id: product.product_product_cpu1}: purchase_requisition: True - - Checking requisition field for another product. + Checked requisition field for '[CPU3] Processor AMD Athlon XP 2200+' product. - !record {model: product.product, id: product.product_product_cpu3}: purchase_requisition: True - - Now check that purchase order's product must have requisition field checked. + I search the purchase orders which have exclusive purchase requisition 'TE00001' and confirm any one of them. + Then check the remaining purchase orders goes in to cancel state. - !python {model: purchase.order}: | import netsvc From 3cba14171c02bdf818ce2b02be2049dbd509fe0e Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Mon, 28 Nov 2011 11:52:47 +0530 Subject: [PATCH 18/66] [IMP] hr_recruitment: improve yml test process to check attachment in email after getting bzr revid: hmo@tinyerp.com-20111128062247-ztxmc9zdrdzy57yp --- addons/hr_recruitment/test/recruitment_process.yml | 8 +++++--- addons/hr_recruitment/test/resume.eml | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/addons/hr_recruitment/test/recruitment_process.yml b/addons/hr_recruitment/test/recruitment_process.yml index 64e8ab687a8..33232ab0f2f 100644 --- a/addons/hr_recruitment/test/recruitment_process.yml +++ b/addons/hr_recruitment/test/recruitment_process.yml @@ -15,8 +15,10 @@ applicant_ids = self.search(cr, uid, [('email_from','=', 'Mr. Richard Anderson ')]) assert applicant_ids, "Applicant is not created after getting the mail" applicant = self.browse(cr, uid, applicant_ids[0], context=context) - assert applicant.name == "Application for the post of Jr.application Programmer", "Subject does not match" + resume_ids = self.pool.get('ir.attachment').search(cr, uid, [('datas_fname','=','resume.doc'),('res_model','=',self._name),('res_id','=',applicant.id)]) + assert applicant.name == "Application for the post of Jr.application Programmer.", "Subject does not match" assert applicant.state == "draft" + assert len(resume_ids), "Resume does not attached." - I assign the Job position to the applicant - @@ -54,7 +56,7 @@ !python {model: hr.applicant}: | self.action_print_survey(cr, uid, [ref('hr_case_programmer')]) - - On a successful meeting with the applicant, I hired employee. + On a successful interview with the applicant, I hired employee. - !python {model: hr.applicant}: | self.case_close(cr, uid, [ref('hr_case_programmer')]) @@ -62,4 +64,4 @@ I check that applicant is "Hired". - !assert {model: hr.applicant, id: hr_case_programmer}: - - state == 'done' \ No newline at end of file + - state == 'done' diff --git a/addons/hr_recruitment/test/resume.eml b/addons/hr_recruitment/test/resume.eml index 9529873a49c..00cc5620563 100644 --- a/addons/hr_recruitment/test/resume.eml +++ b/addons/hr_recruitment/test/resume.eml @@ -24,11 +24,11 @@ X-YMail-OSG: 09Al2uQVM1n5JcQepgua6wQsww7jiatAHXaSsMjP5Qvk9Ba LLM1_BE.EOvXdW38ZC_hHcrM4xYaYSR7c0WaOQsR8EZeXk_Vhio7HHUrdxZl 1oZz7YWK9Q04M023JJoM4v6IrThy3BNepluEFFcavkyOnCw-- X-Yahoo-SMTP: oNtzSBqswBAqJIGYOgyGesyleENrhUEtEgBkQ053 -Received: from [192.168.1.30] (jagdish.n_panchal@180.211.100.2 with plain) +Received: from [192.168.1.30] (test@180.211.100.2 with plain) by smtp205.mail.ne1.yahoo.com with SMTP; 18 Nov 2011 01:26:47 -0800 PST Message-ID: <4EC624C7.6020000@yahoo.in> Date: Fri, 18 Nov 2011 14:56:31 +0530 -From: Richard Anderson +From: Mr. Richard Anderson User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110424 Thunderbird/3.1.10 MIME-Version: 1.0 To: hr@mycompany.com From b281d832197aaa73edc6ffd986c5a81ef723d6fa Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Mon, 28 Nov 2011 11:54:22 +0530 Subject: [PATCH 19/66] [IMP,REMOVE]purchase_requisition: Remove onchange_events.yml Improve the requisition2request_quotation.yml and __openerp__.py bzr revid: dbr@tinyerp.com-20111128062422-1l7jopbjkwajc3dc --- addons/purchase_requisition/__openerp__.py | 1 - .../test/ui/onchange_events.yml | 28 ------------------- .../test/ui/requisiton2request_quotation.yml | 6 ++-- 3 files changed, 3 insertions(+), 32 deletions(-) delete mode 100644 addons/purchase_requisition/test/ui/onchange_events.yml diff --git a/addons/purchase_requisition/__openerp__.py b/addons/purchase_requisition/__openerp__.py index 426e8a770fc..67c916aefae 100644 --- a/addons/purchase_requisition/__openerp__.py +++ b/addons/purchase_requisition/__openerp__.py @@ -48,7 +48,6 @@ This new object will regroup and will allow you to easily keep track and order a 'test/process/purchase_requisition_exclusive.yml', 'test/ui/requisiton2request_quotation.yml', 'test/process/cancel_purchase_requisition.yml', - 'test/ui/onchange_events.yml', 'test/ui/purchase_requisition_report.yml', 'test/ui/delete_requisition.yml', ], diff --git a/addons/purchase_requisition/test/ui/onchange_events.yml b/addons/purchase_requisition/test/ui/onchange_events.yml deleted file mode 100644 index 901c50ca1c9..00000000000 --- a/addons/purchase_requisition/test/ui/onchange_events.yml +++ /dev/null @@ -1,28 +0,0 @@ -- - In order to test the onchange events of purchase requisition. -- - I call onchange event to change the product of purchase requisition line. -- - !python {model: purchase.requisition.line}: | - self.onchange_product_id(cr, uid, [ref('order_purchase_requisition1')],ref('product.product_product_hdd2'), ref('product.product_uom_unit')) -- - I change state of requisition in "In progress". -- - !python {model: purchase.requisition}: | - self.tender_in_progress(cr, uid, ref('order_purchase_requisition1')) -- - I change state of requisition as "done". -- - !python {model: purchase.requisition}: | - self.tender_done(cr, uid, ref('order_purchase_requisition1')) -- - I reset the state of requisition as "New". -- - !python {model: purchase.requisition}: | - self.tender_reset(cr, uid, ref('order_purchase_requisition1')) -- - I call onchange event to change the partner of purchase requisition. -- - !python {model: purchase.requisition.partner}: | - self.onchange_partner_id(cr, uid, ref('order_purchase_requisition1'), ref('base.res_partner_desertic_hispafuentes')) - diff --git a/addons/purchase_requisition/test/ui/requisiton2request_quotation.yml b/addons/purchase_requisition/test/ui/requisiton2request_quotation.yml index 6c0ce5eee0a..722ab6df591 100644 --- a/addons/purchase_requisition/test/ui/requisiton2request_quotation.yml +++ b/addons/purchase_requisition/test/ui/requisiton2request_quotation.yml @@ -5,13 +5,13 @@ partner_address_id: base.res_partner_address_3000 partner_id: base.res_partner_desertic_hispafuentes - - I click on 'Create Quotation' for creating PO. + I click on 'Create Quotation' for creating a Quatation. - !python {model: purchase.requisition.partner}: | self.create_order(cr, uid, [ref("purchase_requisition_partner_0")], {"active_model": "purchase.requisition", "active_ids": [ref("order_purchase_requisition1")],"active_id": ref("order_purchase_requisition1"), }) - - I check that the purchase order is created. + I check that the purchase order created. - !python {model: purchase.order}: | purchase_ids= self.search(cr, uid, [('requisition_id','=',ref("order_purchase_requisition1"))]) @@ -20,4 +20,4 @@ assert rfq.state == 'draft',"Purchase Order should be in draft state" assert rfq.partner_address_id.id == ref('base.res_partner_address_3000'),"Purchase Order Partner address is not correspond" assert rfq.partner_id.id == ref('base.res_partner_desertic_hispafuentes'),"Purchase Order Partner is not correspond" - + From 9c582e04e7b00d0f022f853e6228df2c642e4b7f Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Mon, 28 Nov 2011 12:03:18 +0530 Subject: [PATCH 20/66] [REF] hr_recruitment: refector code of case_close_with_rmp of hr_recruitment bzr revid: hmo@tinyerp.com-20111128063318-02c90onrf005yo9t --- addons/hr_recruitment/hr_recruitment.py | 47 +++++++------------ .../test/recruitment_process.yml | 2 +- 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py index 931600fef9f..60657e9ff85 100644 --- a/addons/hr_recruitment/hr_recruitment.py +++ b/addons/hr_recruitment/hr_recruitment.py @@ -403,14 +403,6 @@ class hr_applicant(crm.crm_case, osv.osv): return res def case_close(self, cr, uid, ids, *args): - """ - @param self: The object pointer - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param ids: List of case's Ids - @param *args: Give Tuple Value - """ - employee_obj = self.pool.get('hr.employee') res = super(hr_applicant, self).case_close(cr, uid, ids, *args) for (id, name) in self.name_get(cr, uid, ids): message = _("Applicant '%s' is being hired.") % name @@ -418,29 +410,22 @@ class hr_applicant(crm.crm_case, osv.osv): return res def case_close_with_emp(self, cr, uid, ids, *args): - """ - @param self: The object pointer - @param cr: the current row, from the database cursor, - @param uid: the current user’s ID for security checks, - @param ids: List of case's Ids - @param *args: Give Tuple Value - """ - employee_obj = self.pool.get('hr.employee') - partner_obj = self.pool.get('res.partner') - address_id = False - applicant = self.browse(cr, uid, ids)[0] - if applicant.partner_id: - address_id = partner_obj.address_get(cr, uid, [applicant.partner_id.id], ['contact'])['contact'] - if applicant.job_id: - self.pool.get('hr.job').write(cr, uid, [applicant.job_id.id], {'no_of_recruitment': applicant.job_id.no_of_recruitment - 1}) - emp_id = employee_obj.create(cr,uid,{'name': applicant.partner_name or applicant.name, - 'job_id': applicant.job_id.id, - 'address_home_id': address_id, - 'department_id': applicant.department_id.id - }) - else: - raise osv.except_osv(_('Warning!'),_('You must define Applied Job for Applicant !')) - return self.case_close(cr, uid, ids, *args) + hr_employee = self.pool.get('hr.employee') + for applicant in self.browse(cr, uid, ids): + address_id = False + if applicant.partner_id: + address_id = applicant.partner_id.address_get(['contact'])['contact'] + if applicant.job_id: + applicant.job_id.write({'no_of_recruitment': applicant.job_id.no_of_recruitment - 1}) + emp_id = hr_employee.create(cr,uid,{'name': applicant.partner_name or applicant.name, + 'job_id': applicant.job_id.id, + 'address_home_id': address_id, + 'department_id': applicant.department_id.id + }) + self.case_close(cr, uid, [applicant.id], *args) + else: + raise osv.except_osv(_('Warning!'),_('You must define Applied Job for Applicant !')) + return True def case_reset(self, cr, uid, ids, *args): """Resets case as draft diff --git a/addons/hr_recruitment/test/recruitment_process.yml b/addons/hr_recruitment/test/recruitment_process.yml index 33232ab0f2f..43575137a6e 100644 --- a/addons/hr_recruitment/test/recruitment_process.yml +++ b/addons/hr_recruitment/test/recruitment_process.yml @@ -59,7 +59,7 @@ On a successful interview with the applicant, I hired employee. - !python {model: hr.applicant}: | - self.case_close(cr, uid, [ref('hr_case_programmer')]) + self.case_close_with_emp(cr, uid, [ref('hr_case_programmer')]) - I check that applicant is "Hired". - From 54d2f76703983cf2ed11e260723f606d9a4234fb Mon Sep 17 00:00:00 2001 From: "DBR (OpenERP)" Date: Mon, 28 Nov 2011 12:39:51 +0530 Subject: [PATCH 21/66] [REMOVE]purchase_requisition: remove duplicate_requisition.yml bzr revid: dbr@tinyerp.com-20111128070951-1pogxrrc3921tv24 --- .../test/ui/duplicate_requisition.yml | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 addons/purchase_requisition/test/ui/duplicate_requisition.yml diff --git a/addons/purchase_requisition/test/ui/duplicate_requisition.yml b/addons/purchase_requisition/test/ui/duplicate_requisition.yml deleted file mode 100644 index 742500d865d..00000000000 --- a/addons/purchase_requisition/test/ui/duplicate_requisition.yml +++ /dev/null @@ -1,8 +0,0 @@ -- - In order to test the duplicate order and check duplicate details. -- - I duplicate order. -- - !python {model: purchase.requisition}: | - context.update({'active_id':ref('order_purchase_requisition1')}) - self.copy(cr, uid, ref('order_purchase_requisition1'), context) From be3f9fa4362d095d6d5268f46e433c7bcbf5b2e3 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Mon, 28 Nov 2011 15:07:23 +0530 Subject: [PATCH 22/66] [IMP] clean YML and added draft2open2close_phase.yml bzr revid: tpa@tinyerp.com-20111128093723-8cny1olo2wcnitxt --- addons/project_long_term/__openerp__.py | 7 +- .../project_long_term_demo.xml | 6 +- .../test/draft2open2close_phase.yml | 40 +++ .../test/phase_constraint.yml | 118 --------- .../test/project_schedule_consecutive_day.yml | 127 --------- .../project_schedule_without_wroking_hour.yml | 76 ------ .../test/schedule_project_phases.yml | 221 ++++------------ .../test/schedule_project_tasks.yml | 93 ++----- .../test/test_schedule_phases_case1.yml | 76 ------ .../test/test_schedule_phases_case2.yml | 193 -------------- .../test/test_schedule_tasks_case1.yml | 246 ------------------ 11 files changed, 112 insertions(+), 1091 deletions(-) create mode 100644 addons/project_long_term/test/draft2open2close_phase.yml delete mode 100644 addons/project_long_term/test/phase_constraint.yml delete mode 100644 addons/project_long_term/test/project_schedule_consecutive_day.yml delete mode 100644 addons/project_long_term/test/project_schedule_without_wroking_hour.yml delete mode 100644 addons/project_long_term/test/test_schedule_phases_case1.yml delete mode 100644 addons/project_long_term/test/test_schedule_phases_case2.yml delete mode 100644 addons/project_long_term/test/test_schedule_tasks_case1.yml diff --git a/addons/project_long_term/__openerp__.py b/addons/project_long_term/__openerp__.py index 31522d63ea2..f4dd4637f0f 100644 --- a/addons/project_long_term/__openerp__.py +++ b/addons/project_long_term/__openerp__.py @@ -43,14 +43,9 @@ Features "init_xml": [], "demo_xml": ["project_long_term_demo.xml"], "test": [ - 'test/test_schedule_phases_case1.yml', 'test/schedule_project_phases.yml', 'test/schedule_project_tasks.yml', - 'test/test_schedule_phases_case2.yml', - 'test/project_schedule_consecutive_day.yml', - 'test/project_schedule_without_wroking_hour.yml', - 'test/phase_constraint.yml', - 'test/test_schedule_tasks_case1.yml', + 'test/draft2open2close_phase.yml', ], "update_xml": [ "security/ir.model.access.csv", diff --git a/addons/project_long_term/project_long_term_demo.xml b/addons/project_long_term/project_long_term_demo.xml index fe3f8c8e510..ac15249499e 100644 --- a/addons/project_long_term/project_long_term_demo.xml +++ b/addons/project_long_term/project_long_term_demo.xml @@ -37,9 +37,9 @@ - + - + Development and Integration @@ -60,7 +60,7 @@ Deployement and Training - + 10 diff --git a/addons/project_long_term/test/draft2open2close_phase.yml b/addons/project_long_term/test/draft2open2close_phase.yml new file mode 100644 index 00000000000..610ccb8180a --- /dev/null +++ b/addons/project_long_term/test/draft2open2close_phase.yml @@ -0,0 +1,40 @@ +- + I make "Collect Requirement and Make SRS" in open state. +- + !python {model: project.phase}: | + self.set_open(cr, uid, [ref("project_phase_1")]) +- + I check state of phase after put in open. +- + !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in open state}: + - state == "open" +- + I make Phase in pending state because of resource problem. +- + !python {model: project.phase}: | + self.set_pending(cr, uid, [ref("project_phase_1")]) +- + I check state of phase after put in pending. +- + !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in pending state}: + - state == "pending" +- + I make Phase in cancel state. +- + !python {model: project.phase}: | + self.set_cancel(cr, uid, [ref("project_phase_1")]) +- + I check state of phase after put in cancel. +- + !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in cancel state}: + - state == "cancelled" +- + I make Phase "Design Model" in done state. +- + !python {model: project.phase}: | + self.set_done(cr, uid, [ref("project_phase_2")]) +- + I check state of phase after put in done. +- + !assert {model: project.phase, id: project_phase_2, severity: error, string: Phase should be in done state}: + - state == "done" \ No newline at end of file diff --git a/addons/project_long_term/test/phase_constraint.yml b/addons/project_long_term/test/phase_constraint.yml deleted file mode 100644 index f4fa09e6e38..00000000000 --- a/addons/project_long_term/test/phase_constraint.yml +++ /dev/null @@ -1,118 +0,0 @@ -- - Given that I have a project 'Test Phases'. -- - !record {model: project.project, id: project_project_developyamlproject0}: - name: "Develop Yaml Project Module" - date_start: !eval time.strftime('%Y-%m-%d') - resource_calendar_id: resource.timesheet_group1 - members: - - base.user_admin -- - And I create three human ressources to work on this project, an analyst. -- - !record {model: resource.resource, id: resource_resource_analyst1}: - calendar_id: resource.timesheet_group1 - name: Analyst - resource_type: user - time_efficiency: 1.0 - user_id: base.user_admin -- - I define a developer HR. -- - !record {model: resource.resource, id: resource_resource_develop0}: - calendar_id: resource.timesheet_group1 - name: Developer - resource_type: user - time_efficiency: 1.0 - user_id: base.user_admin -- - I define a tester HR. -- - !record {model: resource.resource, id: resource_resource_tester1}: - calendar_id: resource.timesheet_group1 - name: tester - resource_type: user - time_efficiency: 1.0 - user_id: base.user_admin -- - Then I create three phases for my projects; Analysis, Development, Testing. -- - The first phase is 'Analysis' and has a duration of 6 days. -- - !record {model: project.phase, id: project_phase_analysisflowforyaml0}: - date_start: !eval time.strftime('%Y-%m-%d') - duration: 6.0 - name: "Analysis" - product_uom: product.uom_day - project_id: project_project_developyamlproject0 - state: draft - -- - I update the constrain and the analysis phase to not start before 4 days. -- - !python {model : project.phase }: | - pass - import datetime - from dateutil.relativedelta import * - start = datetime.date.today() + relativedelta(days=4) - self.write(cr,uid, [(ref("project_phase_analysisflowforyaml0"))], {'constraint_date_start': start}) -- - The second phase is 'Development' and depend on the 'Analysis', with a duration of 6 days. -- - !record {model: project.phase, id: project_phase_developyaml0}: - duration: 6.0 - name: Development - product_uom: product.uom_day - project_id: project_project_developyamlproject0 - previous_phase_ids: - - project_phase_analysisflowforyaml0 - -- - I update the Constrain Date Start adn Date End for phase Develop yaml -- - !python {model : project.phase }: | - pass - import datetime - #from dateutil.relativedelta import * - #start = datetime.date.today() - relativedelta(days=5) - #end = datetime.date.today() + relativedelta(days=10) - #self.write(cr,uid, [(ref("project_phase_developyaml0"))], {'constraint_date_start': start, 'constraint_date_end':end}) -- - The third phase is 'Testing' and depend on the 'Develop' phase, with a duration of 6 days. -- - !record {model: project.phase, id: project_phase_testyaml0}: - duration: 6.0 - name: Testing - product_uom: product.uom_day - project_id: project_project_developyamlproject0 - previous_phase_ids: - - project_phase_developyaml0 -- - Then I launch the scheduler to compute starting and ending phases on all phases of this project. -- - !record {model: project.compute.phases, id: project_compute_phases_0}: - project_id: project_project_developyamlproject0 - target_project: one -- - !python {model: project.project}: | - self.schedule_phases(cr, uid, [ref("project_project_developyamlproject0")]) -- - After scheduling, I check the starting date and ending date on the phases are correct. -- - !python {model: project.phase}: | - import datetime - from dateutil.relativedelta import * - minstart = (datetime.date.today() + relativedelta(days=4)).strftime('%Y-%m-%d') - minend = (datetime.date.today() + relativedelta(days=11)).strftime('%Y-%m-%d') - - phase1=self.browse(cr, uid, ref('project_phase_analysisflowforyaml0')) - assert phase1.date_start>=minstart, 'Error, the Analysis phase '+phase1.date_start+' should start after '+str(minstart) - assert phase1.date_end>=minend, 'Error, the Analysis phase should end after '+str(minend) - - phase2=self.browse(cr, uid, ref('project_phase_developyaml0')) - assert phase2.date_start>=phase1.date_end, 'Error, the phase Development should start after the end of the Analysis phase' - - phase3=self.browse(cr, uid, ref('project_phase_testyaml0')) - assert phase3.date_start>=phase2.date_end, 'Error, the phase Testing should start after the end of the Development phase' - assert phase3.date_start=minstart, 'Error, the Collect Requirement and Make SRS phase '+phase1.date_start+' should start after '+str(minstart) + assert phase1.date_end>=minend, 'Error, the Collect Requirement and Make SRS phase should end after '+str(minend) + phase2=self.browse(cr, uid, ref('project_phase_2')) + assert phase2.date_start>=phase1.date_end, 'Error, the phase Design Model should start after the end of the Collect Requirement and Make SRS phase' + + phase3=self.browse(cr, uid, ref('project_phase_3')) + assert phase3.date_start>=phase2.date_end, 'Error, the phase Development and Integration should start after the end of the Design Model phase' + + phase4=self.browse(cr, uid, ref('project_phase_4')) + assert phase4.date_start>=phase3.date_end, 'Error, the phase Review and Testing should start after the end of the Development and Integration phase' + + phase5=self.browse(cr, uid, ref('project_phase_5')) + assert phase5.date_start>=phase4.date_end, 'Error, the phase Deployement and Training start after the end of the Review and Testing phase' + assert phase5.date_start= start),'Start dates are wrong: %s < %s !' % (first_phase.date_start[:10], start) - assert (first_phase.date_end >= end),'End dates are wrong: %s <%s!' % (first_phase.date_end, end) - - second_phase = self.browse(cr, uid, ref('project_phase_secondphase0_case2')) - start = first_phase.date_end - end = (datetime.date.today() + relativedelta(days=4)).strftime('%Y-%m-%d') - assert second_phase.date_start >= start, 'Dates are wrong on second phase: %s < %s!' % (second_phase.date_start, start) - assert second_phase.date_end >= end, 'Dates are wrong on second phase %s < %s!' % (second_phase.date_end, end) - diff --git a/addons/project_long_term/test/test_schedule_phases_case2.yml b/addons/project_long_term/test/test_schedule_phases_case2.yml deleted file mode 100644 index 35173a897a3..00000000000 --- a/addons/project_long_term/test/test_schedule_phases_case2.yml +++ /dev/null @@ -1,193 +0,0 @@ -- - In order to test scheduling of project phases, I create two different - working periods and resources. And schedule the phases. -- - I create first working period 'Working Time A'. -- - !record {model: resource.calendar, id: resource_calendar_workingtimea0}: - attendance_ids: - - dayofweek: '0' - hour_from: 10.0 - hour_to: 16.0 - name: Monday - - dayofweek: '1' - hour_from: 10.0 - hour_to: 16.0 - name: Tuesday - - dayofweek: '2' - hour_from: 10.0 - hour_to: 16.0 - name: Wednesday - - dayofweek: '3' - hour_from: 10.0 - hour_to: 16.0 - name: Thursday - name: Working Time A - -- - Creating a resource.calendar.attendance record -- - !record {model: resource.calendar.attendance, id: resource_calendar_attendance_monday0}: - calendar_id: resource_calendar_workingtimea0 - dayofweek: '0' - hour_from: 10.0 - hour_to: 16.0 - name: Monday -- - Creating a resource.calendar.attendance record -- - !record {model: resource.calendar.attendance, id: resource_calendar_attendance_tuesday0}: - calendar_id: resource_calendar_workingtimea0 - dayofweek: '1' - hour_from: 10.0 - hour_to: 16.0 - name: Tuesday -- - Creating a resource.calendar.attendance record -- - !record {model: resource.calendar.attendance, id: resource_calendar_attendance_wednesday0}: - calendar_id: resource_calendar_workingtimea0 - dayofweek: '2' - hour_from: 10.0 - hour_to: 16.0 - name: Wednesday -- - Creating a resource.calendar.attendance record -- - !record {model: resource.calendar.attendance, id: resource_calendar_attendance_thursday0}: - calendar_id: resource_calendar_workingtimea0 - dayofweek: '3' - hour_from: 10.0 - hour_to: 16.0 - name: Thursday -- - I create second working period 'Working Time B'. -- - !record {model: resource.calendar, id: resource_calendar_workingtimeb0}: - attendance_ids: - - dayofweek: '4' - hour_from: 9.0 - hour_to: 18.0 - name: Friday - name: Working Time B -- - Creating a resource.calendar.attendance record -- - !record {model: resource.calendar.attendance, id: resource_calendar_attendance_friday0}: - calendar_id: resource_calendar_workingtimeb0 - dayofweek: '4' - hour_from: 9.0 - hour_to: 18.0 - name: Friday -- - I create first resource say 'Resource X' without assigning working period. -- - !record {model: resource.resource, id: resource_resource_resourcex0}: - name: Resource X - resource_type: user - time_efficiency: 1.0 - user_id: base.user_admin -- - I create first resource say 'Resource Y' with working period 'Working Time B'. -- - !record {model: resource.resource, id: resource_resource_resourcey0}: - calendar_id: resource_calendar_workingtimeb0 - name: Resource Y - resource_type: user - time_efficiency: 1.0 - user_id: base.user_admin -- - I create a project 'Development and Testing' and assign working period 'Working Time A'. -- - !record {model: project.project, id: project_project_project0}: - balance: 0.0 - credit: 0.0 - currency_id: base.EUR - debit: 0.0 - effective_hours: 0.0 - members: - - base.user_admin - name: Development and Testing - planned_hours: 20.0 - progress_rate: 0.0 - quantity: 0.0 - quantity_max: 0.0 - resource_calendar_id: resource_calendar_workingtimea0 - state: open - tasks: - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task 1 - planned_hours: 10.0 - remaining_hours: 10.0 - state: draft - total_hours: 10.0 - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task 2 - planned_hours: 10.0 - remaining_hours: 10.0 - state: draft - total_hours: 10.0 - total_hours: 10.0 - members: - - project.res_users_analyst - - project.res_users_project_manager - - project.res_users_technical_leader - - project.res_users_developer - - project.res_users_designer - - project.res_users_tester - type_ids: - - project.project_tt_specification - - project.project_tt_development - - project.project_tt_testing - - project.project_tt_merge - -- - I create a phase 'Initial Phase' for project 'Development and Testing'. -- - !record {model: project.phase, id: project_phase_phase0}: - date_start: '2011-01-03 08:00:00' - duration: 0.0 - name: Initial Phase - product_uom: product.uom_day - project_id: project_project_project0 - state: draft -- - I create first task 'Developing module' and assign 10h. -- - !record {model: project.task, id: project_task_task0}: - delay_hours: 0.0 - effective_hours: 0.0 - name: Developing module - planned_hours: 10.0 - project_id: project_project_project0 - remaining_hours: 10.0 - state: draft - total_hours: 10.0 - phase_id: project_phase_phase0 -- - I create first task 'Testing module' and assign 10h. -- - !record {model: project.task, id: project_task_task1}: - delay_hours: 0.0 - effective_hours: 0.0 - name: Testing module - planned_hours: 10.0 - project_id: project_project_project0 - remaining_hours: 10.0 - state: draft - total_hours: 10.0 - phase_id: project_phase_phase0 -- - Now I create a record to compute the phase of project. -- - !record {model: project.compute.phases, id: project_compute_phases0}: - target_project: 'one' - project_id: project_project_project0 -- - I schedule the phases. -- - !python {model: project.compute.phases}: | - self.check_selection(cr, uid, [ref("project_compute_phases0")]) - diff --git a/addons/project_long_term/test/test_schedule_tasks_case1.yml b/addons/project_long_term/test/test_schedule_tasks_case1.yml deleted file mode 100644 index 3bb0ea87c43..00000000000 --- a/addons/project_long_term/test/test_schedule_tasks_case1.yml +++ /dev/null @@ -1,246 +0,0 @@ -- - In order to test scheduling of tasks, I create four tasks with different sequences and schedule them. -- - I create first user. -- - !record {model: res.users, id: res_users_user0}: - company_id: base.main_company - context_lang: en_US - groups_id: - - base.group_partner_manager - - base.group_user - login: user1 - name: User 1 - password: user1 -- - I create second user. -- - !record {model: res.users, id: res_users_user1}: - company_id: base.main_company - context_lang: en_US - groups_id: - - base.group_partner_manager - - base.group_user - login: user2 - name: User 2 - password: user2 -- - I create a Project. -- - !record {model: project.project, id: project_project_projecta0}: - balance: 0.0 - credit: 0.0 - currency_id: base.EUR - debit: 0.0 - effective_hours: 0.0 - name: Project A - members: - - res_users_user0 - - res_users_user1 - phase_ids: - - date_start: '2011-01-06 08:00:00' - duration: 2.0 - name: Phase A - product_uom: product.uom_day - state: draft - task_ids: - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task D - planned_hours: 5.0 - remaining_hours: 5.0 - state: draft - total_hours: 5.0 - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task C - planned_hours: 5.0 - remaining_hours: 5.0 - sequence: 11 - state: draft - total_hours: 5.0 - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task B - planned_hours: 5.0 - remaining_hours: 5.0 - sequence: 13 - state: draft - total_hours: 5.0 - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task A - planned_hours: 5.0 - remaining_hours: 5.0 - sequence: 14 - state: draft - total_hours: 5.0 - planned_hours: 20.0 - progress_rate: 0.0 - quantity: 0.0 - quantity_max: 0.0 - state: open - tasks: - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task D - planned_hours: 5.0 - remaining_hours: 5.0 - state: draft - total_hours: 5.0 - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task C - planned_hours: 5.0 - remaining_hours: 5.0 - sequence: 11 - state: draft - total_hours: 5.0 - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task B - planned_hours: 5.0 - remaining_hours: 5.0 - sequence: 13 - state: draft - total_hours: 5.0 - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task A - planned_hours: 5.0 - remaining_hours: 5.0 - sequence: 14 - state: draft - total_hours: 5.0 - total_hours: 15.0 -- - I create first task with highest sequence. -- - !record {model: project.task, id: project_task_taska0}: - delay_hours: 0.0 - effective_hours: 0.0 - name: Task A - planned_hours: 5.0 - project_id: project_project_projecta0 - remaining_hours: 5.0 - sequence: 14 - state: draft - total_hours: 5.0 -- - I create second task. -- - !record {model: project.task, id: project_task_taskb0}: - delay_hours: 0.0 - effective_hours: 0.0 - name: Task B - planned_hours: 5.0 - project_id: project_project_projecta0 - remaining_hours: 5.0 - sequence: 13 - state: draft - total_hours: 5.0 -- - I create third task. -- - !record {model: project.task, id: project_task_taskc0}: - delay_hours: 0.0 - effective_hours: 0.0 - name: Task C - planned_hours: 5.0 - project_id: project_project_projecta0 - remaining_hours: 5.0 - sequence: 11 - state: draft - total_hours: 5.0 -- - I create fourth task with lowest sequence. -- - !record {model: project.task, id: project_task_taskd0}: - delay_hours: 0.0 - effective_hours: 0.0 - name: Task D - planned_hours: 5.0 - project_id: project_project_projecta0 - remaining_hours: 5.0 - state: draft - total_hours: 5.0 -- - Now I create a resource for first user. -- - !record {model: resource.resource, id: resource_resource_user0}: - name: User 1 - resource_type: user - time_efficiency: 1.0 - user_id: res_users_user0 -- - I create a resource for second user. -- - !record {model: resource.resource, id: resource_resource_user1}: - name: User 2 - resource_type: user - time_efficiency: 1.0 - user_id: res_users_user1 -- - Now I create one phase for the project. -- - !record {model: project.phase, id: project_phase_phasea0}: - date_start: '2011-01-06 08:00:00' - duration: 2.0 - name: Phase A - product_uom: product.uom_day - project_id: project_project_projecta0 - state: draft - task_ids: - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task D - planned_hours: 5.0 - project_id: project_project_projecta0 - remaining_hours: 5.0 - state: draft - total_hours: 5.0 - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task C - planned_hours: 5.0 - project_id: project_project_projecta0 - remaining_hours: 5.0 - sequence: 11 - state: draft - total_hours: 5.0 - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task B - planned_hours: 5.0 - project_id: project_project_projecta0 - remaining_hours: 5.0 - sequence: 13 - state: draft - total_hours: 5.0 - - delay_hours: 0.0 - effective_hours: 0.0 - name: Task A - planned_hours: 5.0 - project_id: project_project_projecta0 - remaining_hours: 5.0 - sequence: 14 - state: draft - total_hours: 5.0 -- - Now I create a record to schedule the tasks of project. -- - !record {model: project.compute.tasks, id: project_compute_tasks0}: - project_id: project_project_projecta0 -- - I schedule the tasks. -- - !python {model: project.compute.tasks}: | - self.compute_date(cr, uid, [ref("project_compute_tasks0")]) -- - I check that whether the tasks now allocated to respected resources or not. -- - !python {model: project.task}: | - task_ids = self.search(cr, uid, [('project_id','=',ref('project_project_projecta0'))]) - for task in self.browse(cr, uid, task_ids): - if (not task.date_start) or (not task.date_end): - raise AssertionError("Tasks are not scheduled.") From 8108d522e3eb6ccf80db6daaa4cf7a98f7414077 Mon Sep 17 00:00:00 2001 From: "Hemendra Paregi (Open ERP)" Date: Mon, 28 Nov 2011 15:49:52 +0530 Subject: [PATCH 23/66] [IMP]project_gtd: improvement in yml of project_gtd bzr revid: hpa@tinyerp.com-20111128101952-99qis8rd0l9kjkp4 --- addons/project_gtd/test/task_timebox.yml | 29 +++++++++++++----------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/addons/project_gtd/test/task_timebox.yml b/addons/project_gtd/test/task_timebox.yml index 7379f5857cf..84de7bda953 100644 --- a/addons/project_gtd/test/task_timebox.yml +++ b/addons/project_gtd/test/task_timebox.yml @@ -1,42 +1,45 @@ - - In order to set Daily tasks into Weekly Timebox, I create plan for that + In order to test the process of Timebox in Project Management module, + I set my task from Daily to Weekly Timebox through Plannify Timebox - !record {model: project.timebox.fill.plan, id: plan_id}: task_ids: [project.project_task_10] timebox_id: timebox_daily timebox_to_id: timebox_weekly - - I run plan to set Daily tasks into Weekly Timebox + I set the task from Daily Timebox to Weekly Timebox - !python {model: project.timebox.fill.plan}: | self.process(cr, uid, [ref("plan_id")]) - - I check Weekly Timebox of task after set Timebox + I check task is set to Weekly Timebox - !assert {model: project.task, id: project.project_task_10, string: Task should be set to weekly timebox}: - timebox_id.id == ref("timebox_weekly") - - I Empty the Daily Timebox + I Empty the Weekly Timebox - !python {model: project.timebox.empty}: | self._empty(cr, uid, {"active_model": "project.gtd.timebox", - "active_ids":[ref("timebox_daily")], - "active_id": ref("timebox_daily"), + "active_ids":[ref("timebox_weekly")], + "active_id": ref("timebox_weekly"), }) - - I check task 'Develop time management module' is no more in Daily Timebox + I check task 'Develop Module in Sale Management' is no more in Weekly Timebox - - !assert {model: project.task, id: project.project_task_10 , string: Task is not in Daily Timebox}: - - timebox_id.id != ref("timebox_daily") + !assert {model: project.task, id: project.project_task_10 , string: Task is not in Weekly Timebox }: + - timebox_id.id != ref("timebox_weekly") - I set Previous Timebox on task - !python {model: project.task}: | - self.prev_timebox(cr, uid, [ref("project.project_task_10")], - {'active_ids': [ref("project.project_task_1")],}) + previous_timebox = self.prev_timebox(cr, uid, [ref("project.project_task_10")], + {'active_ids': [ref("project_gtd.menu_open_gtd_timebox_tree")],}) + assert previous_timebox == True, "I set Previous Timebox on task" - I set Next Timebox on task - !python {model: project.task}: | - self.next_timebox(cr, uid, [ref("project.project_task_10")], - {'active_ids': [ref("project.project_task_1")],}) + nexts_timebox = self.next_timebox(cr, uid, [ref("project.project_task_10")], + {'active_ids': [ref("project_gtd.menu_open_gtd_timebox_tree")],}) + assert nexts_timebox == True, "I set Previous Timebox on task" \ No newline at end of file From fcce28a1d574f3a7e208d68f903a59180956379b Mon Sep 17 00:00:00 2001 From: "Hemendra Paregi (Open ERP)" Date: Mon, 28 Nov 2011 16:00:56 +0530 Subject: [PATCH 24/66] [IMP]project_gtd: yml improvement bzr revid: hpa@tinyerp.com-20111128103056-ldrcaujjik4zmwqd --- addons/project_gtd/test/task_timebox.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/project_gtd/test/task_timebox.yml b/addons/project_gtd/test/task_timebox.yml index 84de7bda953..8efa7219b21 100644 --- a/addons/project_gtd/test/task_timebox.yml +++ b/addons/project_gtd/test/task_timebox.yml @@ -40,6 +40,6 @@ I set Next Timebox on task - !python {model: project.task}: | - nexts_timebox = self.next_timebox(cr, uid, [ref("project.project_task_10")], + next_timebox = self.next_timebox(cr, uid, [ref("project.project_task_10")], {'active_ids': [ref("project_gtd.menu_open_gtd_timebox_tree")],}) - assert nexts_timebox == True, "I set Previous Timebox on task" \ No newline at end of file + assert next_timebox == True, "I set Next Timebox on task" \ No newline at end of file From 5ea00d2f0c270cd6315251f241d4c51674be9bfa Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Mon, 28 Nov 2011 18:23:28 +0530 Subject: [PATCH 25/66] [IMP] project_long_term: improve YML test cases of phase bzr revid: hmo@tinyerp.com-20111128125328-vd4ovcibw844y0d7 --- addons/project_long_term/__openerp__.py | 4 +- .../project_long_term_demo.xml | 5 ++ .../test/draft2open2close_phase.yml | 40 ---------- .../project_long_term/test/phase_process.yml | 79 +++++++++++++++++++ .../test/schedule_project_phases.yml | 63 --------------- .../test/schedule_project_tasks.yml | 25 ------ 6 files changed, 85 insertions(+), 131 deletions(-) delete mode 100644 addons/project_long_term/test/draft2open2close_phase.yml create mode 100644 addons/project_long_term/test/phase_process.yml delete mode 100644 addons/project_long_term/test/schedule_project_phases.yml delete mode 100644 addons/project_long_term/test/schedule_project_tasks.yml diff --git a/addons/project_long_term/__openerp__.py b/addons/project_long_term/__openerp__.py index f4dd4637f0f..9c6e1410b41 100644 --- a/addons/project_long_term/__openerp__.py +++ b/addons/project_long_term/__openerp__.py @@ -43,9 +43,7 @@ Features "init_xml": [], "demo_xml": ["project_long_term_demo.xml"], "test": [ - 'test/schedule_project_phases.yml', - 'test/schedule_project_tasks.yml', - 'test/draft2open2close_phase.yml', + 'test/phase_process.yml', ], "update_xml": [ "security/ir.model.access.csv", diff --git a/addons/project_long_term/project_long_term_demo.xml b/addons/project_long_term/project_long_term_demo.xml index ac15249499e..4cd6d5cdec4 100644 --- a/addons/project_long_term/project_long_term_demo.xml +++ b/addons/project_long_term/project_long_term_demo.xml @@ -5,6 +5,10 @@ This Demo data file Human Resources, Phases and Resources,Tasks allocation and also run scheduling of phase and tasks. --> + + + + @@ -13,6 +17,7 @@ 30 + diff --git a/addons/project_long_term/test/draft2open2close_phase.yml b/addons/project_long_term/test/draft2open2close_phase.yml deleted file mode 100644 index 610ccb8180a..00000000000 --- a/addons/project_long_term/test/draft2open2close_phase.yml +++ /dev/null @@ -1,40 +0,0 @@ -- - I make "Collect Requirement and Make SRS" in open state. -- - !python {model: project.phase}: | - self.set_open(cr, uid, [ref("project_phase_1")]) -- - I check state of phase after put in open. -- - !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in open state}: - - state == "open" -- - I make Phase in pending state because of resource problem. -- - !python {model: project.phase}: | - self.set_pending(cr, uid, [ref("project_phase_1")]) -- - I check state of phase after put in pending. -- - !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in pending state}: - - state == "pending" -- - I make Phase in cancel state. -- - !python {model: project.phase}: | - self.set_cancel(cr, uid, [ref("project_phase_1")]) -- - I check state of phase after put in cancel. -- - !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in cancel state}: - - state == "cancelled" -- - I make Phase "Design Model" in done state. -- - !python {model: project.phase}: | - self.set_done(cr, uid, [ref("project_phase_2")]) -- - I check state of phase after put in done. -- - !assert {model: project.phase, id: project_phase_2, severity: error, string: Phase should be in done state}: - - state == "done" \ No newline at end of file diff --git a/addons/project_long_term/test/phase_process.yml b/addons/project_long_term/test/phase_process.yml new file mode 100644 index 00000000000..77d7b6bce1a --- /dev/null +++ b/addons/project_long_term/test/phase_process.yml @@ -0,0 +1,79 @@ +- + In order to test process of Phases, +- + I create a record to schedule the phase of project. +- + !record {model: project.compute.phases, id: project_compute_phases01}: + target_project: 'one' + project_id: project.project_integrate_openerp +- + I schedule the phases. +- + !python {model: project.compute.phases}: | + self.check_selection(cr, uid, [ref("project_compute_phases01")]) +- + I check the starting date and ending date on the phases after scheduling. +- + !python {model: project.project}: | + project = self.browse(cr, uid, ref("project.project_integrate_openerp"), context=context) + def _convert(date): + import time + return time.strptime(date, '%Y-%m-%d %H:%M:%S') + def _check(phase, _convert, _check): #TOFIX: why need to pass function ? + for next_phase in phase.next_phase_ids: + assert _convert(next_phase.date_start) >= _convert(phase.date_end), "Phase does not start in proper date." + _check(next_phase, _convert, _check) + return True + + for phase in project.phase_ids: + + assert phase.date_start, "Start date should be computed." + assert phase.date_end, "End date should be computed." + if not phase.previous_phase_ids and phase.constraint_date_start: + assert _convert(phase.date_start) >= _convert(phase.constraint_date_start), "Phase does not start in proper date." + _check(phase, _convert, _check) +- + I open phase. +- + !python {model: project.phase}: | + self.set_open(cr, uid, [ref("project_phase_1")]) +- + I check state of phase after opened. +- + !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in open state}: + - state == "open" +- + I put phase in pending state. +- + !python {model: project.phase}: | + self.set_pending(cr, uid, [ref("project_phase_1")]) +- + I check state of phase after put in pending. +- + !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in pending state}: + - state == "pending" +- + I make Phase in cancel state. +- + !python {model: project.phase}: | + self.set_cancel(cr, uid, [ref("project_phase_1")]) +- + I check state of phase after cancelled. +- + !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in cancel state}: + - state == "cancelled" +- + I put again in draft phase. +- + !python {model: project.phase}: | + self.set_draft(cr, uid, [ref("project_phase_1")]) +- + I close phase. +- + !python {model: project.phase}: | + self.set_done(cr, uid, [ref("project_phase_1")]) +- + I check state of phase after closed. +- + !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in done state}: + - state == "done" diff --git a/addons/project_long_term/test/schedule_project_phases.yml b/addons/project_long_term/test/schedule_project_phases.yml deleted file mode 100644 index c7a2addddb2..00000000000 --- a/addons/project_long_term/test/schedule_project_phases.yml +++ /dev/null @@ -1,63 +0,0 @@ -- - I Set working period to Project 'Integrate a Sale and Warehouse Management' -- - !python {model: project.project}: | - self.write(cr, uid, [ref("project.project_integrate_openerp")], {'resource_calendar_id': ref("resource.timesheet_group1")}) -- - I update the constrain and the "Collect Requirement and Make SRS" to not start before 4 days. -- - !python {model : project.phase }: | - pass - import datetime - from dateutil.relativedelta import * - start = datetime.date.today() + relativedelta(days=4) - self.write(cr,uid, [(ref("project_phase_1"))], {'constraint_date_start': start}) -- - I Schedule Phases of Project. -- - !python {model: project.project}: | - self.schedule_phases(cr, uid, ref("project.project_integrate_openerp")) -- - Now I create a record to compute the phase of project. -- - !record {model: project.compute.phases, id: project_compute_phases01}: - target_project: 'one' - project_id: project.project_integrate_openerp -- - I schedule the phases. -- - !python {model: project.compute.phases}: | - self.check_selection(cr, uid, [ref("project_compute_phases01")]) -- - Check if phases scheduled, check that either of phase's start_date, end_date and user_id is not null -- - !python {model: project.project}: | - prj=self.browse(cr, uid, [ref("project.project_integrate_openerp")])[0] - for phase in prj.phase_ids: - if (not phase.date_start) or (not phase.date_end): - raise AssertionError("Phase not scheduled") -- - After scheduling, I check the starting date and ending date on the phases are correct. -- - !python {model: project.phase}: | - import datetime - from dateutil.relativedelta import * - minstart = (datetime.date.today() + relativedelta(days=4)).strftime('%Y-%m-%d') - minend = (datetime.date.today() + relativedelta(days=5)).strftime('%Y-%m-%d') - - phase1=self.browse(cr, uid, ref('project_phase_1')) - assert phase1.date_start>=minstart, 'Error, the Collect Requirement and Make SRS phase '+phase1.date_start+' should start after '+str(minstart) - assert phase1.date_end>=minend, 'Error, the Collect Requirement and Make SRS phase should end after '+str(minend) - - phase2=self.browse(cr, uid, ref('project_phase_2')) - assert phase2.date_start>=phase1.date_end, 'Error, the phase Design Model should start after the end of the Collect Requirement and Make SRS phase' - - phase3=self.browse(cr, uid, ref('project_phase_3')) - assert phase3.date_start>=phase2.date_end, 'Error, the phase Development and Integration should start after the end of the Design Model phase' - - phase4=self.browse(cr, uid, ref('project_phase_4')) - assert phase4.date_start>=phase3.date_end, 'Error, the phase Review and Testing should start after the end of the Development and Integration phase' - - phase5=self.browse(cr, uid, ref('project_phase_5')) - assert phase5.date_start>=phase4.date_end, 'Error, the phase Deployement and Training start after the end of the Review and Testing phase' - assert phase5.date_start Date: Mon, 28 Nov 2011 18:25:47 +0530 Subject: [PATCH 26/66] [IMP] project_long_term: indetation in yml bzr revid: hmo@tinyerp.com-20111128125547-sy83re0c5vjb51sy --- addons/project_long_term/test/phase_process.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/project_long_term/test/phase_process.yml b/addons/project_long_term/test/phase_process.yml index 77d7b6bce1a..725c5b2a97d 100644 --- a/addons/project_long_term/test/phase_process.yml +++ b/addons/project_long_term/test/phase_process.yml @@ -41,7 +41,7 @@ I check state of phase after opened. - !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in open state}: - - state == "open" + - state == "open" - I put phase in pending state. - @@ -51,7 +51,7 @@ I check state of phase after put in pending. - !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in pending state}: - - state == "pending" + - state == "pending" - I make Phase in cancel state. - @@ -61,7 +61,7 @@ I check state of phase after cancelled. - !assert {model: project.phase, id: project_phase_1, severity: error, string: Phase should be in cancel state}: - - state == "cancelled" + - state == "cancelled" - I put again in draft phase. - From 6ced5c16c1b269f3820588156c0ba197c55e498e Mon Sep 17 00:00:00 2001 From: "Harry (OpenERP)" Date: Fri, 2 Dec 2011 12:57:55 +0530 Subject: [PATCH 27/66] [REF] purchase_requisition: purchase_requisition/wizard/purchase_requisition_partner.py * [REF] In create_order() method, move stuff of creating purchase order into 'purchase.requisition' object. purchase_requisition/purchase_requisition.py * [ADD] introduce new method: make_purchase_order() - to create new RFQ of specified supplier with plannned date, price bzr revid: hmo@tinyerp.com-20111202072755-e3ura2cmnh78utet --- .../purchase_requisition.py | 88 ++++++++++++++++- .../test/purchase_requisition.yml | 9 +- .../wizard/purchase_requisition_partner.py | 95 +------------------ 3 files changed, 95 insertions(+), 97 deletions(-) diff --git a/addons/purchase_requisition/purchase_requisition.py b/addons/purchase_requisition/purchase_requisition.py index 8570f4ba7bb..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 . # ############################################################################## - +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): diff --git a/addons/purchase_requisition/test/purchase_requisition.yml b/addons/purchase_requisition/test/purchase_requisition.yml index a2f9d5851d1..a2e5b743965 100644 --- a/addons/purchase_requisition/test/purchase_requisition.yml +++ b/addons/purchase_requisition/test/purchase_requisition.yml @@ -50,6 +50,7 @@ I check that the RFQ details which created for supplier. - !python {model: purchase.order}: | + 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) @@ -60,10 +61,10 @@ 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." + 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. - diff --git a/addons/purchase_requisition/wizard/purchase_requisition_partner.py b/addons/purchase_requisition/wizard/purchase_requisition_partner.py index 3a758fc46a9..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 _ @@ -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() From 7010922d50f5e1e37f2050dbee1a6a5c7e6de4d7 Mon Sep 17 00:00:00 2001 From: "Yogesh (OpenERP)" Date: Fri, 9 Dec 2011 18:05:14 +0530 Subject: [PATCH 28/66] [FIX] clear value of date and datetime widget in search view on clear button. lp bug: https://launchpad.net/bugs/901665 fixed bzr revid: ysa@tinyerp.com-20111209123514-c54e5ea9tqjuc34s --- addons/web/static/src/js/search.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index c3e27fc52be..0be95af2571 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -7,7 +7,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search /** * @constructs openerp.web.SearchView * @extends openerp.web.Widget - * + * * @param parent * @param element_id * @param dataset @@ -155,7 +155,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search var ext = new openerp.web.search.ExtendedSearch(this, this.model); lines.push([ext]); this.inputs.push(ext); - + var render = QWeb.render("SearchView", { 'view': data.fields_view['arch'], 'lines': lines, @@ -177,7 +177,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search $.when.apply(null, widget_starts).then(function () { self.ready.resolve(); }); - + this.reload_managed_filters(); }, reload_managed_filters: function() { @@ -409,6 +409,11 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search this.$element.find('table:last').hide(); $('.searchview_extended_groups_list').empty(); + _.each(this.inputs, function (input) { + if(input.datewidget && input.datewidget.value) { + input.datewidget.value = false; + } + }); setTimeout(this.on_clear, 0); }, /** @@ -1209,7 +1214,7 @@ openerp.web.search.ExtendedSearchProposition = openerp.web.OldWidget.extend(/** this.$element.find('.searchview_extended_prop_value').html( this.value.render({})); this.value.start(); - + }, get_proposition: function() { if ( this.attrs.selected == null) @@ -1356,7 +1361,7 @@ openerp.web.search.custom_filters = new openerp.web.Registry({ 'one2many': 'openerp.web.search.ExtendedSearchProposition.Char', 'many2one': 'openerp.web.search.ExtendedSearchProposition.Char', 'many2many': 'openerp.web.search.ExtendedSearchProposition.Char', - + 'datetime': 'openerp.web.search.ExtendedSearchProposition.DateTime', 'date': 'openerp.web.search.ExtendedSearchProposition.Date', 'integer': 'openerp.web.search.ExtendedSearchProposition.Integer', From 17b76fdc7e690e67da926a032fbdf67a63089a58 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 12 Dec 2011 10:41:52 +0100 Subject: [PATCH 29/66] [ADD] action.flags.default_view defines default view to switch on when viewmanager is created. bzr revid: fme@openerp.com-20111212094152-26eto8s1k9wlhxne --- addons/web/static/src/js/views.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index e11c0c20f04..d57f9d4a84d 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -234,8 +234,9 @@ session.web.ViewManager = session.web.Widget.extend(/** @lends session.web.View if (this.flags.views_switcher === false) { this.$element.find('.oe_vm_switch').hide(); } - // switch to the first one in sequence - return this.on_mode_switch(this.views_src[0].view_type); + // If no default view defined, switch to the first one in sequence + var default_view = this.flags.default_view || this.views_src[0].view_type; + return this.on_mode_switch(default_view); }, /** * Asks the view manager to switch visualization mode. From 045f4965930b237841759cae85ba829438e15792 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 12 Dec 2011 10:56:08 +0100 Subject: [PATCH 30/66] [IMP] Dashboard: if action@creatable is defined, use it as an action id instead of form view id bzr revid: fme@openerp.com-20111212095608-lbusah7pntzuug3n --- .../web_dashboard/static/src/js/dashboard.js | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/addons/web_dashboard/static/src/js/dashboard.js b/addons/web_dashboard/static/src/js/dashboard.js index c717d629656..a46ffdf5fba 100644 --- a/addons/web_dashboard/static/src/js/dashboard.js +++ b/addons/web_dashboard/static/src/js/dashboard.js @@ -192,17 +192,20 @@ openerp.web.form.DashBoard = openerp.web.form.Widget.extend({ self.do_action(action); } if (action_attrs.creatable && action_attrs.creatable !== 'false') { - var form_id = parseInt(action_attrs.creatable, 10); + var action_id = parseInt(action_attrs.creatable, 10); $action.parent().find('button.oe_dashboard_button_create').click(function() { - var create_action = _.extend({}, action_orig, { - views : [[(isNaN(form_id) ? false : form_id), 'form']] - }); - _.each(action.views, function(v) { - if (v[1] !== 'form') { - create_action.views.push(v); - } - }); - self.do_action(create_action); + if (isNaN(action_id)) { + action.flags.default_view = 'form'; + self.do_action(action_orig); + } else { + self.rpc('/web/action/load', { + action_id: action_id + }, function(result) { + result.result.flags = result.result.flags || {}; + result.result.flags.default_view = 'form'; + self.do_action(result.result); + }); + } }); } if (am.inner_viewmanager) { From 89ee71e74246154407dda030b2189f8b03262162 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 12 Dec 2011 10:57:11 +0100 Subject: [PATCH 31/66] [IMP] Change in dashboard view api. @creatable is an action id, not a form view id bzr revid: fme@openerp.com-20111212095711-hvtk2sa92cnz6oxw --- openerp/addons/base/rng/view.rng | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/rng/view.rng b/openerp/addons/base/rng/view.rng index a95abd9ac4f..7cbe7135106 100644 --- a/openerp/addons/base/rng/view.rng +++ b/openerp/addons/base/rng/view.rng @@ -64,7 +64,7 @@ overrides its own @views. --> + values : [true|false|]. --> From 35895bde21813782b58a20a06a7b2f9e033d560d Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 12 Dec 2011 11:11:21 +0100 Subject: [PATCH 32/66] [FIX] regenerate action's views key if it is empty, not just if it's absent lp bug: https://launchpad.net/bugs/903062 fixed bzr revid: xmo@openerp.com-20111212101121-ljjmq6phxgse0qjq --- addons/web/controllers/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 27cde36fa34..397a6a0d302 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -604,7 +604,7 @@ def fix_view_modes(action): :param dict action: an action descriptor :returns: nothing, the action is modified in place """ - if 'views' not in action: + if not action.get('views'): generate_views(action) id_form = None From e59a57353478283575c3c7714d8616b18fdc7e4f Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Sun, 11 Dec 2011 16:30:10 +0100 Subject: [PATCH 33/66] [REM] revert arrow navigation in editable list (postponed) bzr revid: al@openerp.com-20111211153010-mrydgknz0tg2tbqq --- addons/web/static/src/js/view_form.js | 15 +++---- .../web/static/src/js/view_list_editable.js | 40 +------------------ 2 files changed, 8 insertions(+), 47 deletions(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 2f89eaca5a6..15a402efb47 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -1582,7 +1582,7 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({ .change(function () { ischanging = true; }) .click(function () { ischanging = false; }) .keyup(function (e) { - if (!_([13, 38, 40]).contains(e.which) || !ischanging) { return; } + if (e.which !== 13 || !ischanging) { return; } e.stopPropagation(); ischanging = false; }); @@ -1790,16 +1790,13 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({ minLength: 0, delay: 0 }); - // Don't propagate KEY_UP and KEY_DOWN event to parent (for editable - // list), don't propagate KEY_RETURN either when the autocomplete - // control is currently open + // used to correct a bug when selecting an element by pushing 'enter' in an editable list this.$input.keyup(function(e) { - if (e.which === 38 || e.which === 40) { - e.stopPropagation(); - } else if (isSelecting && e.which === 13) { - e.stopPropagation(); - isSelecting = false; + if (e.which === 13) { + if (isSelecting) + e.stopPropagation(); } + isSelecting = false; }); }, // autocomplete component content handling diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js index 805ce0de1af..b2edf55b314 100644 --- a/addons/web/static/src/js/view_list_editable.js +++ b/addons/web/static/src/js/view_list_editable.js @@ -3,11 +3,8 @@ * @namespace */ openerp.web.list_editable = function (openerp) { - // https://developer.mozilla.org/en/DOM/KeyboardEvent#Virtual_key_codes var KEY_RETURN = 13, - KEY_ESCAPE = 27, - KEY_UP = 38, - KEY_DOWN = 40; + KEY_ESCAPE = 27; var QWeb = openerp.web.qweb; // editability status of list rows @@ -181,7 +178,7 @@ openerp.web.list_editable = function (openerp) { var next_record_id, next_record = self.records.at( - self.records.indexOf(result.edited_record) + 1); + self.records.indexOf(result.edited_record) + 1); if (next_record) { next_record_id = next_record.get('id'); self.dataset.index = _(self.dataset.ids) @@ -193,39 +190,6 @@ openerp.web.list_editable = function (openerp) { self.edit_record(next_record_id); }); break; - case KEY_DOWN: - this.save_row().then(function (result) { - var next_record_id, - next_record = self.records.at( - self.records.indexOf(result.edited_record) + 1); - if (next_record) { - next_record_id = next_record.get('id'); - self.dataset.index = _(self.dataset.ids) - .indexOf(next_record_id); - } else { - self.dataset.index = 0; - next_record_id = self.records.at(0).get('id'); - } - self.edit_record(next_record_id); - }); - break; - case KEY_UP: - this.save_row().then(function (result) { - var previous_record_id, - previous_record = self.records.at( - self.records.indexOf(result.edited_record) - 1); - if (previous_record) { - previous_record_id = previous_record.get('id'); - self.dataset.index = _(self.dataset.ids) - .indexOf(previous_record_id); - } else { - var last = self.records.length - 1; - self.dataset.index = last; - previous_record_id = self.records.at(last).get('id'); - } - self.edit_record(previous_record_id); - }); - break; case KEY_ESCAPE: this.cancel_edition(); break; From dce7b0bb00008fa99ec91f11efb4eefef703509a Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of openerp <> Date: Mon, 12 Dec 2011 05:17:30 +0000 Subject: [PATCH 34/66] Launchpad automatic translations update. bzr revid: launchpad_translations_on_behalf_of_openerp-20111212051730-t3td2i6rkaj99aex --- addons/procurement/i18n/hr.po | 890 +++++++++++++++++++++++++ addons/project_mrp/i18n/hr.po | 102 ++- addons/purchase_requisition/i18n/hr.po | 436 ++++++++++++ addons/report_webkit/i18n/hr.po | 613 +++++++++++++++++ addons/report_webkit_sample/i18n/hr.po | 153 +++++ addons/resource/i18n/hr.po | 115 ++-- 6 files changed, 2247 insertions(+), 62 deletions(-) create mode 100644 addons/procurement/i18n/hr.po create mode 100644 addons/purchase_requisition/i18n/hr.po create mode 100644 addons/report_webkit/i18n/hr.po create mode 100644 addons/report_webkit_sample/i18n/hr.po diff --git a/addons/procurement/i18n/hr.po b/addons/procurement/i18n/hr.po new file mode 100644 index 00000000000..ae7312f9da2 --- /dev/null +++ b/addons/procurement/i18n/hr.po @@ -0,0 +1,890 @@ +# 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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-11 11:15+0000\n" +"PO-Revision-Date: 2011-12-11 22:33+0000\n" +"Last-Translator: Tomislav Bosnjakovic \n" +"Language-Team: Croatian \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: procurement +#: view:make.procurement:0 +msgid "Ask New Products" +msgstr "Traži nove artikle" + +#. module: procurement +#: model:ir.ui.menu,name:procurement.menu_stock_sched +msgid "Schedulers" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_make_procurement +msgid "Make Procurements" +msgstr "" + +#. module: procurement +#: help:procurement.order.compute.all,automatic:0 +msgid "" +"Triggers an automatic procurement for all products that have a virtual stock " +"under 0. You should probably not use this option, we suggest using a MTO " +"configuration on products." +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "Group By..." +msgstr "Grupiraj po..." + +#. module: procurement +#: help:stock.warehouse.orderpoint,procurement_draft_ids:0 +msgid "Draft procurement of the product and location of that orderpoint" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:288 +#, python-format +msgid "No supplier defined for this product !" +msgstr "" + +#. module: procurement +#: field:make.procurement,uom_id:0 +msgid "Unit of Measure" +msgstr "Jedinica mjere" + +#. module: procurement +#: field:procurement.order,procure_method:0 +msgid "Procurement Method" +msgstr "Metoda nabave" + +#. module: procurement +#: code:addons/procurement/procurement.py:304 +#, python-format +msgid "No address defined for the supplier" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.action_procurement_compute +msgid "Compute Stock Minimum Rules Only" +msgstr "" + +#. module: procurement +#: field:procurement.order,company_id:0 +#: field:stock.warehouse.orderpoint,company_id:0 +msgid "Company" +msgstr "" + +#. module: procurement +#: field:procurement.order,product_uos_qty:0 +msgid "UoS Quantity" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +#: field:procurement.order,name:0 +msgid "Reason" +msgstr "" + +#. module: procurement +#: view:procurement.order.compute:0 +msgid "Compute Procurements" +msgstr "" + +#. module: procurement +#: field:procurement.order,message:0 +msgid "Latest error" +msgstr "" + +#. module: procurement +#: help:mrp.property,composition:0 +msgid "Not used in computations, for information purpose only." +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,procurement_id:0 +msgid "Latest procurement" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Notes" +msgstr "" + +#. module: procurement +#: selection:procurement.order,procure_method:0 +msgid "on order" +msgstr "" + +#. module: procurement +#: help:procurement.order,message:0 +msgid "Exception occurred while computing procurement orders." +msgstr "" + +#. module: procurement +#: help:procurement.order,state:0 +msgid "" +"When a procurement is created the state is set to 'Draft'.\n" +" If the procurement is confirmed, the state is set to 'Confirmed'. " +" \n" +"After confirming the state is set to 'Running'.\n" +" If any exception arises in the order then the state is set to 'Exception'.\n" +" Once the exception is removed the state becomes 'Ready'.\n" +" It is in 'Waiting'. state when the procurement is waiting for another one " +"to finish." +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "Minimum Stock Rules Search" +msgstr "" + +#. module: procurement +#: help:stock.warehouse.orderpoint,product_min_qty:0 +msgid "" +"When the virtual stock goes belong the Min Quantity, OpenERP generates a " +"procurement to bring the virtual stock to the Max Quantity." +msgstr "" + +#. module: procurement +#: view:procurement.order.compute.all:0 +msgid "Scheduler Parameters" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_stock_move +msgid "Stock Move" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Planification" +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Ready" +msgstr "" + +#. module: procurement +#: field:procurement.order.compute.all,automatic:0 +msgid "Automatic orderpoint" +msgstr "" + +#. module: procurement +#: field:mrp.property,composition:0 +msgid "Properties composition" +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Confirmed" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Retry" +msgstr "" + +#. module: procurement +#: view:procurement.order.compute:0 +#: view:procurement.orderpoint.compute:0 +msgid "Parameters" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Confirm" +msgstr "" + +#. module: procurement +#: help:procurement.order,origin:0 +msgid "" +"Reference of the document that created this Procurement.\n" +"This is automatically completed by OpenERP." +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "Procurement Orders to Process" +msgstr "" + +#. module: procurement +#: constraint:res.company:0 +msgid "Error! You can not create recursive companies." +msgstr "" + +#. module: procurement +#: field:procurement.order,priority:0 +msgid "Priority" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +#: field:procurement.order,state:0 +msgid "State" +msgstr "" + +#. module: procurement +#: field:procurement.order,location_id:0 +#: view:stock.warehouse.orderpoint:0 +#: field:stock.warehouse.orderpoint,location_id:0 +msgid "Location" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_stock_picking +msgid "Picking List" +msgstr "" + +#. module: procurement +#: field:make.procurement,warehouse_id:0 +#: view:stock.warehouse.orderpoint:0 +#: field:stock.warehouse.orderpoint,warehouse_id:0 +msgid "Warehouse" +msgstr "" + +#. module: procurement +#: selection:stock.warehouse.orderpoint,logic:0 +msgid "Best price (not yet active!)" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Product & Location" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_procurement_order_compute +msgid "Compute Procurement" +msgstr "" + +#. module: procurement +#: model:ir.module.module,shortdesc:procurement.module_meta_information +#: field:stock.move,procurements:0 +msgid "Procurements" +msgstr "" + +#. module: procurement +#: field:res.company,schedule_range:0 +msgid "Scheduler Range Days" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,help:procurement.procurement_action +msgid "" +"A procurement order is used to record a need for a specific product at a " +"specific location. A procurement order is usually created automatically from " +"sales orders, a Pull Logistics rule or Minimum Stock Rules. When the " +"procurement order is confirmed, it automatically creates the necessary " +"operations to fullfil the need: purchase order proposition, manufacturing " +"order, etc." +msgstr "" + +#. module: procurement +#: field:make.procurement,date_planned:0 +msgid "Planned Date" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Group By" +msgstr "" + +#. module: procurement +#: field:make.procurement,qty:0 +#: field:procurement.order,product_qty:0 +msgid "Quantity" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:377 +#, python-format +msgid "Not enough stock and no minimum orderpoint rule defined." +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:137 +#, python-format +msgid "Invalid action !" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "References" +msgstr "" + +#. module: procurement +#: view:res.company:0 +msgid "Configuration" +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,qty_multiple:0 +msgid "Qty Multiple" +msgstr "" + +#. module: procurement +#: help:procurement.order,procure_method:0 +msgid "" +"If you encode manually a Procurement, you probably want to use a make to " +"order method." +msgstr "" + +#. module: procurement +#: model:ir.ui.menu,name:procurement.menu_stock_procurement +msgid "Automatic Procurements" +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,product_max_qty:0 +msgid "Max Quantity" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_procurement_order +#: model:process.process,name:procurement.process_process_procurementprocess0 +#: view:procurement.order:0 +msgid "Procurement" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.procurement_action +msgid "Procurement Orders" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "To Fix" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Exceptions" +msgstr "" + +#. module: procurement +#: model:process.node,note:procurement.process_node_serviceonorder0 +msgid "Assignment from Production or Purchase Order." +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_mrp_property +msgid "Property" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.act_make_procurement +#: view:make.procurement:0 +msgid "Procurement Request" +msgstr "" + +#. module: procurement +#: view:procurement.orderpoint.compute:0 +msgid "Compute Stock" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Late" +msgstr "" + +#. module: procurement +#: model:process.process,name:procurement.process_process_serviceproductprocess0 +msgid "Service" +msgstr "" + +#. module: procurement +#: model:ir.module.module,description:procurement.module_meta_information +msgid "" +"\n" +" This is the module for computing Procurements.\n" +" " +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,procurement_draft_ids:0 +msgid "Related Procurement Orders" +msgstr "" + +#. module: procurement +#: view:procurement.orderpoint.compute:0 +msgid "" +"Wizard checks all the stock minimum rules and generate procurement order." +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,product_min_qty:0 +msgid "Min Quantity" +msgstr "" + +#. module: procurement +#: selection:procurement.order,priority:0 +msgid "Urgent" +msgstr "" + +#. module: procurement +#: selection:mrp.property,composition:0 +msgid "plus" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:325 +#, python-format +msgid "" +"Please check the Quantity in Procurement Order(s), it should not be less " +"than 1!" +msgstr "" + +#. module: procurement +#: help:stock.warehouse.orderpoint,active:0 +msgid "" +"If the active field is set to False, it will allow you to hide the " +"orderpoint without removing it." +msgstr "" + +#. module: procurement +#: help:stock.warehouse.orderpoint,product_max_qty:0 +msgid "" +"When the virtual stock goes belong the Max Quantity, OpenERP generates a " +"procurement to bring the virtual stock to the Max Quantity." +msgstr "" + +#. module: procurement +#: help:procurement.orderpoint.compute,automatic:0 +msgid "If the stock of a product is under 0, it will act like an orderpoint" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Procurement Lines" +msgstr "" + +#. module: procurement +#: view:procurement.order.compute.all:0 +msgid "" +"This wizard allows you to run all procurement, production and/or purchase " +"orders that should be processed based on their configuration. By default, " +"the scheduler is launched automatically every night by OpenERP. You can use " +"this menu to force it to be launched now. Note that it runs in the " +"background, you may have to wait for a few minutes until it has finished " +"computing." +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +#: field:procurement.order,note:0 +msgid "Note" +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Draft" +msgstr "" + +#. module: procurement +#: view:procurement.order.compute:0 +msgid "This wizard will schedule procurements." +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Status" +msgstr "" + +#. module: procurement +#: selection:procurement.order,priority:0 +msgid "Normal" +msgstr "" + +#. module: procurement +#: constraint:stock.move:0 +msgid "You try to assign a lot which is not from the same product" +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,active:0 +msgid "Active" +msgstr "" + +#. module: procurement +#: model:process.node,name:procurement.process_node_procureproducts0 +msgid "Procure Products" +msgstr "" + +#. module: procurement +#: field:procurement.order,date_planned:0 +msgid "Scheduled date" +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Exception" +msgstr "" + +#. module: procurement +#: code:addons/procurement/schedulers.py:179 +#, python-format +msgid "Automatic OP: %s" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_procurement_orderpoint_compute +msgid "Automatic Order Point" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_stock_warehouse_orderpoint +msgid "Minimum Inventory Rule" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_res_company +msgid "Companies" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Extra Information" +msgstr "" + +#. module: procurement +#: help:procurement.order,name:0 +msgid "Procurement name." +msgstr "" + +#. module: procurement +#: constraint:stock.move:0 +msgid "You must assign a production lot for this product" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Procurement Reason" +msgstr "" + +#. module: procurement +#: sql_constraint:stock.warehouse.orderpoint:0 +msgid "Qty Multiple must be greater than zero." +msgstr "" + +#. module: procurement +#: selection:stock.warehouse.orderpoint,logic:0 +msgid "Order to Max" +msgstr "" + +#. module: procurement +#: field:procurement.order,date_close:0 +msgid "Date Closed" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:372 +#, python-format +msgid "Procurement '%s' is in exception: not enough stock." +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:138 +#, python-format +msgid "Cannot delete Procurement Order(s) which are in %s State!" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:324 +#, python-format +msgid "Data Insufficient !" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_mrp_property_group +#: field:mrp.property,group_id:0 +#: field:mrp.property.group,name:0 +msgid "Property Group" +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "Misc" +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "Locations" +msgstr "" + +#. module: procurement +#: selection:procurement.order,procure_method:0 +msgid "from stock" +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "General Information" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Run Procurement" +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Done" +msgstr "" + +#. module: procurement +#: help:stock.warehouse.orderpoint,qty_multiple:0 +msgid "The procurement quantity will by rounded up to this multiple." +msgstr "" + +#. module: procurement +#: view:make.procurement:0 +#: view:procurement.order:0 +#: selection:procurement.order,state:0 +#: view:procurement.order.compute:0 +#: view:procurement.order.compute.all:0 +#: view:procurement.orderpoint.compute:0 +msgid "Cancel" +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,logic:0 +msgid "Reordering Mode" +msgstr "" + +#. module: procurement +#: field:procurement.order,origin:0 +msgid "Source Document" +msgstr "" + +#. module: procurement +#: selection:procurement.order,priority:0 +msgid "Not urgent" +msgstr "" + +#. module: procurement +#: model:ir.model,name:procurement.model_procurement_order_compute_all +msgid "Compute all schedulers" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Current" +msgstr "" + +#. module: procurement +#: view:board.board:0 +msgid "Procurements in Exception" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Details" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.procurement_action5 +#: model:ir.actions.act_window,name:procurement.procurement_action_board +#: model:ir.actions.act_window,name:procurement.procurement_exceptions +#: model:ir.ui.menu,name:procurement.menu_stock_procurement_action +msgid "Procurement Exceptions" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.act_procurement_2_stock_warehouse_orderpoint +#: model:ir.actions.act_window,name:procurement.act_product_product_2_stock_warehouse_orderpoint +#: model:ir.actions.act_window,name:procurement.act_stock_warehouse_2_stock_warehouse_orderpoint +#: model:ir.actions.act_window,name:procurement.action_orderpoint_form +#: model:ir.ui.menu,name:procurement.menu_stock_order_points +#: view:stock.warehouse.orderpoint:0 +msgid "Minimum Stock Rules" +msgstr "" + +#. module: procurement +#: field:procurement.order,close_move:0 +msgid "Close Move at end" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Scheduled Date" +msgstr "" + +#. module: procurement +#: field:make.procurement,product_id:0 +#: view:procurement.order:0 +#: field:procurement.order,product_id:0 +#: field:stock.warehouse.orderpoint,product_id:0 +msgid "Product" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Temporary" +msgstr "" + +#. module: procurement +#: field:mrp.property,description:0 +#: field:mrp.property.group,description:0 +msgid "Description" +msgstr "" + +#. module: procurement +#: selection:mrp.property,composition:0 +msgid "min" +msgstr "" + +#. module: procurement +#: view:stock.warehouse.orderpoint:0 +msgid "Quantity Rules" +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Running" +msgstr "" + +#. module: procurement +#: field:stock.warehouse.orderpoint,product_uom:0 +msgid "Product UOM" +msgstr "" + +#. module: procurement +#: model:process.node,name:procurement.process_node_serviceonorder0 +msgid "Make to Order" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "UOM" +msgstr "" + +#. module: procurement +#: selection:procurement.order,state:0 +msgid "Waiting" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,help:procurement.action_orderpoint_form +msgid "" +"You can define your minimum stock rules, so that OpenERP will automatically " +"create draft manufacturing orders or purchase quotations according to the " +"stock level. Once the virtual stock of a product (= stock on hand minus all " +"confirmed orders and reservations) is below the minimum quantity, OpenERP " +"will generate a procurement request to increase the stock up to the maximum " +"quantity." +msgstr "" + +#. module: procurement +#: field:procurement.order,move_id:0 +msgid "Reservation" +msgstr "" + +#. module: procurement +#: model:process.node,note:procurement.process_node_procureproducts0 +msgid "The way to procurement depends on the product type." +msgstr "" + +#. module: procurement +#: view:make.procurement:0 +msgid "" +"This wizard will plan the procurement for this product. This procurement may " +"generate task, production orders or purchase orders." +msgstr "" + +#. module: procurement +#: view:res.company:0 +msgid "MRP & Logistics Scheduler" +msgstr "" + +#. module: procurement +#: field:mrp.property,name:0 +#: field:stock.warehouse.orderpoint,name:0 +msgid "Name" +msgstr "" + +#. module: procurement +#: selection:mrp.property,composition:0 +msgid "max" +msgstr "" + +#. module: procurement +#: field:procurement.order,product_uos:0 +msgid "Product UoS" +msgstr "" + +#. module: procurement +#: code:addons/procurement/procurement.py:353 +#, python-format +msgid "from stock: products assigned." +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,name:procurement.action_compute_schedulers +#: model:ir.ui.menu,name:procurement.menu_stock_proc_schedulers +#: view:procurement.order.compute.all:0 +msgid "Compute Schedulers" +msgstr "" + +#. module: procurement +#: model:ir.actions.act_window,help:procurement.procurement_exceptions +msgid "" +"Procurement Orders represent the need for a certain quantity of products, at " +"a given time, in a given location. Sales Orders are one typical source of " +"Procurement Orders (but these are distinct documents). Depending on the " +"procurement parameters and the product configuration, the procurement engine " +"will attempt to satisfy the need by reserving products from stock, ordering " +"products from a supplier, or passing a manufacturing order, etc. A " +"Procurement Exception occurs when the system cannot find a way to fulfill a " +"procurement. Some exceptions will resolve themselves automatically, but " +"others require manual intervention (those are identified by a specific error " +"message)." +msgstr "" + +#. module: procurement +#: field:procurement.order,product_uom:0 +msgid "Product UoM" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Search Procurement" +msgstr "" + +#. module: procurement +#: help:res.company,schedule_range:0 +msgid "" +"This is the time frame analysed by the scheduler when computing " +"procurements. All procurements that are not between today and today+range " +"are skipped for future computation." +msgstr "" + +#. module: procurement +#: selection:procurement.order,priority:0 +msgid "Very Urgent" +msgstr "" + +#. module: procurement +#: field:procurement.orderpoint.compute,automatic:0 +msgid "Automatic Orderpoint" +msgstr "" + +#. module: procurement +#: view:procurement.order:0 +msgid "Procurement Details" +msgstr "" + +#. module: procurement +#: code:addons/procurement/schedulers.py:180 +#, python-format +msgid "SCHEDULER" +msgstr "" diff --git a/addons/project_mrp/i18n/hr.po b/addons/project_mrp/i18n/hr.po index a5bf98634cf..e0658f8525f 100644 --- a/addons/project_mrp/i18n/hr.po +++ b/addons/project_mrp/i18n/hr.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:15+0000\n" -"PO-Revision-Date: 2010-08-03 09:34+0000\n" -"Last-Translator: Mantavya Gajjar (Open ERP) \n" +"PO-Revision-Date: 2011-12-12 00:12+0000\n" +"Last-Translator: Tomislav Bosnjakovic \n" "Language-Team: Vinteh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-11-05 05:23+0000\n" -"X-Generator: Launchpad (build 14231)\n" +"X-Launchpad-Export-Date: 2011-12-12 05:17+0000\n" +"X-Generator: Launchpad (build 14458)\n" "Language: hr\n" #. module: project_mrp @@ -25,7 +25,7 @@ msgstr "Za svaki proizvod, pri vrsti usluge i pri narudžbi" #. module: project_mrp #: model:process.transition,name:project_mrp.process_transition_procuretask0 msgid "Procurement Task" -msgstr "" +msgstr "Procurement Task" #. module: project_mrp #: model:ir.module.module,shortdesc:project_mrp.module_meta_information @@ -45,28 +45,28 @@ msgstr "Ako je tip proizvoda 'usluga' tada kreira zadatak" #. module: project_mrp #: constraint:project.task:0 msgid "Error ! You cannot create recursive tasks." -msgstr "" +msgstr "Greška! Rekurzivni zadaci." #. module: project_mrp #: model:ir.model,name:project_mrp.model_product_product msgid "Product" -msgstr "" +msgstr "Proizvod" #. module: project_mrp #: constraint:product.product:0 msgid "Error: Invalid ean code" -msgstr "" +msgstr "Greška: Neispravan barkod!" #. module: project_mrp #: field:product.product,project_id:0 msgid "Project" -msgstr "" +msgstr "Projekt" #. module: project_mrp #: model:ir.model,name:project_mrp.model_procurement_order #: field:project.task,procurement_id:0 msgid "Procurement" -msgstr "Nabava" +msgstr "Procurement" #. module: project_mrp #: model:ir.model,name:project_mrp.model_project_task @@ -74,7 +74,7 @@ msgstr "Nabava" #: model:process.node,name:project_mrp.process_node_procuretasktask0 #: field:procurement.order,task_id:0 msgid "Task" -msgstr "Zadatak" +msgstr "Task" #. module: project_mrp #: model:process.node,note:project_mrp.process_node_mrptask0 @@ -84,12 +84,12 @@ msgstr "Stvara se zadatak kako bi se pružila usluga" #. module: project_mrp #: model:process.transition,name:project_mrp.process_transition_ordertask0 msgid "Order Task" -msgstr "Zadatak narudžbe" +msgstr "Zadatak naloga" #. module: project_mrp #: model:process.node,name:project_mrp.process_node_saleordertask0 msgid "Sale Order Task" -msgstr "Zadatak Prodajne Narudžbe" +msgstr "Zadatak prodajnog naloga" #. module: project_mrp #: model:process.transition,name:project_mrp.process_transition_createtask0 @@ -125,12 +125,12 @@ msgstr "" #. module: project_mrp #: model:process.transition,note:project_mrp.process_transition_ordertask0 msgid "If procurement method is Make to order and supply method is produce" -msgstr "" +msgstr "If procurement method is Make to order and supply method is produce" #. module: project_mrp #: model:process.node,note:project_mrp.process_node_saleordertask0 msgid "In case you sell services on sale order" -msgstr "U slučaju da prodajete usluge prema narudžbi prodaje" +msgstr "U slučaju kada prodajete usluge na prodajnim nalozima" #~ msgid "Procure Task" #~ msgstr "Zadatak nabave" @@ -142,3 +142,75 @@ msgstr "U slučaju da prodajete usluge prema narudžbi prodaje" #~ msgid "Project Management - MRP and Sale Integration" #~ msgstr "Upravljanje projektima - MRP i Integracija Prodaje" + +#~ msgid "Order Reference must be unique per Company!" +#~ msgstr "Order Reference must be unique per Company!" + +#~ msgid "Create Tasks on SO" +#~ msgstr "Create Tasks on SO" + +#~ msgid "Sale Order Line" +#~ msgstr "Sale Order Line" + +#~ msgid "" +#~ "\n" +#~ "Automatically creates project tasks from procurement lines\n" +#~ "==========================================================\n" +#~ "\n" +#~ "This module will automatically create a new task for each procurement\n" +#~ "order line (e.g. for sale order lines), if the corresponding product\n" +#~ "meets the following characteristics:\n" +#~ "\n" +#~ " * Type = Service\n" +#~ " * Procurement method (Order fulfillment) = MTO (make to order)\n" +#~ " * Supply/Procurement method = Produce\n" +#~ "\n" +#~ "If on top of that a projet is specified on the product form (in the " +#~ "Procurement\n" +#~ "tab), then the new task will be created in that specific project.\n" +#~ "Otherwise, the new task will not belong to any project, and may be added to " +#~ "a\n" +#~ "project manually later.\n" +#~ "\n" +#~ "When the project task is completed or cancelled, the workflow of the " +#~ "corresponding\n" +#~ "procurement line is updated accordingly. For example if this procurement " +#~ "corresponds\n" +#~ "to a sale order line, the sale order line will be considered delivered when " +#~ "the\n" +#~ "task is completed.\n" +#~ "\n" +#~ msgstr "" +#~ "\n" +#~ "Automatically creates project tasks from procurement lines\n" +#~ "==========================================================\n" +#~ "\n" +#~ "This module will automatically create a new task for each procurement\n" +#~ "order line (e.g. for sale order lines), if the corresponding product\n" +#~ "meets the following characteristics:\n" +#~ "\n" +#~ " * Type = Service\n" +#~ " * Procurement method (Order fulfillment) = MTO (make to order)\n" +#~ " * Supply/Procurement method = Produce\n" +#~ "\n" +#~ "If on top of that a projet is specified on the product form (in the " +#~ "Procurement\n" +#~ "tab), then the new task will be created in that specific project.\n" +#~ "Otherwise, the new task will not belong to any project, and may be added to " +#~ "a\n" +#~ "project manually later.\n" +#~ "\n" +#~ "When the project task is completed or cancelled, the workflow of the " +#~ "corresponding\n" +#~ "procurement line is updated accordingly. For example if this procurement " +#~ "corresponds\n" +#~ "to a sale order line, the sale order line will be considered delivered when " +#~ "the\n" +#~ "task is completed.\n" +#~ "\n" + +#~ msgid "Sale order line" +#~ msgstr "Sale order line" + +#~ msgid "Sales Order" +#~ msgstr "Prodajni nalog" 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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \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 \n" +"Language-Team: Croatian \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/report_webkit/i18n/hr.po b/addons/report_webkit/i18n/hr.po new file mode 100644 index 00000000000..01ec38be92b --- /dev/null +++ b/addons/report_webkit/i18n/hr.po @@ -0,0 +1,613 @@ +# 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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-11 11:16+0000\n" +"PO-Revision-Date: 2011-12-11 21:52+0000\n" +"Last-Translator: Tomislav Bosnjakovic \n" +"Language-Team: Croatian \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: report_webkit +#: field:ir.actions.report.xml,webkit_header:0 +msgid "WebKit Header" +msgstr "Zaglavlje Webkita" + +#. module: report_webkit +#: view:ir.actions.report.xml:0 +msgid "Webkit Template (used if Report File is not found)" +msgstr "Predložak Webkita (koristi se ako datoteka izvještaja nije nađena)" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Tabloid 29 279.4 x 431.8 mm" +msgstr "" + +#. module: report_webkit +#: model:ir.actions.act_window,name:report_webkit.action_header_img +#: model:ir.ui.menu,name:report_webkit.menu_header_img +msgid "Header IMG" +msgstr "" + +#. module: report_webkit +#: field:res.company,lib_path:0 +msgid "Webkit Executable Path" +msgstr "Webkit izvršna putanja" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Ledger 28 431.8 x 279.4 mm" +msgstr "" + +#. module: report_webkit +#: help:ir.header_img,type:0 +msgid "Image type(png,gif,jpeg)" +msgstr "Vrsta slike (png,gif,jpeg)" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Executive 4 7.5 x 10 inches, 190.5 x 254 mm" +msgstr "" + +#. module: report_webkit +#: field:ir.header_img,company_id:0 +#: field:ir.header_webkit,company_id:0 +msgid "Company" +msgstr "Organizacija" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:97 +#, python-format +msgid "path to Wkhtmltopdf is not absolute" +msgstr "putanja do Wkhtmltopdf nije apsolutna" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "DLE 26 110 x 220 mm" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B7 21 88 x 125 mm" +msgstr "B7 21 88 x 125 mm" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:306 +#: code:addons/report_webkit/webkit_report.py:320 +#: code:addons/report_webkit/webkit_report.py:338 +#: code:addons/report_webkit/webkit_report.py:354 +#, python-format +msgid "Webkit render" +msgstr "" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Folio 27 210 x 330 mm" +msgstr "" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:67 +#, python-format +msgid "" +"Please install executable on your system'+\n" +" ' (sudo apt-get install wkhtmltopdf) or " +"download it from here:'+\n" +" ' " +"http://code.google.com/p/wkhtmltopdf/downloads/list and set the'+\n" +" ' path to the executable on the Company form." +msgstr "" +"Molim instalirajte izvršnu datoteku u vaš sustav'+\n" +" ' (sudo apt-get install wkhtmltopdf) ili " +"skinite odavde:'+\n" +" ' " +"http://code.google.com/p/wkhtmltopdf/downloads/list i postavite'+\n" +" ' putanju do izvršne datoteke na formi " +"organizacije." + +#. module: report_webkit +#: help:ir.header_img,name:0 +msgid "Name of Image" +msgstr "Naziv slike" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:91 +#, python-format +msgid "" +"Wrong Wkhtmltopdf path set in company'+\n" +" 'Given path is not executable or path is " +"wrong" +msgstr "" +"Pogrešna Wkhtmltopdf putanja postavljena u organizaciji'+\n" +" 'Odabrana putanja nije izvršna datoteka ili " +"je putanja pogrešna" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:166 +#, python-format +msgid "Webkit raise an error" +msgstr "Webkit je uzrokovao grešku" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Legal 3 8.5 x 14 inches, 215.9 x 355.6 mm" +msgstr "Legal 3 8.5 x 14 inches, 215.9 x 355.6 mm" + +#. module: report_webkit +#: model:ir.model,name:report_webkit.model_ir_header_webkit +msgid "ir.header_webkit" +msgstr "ir.header_webkit" + +#. module: report_webkit +#: model:ir.actions.act_window,name:report_webkit.action_header_webkit +#: model:ir.ui.menu,name:report_webkit.menu_header_webkit +msgid "Header HTML" +msgstr "HTML zaglavlja" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A4 0 210 x 297 mm, 8.26 x 11.69 inches" +msgstr "A4 0 210 x 297 mm, 8.26 x 11.69 inches" + +#. module: report_webkit +#: view:report.webkit.actions:0 +msgid "_Cancel" +msgstr "_Otkaži" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B2 17 500 x 707 mm" +msgstr "B2 17 500 x 707 mm" + +#. module: report_webkit +#: model:ir.model,name:report_webkit.model_ir_header_img +msgid "ir.header_img" +msgstr "ir.header_img" + +#. module: report_webkit +#: constraint:res.company:0 +msgid "Error! You can not create recursive companies." +msgstr "Pogreška! Ne možete kreirati rekurzivne organizacije." + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A0 5 841 x 1189 mm" +msgstr "A0 5 841 x 1189 mm" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "C5E 24 163 x 229 mm" +msgstr "C5E 24 163 x 229 mm" + +#. module: report_webkit +#: field:ir.header_img,type:0 +msgid "Type" +msgstr "Vrsta" + +#. module: report_webkit +#: code:addons/report_webkit/wizard/report_webkit_actions.py:134 +#, python-format +msgid "Client Actions Connections" +msgstr "Veze klijentskih radnji" + +#. module: report_webkit +#: field:res.company,header_image:0 +msgid "Available Images" +msgstr "Raspložive slike" + +#. module: report_webkit +#: field:ir.header_webkit,html:0 +msgid "webkit header" +msgstr "zaglavlje webkita" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B1 15 707 x 1000 mm" +msgstr "B1 15 707 x 1000 mm" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A1 6 594 x 841 mm" +msgstr "A1 6 594 x 841 mm" + +#. module: report_webkit +#: help:ir.actions.report.xml,webkit_header:0 +msgid "The header linked to the report" +msgstr "zaglavlje povezano s izvještajem" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:78 +#, python-format +msgid "Wkhtmltopdf library path is not set in company" +msgstr "Wkhtmltopdf library putanja nije povezana s organizacijom" + +#. module: report_webkit +#: model:ir.module.module,description:report_webkit.module_meta_information +msgid "" +"This module adds a new Report Engine based on WebKit library (wkhtmltopdf) " +"to support reports designed in HTML + CSS.\n" +"The module structure and some code is inspired by the report_openoffice " +"module.\n" +"The module allows:\n" +" -HTML report definition\n" +" -Multi header support \n" +" -Multi logo\n" +" -Multi company support\n" +" -HTML and CSS-3 support (In the limit of the actual WebKIT version)\n" +" -JavaScript support \n" +" -Raw HTML debugger\n" +" -Book printing capabilities\n" +" -Margins definition \n" +" -Paper size definition\n" +"and much more\n" +"\n" +"Multiple headers and logos can be defined per company.\n" +"CSS style, header and footer body are defined per company\n" +"\n" +"The library to install can be found here\n" +"http://code.google.com/p/wkhtmltopdf/\n" +"The system libraries are available for Linux, Mac OS X i386 and Windows 32.\n" +"\n" +"After installing the wkhtmltopdf library on the OpenERP Server machine, you " +"need to set the\n" +"path to the wkthtmltopdf executable file on the Company.\n" +"\n" +"For a sample report see also the webkit_report_sample module, and this " +"video:\n" +" http://files.me.com/nbessi/06n92k.mov \n" +"\n" +"\n" +"TODO :\n" +"JavaScript support activation deactivation\n" +"Collated and book format support\n" +"Zip return for separated PDF\n" +"Web client WYSIWYG\n" +" " +msgstr "" +"Ovaj modul dodaje novu izvještajnu platformu na Webkit library (wkhtmltopdf) " +"za podršku izvještajima dizajniranim u HTML + CSS.\n" +"Struktura modula i dio koda je inspiriran sa modulom report_openoffice.\n" +"Modul omogućuje:\n" +" -Definicije HTML izvještaja\n" +" -Podršku za više zaglavlja\n" +" -Više loga\n" +" -Podrušku za više kompanija\n" +" -Podršku za HTML i CSS-3 (U granicama WebKIT verzije)\n" +" -Podršku za JavaScript\n" +" -Debuger za HTML\n" +" -Mogućnost ispisa knjiga\n" +" -Definiranje margina\n" +" -Definiranje veličine papira\n" +"i još mnogo toga\n" +"\n" +"Višestruka zaglavlja i loga se mogu definirati po organizaciji.\n" +"Stilovi CSS-a, tijela zaglavlja i podnožja se definiraju po organizaciji\n" +"Library za instalaciju se može naći ovdje\n" +"http://code.google.com/p/wkhtmltopdf/\n" +"Sistemski library je dobavljiv za Linux, Mac OS X i386 i Windows 32.\n" +"\n" +"Nakon instalacije wkhtmltopdf library na OpenERP poslužitelju, morate " +"postaviti putanju \n" +"do izvršne datoteke wkthtmltopdf na organizaciji.\n" +"\n" +"Za primjer izvještaja pogledajte modul webkit_report_sample i sljedeći " +"video:\n" +" http://files.me.com/nbessi/06n92k.mov \n" +"\n" +"\n" +"TODO :\n" +"Podrška za aktivaciju deaktivaciju JavaScripta\n" +"\n" +"Podrška za razvrstavanje i knjižni format\n" +"Zip povrat za odvojeni PDF\n" +"Web klijent WYSIWYG\n" +" " + +#. module: report_webkit +#: view:ir.actions.report.xml:0 +#: view:res.company:0 +msgid "Webkit" +msgstr "Webkit" + +#. module: report_webkit +#: help:ir.header_webkit,format:0 +msgid "Select Proper Paper size" +msgstr "Odaberite odgovarajuću veličinu papira" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B5 1 176 x 250 mm, 6.93 x 9.84 inches" +msgstr "B5 1 176 x 250 mm, 6.93 x 9.84 inches" + +#. module: report_webkit +#: view:ir.header_webkit:0 +msgid "Content and styling" +msgstr "Sadržaj i stilsko oblikovanje" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A7 11 74 x 105 mm" +msgstr "A7 11 74 x 105 mm" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A6 10 105 x 148 mm" +msgstr "A6 10 105 x 148 mm" + +#. module: report_webkit +#: help:ir.actions.report.xml,report_webkit_data:0 +msgid "This template will be used if the main report file is not found" +msgstr "" +"Ovaj predložak će se koristiti ako glavna datoteka izvještaja nije pronađena" + +#. module: report_webkit +#: field:ir.header_webkit,margin_top:0 +msgid "Top Margin (mm)" +msgstr "Gornja margina (mm)" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:261 +#, python-format +msgid "Please set a header in company settings" +msgstr "Molim postavite zaglavlje u postavkama organizacije" + +#. module: report_webkit +#: view:report.webkit.actions:0 +msgid "_Ok" +msgstr "_U redu" + +#. module: report_webkit +#: help:report.webkit.actions,print_button:0 +msgid "" +"Check this to add a Print action for this Report in the sidebar of the " +"corresponding document types" +msgstr "" +"Označite ovo za dodavanje akcije ispisa za ovaj izvještaj na bočnoj traci " +"odgovarajuće vrste dokumenta" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B3 18 353 x 500 mm" +msgstr "B3 18 353 x 500 mm" + +#. module: report_webkit +#: help:ir.actions.report.xml,webkit_debug:0 +msgid "Enable the webkit engine debugger" +msgstr "Omogući debuger webkit platforme" + +#. module: report_webkit +#: field:ir.header_img,img:0 +msgid "Image" +msgstr "Slika" + +#. module: report_webkit +#: field:res.company,header_webkit:0 +msgid "Available html" +msgstr "Raspoloživ html" + +#. module: report_webkit +#: help:report.webkit.actions,open_action:0 +msgid "" +"Check this to view the newly added internal print action after creating it " +"(technical view) " +msgstr "" +"Označi ovo da bi pogledali novododanu internu akciju ispisa nakon kreiranja " +"(tehnički pogled) " + +#. module: report_webkit +#: view:res.company:0 +msgid "Images" +msgstr "Slike" + +#. module: report_webkit +#: selection:ir.header_webkit,orientation:0 +msgid "Portrait" +msgstr "Portret" + +#. module: report_webkit +#: selection:ir.header_webkit,orientation:0 +msgid "Landscape" +msgstr "Pejzažno" + +#. module: report_webkit +#: view:ir.header_webkit:0 +msgid "page setup" +msgstr "postava stranice" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B8 22 62 x 88 mm" +msgstr "B8 22 62 x 88 mm" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A2 7 420 x 594 mm" +msgstr "A2 7 420 x 594 mm" + +#. module: report_webkit +#: field:report.webkit.actions,print_button:0 +msgid "Add print button" +msgstr "Dodaj gumb za ispis" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A9 13 37 x 52 mm" +msgstr "A9 13 37 x 52 mm" + +#. module: report_webkit +#: model:ir.model,name:report_webkit.model_res_company +msgid "Companies" +msgstr "Organizacije" + +#. module: report_webkit +#: field:ir.header_webkit,margin_bottom:0 +msgid "Bottom Margin (mm)" +msgstr "Donja margina (mm)" + +#. module: report_webkit +#: model:ir.model,name:report_webkit.model_report_webkit_actions +msgid "Webkit Actions" +msgstr "Webkit akcije" + +#. module: report_webkit +#: field:report.webkit.actions,open_action:0 +msgid "Open added action" +msgstr "Otvori dodanu akciju" + +#. module: report_webkit +#: field:ir.header_webkit,margin_right:0 +msgid "Right Margin (mm)" +msgstr "Desna margina (mm)" + +#. module: report_webkit +#: field:ir.header_webkit,orientation:0 +msgid "Orientation" +msgstr "Orijentacija" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B6 20 125 x 176 mm" +msgstr "B6 20 125 x 176 mm" + +#. module: report_webkit +#: help:ir.header_webkit,html:0 +msgid "Set Webkit Report Header" +msgstr "Postavi zaglavlje Webkit izvještaja" + +#. module: report_webkit +#: field:ir.header_webkit,format:0 +msgid "Paper size" +msgstr "Veličina papira" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid ":B10 16 31 x 44 mm" +msgstr ":B10 16 31 x 44 mm" + +#. module: report_webkit +#: field:ir.header_webkit,css:0 +msgid "Header CSS" +msgstr "Zaglavlje CSS" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B4 19 250 x 353 mm" +msgstr "B4 19 250 x 353 mm" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A3 8 297 x 420 mm" +msgstr "A3 8 297 x 420 mm" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:240 +#, python-format +msgid "" +"'))\n" +" header = report_xml.webkit_header.html\n" +" footer = report_xml.webkit_header.footer_html\n" +" if not header and report_xml.header:\n" +" raise except_osv(\n" +" _('No header defined for this Webkit report!" +msgstr "" + +#. module: report_webkit +#: help:res.company,lib_path:0 +msgid "Complete (Absolute) path to the wkhtmltopdf executable." +msgstr "Dovrši (apsolutnu) putanju do izvršen datoteke wkhtmltopdf" + +#. module: report_webkit +#: field:ir.header_webkit,footer_html:0 +msgid "webkit footer" +msgstr "podnožje webkita" + +#. module: report_webkit +#: field:ir.actions.report.xml,webkit_debug:0 +msgid "Webkit debug" +msgstr "Webkit debug" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Letter 2 8.5 x 11 inches, 215.9 x 279.4 mm" +msgstr "Letter 2 8.5 x 11 inches, 215.9 x 279.4 mm" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B0 14 1000 x 1414 mm" +msgstr "B0 14 1000 x 1414 mm" + +#. module: report_webkit +#: field:ir.actions.report.xml,report_webkit_data:0 +msgid "Webkit Template" +msgstr "Predložak Webkita" + +#. module: report_webkit +#: model:ir.module.module,shortdesc:report_webkit.module_meta_information +msgid "Webkit Report Engine" +msgstr "Platforma Webkit izvještaja" + +#. module: report_webkit +#: field:ir.header_img,name:0 +#: field:ir.header_webkit,name:0 +msgid "Name" +msgstr "Naziv" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A5 9 148 x 210 mm" +msgstr "A5 9 148 x 210 mm" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "A8 12 52 x 74 mm" +msgstr "A8 12 52 x 74 mm" + +#. module: report_webkit +#: model:ir.actions.act_window,name:report_webkit.wizard_ofdo_report_actions +#: view:report.webkit.actions:0 +msgid "Add Print Buttons" +msgstr "Dodaj gumbe za ispis" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "Comm10E 25 105 x 241 mm, U.S. Common 10 Envelope" +msgstr "Comm10E 25 105 x 241 mm, U.S. normalna 10 omotnica" + +#. module: report_webkit +#: code:addons/report_webkit/webkit_report.py:255 +#, python-format +msgid "Webkit Report template not found !" +msgstr "Predložak Webkit izvještaja nije pronađen" + +#. module: report_webkit +#: field:ir.header_webkit,margin_left:0 +msgid "Left Margin (mm)" +msgstr "Lijeva margina (mm)" + +#. module: report_webkit +#: view:res.company:0 +msgid "Headers" +msgstr "Zaglavlja" + +#. module: report_webkit +#: help:ir.header_webkit,footer_html:0 +msgid "Set Webkit Report Footer." +msgstr "Postavi podnožje Webkit izvještaja" + +#. module: report_webkit +#: selection:ir.header_webkit,format:0 +msgid "B9 23 33 x 62 mm" +msgstr "B9 23 33 x 62 mm" + +#. module: report_webkit +#: model:ir.model,name:report_webkit.model_ir_actions_report_xml +msgid "ir.actions.report.xml" +msgstr "ir.actions.report.xml" diff --git a/addons/report_webkit_sample/i18n/hr.po b/addons/report_webkit_sample/i18n/hr.po new file mode 100644 index 00000000000..184eca13c99 --- /dev/null +++ b/addons/report_webkit_sample/i18n/hr.po @@ -0,0 +1,153 @@ +# 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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-11 11:16+0000\n" +"PO-Revision-Date: 2011-12-11 20:28+0000\n" +"Last-Translator: Tomislav Bosnjakovic \n" +"Language-Team: Croatian \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: report_webkit_sample +#: model:ir.actions.report.xml,name:report_webkit_sample.report_webkit_html +msgid "WebKit invoice" +msgstr "WebKit račun" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:35 +msgid "Supplier Invoice" +msgstr "Ulazni račun" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:49 +msgid "Unit Price" +msgstr "Jedinična cijena" + +#. module: report_webkit_sample +#: model:ir.module.module,description:report_webkit_sample.module_meta_information +msgid "" +"Samples for Webkit Report Engine (report_webkit module).\n" +"\n" +" A sample invoice report is included in this module, as well as a wizard " +"to\n" +" add Webkit Report entries on any Document in the system.\n" +" \n" +" You have to create the print buttons by calling the wizard. For more " +"details see:\n" +" http://files.me.com/nbessi/06n92k.mov \n" +" " +msgstr "" +"Samples for Webkit Report Engine (report_webkit module).\n" +"Primjeri Webkit izvještajne platforme (report_webkit modul).\n" +"\n" +" U modul je uključen primjer izvještaja računa, kao i asistent za \n" +" dodavanje stavaka Webkit izvještaja na bilo koji dokument u sustavu.\n" +"\n" +" Morate kreirati gumbe za ispis pozivajući asistenta. Za više detalja " +"pogledajte: \n" +" http://files.me.com/nbessi/06n92k.mov \n" +" " + +#. module: report_webkit_sample +#: model:ir.module.module,shortdesc:report_webkit_sample.module_meta_information +msgid "Webkit Report Samples" +msgstr "Primjeri Webkit izvještaja" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:49 +msgid "Disc.(%)" +msgstr "Popust (%)" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:22 +msgid "Fax" +msgstr "Fax" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:44 +msgid "Document" +msgstr "Dokument" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:49 +msgid "Description" +msgstr "Opis" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:49 +msgid "Price" +msgstr "Cijena" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:44 +msgid "Invoice Date" +msgstr "Datum računa" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:49 +msgid "QTY" +msgstr "Kol." + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:64 +msgid "Base" +msgstr "Osnovica" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:44 +msgid "Partner Ref." +msgstr "Partnerova oznaka" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:49 +msgid "Taxes" +msgstr "Porezi" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:64 +msgid "Amount" +msgstr "Iznos" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:28 +msgid "VAT" +msgstr "PDV" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:37 +msgid "Refund" +msgstr "Povrat" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:19 +msgid "Tel" +msgstr "Tel" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:25 +msgid "E-mail" +msgstr "E-pošta" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:33 +msgid "Invoice" +msgstr "Račun" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:39 +msgid "Supplier Refund" +msgstr "Odobrenje dobavljača" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:76 +msgid "Total" +msgstr "Ukupno" diff --git a/addons/resource/i18n/hr.po b/addons/resource/i18n/hr.po index f9508416a4c..8f18314bc61 100644 --- a/addons/resource/i18n/hr.po +++ b/addons/resource/i18n/hr.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-11 11:16+0000\n" -"PO-Revision-Date: 2011-12-10 11:03+0000\n" +"PO-Revision-Date: 2011-12-11 19:39+0000\n" "Last-Translator: Tomislav Bosnjakovic \n" "Language-Team: Croatian \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-11 05:36+0000\n" -"X-Generator: Launchpad (build 14450)\n" +"X-Launchpad-Export-Date: 2011-12-12 05:17+0000\n" +"X-Generator: Launchpad (build 14458)\n" #. module: resource #: help:resource.calendar.leaves,resource_id:0 @@ -23,6 +23,8 @@ msgid "" "If empty, this is a generic holiday for the company. If a resource is set, " "the holiday/leave is only for this resource" msgstr "" +"Ako je prazno, ovo je generički praznik za organizaciju. Ako je resurs " +"postavljen, praznik/odsustvo je samo za taj resurs." #. module: resource #: selection:resource.calendar.attendance,dayofweek:0 @@ -32,18 +34,18 @@ msgstr "petak" #. module: resource #: field:resource.resource,resource_type:0 msgid "Resource Type" -msgstr "" +msgstr "Tip resursa" #. module: resource #: model:ir.model,name:resource.model_resource_calendar_leaves #: view:resource.calendar.leaves:0 msgid "Leave Detail" -msgstr "" +msgstr "Detalji o odsustvu" #. module: resource #: model:ir.actions.act_window,name:resource.resource_calendar_resources_leaves msgid "Resources Leaves" -msgstr "" +msgstr "Odsustva resursa" #. module: resource #: model:ir.actions.act_window,name:resource.action_resource_calendar_form @@ -51,59 +53,60 @@ msgstr "" #: field:resource.calendar,attendance_ids:0 #: view:resource.calendar.attendance:0 msgid "Working Time" -msgstr "" +msgstr "Radno vrijeme" #. module: resource #: selection:resource.calendar.attendance,dayofweek:0 msgid "Thursday" -msgstr "" +msgstr "četvrtak" #. module: resource #: view:resource.calendar.leaves:0 #: view:resource.resource:0 msgid "Group By..." -msgstr "" +msgstr "Grupiraj po..." #. module: resource #: selection:resource.calendar.attendance,dayofweek:0 msgid "Sunday" -msgstr "" +msgstr "Nedelja" #. module: resource #: view:resource.resource:0 msgid "Search Resource" -msgstr "" +msgstr "Pretraži resurse" #. module: resource #: view:resource.resource:0 msgid "Type" -msgstr "" +msgstr "Vrsta" #. module: resource #: model:ir.actions.act_window,name:resource.action_resource_resource_tree #: view:resource.resource:0 msgid "Resources" -msgstr "" +msgstr "Resursi" #. module: resource #: field:resource.calendar,manager:0 msgid "Workgroup manager" -msgstr "" +msgstr "Voditelj radne grupe" #. module: resource #: help:resource.calendar.attendance,hour_from:0 msgid "Working time will start from" -msgstr "" +msgstr "Radno vrijeme počinje od" #. module: resource #: constraint:resource.calendar.leaves:0 msgid "Error! leave start-date must be lower then leave end-date." msgstr "" +"Greška! Datum početka odsustva mora biti manji od završnog datuma odsustva" #. module: resource #: model:ir.model,name:resource.model_resource_calendar msgid "Resource Calendar" -msgstr "" +msgstr "Kalendar resursa" #. module: resource #: field:resource.calendar,company_id:0 @@ -112,48 +115,48 @@ msgstr "" #: view:resource.resource:0 #: field:resource.resource,company_id:0 msgid "Company" -msgstr "" +msgstr "Organizacija" #. module: resource #: selection:resource.resource,resource_type:0 msgid "Material" -msgstr "" +msgstr "Materijal" #. module: resource #: field:resource.calendar.attendance,dayofweek:0 msgid "Day of week" -msgstr "" +msgstr "Dan u tjednu" #. module: resource #: help:resource.calendar.attendance,hour_to:0 msgid "Working time will end at" -msgstr "" +msgstr "Radno vrijeme će završiti u" #. module: resource #: field:resource.calendar.attendance,date_from:0 msgid "Starting date" -msgstr "" +msgstr "Početni datum" #. module: resource #: view:resource.calendar:0 msgid "Search Working Time" -msgstr "" +msgstr "Pretraži radno vrijeme" #. module: resource #: view:resource.calendar.leaves:0 msgid "Reason" -msgstr "" +msgstr "Razlog" #. module: resource #: view:resource.resource:0 #: field:resource.resource,user_id:0 msgid "User" -msgstr "" +msgstr "Korisnik" #. module: resource #: view:resource.calendar.leaves:0 msgid "Date" -msgstr "" +msgstr "Datum" #. module: resource #: view:resource.calendar.leaves:0 @@ -163,7 +166,7 @@ msgstr "" #. module: resource #: field:resource.calendar.leaves,date_to:0 msgid "End Date" -msgstr "" +msgstr "Završni datum" #. module: resource #: model:ir.actions.act_window,name:resource.resource_calendar_closing_days @@ -177,7 +180,7 @@ msgstr "" #: field:resource.calendar.leaves,resource_id:0 #: view:resource.resource:0 msgid "Resource" -msgstr "" +msgstr "Resurs" #. module: resource #: view:resource.calendar:0 @@ -186,7 +189,7 @@ msgstr "" #: field:resource.calendar.leaves,name:0 #: field:resource.resource,name:0 msgid "Name" -msgstr "" +msgstr "Naziv" #. module: resource #: model:ir.module.module,description:resource.module_meta_information @@ -200,11 +203,21 @@ msgid "" "\n" " " msgstr "" +"\n" +" Module for resource management\n" +" Modul za upravljanje resursima\n" +" Resurs predstavlja nešto što može biti dodjeljeno\n" +" (programer na zadataku ili proizvodni centar na radnom nalogu " +"proizvodnje).\n" +" Ovaj modul upravlja kalendarom resursa dodjeljenom svakom resursu.\n" +" Također upravlja odsustvima svih resursa.\n" +"\n" +" " #. module: resource #: selection:resource.calendar.attendance,dayofweek:0 msgid "Wednesday" -msgstr "" +msgstr "Srijeda" #. module: resource #: view:resource.calendar.leaves:0 @@ -216,12 +229,12 @@ msgstr "" #. module: resource #: model:ir.model,name:resource.model_resource_resource msgid "Resource Detail" -msgstr "" +msgstr "Detalji resursa" #. module: resource #: field:resource.resource,active:0 msgid "Active" -msgstr "" +msgstr "Aktivan" #. module: resource #: help:resource.resource,active:0 @@ -229,11 +242,12 @@ msgid "" "If the active field is set to False, it will allow you to hide the resource " "record without removing it." msgstr "" +"Ako je ovo polje postavljeno na NE, moežte sakriti resurs bez da ga uklonite." #. module: resource #: field:resource.calendar.attendance,calendar_id:0 msgid "Resource's Calendar" -msgstr "" +msgstr "Kalendar resursa" #. module: resource #: help:resource.resource,user_id:0 @@ -253,17 +267,17 @@ msgstr "" #. module: resource #: field:resource.resource,code:0 msgid "Code" -msgstr "" +msgstr "Šifra" #. module: resource #: selection:resource.calendar.attendance,dayofweek:0 msgid "Monday" -msgstr "" +msgstr "Ponedjeljak" #. module: resource #: field:resource.calendar.attendance,hour_to:0 msgid "Work to" -msgstr "" +msgstr "Radi do" #. module: resource #: help:resource.resource,time_efficiency:0 @@ -273,27 +287,31 @@ msgid "" "show a load of 100% for this phase by default, but if we put a efficency of " "200%, then his load will only be 50%." msgstr "" +"Ovo polje prikazuje efikasnost svakog resursa u izvršavanju zadataka. Npr. " +"resurs se ostavi sam na 5 dana, sa 5 dodjeljenih zadataka. Predefinirano se " +"prikazuje opterećenje od 100%, ali ako stavimo efikasnost od 200%, tada je " +"njegovo opterećenje samo 50%." #. module: resource #: selection:resource.calendar.attendance,dayofweek:0 msgid "Tuesday" -msgstr "" +msgstr "Utorak" #. module: resource #: field:resource.calendar.leaves,calendar_id:0 msgid "Working time" -msgstr "" +msgstr "Radno vrijeme" #. module: resource #: model:ir.actions.act_window,name:resource.action_resource_calendar_leave_tree #: model:ir.ui.menu,name:resource.menu_view_resource_calendar_leaves_search msgid "Resource Leaves" -msgstr "" +msgstr "Odsustva resursa" #. module: resource #: view:resource.resource:0 msgid "General Information" -msgstr "" +msgstr "Opći podaci" #. module: resource #: model:ir.actions.act_window,help:resource.action_resource_resource_tree @@ -302,45 +320,48 @@ msgid "" "in a specific project phase. You can also set their efficiency level and " "workload based on their weekly working hours." msgstr "" +"Resursi vam omogućuju kreiranje i upravljanje resursima koji trebaju biti " +"uključeni u neku fazu projekta. Također možete postaviti njihovu razinu " +"efikasnosti i opterećenje na osnovi njihovih tjednih radnih sati." #. module: resource #: view:resource.resource:0 msgid "Inactive" -msgstr "" +msgstr "Neaktivan" #. module: resource #: code:addons/resource/faces/resource.py:340 #, python-format msgid "(vacation)" -msgstr "" +msgstr "(odmor)" #. module: resource #: field:resource.resource,time_efficiency:0 msgid "Efficiency factor" -msgstr "" +msgstr "Faktor efikasnosti" #. module: resource #: selection:resource.resource,resource_type:0 msgid "Human" -msgstr "" +msgstr "Čovjek" #. module: resource #: model:ir.model,name:resource.model_resource_calendar_attendance msgid "Work Detail" -msgstr "" +msgstr "Detalj posla" #. module: resource #: field:resource.calendar.leaves,date_from:0 msgid "Start Date" -msgstr "" +msgstr "Početni datum" #. module: resource #: code:addons/resource/resource.py:246 #, python-format msgid " (copy)" -msgstr "" +msgstr " (kopija)" #. module: resource #: selection:resource.calendar.attendance,dayofweek:0 msgid "Saturday" -msgstr "" +msgstr "Subota" From 3635fd9ce0ac1a64750b699ec17f82632142c7e3 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Mon, 12 Dec 2011 08:16:33 +0100 Subject: [PATCH 35/66] fix bzr revid: fp@tinyerp.com-20111212071633-fk0h89wuq43q5x4n --- addons/project_caldav/project_caldav_view.xml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/addons/project_caldav/project_caldav_view.xml b/addons/project_caldav/project_caldav_view.xml index 0d566be4619..c88892eae11 100644 --- a/addons/project_caldav/project_caldav_view.xml +++ b/addons/project_caldav/project_caldav_view.xml @@ -57,20 +57,6 @@
- - - project.task.caldav.form2 - project.task - - form - - - - - - - - project.task.caldav.form3 From a03ce1d5d8796c570340ae07487f9a18e406b7c1 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Mon, 12 Dec 2011 09:34:21 +0100 Subject: [PATCH 36/66] [FIX] modules: remove empty string certificates that violate unique key constraint bzr revid: rco@openerp.com-20111212083421-7m7evgqnv0pdasbz --- addons/google_base_account/__openerp__.py | 1 - addons/import_google/__openerp__.py | 1 - addons/l10n_hn/__openerp__.py | 1 - addons/portal/__openerp__.py | 1 - 4 files changed, 4 deletions(-) diff --git a/addons/google_base_account/__openerp__.py b/addons/google_base_account/__openerp__.py index ed5700b3116..ec204f0f77c 100644 --- a/addons/google_base_account/__openerp__.py +++ b/addons/google_base_account/__openerp__.py @@ -36,6 +36,5 @@ 'demo_xml': [], 'installable': True, 'active': False, - 'certificate': '', } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/import_google/__openerp__.py b/addons/import_google/__openerp__.py index a0a15756ec3..fe469c94504 100644 --- a/addons/import_google/__openerp__.py +++ b/addons/import_google/__openerp__.py @@ -42,6 +42,5 @@ ], 'installable': True, 'active': False, - 'certificate': '', } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/l10n_hn/__openerp__.py b/addons/l10n_hn/__openerp__.py index 31d9344cb65..b590e65af67 100644 --- a/addons/l10n_hn/__openerp__.py +++ b/addons/l10n_hn/__openerp__.py @@ -49,6 +49,5 @@ ], 'demo_xml': [], 'installable': True, - 'certificate': '', } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/portal/__openerp__.py b/addons/portal/__openerp__.py index d76917fcf45..035ee45b4df 100644 --- a/addons/portal/__openerp__.py +++ b/addons/portal/__openerp__.py @@ -45,7 +45,6 @@ module 'share'. 'wizard/share_wizard_view.xml', ], 'installable': True, - 'certificate' : '', } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From bee181deab05279601f354666ee929bfd21da83b Mon Sep 17 00:00:00 2001 From: "Yogesh (OpenERP)" Date: Mon, 12 Dec 2011 14:14:17 +0530 Subject: [PATCH 37/66] [FIX] use set_value method instead of direct assign value in do_clear method. bzr revid: ysa@tinyerp.com-20111212084417-w4r16uesqqz5w51c --- addons/web/static/src/js/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 0be95af2571..d1e4b161b39 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -411,7 +411,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search $('.searchview_extended_groups_list').empty(); _.each(this.inputs, function (input) { if(input.datewidget && input.datewidget.value) { - input.datewidget.value = false; + input.datewidget.set_value(false); } }); setTimeout(this.on_clear, 0); From 900c2e2daad2e99f8701d47c8a91522efe4163c4 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 12 Dec 2011 11:39:05 +0100 Subject: [PATCH 38/66] [IMP] action ir.ui.menu bzr revid: al@openerp.com-20111212103905-6zjkkou9cquxs2ys --- addons/web/static/src/js/chrome.js | 7 +++++++ addons/web/static/src/js/views.js | 3 +++ 2 files changed, 10 insertions(+) diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 3c212616496..fa3d1d037a7 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -1120,6 +1120,13 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie on_menu_action: function(action) { this.action_manager.do_action(action); }, + do_action: function(action) { + console.log("Action",action); + if(action.type === "ir.ui.menu") { + this.do_reload(); + this.rpc('/web/menu/action', {'menu_id': action.menu_id}, this.menu.on_menu_action_loaded); + } + }, do_about: function() { } diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index d57f9d4a84d..f983cd71cc8 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -177,6 +177,9 @@ session.web.ActionManager = session.web.Widget.extend({ }, ir_actions_act_url: function (action) { window.open(action.url, action.target === 'self' ? '_self' : '_blank'); + }, + ir_ui_menu: function (action) { + this.widget_parent.do_action(action); } }); From 799340ad0a6fb626cd9bcbc9bf3a28adfd5d6e01 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 12 Dec 2011 11:40:29 +0100 Subject: [PATCH 39/66] [IMP] immediate install, remove old web modules bzr revid: al@openerp.com-20111212104029-fn7h53l24c7349j8 --- openerp/addons/base/module/module.py | 147 +++++---------------------- 1 file changed, 23 insertions(+), 124 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 27cb1d42d67..2c6dafb5b43 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -40,7 +40,6 @@ from tools.translate import _ from osv import fields, osv, orm - ACTION_DICT = { 'view_type': 'form', 'view_mode': 'form', @@ -214,7 +213,6 @@ class module(osv.osv): 'reports_by_module': fields.function(_get_views, method=True, string='Reports', type='text', multi="meta", store=True), 'views_by_module': fields.function(_get_views, method=True, string='Views', type='text', multi="meta", store=True), 'certificate' : fields.char('Quality Certificate', size=64, readonly=True), - 'web': fields.boolean('Has a web component', readonly=True), 'application': fields.boolean('Application', readonly=True), 'icon': fields.char('Icon URL', size=128), 'complexity': fields.selection([('easy','Easy'), ('normal','Normal'), ('expert','Expert')], @@ -226,7 +224,6 @@ class module(osv.osv): 'state': 'uninstalled', 'demo': False, 'license': 'AGPL-3', - 'web': False, 'complexity': 'normal', } _order = 'name' @@ -333,7 +330,16 @@ class module(osv.osv): self.state_update(cr, uid, ids, 'to install', ['uninstalled'], context) cr.commit() db, pool = pooler.restart_pool(cr.dbname, update_module=True) - return pool.get('res.config').next(db.cursor(), uid, [], context=context) + menu_ids = self.root_menus(cr,uid,ids,context) + print "Menus, Menus:",menu_ids + if menu_ids: + action = { + 'type': 'ir.ui.menu', + 'menu_id': menu_ids[0], + 'reload' : True, + } + return action + return False def button_install_cancel(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'uninstalled', 'demo':False}) @@ -411,7 +417,6 @@ class module(osv.osv): 'website': terp.get('website', ''), 'license': terp.get('license', 'AGPL-3'), 'certificate': terp.get('certificate') or False, - 'web': terp.get('web') or False, 'complexity': terp.get('complexity', ''), } @@ -584,31 +589,6 @@ class module(osv.osv): logger.critical('module %s: invalid quality certificate: %s', mod.name, mod.certificate) raise osv.except_osv(_('Error'), _('Module %s: Invalid Quality Certificate') % (mod.name,)) - def list_web(self, cr, uid, context=None): - """ list_web(cr, uid, context) -> [(module_name, module_version)] - Lists all the currently installed modules with a web component. - - Returns a list of a tuple of addon names and addon versions. - """ - return [ - (module['name'], module['installed_version']) - for module in self.browse(cr, uid, - self.search(cr, uid, - [('web', '=', True), - ('state', 'in', ['installed','to upgrade','to remove'])], - context=context), - context=context)] - def _web_dependencies(self, cr, uid, module, context=None): - for dependency in module.dependencies_id: - (parent,) = self.browse(cr, uid, self.search(cr, uid, - [('name', '=', dependency.name)], context=context), - context=context) - if parent.web: - yield parent.name - else: - self._web_dependencies( - cr, uid, parent, context=context) - def _translations_subdir(self, module): """ Returns the path to the subdirectory holding translations for the module files, or None if it can't find one @@ -623,106 +603,26 @@ class module(osv.osv): if subdir: return subdir return None - def _add_translations(self, module, web_data): - """ Adds translation data to a zipped web module - - :param module: a module descriptor - :type module: browse(ir.module.module) - :param web_data: zipped data of a web module - :type web_data: bytes - """ - # cStringIO.StringIO is either read or write, not r/w - web_zip = StringIO.StringIO(web_data) - web_archive = zipfile.ZipFile(web_zip, 'a') - - # get the contents of the i18n or po folder and move them to the - # po/messages subdirectory of the web module. - # The POT file will be incorrectly named, but that should not - # matter since the web client is not going to use it, only the PO - # files. - translations_file = cStringIO.StringIO( - addons.zip_directory(self._translations_subdir(module), False)) - translations_archive = zipfile.ZipFile(translations_file) - - for path in translations_archive.namelist(): - web_path = os.path.join( - 'web', 'po', 'messages', os.path.basename(path)) - web_archive.writestr( - web_path, - translations_archive.read(path)) - - translations_archive.close() - translations_file.close() - - web_archive.close() - try: - return web_zip.getvalue() - finally: - web_zip.close() - - def get_web(self, cr, uid, names, context=None): - """ get_web(cr, uid, [module_name], context) -> [{name, depends, content}] - - Returns the web content of all the named addons. - - The toplevel directory of the zipped content is called 'web', - its final naming has to be managed by the client - """ - modules = self.browse(cr, uid, - self.search(cr, uid, [('name', 'in', names)], context=context), - context=context) - if not modules: return [] - self.__logger.info('Sending web content of modules %s ' - 'to web client', names) - - modules_data = [] - for module in modules: - web_data = addons.zip_directory( - addons.get_module_resource(module.name, 'web'), False) - if self._translations_subdir(module): - web_data = self._add_translations(module, web_data) - modules_data.append({ - 'name': module.name, - 'version': module.installed_version, - 'depends': list(self._web_dependencies( - cr, uid, module, context=context)), - 'content': base64.encodestring(web_data) - }) - return modules_data - - def menus(self, cr, uid, ids, maxdepth=0, context=None): - """ Returns ids of all menus of depth below ``maxdepth`` - created by the modules whose ids are provided. + def root_menus(self, cr, uid, ids, context=None): + """ Return root menu ids the menus created by the modules whose ids are + provided. :param list[int] ids: modules to get menus from - :param list[str] fields: list of menu fields to fetch, defaults to all - :param int maxdepth: maximum depth of menus to return, returns all menus by default - :returns: a list of menu object dicts - :rtype: list[int] """ - IrModelData = self.pool.get('ir.model.data') - menus = [] - module_names = [module.name for module in self.browse(cr, uid, ids, context=context)] + values = self.read(cr, uid, ids, ['name'], context=context) + module_names = [i['name'] for i in values] - all_menu_ids = [model.res_id for model in IrModelData.browse(cr, uid, - IrModelData.search(cr, uid, [ - ('model', '=', 'ir.ui.menu'), ('module', 'in', module_names) - ], context=context), - context=context)] + ids = self.pool.get('ir.model.data').search(cr, uid, [ ('model', '=', 'ir.ui.menu'), ('module', 'in', module_names) ], context=context) + values = self.pool.get('ir.model.data').read(cr, uid, ids, ['res_id'], context=context) + all_menu_ids = [i['res_id'] for i in values] - for candidate in self.pool.get('ir.ui.menu').browse(cr, uid, all_menu_ids, context=context): - if not maxdepth: - menus.append(candidate.id) - continue - depth = 1 - menu = candidate + root_menu_ids = [] + for menu in self.pool.get('ir.ui.menu').browse(cr, uid, all_menu_ids, context=context): while menu.parent_id: - depth += 1 menu = menu.parent_id - if depth <= maxdepth: - menus.append(candidate.id) - return menus -module() + if not menu.id in root_menu_ids: + root_menu_ids.append(menu.id) + return root_menu_ids class module_dependency(osv.osv): _name = "ir.module.module.dependency" @@ -752,6 +652,5 @@ class module_dependency(osv.osv): ('unknown', 'Unknown'), ], string='State', readonly=True, select=True), } -module_dependency() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From d47871a6e702df928cea05dc929850c932b4ceec Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 12 Dec 2011 11:57:14 +0100 Subject: [PATCH 40/66] [FIX] more web removal bzr revid: al@openerp.com-20111212105714-2qadzhd4kga9qqdq --- openerp/addons/base/module/module.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 2c6dafb5b43..05ad5fccca4 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -331,7 +331,6 @@ class module(osv.osv): cr.commit() db, pool = pooler.restart_pool(cr.dbname, update_module=True) menu_ids = self.root_menus(cr,uid,ids,context) - print "Menus, Menus:",menu_ids if menu_ids: action = { 'type': 'ir.ui.menu', @@ -589,20 +588,6 @@ class module(osv.osv): logger.critical('module %s: invalid quality certificate: %s', mod.name, mod.certificate) raise osv.except_osv(_('Error'), _('Module %s: Invalid Quality Certificate') % (mod.name,)) - def _translations_subdir(self, module): - """ Returns the path to the subdirectory holding translations for the - module files, or None if it can't find one - - :param module: a module object - :type module: browse(ir.module.module) - """ - subdir = addons.get_module_resource(module.name, 'po') - if subdir: return subdir - # old naming convention - subdir = addons.get_module_resource(module.name, 'i18n') - if subdir: return subdir - return None - def root_menus(self, cr, uid, ids, context=None): """ Return root menu ids the menus created by the modules whose ids are provided. From 802ca760a01e5ad3cf1f895d5f504db0d2285777 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 12 Dec 2011 12:36:24 +0100 Subject: [PATCH 41/66] [FIX] positioning of datetime widget trigger button in date-related searchview widgets lp bug: https://launchpad.net/bugs/902122 fixed bzr revid: xmo@openerp.com-20111212113624-667rvjycmuto1oid --- addons/web/static/src/css/base.css | 10 +++++++++- addons/web/static/src/xml/base.xml | 8 ++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 3a163beb832..a52510b8275 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -570,8 +570,16 @@ label.error { } /* SearchView */ +.openerp .oe_searchview_field { + position: relative; + white-space: nowrap; +} +.openerp .oe_searchview_field .oe_input_icon { + top: auto; + bottom: 5px; +} + .openerp .filter_label, .openerp .filter_icon { - border-left-width: 0; background: #F0F0F0; border: 1px solid #999; background: -moz-linear-gradient(top, #F0F0F0 0%, #C0C0C0 100%); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 04b801b4ed0..9333a3bdbca 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1172,7 +1172,7 @@ - @@ -1198,7 +1198,7 @@ ? -
+
? -
+
@@ -1225,7 +1225,7 @@ ? -
+
+
') - .text(_.str.sprintf(format, value)) + .text(openerp.web.format_value(value, column)) .appendTo($row); } else { $row.append(''); diff --git a/addons/web/static/test/formats.js b/addons/web/static/test/formats.js index 9a8f39bfa90..69557e98d5e 100644 --- a/addons/web/static/test/formats.js +++ b/addons/web/static/test/formats.js @@ -165,4 +165,23 @@ $(document).ready(function () { equal(openerp.web.format_value(106500, {type: 'integer'}), '106,50,0'); }); + test('format_float', function () { + openerp.web._t.database.parameters.grouping = [3, 3, 3, 3]; + equal(openerp.web.format_value(1000000, {type: 'float'}), + '1,000,000.00'); + openerp.web._t.database.parameters.grouping = [3, 2, -1]; + equal(openerp.web.format_value(106500, {type: 'float'}), + '1,06,500.00'); + openerp.web._t.database.parameters.grouping = [1, 2, -1]; + equal(openerp.web.format_value(106500, {type: 'float'}), + '106,50,0.00'); + + _.extend(openerp.web._t.database.parameters, { + grouping: [3, 0], + decimal_point: ',', + thousands_sep: '.' + }); + equal(openerp.web.format_value(6000, {type: 'float'}), + '6.000,00'); + }); }); From 26eac2765c9ad0cfba472199c12547200912cecf Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 12 Dec 2011 14:40:43 +0100 Subject: [PATCH 46/66] [FIX] outlook build bzr revid: al@openerp.com-20111212134043-wlot6zc34tv4vmvh --- addons/outlook/installer.py | 2 +- .../OpenERPClient/OpenERPClient.csproj | 10 ++++------ .../openerp-outlook-plugin/OpenERPOutlookPlugin.sln | 6 ------ 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/addons/outlook/installer.py b/addons/outlook/installer.py index 602afe0845d..547d0b18650 100644 --- a/addons/outlook/installer.py +++ b/addons/outlook/installer.py @@ -32,7 +32,7 @@ class outlook_installer(osv.osv_memory): def default_get(self, cr, uid, fields, context=None): data = super(outlook_installer, self).default_get(cr, uid, fields, context=context) data['doc_file'] = 'http://doc.openerp.com/book/2/2_6_Comms/2_6_Comms_outlook.html' - file = open(addons.get_module_resource('outlook','plugin','openerp-outlook-plugin_v2.0','OpenERPOutlookPluginSetup','Release','OpenERPOutlookPluginSetup.msi'), 'r') + file = open(addons.get_module_resource('outlook','static','openerp-outlook-plugin','OpenERPOutlookPluginSetup','Release','OpenERPOutlookPluginSetup.msi'), 'r') data['plugin_file'] = base64.encodestring(file.read()) return data diff --git a/addons/outlook/static/openerp-outlook-plugin/OpenERPClient/OpenERPClient.csproj b/addons/outlook/static/openerp-outlook-plugin/OpenERPClient/OpenERPClient.csproj index 79f03ae3f7a..c37098ad3ea 100644 --- a/addons/outlook/static/openerp-outlook-plugin/OpenERPClient/OpenERPClient.csproj +++ b/addons/outlook/static/openerp-outlook-plugin/OpenERPClient/OpenERPClient.csproj @@ -31,6 +31,10 @@ 4 + + False + ..\..\openerp-outlook-plugin_v2.0\OpenERPClient\bin\Debug\CookComputing.XmlRpcV2.dll + 3.5 @@ -52,12 +56,6 @@ - - - {1B4B0A58-0AFB-4090-91DD-18912CC7DE65} - xmlrpc - -