Merge lp:~camptocamp/openerp-humanitarian-ngo/ngo-addons-add_other_procurement_method-nbi into lp:~humanitarian-core-editors/openerp-humanitarian-ngo/ngo-addons

Proposed by Nicolas Bessi - Camptocamp
Status: Merged
Merged at revision: 110
Proposed branch: lp:~camptocamp/openerp-humanitarian-ngo/ngo-addons-add_other_procurement_method-nbi
Merge into: lp:~humanitarian-core-editors/openerp-humanitarian-ngo/ngo-addons
Diff against target: 7205 lines (+3674/-1181)
60 files modified
framework_agreement_requisition/model/purchase.py (+1/-0)
framework_agreement_requisition/model/purchase_requisition.py (+36/-9)
framework_agreement_sourcing/__init__.py (+1/-0)
framework_agreement_sourcing/__openerp__.py (+14/-3)
framework_agreement_sourcing/i18n/en_US.po (+220/-0)
framework_agreement_sourcing/i18n/framework_agreement_sourcing.pot (+209/-0)
framework_agreement_sourcing/model/__init__.py (+0/-1)
framework_agreement_sourcing/model/adapter_util.py (+0/-116)
framework_agreement_sourcing/model/logistic_requisition.py (+88/-88)
framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py (+15/-52)
framework_agreement_sourcing/model/logistic_requisition_source.py (+176/-156)
framework_agreement_sourcing/model/purchase.py (+4/-59)
framework_agreement_sourcing/security/ir.model.access.csv (+2/-0)
framework_agreement_sourcing/tests/common.py (+13/-1)
framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py (+47/-22)
framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py (+10/-7)
framework_agreement_sourcing/view/requisition_view.xml (+24/-74)
framework_agreement_sourcing/wizard/__init__.py (+21/-0)
framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py (+103/-0)
framework_agreement_sourcing/wizard/logistic_requisition_source_create_po_view.xml (+52/-0)
logistic_requisition/__openerp__.py (+32/-2)
logistic_requisition/i18n/en_US.po (+360/-168)
logistic_requisition/i18n/logistic_requisition.pot (+340/-148)
logistic_requisition/model/logistic_requisition.py (+100/-94)
logistic_requisition/model/purchase.py (+95/-3)
logistic_requisition/model/purchase_requisition.py (+10/-14)
logistic_requisition/report/logistic_requisition.mako (+0/-23)
logistic_requisition/security/ir.model.access.csv (+2/-0)
logistic_requisition/test/line_assigned.yml (+1/-2)
logistic_requisition/test/logistic_requisition_report_test.yml (+1/-1)
logistic_requisition/test/requisition_cancel_reason.yml (+1/-0)
logistic_requisition/test/requisition_create_cost_estimate.yml (+1/-7)
logistic_requisition/test/transport_plan.yml (+2/-3)
logistic_requisition/test/transport_plan_from_lr_line_wizard.yml (+1/-2)
logistic_requisition/test/transport_plan_to_cost_estimate.yml (+1/-5)
logistic_requisition/tests/__init__.py (+2/-0)
logistic_requisition/tests/logistic_requisition.py (+20/-16)
logistic_requisition/tests/purchase_requisition.py (+6/-0)
logistic_requisition/tests/test_mto_workflow.py (+5/-4)
logistic_requisition/tests/test_mutlicurrency_update_po_line.py (+131/-0)
logistic_requisition/tests/test_purchase_split_requisition.py (+5/-36)
logistic_requisition/tests/test_sale_order_from_lr_confirm.py (+2/-3)
logistic_requisition/view/logistic_requisition.xml (+24/-52)
logistic_requisition/wizard/cost_estimate.py (+4/-8)
logistic_requisition/wizard/logistic_line_create_requisition.py (+30/-2)
logistic_requisition/wizard/logistic_line_create_requisition_view.xml (+2/-0)
logistic_requisition_budget/__init__.py (+22/-0)
logistic_requisition_budget/__openerp__.py (+53/-0)
logistic_requisition_budget/i18n/en_US.po (+227/-0)
logistic_requisition_budget/i18n/logistic_requisition_budget.pot (+227/-0)
logistic_requisition_budget/model/__init__.py (+23/-0)
logistic_requisition_budget/model/logistic_requisition.py (+149/-0)
logistic_requisition_budget/report/logistic_requisition.mako (+226/-0)
logistic_requisition_budget/report/logistic_requisition_report.xml (+13/-0)
logistic_requisition_budget/test/requisition_create_cost_estimate.yml (+197/-0)
logistic_requisition_budget/tests/__init__.py (+29/-0)
logistic_requisition_budget/tests/test_purchase_split_requisition.py (+144/-0)
logistic_requisition_budget/view/logistic_requisition.xml (+89/-0)
logistic_requisition_budget/wizard/__init__.py (+21/-0)
logistic_requisition_budget/wizard/cost_estimate.py (+40/-0)
To merge this branch: bzr merge lp:~camptocamp/openerp-humanitarian-ngo/ngo-addons-add_other_procurement_method-nbi
Reviewer Review Type Date Requested Status
Joël Grand-Guillaume @ camptocamp code review, no tests Approve
Review via email: mp+205155@code.launchpad.net

Commit message

[ADD] support of "other" sourcing method.
Allows to create a call for bid or an agreement purchase order from many source lines including service source lines.

[Add] multi-currency:

Allows to have a currency (pricelist) defined in on logisitc request and have sourcing process (call for bid or agreement PO) in an other currency.

[IMP] separate budget in an external module

Description of the change

[ADD] support of "other" sourcing method.
Allows to create a call for bid or an agreement purchase order from many source lines including service source lines.

[Add] multi-currency:

Allows to have a currency (pricelist) defined in on logisitc request and have sourcing process (call for bid or agreement PO) in an other currency.

[IMP] separate budget in an external module

Depends on https://code.launchpad.net/~camptocamp/openerp-humanitarian-ngo/ngo-addons-add_agreement_sourcing-nbi/+merge/196676

To post a comment you must log in.
190. By Nicolas Bessi - Camptocamp

[IMP] when a agreement purchase requisition is chosen, all non selected PO are passed to the state cancel.
This mimic the flow of a standrad purchase requisiton

191. By Nicolas Bessi - Camptocamp

[MRG] from head

192. By Nicolas Bessi - Camptocamp

[FIX] manually created PO confirmation if no procurement is present

193. By Nicolas Bessi - Camptocamp

[TYPO]

194. By Nicolas Bessi - Camptocamp

[TYPO]

195. By Nicolas Bessi - Camptocamp

[FIX] logisitic_request tests product procure method as to be make_to_order in order to have sale.order.line type set correctly

Revision history for this message
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote :

LGTM, thanks a lot

review: Approve (code review, no tests)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'framework_agreement_requisition/model/purchase.py'
2--- framework_agreement_requisition/model/purchase.py 2014-01-17 14:59:31 +0000
3+++ framework_agreement_requisition/model/purchase.py 2014-05-07 09:53:02 +0000
4@@ -87,6 +87,7 @@
5 vals['supplier_id'] = po_line.order_id.partner_id.id
6 vals['product_id'] = po_line.product_id.id
7 vals['quantity'] = po_line.product_qty
8+ vals['delay'] = po_line.product_lead_time
9 vals['origin'] = origin if origin else False
10 return vals
11
12
13=== modified file 'framework_agreement_requisition/model/purchase_requisition.py'
14--- framework_agreement_requisition/model/purchase_requisition.py 2014-01-17 14:59:31 +0000
15+++ framework_agreement_requisition/model/purchase_requisition.py 2014-05-07 09:53:02 +0000
16@@ -62,10 +62,11 @@
17 return wf_service.trg_validate(uid, 'purchase.requisition',
18 agr_id, 'select_agreement', cr)
19
20- def agreement_selected(self, cr, uid, ids, context=None):
21+ def _agreement_selected(self, cr, uid, ids, context=None):
22 """Tells tender that an agreement has been selected"""
23 if isinstance(ids, (int, long)):
24 ids = [ids]
25+ generated = []
26 for req in self.browse(cr, uid, ids, context=context):
27 if not req.framework_agreement_tender:
28 raise orm.except_orm(_('Invalid tender'),
29@@ -73,21 +74,47 @@
30 self.select_agreement(cr, uid, req.id, context=context)
31 req.refresh()
32 if req.state != AGR_SELECT:
33- raise RuntimeError('requisiton %s does not pass to state'
34+ raise RuntimeError('requisition %s does not pass to state'
35 ' agreement_selected' %
36 req.name)
37 rfqs = chain.from_iterable(req_line.purchase_line_ids
38 for req_line in req.line_ids)
39- rfqs = [rfq for rfq in rfqs if rfq.state == 'confirmed']
40- if not rfqs:
41+ po_to_select = []
42+ po_to_cancel = []
43+ for rfq in rfqs:
44+ if rfq.state == 'confirmed':
45+ agr_record = rfq.make_agreement(req.name)
46+ generated.append(agr_record)
47+ po_to_select.append(rfq.order_id)
48+ else:
49+ po_to_cancel.append(rfq.order_id)
50+
51+ if not po_to_select:
52 raise orm.except_orm(_('No confirmed RFQ related to tender'),
53 _('Please choose at least one'))
54- for rfq in rfqs:
55- rfq.make_agreement(req.name)
56- p_order = rfq.order_id
57+
58+ for p_order in set(po_to_select):
59 p_order.select_agreement()
60 p_order.refresh()
61 if p_order.state != PO_AGR_SELECT:
62- raise RuntimeError('Purchase order %s does not pass to %' %
63+ raise RuntimeError('Purchase order %s does not pass to %s' %
64 (p_order.name, PO_AGR_SELECT))
65- return True
66+ wf_service = netsvc.LocalService("workflow")
67+ for p_order in set(po_to_cancel):
68+ wf_service.trg_validate(uid, 'purchase.order', p_order.id,
69+ 'purchase_cancel', cr)
70+ return generated
71+
72+ def agreement_selected(self, cr, uid, ids, context=None):
73+ agrements = self._agreement_selected(cr, uid, ids, context=context)
74+ a_ids = [x.id for x in agrements]
75+ return {
76+ 'name': _('Generated Agreements'),
77+ 'view_mode': 'tree,form',
78+ 'res_model': 'framework.agreement',
79+ 'domain': [('id', 'in', a_ids)],
80+ 'target': 'current',
81+ 'view_id': False,
82+ 'context': {},
83+ 'type': 'ir.actions.act_window',
84+ }
85
86=== modified file 'framework_agreement_sourcing/__init__.py'
87--- framework_agreement_sourcing/__init__.py 2013-10-25 11:10:32 +0000
88+++ framework_agreement_sourcing/__init__.py 2014-05-07 09:53:02 +0000
89@@ -19,3 +19,4 @@
90 #
91 ##############################################################################
92 from . import model
93+from . import wizard
94
95=== modified file 'framework_agreement_sourcing/__openerp__.py'
96--- framework_agreement_sourcing/__openerp__.py 2014-01-17 13:43:36 +0000
97+++ framework_agreement_sourcing/__openerp__.py 2014-05-07 09:53:02 +0000
98@@ -37,15 +37,26 @@
99 In this case tender flow is byassed and confirmed PO will be generated
100 when logistic requisition is confirmed.
101
102-By default the sourcing process will look in all agreements for a product
103-and use them one after the other as long as possible sorted by price.
104+When confirming Logistic request sourcing lines are generating.
105+Generation process will look up all agreements with remaining quantity
106+and use them one after the other.
107+
108+We will first choose cheapest agreements with price in negociated currency even
109+if they are cheaper in other currences.
110+
111+Then we will choose remaining agreements ordered
112+by price converted in company currency.
113
114 You can prevent this behavior by forcing only one agreement per product at
115 the same time in company.
116
117 """,
118 'website': 'http://www.camptocamp.com',
119- 'data': ['view/requisition_view.xml'],
120+ 'data': [
121+ 'view/requisition_view.xml',
122+ 'wizard/logistic_requisition_source_create_po_view.xml',
123+ 'security/ir.model.access.csv'
124+ ],
125 'demo': [],
126 'test': [],
127 'installable': True,
128
129=== added file 'framework_agreement_sourcing/i18n/en_US.po'
130--- framework_agreement_sourcing/i18n/en_US.po 1970-01-01 00:00:00 +0000
131+++ framework_agreement_sourcing/i18n/en_US.po 2014-05-07 09:53:02 +0000
132@@ -0,0 +1,220 @@
133+# Translation of OpenERP Server.
134+# This file contains the translation of the following modules:
135+# * framework_agreement_sourcing
136+#
137+msgid ""
138+msgstr ""
139+"Project-Id-Version: OpenERP Server 7.0\n"
140+"Report-Msgid-Bugs-To: \n"
141+"POT-Creation-Date: 2014-02-04 10:39+0000\n"
142+"PO-Revision-Date: 2014-02-04 10:39+0000\n"
143+"Last-Translator: <>\n"
144+"Language-Team: \n"
145+"MIME-Version: 1.0\n"
146+"Content-Type: text/plain; charset=UTF-8\n"
147+"Content-Transfer-Encoding: \n"
148+"Plural-Forms: \n"
149+
150+#. module: framework_agreement_sourcing
151+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:72
152+#, python-format
153+msgid "Please cancel uneeded one"
154+msgstr "Please cancel uneeded one"
155+
156+#. module: framework_agreement_sourcing
157+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py:64
158+#, python-format
159+msgid "Please add one"
160+msgstr "Please add one"
161+
162+#. module: framework_agreement_sourcing
163+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:240
164+#, python-format
165+msgid "Source line must be of type other or agreement"
166+msgstr "Source line must be of type other or agreement"
167+
168+#. module: framework_agreement_sourcing
169+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py:63
170+#, python-format
171+msgid "No stockable product in related PO"
172+msgstr "No stockable product in related PO"
173+
174+#. module: framework_agreement_sourcing
175+#: model:ir.model,name:framework_agreement_sourcing.model_logistic_requisition_source_create_agr_po
176+msgid "logistic.requisition.source.create.agr.po"
177+msgstr "logistic.requisition.source.create.agr.po"
178+
179+#. module: framework_agreement_sourcing
180+#: view:logistic.requisition.source.create.agr.po:0
181+msgid "Which pricelist / currency you want ?"
182+msgstr "Which pricelist / currency you want ?"
183+
184+#. module: framework_agreement_sourcing
185+#: model:ir.model,name:framework_agreement_sourcing.model_logistic_requisition_line
186+msgid "Logistic Requisition Line"
187+msgstr "Logistic Requisition Line"
188+
189+#. module: framework_agreement_sourcing
190+#: view:logistic.requisition.source:0
191+msgid "{'invisible': [('procurement_method', '=', 'fw_agreement')]}"
192+msgstr "{'invisible': [('procurement_method', '=', 'fw_agreement')]}"
193+
194+#. module: framework_agreement_sourcing
195+#: view:logistic.requisition.source:0
196+msgid "onchange_sourcing_method(procurement_method, requisition_line_id, proposed_product_id, proposed_qty)"
197+msgstr "onchange_sourcing_method(procurement_method, requisition_line_id, proposed_product_id, proposed_qty)"
198+
199+#. module: framework_agreement_sourcing
200+#: model:ir.model,name:framework_agreement_sourcing.model_logistic_requisition_cost_estimate
201+msgid "Create cost estimate of logistic requisition lines"
202+msgstr "Create cost estimate of logistic requisition lines"
203+
204+#. module: framework_agreement_sourcing
205+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:71
206+#, python-format
207+msgid "Many Purchase order lines found for %s"
208+msgstr "Many Purchase order lines found for %s"
209+
210+#. module: framework_agreement_sourcing
211+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:241
212+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:246
213+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:249
214+#, python-format
215+msgid "Please correct selection"
216+msgstr "Please correct selection"
217+
218+#. module: framework_agreement_sourcing
219+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:248
220+#, python-format
221+msgid "There should be at least one agreement line"
222+msgstr "There should be at least one agreement line"
223+
224+#. module: framework_agreement_sourcing
225+#: field:logistic.requisition.source,framework_agreement_id:0
226+msgid "Agreement"
227+msgstr "Agreement"
228+
229+#. module: framework_agreement_sourcing
230+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:245
231+#, python-format
232+msgid "There should be only one agreement line"
233+msgstr "There should be only one agreement line"
234+
235+#. module: framework_agreement_sourcing
236+#: code:addons/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py:85
237+#, python-format
238+msgid "User Error"
239+msgstr "User Error"
240+
241+#. module: framework_agreement_sourcing
242+#: model:ir.actions.act_window,name:framework_agreement_sourcing.action_view_create_agr_po_from_source
243+msgid "Create Agreement Purchase Order"
244+msgstr "Create Agreement Purchase Order"
245+
246+#. module: framework_agreement_sourcing
247+#: field:logistic.requisition.source.create.agr.po,pricelist_id:0
248+msgid "Pricelist / Currency"
249+msgstr "Pricelist / Currency"
250+
251+#. module: framework_agreement_sourcing
252+#: field:logistic.requisition.source.create.agr.po,framework_currency_ids:0
253+msgid "Available Currency"
254+msgstr "Available Currency"
255+
256+#. module: framework_agreement_sourcing
257+#: field:logistic.requisition.source,supplier_id:0
258+msgid "Agreement Supplier"
259+msgstr "Agreement Supplier"
260+
261+#. module: framework_agreement_sourcing
262+#: view:logistic.requisition.source.create.agr.po:0
263+msgid " Please note that: \n"
264+" \n"
265+" Requisition will only be created if: \n"
266+" * Lines belong to the same company \n"
267+" * There is only one agreement line in selection \n"
268+" * Products are define on all selected lines \n"
269+" * Non agreement line are of type other \n"
270+" \n"
271+" \n"
272+" "
273+msgstr " Please note that: \n"
274+" \n"
275+" Requisition will only be created if: \n"
276+" * Lines belong to the same company \n"
277+" * There is only one agreement line in selection \n"
278+" * Products are define on all selected lines \n"
279+" * Non agreement line are of type other \n"
280+" \n"
281+" \n"
282+" "
283+
284+#. module: framework_agreement_sourcing
285+#: model:ir.model,name:framework_agreement_sourcing.model_purchase_order
286+msgid "Purchase Order"
287+msgstr "Purchase Order"
288+
289+#. module: framework_agreement_sourcing
290+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:327
291+#, python-format
292+msgid "You have ask for a quantity of %s \n"
293+" but there is only %s available for current agreement"
294+msgstr "You have ask for a quantity of %s \n"
295+" but there is only %s available for current agreement"
296+
297+#. module: framework_agreement_sourcing
298+#: model:ir.model,name:framework_agreement_sourcing.model_logistic_requisition_source
299+msgid "Logistic Requisition Source"
300+msgstr "Logistic Requisition Source"
301+
302+#. module: framework_agreement_sourcing
303+#: view:logistic.requisition.source.create.agr.po:0
304+msgid "You can only chose a pricelist with a currency that is included in the framewrok agreement you have chosen."
305+msgstr "You can only chose a pricelist with a currency that is included in the framewrok agreement you have chosen."
306+
307+#. module: framework_agreement_sourcing
308+#: view:logistic.requisition.source:0
309+msgid "onchange_quantity(procurement_method, requisition_line_id, proposed_qty, proposed_product_id)"
310+msgstr "onchange_quantity(procurement_method, requisition_line_id, proposed_qty, proposed_product_id)"
311+
312+#. module: framework_agreement_sourcing
313+#: view:logistic.requisition.source.create.agr.po:0
314+msgid "Create Purchase Order"
315+msgstr "Create Purchase Order"
316+
317+#. module: framework_agreement_sourcing
318+#: code:addons/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py:85
319+#, python-format
320+msgid "You must chose a pricelist that is in the same currency than one of the available in the framework agreement."
321+msgstr "You must chose a pricelist that is in the same currency than one of the available in the framework agreement."
322+
323+#. module: framework_agreement_sourcing
324+#: field:logistic.requisition.source,framework_agreement_po_id:0
325+msgid "Agreement Purchase"
326+msgstr "Agreement Purchase"
327+
328+#. module: framework_agreement_sourcing
329+#: view:logistic.requisition.source.create.agr.po:0
330+msgid "Cancel"
331+msgstr "Cancel"
332+
333+#. module: framework_agreement_sourcing
334+#: view:logistic.requisition.source:0
335+msgid "onchange_product_id(procurement_method, requisition_line_id, proposed_product_id, proposed_qty)"
336+msgstr "onchange_product_id(procurement_method, requisition_line_id, proposed_product_id, proposed_qty)"
337+
338+#. module: framework_agreement_sourcing
339+#: view:logistic.requisition.source.create.agr.po:0
340+msgid "Are you sure you want to create a Purchase Order from those lines ?"
341+msgstr "Are you sure you want to create a Purchase Order from those lines ?"
342+
343+#. module: framework_agreement_sourcing
344+#: view:logistic.requisition.source.create.agr.po:0
345+msgid "or"
346+msgstr "or"
347+
348+#. module: framework_agreement_sourcing
349+#: model:ir.model,name:framework_agreement_sourcing.model_sale_order_line
350+msgid "Sales Order Line"
351+msgstr "Sales Order Line"
352+
353
354=== added file 'framework_agreement_sourcing/i18n/framework_agreement_sourcing.pot'
355--- framework_agreement_sourcing/i18n/framework_agreement_sourcing.pot 1970-01-01 00:00:00 +0000
356+++ framework_agreement_sourcing/i18n/framework_agreement_sourcing.pot 2014-05-07 09:53:02 +0000
357@@ -0,0 +1,209 @@
358+# Translation of OpenERP Server.
359+# This file contains the translation of the following modules:
360+# * framework_agreement_sourcing
361+#
362+msgid ""
363+msgstr ""
364+"Project-Id-Version: OpenERP Server 7.0\n"
365+"Report-Msgid-Bugs-To: \n"
366+"POT-Creation-Date: 2014-02-04 10:37+0000\n"
367+"PO-Revision-Date: 2014-02-04 10:37+0000\n"
368+"Last-Translator: <>\n"
369+"Language-Team: \n"
370+"MIME-Version: 1.0\n"
371+"Content-Type: text/plain; charset=UTF-8\n"
372+"Content-Transfer-Encoding: \n"
373+"Plural-Forms: \n"
374+
375+#. module: framework_agreement_sourcing
376+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:72
377+#, python-format
378+msgid "Please cancel uneeded one"
379+msgstr ""
380+
381+#. module: framework_agreement_sourcing
382+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py:64
383+#, python-format
384+msgid "Please add one"
385+msgstr ""
386+
387+#. module: framework_agreement_sourcing
388+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:240
389+#, python-format
390+msgid "Source line must be of type other or agreement"
391+msgstr ""
392+
393+#. module: framework_agreement_sourcing
394+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py:63
395+#, python-format
396+msgid "No stockable product in related PO"
397+msgstr ""
398+
399+#. module: framework_agreement_sourcing
400+#: model:ir.model,name:framework_agreement_sourcing.model_logistic_requisition_source_create_agr_po
401+msgid "logistic.requisition.source.create.agr.po"
402+msgstr ""
403+
404+#. module: framework_agreement_sourcing
405+#: view:logistic.requisition.source.create.agr.po:0
406+msgid "Which pricelist / currency you want ?"
407+msgstr ""
408+
409+#. module: framework_agreement_sourcing
410+#: model:ir.model,name:framework_agreement_sourcing.model_logistic_requisition_line
411+msgid "Logistic Requisition Line"
412+msgstr ""
413+
414+#. module: framework_agreement_sourcing
415+#: view:logistic.requisition.source:0
416+msgid "{'invisible': [('procurement_method', '=', 'fw_agreement')]}"
417+msgstr ""
418+
419+#. module: framework_agreement_sourcing
420+#: view:logistic.requisition.source:0
421+msgid "onchange_sourcing_method(procurement_method, requisition_line_id, proposed_product_id, proposed_qty)"
422+msgstr ""
423+
424+#. module: framework_agreement_sourcing
425+#: model:ir.model,name:framework_agreement_sourcing.model_logistic_requisition_cost_estimate
426+msgid "Create cost estimate of logistic requisition lines"
427+msgstr ""
428+
429+#. module: framework_agreement_sourcing
430+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:71
431+#, python-format
432+msgid "Many Purchase order lines found for %s"
433+msgstr ""
434+
435+#. module: framework_agreement_sourcing
436+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:241
437+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:246
438+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:249
439+#, python-format
440+msgid "Please correct selection"
441+msgstr ""
442+
443+#. module: framework_agreement_sourcing
444+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:248
445+#, python-format
446+msgid "There should be at least one agreement line"
447+msgstr ""
448+
449+#. module: framework_agreement_sourcing
450+#: field:logistic.requisition.source,framework_agreement_id:0
451+msgid "Agreement"
452+msgstr ""
453+
454+#. module: framework_agreement_sourcing
455+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:245
456+#, python-format
457+msgid "There should be only one agreement line"
458+msgstr ""
459+
460+#. module: framework_agreement_sourcing
461+#: code:addons/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py:85
462+#, python-format
463+msgid "User Error"
464+msgstr ""
465+
466+#. module: framework_agreement_sourcing
467+#: model:ir.actions.act_window,name:framework_agreement_sourcing.action_view_create_agr_po_from_source
468+msgid "Create Agreement Purchase Order"
469+msgstr ""
470+
471+#. module: framework_agreement_sourcing
472+#: field:logistic.requisition.source.create.agr.po,pricelist_id:0
473+msgid "Pricelist / Currency"
474+msgstr ""
475+
476+#. module: framework_agreement_sourcing
477+#: field:logistic.requisition.source.create.agr.po,framework_currency_ids:0
478+msgid "Available Currency"
479+msgstr ""
480+
481+#. module: framework_agreement_sourcing
482+#: field:logistic.requisition.source,supplier_id:0
483+msgid "Agreement Supplier"
484+msgstr ""
485+
486+#. module: framework_agreement_sourcing
487+#: view:logistic.requisition.source.create.agr.po:0
488+msgid " Please note that: \n"
489+" \n"
490+" Requisition will only be created if: \n"
491+" * Lines belong to the same company \n"
492+" * There is only one agreement line in selection \n"
493+" * Products are define on all selected lines \n"
494+" * Non agreement line are of type other \n"
495+" \n"
496+" \n"
497+" "
498+msgstr ""
499+
500+#. module: framework_agreement_sourcing
501+#: model:ir.model,name:framework_agreement_sourcing.model_purchase_order
502+msgid "Purchase Order"
503+msgstr ""
504+
505+#. module: framework_agreement_sourcing
506+#: code:addons/framework_agreement_sourcing/model/logistic_requisition_source.py:327
507+#, python-format
508+msgid "You have ask for a quantity of %s \n"
509+" but there is only %s available for current agreement"
510+msgstr ""
511+
512+#. module: framework_agreement_sourcing
513+#: model:ir.model,name:framework_agreement_sourcing.model_logistic_requisition_source
514+msgid "Logistic Requisition Source"
515+msgstr ""
516+
517+#. module: framework_agreement_sourcing
518+#: view:logistic.requisition.source.create.agr.po:0
519+msgid "You can only chose a pricelist with a currency that is included in the framewrok agreement you have chosen."
520+msgstr ""
521+
522+#. module: framework_agreement_sourcing
523+#: view:logistic.requisition.source:0
524+msgid "onchange_quantity(procurement_method, requisition_line_id, proposed_qty, proposed_product_id)"
525+msgstr ""
526+
527+#. module: framework_agreement_sourcing
528+#: view:logistic.requisition.source.create.agr.po:0
529+msgid "Create Purchase Order"
530+msgstr ""
531+
532+#. module: framework_agreement_sourcing
533+#: code:addons/framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py:85
534+#, python-format
535+msgid "You must chose a pricelist that is in the same currency than one of the available in the framework agreement."
536+msgstr ""
537+
538+#. module: framework_agreement_sourcing
539+#: field:logistic.requisition.source,framework_agreement_po_id:0
540+msgid "Agreement Purchase"
541+msgstr ""
542+
543+#. module: framework_agreement_sourcing
544+#: view:logistic.requisition.source.create.agr.po:0
545+msgid "Cancel"
546+msgstr ""
547+
548+#. module: framework_agreement_sourcing
549+#: view:logistic.requisition.source:0
550+msgid "onchange_product_id(procurement_method, requisition_line_id, proposed_product_id, proposed_qty)"
551+msgstr ""
552+
553+#. module: framework_agreement_sourcing
554+#: view:logistic.requisition.source.create.agr.po:0
555+msgid "Are you sure you want to create a Purchase Order from those lines ?"
556+msgstr ""
557+
558+#. module: framework_agreement_sourcing
559+#: view:logistic.requisition.source.create.agr.po:0
560+msgid "or"
561+msgstr ""
562+
563+#. module: framework_agreement_sourcing
564+#: model:ir.model,name:framework_agreement_sourcing.model_sale_order_line
565+msgid "Sales Order Line"
566+msgstr ""
567
568=== modified file 'framework_agreement_sourcing/model/__init__.py'
569--- framework_agreement_sourcing/model/__init__.py 2013-11-15 11:08:08 +0000
570+++ framework_agreement_sourcing/model/__init__.py 2014-05-07 09:53:02 +0000
571@@ -21,6 +21,5 @@
572 from . import logistic_requisition
573 from . import logistic_requisition_source
574 from . import purchase
575-from . import adapter_util
576 from . import sale_order
577 from . import logistic_requisition_cost_estimate
578
579=== removed file 'framework_agreement_sourcing/model/adapter_util.py'
580--- framework_agreement_sourcing/model/adapter_util.py 2013-11-07 09:29:57 +0000
581+++ framework_agreement_sourcing/model/adapter_util.py 1970-01-01 00:00:00 +0000
582@@ -1,116 +0,0 @@
583-# -*- coding: utf-8 -*-
584-##############################################################################
585-#
586-# Author: Nicolas Bessi
587-# Copyright 2013 Camptocamp SA
588-#
589-# This program is free software: you can redistribute it and/or modify
590-# it under the terms of the GNU Affero General Public License as
591-# published by the Free Software Foundation, either version 3 of the
592-# License, or (at your option) any later version.
593-#
594-# This program is distributed in the hope that it will be useful,
595-# but WITHOUT ANY WARRANTY; without even the implied warranty of
596-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
597-# GNU Affero General Public License for more details.
598-#
599-# You should have received a copy of the GNU Affero General Public License
600-# along with this program. If not, see <http://www.gnu.org/licenses/>.
601-#
602-##############################################################################
603-"""Provides basic mechanism to unify the way records are transformed into
604-other records
605-
606-"""
607-
608-from openerp.osv import orm
609-
610-
611-class BrowseAdapterSourceMixin(object):
612- """Mixin class used by Model that are transformation sources"""
613-
614- def _company(self, cr, uid, context):
615- """Return company id
616-
617- :returns: company id
618-
619- """
620- return self.pool['res.company']._company_default_get(cr, uid, 'purchase.order',
621- context=context)
622-
623- def _direct_map(self, line, mapping, context=None):
624- """Take a dict of left key right key and make direct mapping
625- into the model
626-
627- :returns: data dict ready to be used
628- """
629- data = {}
630- for po_key, source_key in mapping.iteritems():
631- value = line[source_key]
632- if isinstance(value, orm.browse_record):
633- value = value.id
634- elif isinstance(value, orm.browse_null):
635- value = False
636- elif isinstance(value, orm.browse_record_list):
637- raise NotImplementedError('List are not supported in direct map')
638-
639- data[po_key] = value
640- return data
641-
642-
643-class BrowseAdapterMixin(object):
644-
645- def _do_checks(self, cr, uid, model, data, context=None):
646- """Perform validation check of adapted data.
647-
648- All missing or incorrect values are return at once.
649-
650- :returns: array of exceptions
651-
652- """
653- required_keys = set(k for k, v in model._columns.iteritems()
654- if v.required and not getattr(v, '_fnct', False))
655- empty_required = set(x for x in data
656- if x in required_keys and not data[x])
657- missing_required = required_keys - set(data.keys())
658- missing_required.update(empty_required)
659- if missing_required:
660- return[ValueError('Following value are missing or False'
661- ' while adapting %s: %s' %
662- (model._name, ", ".join(missing_required)))]
663- return []
664-
665- def _validate_adapted_data(self, cr, uid, model, data, context=None):
666- """Perform validation check of adapted data.
667-
668- All missing or incorrect values are return at once.
669-
670- :returns: validated data or raise Value error
671-
672- """
673- errors = self._do_checks(cr, uid, model, data, context=context)
674- if errors:
675- raise ValueError('Data are invalid for following reason %s' %
676- ("\n".join(repr(e) for e in errors)))
677- return data
678-
679- def _adapt_origin(self, cr, uid, model, origin,
680- map_fun, post_fun=None, context=None, **kwargs):
681- """Do transformation of source data to dest data using transforms function.
682-
683- :param origin: source record
684- :param map_fun: transform function
685- :param post_fun: post transformation hook function
686-
687- :returns: transformed data
688-
689- """
690- if not callable(map_fun):
691- raise ValueError('Mapping function is not callable')
692- if post_fun and not callable(post_fun):
693- raise ValueError('Post hook function is not callable')
694- data = map_fun(cr, uid, origin, context=context, **kwargs)
695- # we complete with default
696- missing = set(model._columns.keys()) - set(data.keys())
697- data.update(model.default_get(cr, uid, missing, context=context))
698- return data
699
700=== modified file 'framework_agreement_sourcing/model/logistic_requisition.py'
701--- framework_agreement_sourcing/model/logistic_requisition.py 2013-11-15 11:04:51 +0000
702+++ framework_agreement_sourcing/model/logistic_requisition.py 2014-05-07 09:53:02 +0000
703@@ -21,18 +21,23 @@
704 from collections import namedtuple
705 from openerp.tools.translate import _
706 from openerp.osv import orm
707-from .adapter_util import BrowseAdapterSourceMixin
708 from .logistic_requisition_source import AGR_PROC
709
710
711-class logistic_requisition_line(orm.Model, BrowseAdapterSourceMixin):
712+class logistic_requisition_line(orm.Model):
713 """Override to enable generation of source line"""
714
715 _inherit = "logistic.requisition.line"
716
717- def _map_agr_requisiton_to_source(self, cr, uid, line, context=None,
718- qty=0, agreement=None, **kwargs):
719- """Prepare data dict for source line using agreement as source
720+ def _prepare_line_source(self, cr, uid, line,
721+ qty=None, agreement=None,
722+ context=None):
723+ """Prepare data dict for source line creation. If an agreement
724+ is given, the procurement_method will be an LTA (AGR_PROC).
725+ Otherwise, if it's a stockable product we'll go to tender
726+ by setting procurement_method as 'procurement'. Finally marke the
727+ rest as 'other'. Those are default value that can be changed afterward
728+ by the user.
729
730 :params line: browse record of origin requistion.line
731 :params agreement: browse record of origin agreement
732@@ -42,52 +47,83 @@
733
734 """
735 res = {}
736- direct_map = {
737- 'proposed_product_id': 'product_id',
738- 'requisition_line_id': 'id',
739- 'proposed_uom_id': 'requested_uom_id'}
740-
741- if not agreement:
742- raise ValueError("Missing agreement")
743- if not agreement.product_id.id == line.product_id.id:
744- raise ValueError("Product mismatch for agreement and requisition line")
745- # currency = self._get_source_currency(cr, uid, line, context=context)
746- res['unit_cost'] = 0.0
747- res['proposed_qty'] = qty
748- res['framework_agreement_id'] = agreement.id
749- res['procurement_method'] = AGR_PROC
750- res.update(self._direct_map(line, direct_map))
751- return res
752-
753- def _map_requisition_to_source(self, cr, uid, line, context=None,
754- qty=0, **kwargs):
755- """Prepare data dict to generate source line using requisition as source
756-
757- :params line: browse record of origin requistion.line
758- :params qty: quantity to be set on source line
759-
760- :returns: dict to be used by Model.create
761-
762- """
763- res = {}
764- direct_map = {'proposed_product_id': 'product_id',
765- 'requisition_line_id': 'id',
766- 'proposed_uom_id': 'requested_uom_id'}
767+ res['proposed_product_id'] = line.product_id.id
768+ res['requisition_line_id'] = line.id
769+ res['proposed_uom_id'] = line.requested_uom_id.id
770 res['unit_cost'] = 0.0
771 res['proposed_qty'] = qty
772 res['framework_agreement_id'] = False
773- res['procurement_method'] = 'procurement'
774- res.update(self._direct_map(line, direct_map))
775+ if agreement:
776+ if not agreement.product_id.id == line.product_id.id:
777+ raise ValueError("Product mismatch for agreement and requisition line")
778+ res['framework_agreement_id'] = agreement.id
779+ res['procurement_method'] = AGR_PROC
780+ else:
781+ if line.product_id.type == 'product':
782+ res['procurement_method'] = 'procurement'
783+ else:
784+ res['procurement_method'] = 'other'
785 return res
786
787+ def _sort_agreements(self, cr, uid, agreements, qty, currency=None,
788+ context=None):
789+ """Sort agreements to be proposed
790+
791+ Agreement with negociated currency will first be taken in account
792+ then they will be choosen by price converted in currency company
793+
794+ :param agreements: list of agreements to be sorted
795+ :param currency: prefered currrency
796+
797+ :returns: sorted agreements list
798+
799+ """
800+ if not agreements:
801+ return agreements
802+
803+ def _best_company_price(cr, uid, agreement, qty):
804+ """Returns the best price in company currency
805+
806+ For given agreement and price
807+
808+ """
809+ comp_id = self.pool['framework.agreement']._company_get(cr, uid)
810+ comp_obj = self.pool['res.company']
811+ currency_obj = self.pool['res.currency']
812+ comp_currency = comp_obj.browse(cr, uid, comp_id,
813+ context=context).currency_id
814+ prices = []
815+ for pl in agreement.framework_agreement_pricelist_ids:
816+ price = agreement.get_price(qty, currency=pl.currency_id)
817+ comp_price = currency_obj.compute(cr, uid,
818+ pl.currency_id.id,
819+ comp_currency.id,
820+ price, False)
821+ prices.append(comp_price)
822+ return min(prices)
823+
824+ firsts = []
825+ if currency:
826+ firsts = [x for x in agreements if x.has_currency(currency)]
827+ lasts = [x for x in agreements if not x.has_currency(currency)]
828+ firsts.sort(key=lambda x: x.get_price(qty, currency=currency))
829+ lasts.sort(key=lambda x: _best_company_price(cr, uid, x, qty))
830+ return firsts + lasts
831+ else:
832+ agreements.sort(key=lambda x: _best_company_price(cr, uid, x, qty))
833+ return agreements
834+
835 def _generate_lines_from_agreements(self, cr, uid, container, line,
836 agreements, qty, currency=None, context=None):
837 """Generate 1/n source line(s) for one requisition line.
838
839 This is done using available agreements.
840 We first look for cheapeast agreement.
841- Then if no more quantity are available and there is still remaining needs
842- we look for next cheapest agreement or return remaining qty
843+ Then if no more quantity are available and there is still remaining
844+ needs we look for next cheapest agreement or return remaining qty.
845+ we prefer to use agreement with negociated currency first even
846+ if they are cheaper in other currences. Then it will choose remaining
847+ agreements ordered by price converted in company currency
848
849 :param container: list of agreements browse
850 :param qty: quantity to be sourced
851@@ -97,11 +133,10 @@
852
853 """
854 agreements = agreements if agreements is not None else []
855- if currency:
856- agreements = [x for x in agreements if x.has_currency(currency)]
857+ agreements = self._sort_agreements(cr, uid, agreements, qty,
858+ currency=currency)
859 if not agreements:
860 return qty
861- agreements.sort(key=lambda x: x.get_price(qty, currency=currency))
862 current_agr = agreements.pop(0)
863 avail = current_agr.available_quantity
864 if not avail:
865@@ -115,7 +150,8 @@
866 difference = qty - to_consume
867 if difference:
868 return self._generate_lines_from_agreements(cr, uid, container, line,
869- agreements, difference, context=context)
870+ agreements, difference,
871+ context=context)
872 else:
873 return 0
874
875@@ -140,7 +176,8 @@
876 return Sourced(generated, remaining_qty)
877
878 def make_source_line(self, cr, uid, line, force_qty=None, agreement=None, context=None):
879- """Generate a source line for a tender from a requisition line
880+ """Generate a source line from a requisition line, see
881+ _prepare_line_source for details.
882
883 :param line: browse record of origin logistic.request
884 :param force_qty: if set this quantity will be used instead
885@@ -150,25 +187,11 @@
886 """
887 qty = force_qty if force_qty else line.requested_qty
888 src_obj = self.pool['logistic.requisition.source']
889- if agreement:
890- return src_obj._make_source_line_from_origin(cr, uid, line,
891- self._map_agr_requisiton_to_source,
892- context=context, qty=qty,
893- agreement=agreement)
894- else:
895- return src_obj._make_source_line_from_origin(cr, uid, line,
896- self._map_requisition_to_source,
897- context=context, qty=qty)
898-
899- def _get_source_currency(self, cr, uid, line, context=None):
900- agr_obj = self.pool['framework.agreement']
901- comp_obj = self.pool['res.company']
902- currency = line.requisition_id.get_pricelist().currency_id
903- company_id = agr_obj._company_get(cr, uid, context=context)
904- comp_currency = comp_obj.browse(cr, uid, company_id, context=context).currency_id
905- if currency == comp_currency:
906- return None
907- return currency
908+ vals = self._prepare_line_source(cr, uid, line,
909+ qty=qty,
910+ agreement=agreement,
911+ context=None)
912+ return src_obj.create(cr, uid, vals, context=context)
913
914 def _generate_source_line(self, cr, uid, line, context=None):
915 """Generate one or n source line(s) per requisition line.
916@@ -186,7 +209,7 @@
917 return None
918 agr_obj = self.pool['framework.agreement']
919 date = line.requisition_id.date
920- currency = self._get_source_currency(cr, uid, line, context=context)
921+ currency = line.currency_id
922 product_id = line.product_id.id
923 agreements = agr_obj.get_all_product_agreements(cr, uid, product_id, date,
924 context=context)
925@@ -218,26 +241,3 @@
926 for line_br in self.browse(cr, uid, ids, context=context):
927 self._generate_source_line(cr, uid, line_br, context=context)
928 return res
929-
930-
931-class logistic_requisition(orm.Model):
932- """Add get pricelist function"""
933-
934- _inherit = "logistic.requisition"
935-
936- def get_pricelist(self, cr, uid, requisition_id, context=None):
937- """Retrive pricelist id to use in sourcing by agreement process
938-
939- :returns: pricelist record
940-
941- """
942- if isinstance(requisition_id, (list, tuple)):
943- assert len(requisition_id) == 1
944- requisition_id = requisition_id[0]
945- requisiton = self.browse(cr, uid, requisition_id, context=context)
946- plist = requisiton.partner_id.property_product_pricelist
947- if not plist:
948- raise orm.except_orm(_('No price list on customer'),
949- _('Please set sale price list on %s partner') %
950- requisiton.partner_id.name)
951- return plist
952
953=== modified file 'framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py'
954--- framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py 2014-01-20 13:54:30 +0000
955+++ framework_agreement_sourcing/model/logistic_requisition_cost_estimate.py 2014-05-07 09:53:02 +0000
956@@ -28,45 +28,11 @@
957
958 _inherit = "logistic.requisition.cost.estimate"
959
960- def _update_agreement_source(self, cr, uid, source, context=None):
961- """Update price of source line using related confirmed PO"""
962- if source.procurement_method == AGR_PROC:
963- self._link_po_lines_to_source(cr, uid, source, context=context)
964- price = source.get_agreement_price_from_po()
965- source.write({'unit_cost': price})
966- source.refresh()
967-
968- def _link_po_lines_to_source(self, cr, uid, source, context=None):
969- po_l_obj = self.pool['purchase.order.line']
970- agr = source.framework_agreement_id
971- line_ids = po_l_obj.search(
972- cr, uid,
973- [('order_id.framework_agreement_id', '=', agr.id),
974- ('lr_source_line_id', '=', source.id),
975- ('order_id.partner_id', '=', agr.supplier_id.id)],
976- context=context)
977- lines = po_l_obj.browse(cr, uid, line_ids, context=context)
978- po_ids = ([line.order_id.id for line in lines
979- if line.product_id and line.product_id.type == 'product'])
980-
981- all_line_ids = po_l_obj.search(
982- cr, uid,
983- [('order_id', 'in', po_ids),
984- ('product_id.type', '=', 'product')],
985- context=context)
986-
987- po_l_obj.write(cr, uid, all_line_ids,
988- {'lr_source_line_id': source.id},
989- context=context)
990- source.refresh()
991
992 def _prepare_cost_estimate_line(self, cr, uid, sourcing, context=None):
993 """Override in order to update agreement source line
994
995- We update the price of source line that will be used in cost estimate
996-
997 """
998- self._update_agreement_source(cr, uid, sourcing, context=context)
999 res = super(logistic_requisition_cost_estimate,
1000 self)._prepare_cost_estimate_line(cr, uid, sourcing,
1001 context=context)
1002@@ -87,12 +53,11 @@
1003
1004 """
1005
1006- so_lines = [x for x in so.order_line]
1007+ so_lines = [x for x in so.order_line if x.product_id]
1008 po_lines = set(x.purchase_line_id for x in sources
1009- if x.purchase_line_id and
1010- x.purchase_line_id.product_id.type == 'product')
1011+ if x.purchase_line_id)
1012 product_dict = dict((x.product_id.id, x.id) for x in so_lines
1013- if x.product_id and x.product_id.type == 'product')
1014+ if x.product_id)
1015 default = product_dict[product_dict.keys()[0]]
1016 if not product_dict:
1017 raise orm.except_orm(_('No stockable product in related PO'),
1018@@ -102,20 +67,18 @@
1019 po_line.write({'sale_order_line_id': product_dict.get(key, default)})
1020
1021 def cost_estimate(self, cr, uid, ids, context=None):
1022- """Override to link PO to cost_estimate
1023-
1024- We have to do this because when we source with agreement we do
1025- not copy the PO it is meaningless has we have no choice to make.
1026- But in tender flow you first cancel PO then the sale order mark
1027- canceled PO as dropshipping and then copy them.
1028-
1029- So you have to create link between SO and PO/PO line that are
1030- normally done when SO procurement generate PO and picking
1031-
1032-
1033- With agreement PO is confirmed before be marked as dropshipping.
1034-
1035- So we have to link it first"""
1036+ """Override to link PO to cost_estimate$
1037+
1038+ In a normal flow, when you chose a bid as the winning one, the bid is
1039+ dupplicated to generate the draft PO. On this action, it link the LRS
1040+ to the generated PO line.
1041+
1042+ In a tender flow, we don't dupplicate the bid, it's only a PO. The link
1043+ between the LRS and the PO line should then be created here.
1044+
1045+ This is for the drop shipping to work propely cause in that case, SO
1046+ and PO are linked together.
1047+ """
1048 so_model = self.pool['sale.order']
1049 po_model = self.pool['purchase.order']
1050 res = super(logistic_requisition_cost_estimate,
1051
1052=== modified file 'framework_agreement_sourcing/model/logistic_requisition_source.py'
1053--- framework_agreement_sourcing/model/logistic_requisition_source.py 2014-01-17 13:48:46 +0000
1054+++ framework_agreement_sourcing/model/logistic_requisition_source.py 2014-05-07 09:53:02 +0000
1055@@ -1,4 +1,4 @@
1056-# -*- coding: utf-8 -*-
1057+ # -*- coding: utf-8 -*-
1058 ##############################################################################
1059 #
1060 # Author: Nicolas Bessi
1061@@ -18,38 +18,26 @@
1062 # along with this program. If not, see <http://www.gnu.org/licenses/>.
1063 #
1064 ##############################################################################
1065+from itertools import chain
1066 from openerp.osv import orm, fields
1067 from openerp.tools.translate import _
1068 from openerp.addons.framework_agreement.model.framework_agreement import\
1069 FrameworkAgreementObservable
1070 from openerp.addons.framework_agreement.utils import id_boilerplate
1071
1072-from .adapter_util import BrowseAdapterMixin, BrowseAdapterSourceMixin
1073
1074 AGR_PROC = 'fw_agreement'
1075
1076
1077-class logistic_requisition_source(orm.Model, BrowseAdapterMixin,
1078- BrowseAdapterSourceMixin, FrameworkAgreementObservable):
1079+class logistic_requisition_source(orm.Model, FrameworkAgreementObservable):
1080 """Adds support of framework agreement to source line"""
1081
1082 _inherit = "logistic.requisition.source"
1083
1084 _columns = {'framework_agreement_id': fields.many2one('framework.agreement',
1085 'Agreement'),
1086-
1087- 'purchase_pricelist_id': fields.many2one('product.pricelist',
1088- 'Purchase (PO) Pricelist',
1089- help="This pricelist will be used"
1090- " when generating PO"),
1091- 'pricelist_id': fields.related('requisition_line_id', 'requisition_id',
1092- 'partner_id',
1093- 'property_product_pricelist',
1094- relation='product.pricelist',
1095- type='many2one',
1096- string='Price list',
1097- readonly=True),
1098-
1099+ 'framework_agreement_po_id': fields.many2one('purchase.order',
1100+ 'Agreement Purchase'),
1101 'supplier_id': fields.related('framework_agreement_id', 'supplier_id',
1102 type='many2one', relation='res.partner',
1103 string='Agreement Supplier')}
1104@@ -88,11 +76,22 @@
1105 return res
1106
1107 #------------------ adapting source line to po -----------------------------
1108-
1109- def _map_source_to_po(self, cr, uid, line, context=None, **kwargs):
1110- """Map source line to dict to be used by PO create defaults are optional
1111-
1112- :returns: data dict to be used by adapter
1113+ def _company(self, cr, uid, context):
1114+ """Return company id
1115+
1116+ :returns: company id
1117+
1118+ """
1119+ return self.pool['res.company']._company_default_get(cr, uid, self._name,
1120+ context=context)
1121+
1122+ def _prepare_purchase_order(self, cr, uid, line, po_pricelist, context=None):
1123+ """Prepare the dict of values to create the PO from a
1124+ source line.
1125+
1126+ :param browse_record line: logistic.requisition.source
1127+ :param browse_record pricelist: product.pricelist
1128+ :returns: data dict to be used by orm.Model.create
1129
1130 """
1131 supplier = line.framework_agreement_id.supplier_id
1132@@ -106,7 +105,7 @@
1133 data['framework_agreement_id'] = line.framework_agreement_id.id
1134 data['partner_id'] = supplier.id
1135 data['company_id'] = self._company(cr, uid, context)
1136- data['pricelist_id'] = line.purchase_pricelist_id.id
1137+ data['pricelist_id'] = po_pricelist.id
1138 data['dest_address_id'] = add.id
1139 data['location_id'] = add.property_stock_customer.id
1140 data['payment_term_id'] = term
1141@@ -120,30 +119,50 @@
1142 data['type'] = 'purchase'
1143 return data
1144
1145- def _map_source_to_po_line(self, cr, uid, line, context=None, **kwargs):
1146- """Map source line to dict to be used by PO line create
1147- Map source line to dict to be used by PO create
1148- defaults are optional
1149+ def _prepare_purchase_order_line(self, cr, uid, po_id, line,
1150+ po_supplier, po_pricelist, context=None):
1151+ """Prepare the dict of values to create the PO Line from args.
1152
1153- :returns: data dict to be used by adapter
1154+ :param integer po_id: ids of purchase.order
1155+ :param browse_record line: logistic.requisition.source
1156+ :param browse_record po_supplier: res.partner
1157+ :param browse_record po_pricelist: product.pricelist
1158+ :returns: data dict to be used by orm.Model.create
1159
1160 """
1161+ data = {}
1162 acc_pos_obj = self.pool['account.fiscal.position']
1163- supplier = line.framework_agreement_id.supplier_id
1164+ pl_model = self.pool['product.pricelist']
1165+ currency = po_pricelist.currency_id
1166+
1167+ if line.framework_agreement_id:
1168+ price = line.framework_agreement_id.get_price(line.proposed_qty, currency=currency)
1169+ lead_time = line.framework_agreement_id.delay
1170+ supplier = line.framework_agreement_id.supplier_id
1171+ data['framework_agreement_id'] = line.framework_agreement_id.id
1172+ else:
1173+ supplier = po_supplier
1174+ lead_time = 0
1175+ price = 0.0
1176+ if po_pricelist:
1177+ price = pl_model.price_get(cr, uid,
1178+ [po_pricelist.id],
1179+ line.proposed_product_id.id,
1180+ line.proposed_qty or 1.0,
1181+ po_supplier.id,
1182+ {'uom': line.proposed_uom_id.id})[po_pricelist.id]
1183+
1184+ if not price:
1185+ price = line.proposed_product_id.standard_price or 1.00
1186 taxes_ids = line.proposed_product_id.supplier_taxes_id
1187 taxes = acc_pos_obj.map_tax(cr, uid, supplier.property_account_position,
1188 taxes_ids)
1189- currency = line.purchase_pricelist_id.currency_id
1190- price = line.framework_agreement_id.get_price(line.proposed_qty, currency=currency)
1191- lead_time = line.framework_agreement_id.delay
1192- data = {}
1193- direct_map = {'product_qty': 'proposed_qty',
1194- 'product_id': 'proposed_product_id',
1195- 'product_uom': 'proposed_uom_id',
1196- 'lr_source_line_id': 'id',
1197- }
1198
1199- data.update(self._direct_map(line, direct_map))
1200+ data['order_id'] = po_id
1201+ data['product_qty'] = line.proposed_qty
1202+ data['product_id'] = line.proposed_product_id.id
1203+ data['product_uom'] = line.proposed_uom_id.id
1204+ data['lr_source_line_id']= line.id
1205 data['product_lead_time'] = lead_time
1206 data['price_unit'] = price
1207 data['name'] = line.proposed_product_id.name
1208@@ -151,47 +170,99 @@
1209 data['taxes_id'] = [(6, 0, taxes)]
1210 return data
1211
1212- def _make_po_from_source_line(self, cr, uid, source_line, context=None):
1213- """adapt a source line to purchase order
1214+ def _make_po_from_source_lines(self, cr, uid, main_source, other_sources,
1215+ pricelist, context=None):
1216+ """Create a purchase order from a source line. After creating it,
1217+ it'll update the unit_cost of the source line accoring to the PO
1218+ price. We do this because the currency of the PO may not be the same
1219+ than the LRS so it may happends that value vary because of exchange
1220+ rate.
1221
1222- :returns: generated PO id
1223+ :param browse_record main_source: logistic.requisition.source of
1224+ type LTA from which you want to generate to PO
1225+ :param browse_record other_sources: logistic.requisition.source of
1226+ type other to indlue in the PO
1227+ :param browse_record pricelist: product.pricelist to be used in PO to
1228+ know the currency mainly (as the prices will be computed from LTA)
1229+ :returns integer : generated PO id
1230
1231 """
1232 if context is None:
1233 context = {}
1234 context['draft_po'] = True
1235+ currency_obj = self.pool['res.currency']
1236 po_obj = self.pool['purchase.order']
1237- pid = po_obj._make_purchase_order_from_origin(cr, uid, source_line,
1238- self._map_source_to_po,
1239- self._map_source_to_po_line,
1240- context=context)
1241-
1242- return pid
1243-
1244- def make_purchase_order(self, cr, uid, ids, context=None):
1245- """ adapt each source line to purchase order
1246-
1247- :returns: generated PO ids
1248+ po_l_obj = self.pool['purchase.order.line']
1249+ supplier = main_source.framework_agreement_id.supplier_id
1250+ to_curr = pricelist.currency_id.id
1251+ po_vals = self._prepare_purchase_order(cr, uid, main_source,
1252+ pricelist, context=context)
1253+ po_id = po_obj.create(cr, uid, po_vals, context=context)
1254+ other_sources = other_sources if other_sources else []
1255+ for source in chain([main_source], other_sources):
1256+ line_vals = self._prepare_purchase_order_line(cr, uid, po_id,
1257+ source, supplier,
1258+ pricelist, context=context)
1259+ po_l_obj.create(cr, uid, line_vals, context=context)
1260+ # TODO: Update LRS unit_cost from po line, with currency conversion
1261+ from_curr = source.requisition_id.currency_id.id
1262+ # Compute from bid currency to LRS currency
1263+ price = currency_obj.compute(cr, uid, from_curr, to_curr,
1264+ line_vals['price_unit'], False)
1265+ source.write({'framework_agreement_po_id': po_id, 'unit_cost':price})
1266+ return po_id
1267+
1268+ def make_purchase_order(self, cr, uid, ids, pricelist, context=None):
1269+ """Create a purchase order from the LRS ids list. This method will
1270+ create one PO with all lines. Between them, you'll have line of type
1271+ LTA (framewrok agreement) and line of type other.
1272+ Currently, only one line of type LTA is accepted at a time.
1273+
1274+ We'll raise an error if other types are selected here.
1275+ We accept line of type other here to include products not included
1276+ in the LTA for example : you order Product A under LTA + the transport
1277+ as a LRS of type other.
1278+
1279+ :param integer list ids: ids of logistic.requisition.source
1280+ :param browse_record pricelist: product.pricelist
1281+ :returns integer : generated PO id
1282
1283 """
1284- po_ids = []
1285- for source_line in self.browse(cr, uid, ids, context=context):
1286- po_id = self._make_po_from_source_line(cr, uid, source_line, context=None)
1287- po_ids.append(po_id)
1288- return po_ids
1289-
1290- def action_create_agreement_po_requisition(self, cr, uid, ids, context=None):
1291- """ Implement buttons that create PO from selected source lines"""
1292- # We force empty context
1293- act_obj = self.pool.get('ir.actions.act_window')
1294- po_ids = self.make_purchase_order(cr, uid, ids, context=context)
1295- res = act_obj.for_xml_id(cr, uid,
1296- 'purchase', 'purchase_rfq', context=context)
1297- res.update({'domain': [('id', 'in', po_ids)],
1298- 'res_id': False,
1299- 'context': '{}',
1300- })
1301- return res
1302+ sources = self.browse(cr, uid, ids, context=context)
1303+ # LRS of type LTA (framework agreement)
1304+ agreement_sources = []
1305+ # LRS of type other
1306+ other_sources = []
1307+ for source in sources:
1308+ if source.procurement_method == AGR_PROC:
1309+ agreement_sources.append(source)
1310+ elif source.procurement_method == 'other':
1311+ other_sources.append(source)
1312+ else:
1313+ raise orm.except_orm(_('Source line must be of type other or agreement'),
1314+ _('Please correct selection'))
1315+
1316+ main_source = agreement_sources[0] if agreement_sources else False
1317+ if len(agreement_sources) > 1:
1318+ raise orm.except_orm(_('There should be only one agreement line'),
1319+ _('Please correct selection'))
1320+ if not main_source:
1321+ raise orm.except_orm(_('There should be at least one agreement line'),
1322+ _('Please correct selection'))
1323+ fback = main_source.framework_agreement_id.supplier_id.property_product_pricelist_purchase
1324+ pricelist = pricelist if pricelist else fback
1325+ po_id = self._make_po_from_source_lines(cr, uid, main_source,
1326+ other_sources, pricelist, context=None)
1327+ return po_id
1328+
1329+ def _is_sourced_other(self, cr, uid, source, context=None):
1330+ """Predicate function to test if line on other
1331+ method are sourced"""
1332+ tender_ok = self._is_sourced_procurement(cr, uid, source,
1333+ context=context)
1334+ agr_ok = self._is_sourced_fw_agreement(cr, uid, source,
1335+ context=context)
1336+ return (tender_ok or agr_ok)
1337
1338 def _is_sourced_fw_agreement(self, cr, uid, source, context=None):
1339 """Predicate that tells if source line of type agreement are sourced
1340@@ -200,56 +271,12 @@
1341
1342 """
1343 po_line_obj = self.pool['purchase.order.line']
1344- sources_ids = po_line_obj.search(cr, uid, [('lr_source_line_id', '=', source.id)],
1345+ sources_ids = po_line_obj.search(cr, uid,
1346+ [('lr_source_line_id', '=', source.id)],
1347 context=context)
1348 # predicate
1349 return bool(sources_ids)
1350
1351- def get_agreement_price_from_po(self, cr, uid, source_id, context=None):
1352- """Get price from PO.
1353-
1354- The price is retreived on the po line generated by sourced line.
1355-
1356- :returns: price in float
1357- """
1358- if isinstance(source_id, (list, tuple)):
1359- assert len(source_id) == 1
1360- source_id = source_id[0]
1361- po_l_obj = self.pool['purchase.order.line']
1362- currency_obj = self.pool['res.currency']
1363- current = self.browse(cr, uid, source_id, context=context)
1364- agreement = current.framework_agreement_id
1365-
1366- if not agreement:
1367- raise ValueError('No framework agreement on source line %s' %
1368- current.name)
1369- line_ids = po_l_obj.search(cr, uid,
1370- [('order_id.framework_agreement_id', '=', agreement.id),
1371- ('lr_source_line_id', '=', current.id),
1372- ('order_id.partner_id', '=', agreement.supplier_id.id)],
1373- context=context)
1374- price = 0.0
1375- lines = po_l_obj.browse(cr, uid, line_ids, context=context)
1376- if lines:
1377- price = sum(x.price_subtotal for x in lines) # To avoid rounding problems
1378- from_curr = lines[0].order_id.pricelist_id.currency_id.id
1379- to_curr = current.pricelist_id.currency_id.id
1380- price = currency_obj.compute(cr, uid, from_curr, to_curr, price, False)
1381- return price
1382-
1383- #---------------------- provide adapter middleware -------------------------
1384-
1385- def _make_source_line_from_origin(self, cr, uid, origin, map_fun,
1386- post_fun=None, context=None, **kwargs):
1387- model = self.pool['logistic.requisition.source']
1388- data = self._adapt_origin(cr, uid, model, origin, map_fun,
1389- post_fun=post_fun, context=context, **kwargs)
1390- self._validate_adapted_data(cr, uid, model, data, context=context)
1391- s_id = self.create(cr, uid, data, context=context)
1392- if callable(post_fun):
1393- post_fun(cr, uid, s_id, origin, context=context, **kwargs)
1394- return s_id
1395-
1396 #---------------OpenERP tedious onchange management ------------------------
1397
1398 def _get_date(self, cr, uid, requision_line_id, context=None):
1399@@ -268,8 +295,8 @@
1400 return current.requisition_id.date or now
1401
1402 @id_boilerplate
1403- def onchange_sourcing_method(self, cr, uid, source_id, method, req_line_id, proposed_product_id,
1404- pricelist_id, proposed_qty=0, context=None):
1405+ def onchange_sourcing_method(self, cr, uid, ids, method, req_line_id, proposed_product_id,
1406+ proposed_qty=0, context=None):
1407 """
1408 Called when source method is set on a source line.
1409
1410@@ -278,10 +305,11 @@
1411 and raise quantity warning.
1412
1413 """
1414+ line_source = self.browse(cr, uid, ids, context=context)
1415 res = {'value': {'framework_agreement_id': False}}
1416- if (method != AGR_PROC or not proposed_product_id or not pricelist_id):
1417+ if (method != AGR_PROC or not proposed_product_id):
1418 return res
1419- currency = self._currency_get(cr, uid, pricelist_id, context=context)
1420+ currency = line_source.currency_id
1421 agreement_obj = self.pool['framework.agreement']
1422 date = self._get_date(cr, uid, req_line_id, context=context)
1423 agreement, enough_qty = agreement_obj.get_cheapest_agreement_for_qty(cr, uid,
1424@@ -300,48 +328,30 @@
1425 if not enough_qty:
1426 msg = _("You have ask for a quantity of %s \n"
1427 " but there is only %s available"
1428- " for current agreement") % (proposed_qty, agreement.available_quantity)
1429+ " for current agreement") % (proposed_qty,
1430+ agreement.available_quantity)
1431 res['warning'] = msg
1432 return res
1433
1434 @id_boilerplate
1435- def onchange_pricelist(self, cr, uid, source_id, method, req_line_id,
1436- proposed_product_id, proposed_qty,
1437- pricelist_id, context=None):
1438- """Call when pricelist is set on a source line.
1439-
1440- If sourcing method is framework agreement
1441- it will set price, agreement and supplier if possible
1442- and raise quantity warning.
1443-
1444- """
1445- res = {}
1446- if (method != AGR_PROC or not proposed_product_id or not pricelist_id):
1447- return res
1448-
1449- return self.onchange_sourcing_method(cr, uid, source_id, method, req_line_id,
1450- proposed_product_id, pricelist_id,
1451- proposed_qty=proposed_qty,
1452- context=context)
1453-
1454- @id_boilerplate
1455- def onchange_quantity(self, cr, uid, source_id, method, req_line_id, qty,
1456- proposed_product_id, pricelist_id, context=None):
1457+ def onchange_quantity(self, cr, uid, ids, method, req_line_id, qty,
1458+ proposed_product_id, context=None):
1459 """Raise a warning if agreed qty is not sufficient"""
1460+ line_source = self.browse(cr, uid, ids, context=context)
1461 if (method != AGR_PROC or not proposed_product_id):
1462 return {}
1463- currency = self._currency_get(cr, uid, pricelist_id, context=context)
1464+ currency = line_source.currency_id
1465 date = self._get_date(cr, uid, req_line_id, context=context)
1466- return self.onchange_quantity_obs(cr, uid, source_id, qty, date,
1467+ return self.onchange_quantity_obs(cr, uid, ids, qty, date,
1468 proposed_product_id,
1469 currency=currency,
1470 price_field='dummy',
1471 context=context)
1472
1473 @id_boilerplate
1474- def onchange_product_id(self, cr, uid, source_id, method, req_line_id,
1475+ def onchange_product_id(self, cr, uid, ids, method, req_line_id,
1476 proposed_product_id, proposed_qty,
1477- pricelist_id, context=None):
1478+ context=None):
1479 """Call when product is set on a source line.
1480
1481 If sourcing method is framework agreement
1482@@ -349,21 +359,31 @@
1483 and raise quantity warning.
1484
1485 """
1486- if (method != AGR_PROC or not proposed_product_id):
1487+ if method != AGR_PROC:
1488+ if proposed_product_id:
1489+ value = {'proposed_uom_id': ''}
1490+ if proposed_product_id:
1491+ prod_obj = self.pool.get('product.product')
1492+ prod = prod_obj.browse(cr, uid, proposed_product_id, context=context)
1493+ value = {
1494+ 'proposed_uom_id': prod.uom_id.id,
1495+ }
1496+ return {'value': value}
1497 return {}
1498
1499- return self.onchange_sourcing_method(cr, uid, source_id, method, req_line_id,
1500- proposed_product_id, pricelist_id,
1501+ return self.onchange_sourcing_method(cr, uid, ids, method, req_line_id,
1502+ proposed_product_id,
1503 proposed_qty=proposed_qty,
1504 context=context)
1505
1506 @id_boilerplate
1507- def onchange_agreement(self, cr, uid, source_id, agreement_id, req_line_id, qty,
1508- proposed_product_id, pricelist_id, context=None):
1509- if not proposed_product_id or not pricelist_id or not agreement_id:
1510+ def onchange_agreement(self, cr, uid, ids, agreement_id, req_line_id, qty,
1511+ proposed_product_id, context=None):
1512+ line_source = self.browse(cr, uid, ids, context=context)
1513+ if not proposed_product_id or not agreement_id:
1514 return {}
1515- currency = self._currency_get(cr, uid, pricelist_id, context=context)
1516+ currency = line_source.currency_id
1517 date = self._get_date(cr, uid, req_line_id, context=context)
1518- return self.onchange_agreement_obs(cr, uid, source_id, agreement_id, qty,
1519+ return self.onchange_agreement_obs(cr, uid, ids, agreement_id, qty,
1520 date, proposed_product_id,
1521 currency=currency, price_field='dummy')
1522
1523=== modified file 'framework_agreement_sourcing/model/purchase.py'
1524--- framework_agreement_sourcing/model/purchase.py 2013-12-11 17:57:19 +0000
1525+++ framework_agreement_sourcing/model/purchase.py 2014-05-07 09:53:02 +0000
1526@@ -19,69 +19,13 @@
1527 #
1528 ##############################################################################
1529 from openerp.osv import orm
1530-from .adapter_util import BrowseAdapterMixin
1531-
1532-
1533-class purchase_order(orm.Model, BrowseAdapterMixin):
1534- """Add function to create PO from source line.
1535- It maybe goes against YAGNI principle.
1536- The idea would be to propose a small design
1537- to be ported back into purchase_requisition_extended module
1538- or an other base modules.
1539-
1540- Then we should extend it to propose an API
1541- to generate PO from various sources
1542+
1543+class purchase_order(orm.Model):
1544+ """ Override action_confirm to set quantity bid if LTA
1545 """
1546
1547 _inherit = "purchase.order"
1548
1549- #------ PO adapter middleware maybe to put in aside class but not easy in OpenERP context ----
1550- def _make_purchase_order_from_origin(self, cr, uid, origin, map_fun, map_line_fun,
1551- post_fun=None, post_line_fun=None, context=None):
1552- """Create a PO browse record from any other record
1553-
1554- :returns: created record ids
1555-
1556- """
1557- po_id = self._adapt_origin_to_po(cr, uid, origin, map_fun,
1558- post_fun=post_fun, context=context)
1559- self._adapt_origin_to_po_line(cr, uid, po_id, origin, map_line_fun,
1560- post_fun=post_line_fun,
1561- context=context)
1562- return po_id
1563-
1564- def _adapt_origin_to_po(self, cr, uid, origin, map_fun,
1565- post_fun=None, context=None):
1566- """PO adapter function
1567-
1568- :returns: created PO id
1569-
1570- """
1571- model = self.pool['purchase.order']
1572- data = self._adapt_origin(cr, uid, model, origin, map_fun,
1573- post_fun=post_fun, context=context)
1574- self._validate_adapted_data(cr, uid, model, data, context=context)
1575- po_id = self.create(cr, uid, data, context=context)
1576- if callable(post_fun):
1577- post_fun(cr, uid, po_id, origin, context=context)
1578- return po_id
1579-
1580- def _adapt_origin_to_po_line(self, cr, uid, po_id, origin, map_fun,
1581- post_fun=None, context=None):
1582- """PO line adapter
1583-
1584- :returns: created PO line id
1585-
1586- """
1587- model = self.pool['purchase.order.line']
1588- data = self._adapt_origin(cr, uid, model, origin, map_fun,
1589- post_fun=post_fun, context=context)
1590- data['order_id'] = po_id
1591- self._validate_adapted_data(cr, uid, model, data, context=context)
1592- l_id = model.create(cr, uid, data, context=context)
1593- if callable(post_fun):
1594- post_fun(cr, uid, l_id, origin, context=context)
1595- return l_id
1596
1597 def action_confirm(self, cr, uid, ids, context=None):
1598 super(purchase_order_line, self).action_confirm(cr, uid, ids, context=context)
1599@@ -89,3 +33,4 @@
1600 if not element.quantity_bid and not element.framework_agreement_id:
1601 self.write(cr, uid, ids, {'quantity_bid': element.product_qty}, context=context)
1602 return True
1603+
1604
1605=== added file 'framework_agreement_sourcing/security/ir.model.access.csv'
1606--- framework_agreement_sourcing/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
1607+++ framework_agreement_sourcing/security/ir.model.access.csv 2014-05-07 09:53:02 +0000
1608@@ -0,0 +1,2 @@
1609+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
1610+access_po_creator,po_creator,model_logistic_requisition_source_create_agr_po,purchase.group_purchase_user,1,1,1,1
1611
1612=== modified file 'framework_agreement_sourcing/tests/common.py'
1613--- framework_agreement_sourcing/tests/common.py 2013-11-29 09:55:12 +0000
1614+++ framework_agreement_sourcing/tests/common.py 2014-05-07 09:53:02 +0000
1615@@ -51,6 +51,7 @@
1616 'user_id': self.uid,
1617 'budget_holder_id': self.uid,
1618 'finance_officer_id': self.uid,
1619+ 'pricelist_id': self.ref('product.list0'),
1620 }
1621 agr_line = {
1622 'product_id': self.product_id,
1623@@ -59,7 +60,7 @@
1624 'date_delivery': self.now.strftime(DEFAULT_SERVER_DATE_FORMAT),
1625 'budget_tot_price': 100000000,
1626 }
1627- other_line = {
1628+ product_line = {
1629 'product_id': self.ref('product.product_product_7'),
1630 'requested_qty': 10,
1631 'requested_uom_id': self.ref('product.product_uom_unit'),
1632@@ -67,10 +68,21 @@
1633 'budget_tot_price': 100000000,
1634 }
1635
1636+ other_line = {
1637+ 'product_id': self.ref('logistic_requisition.product_transport'),
1638+ 'requested_qty': 1,
1639+ 'requested_uom_id': self.ref('product.product_uom_unit'),
1640+ 'date_delivery': self.now.strftime(DEFAULT_SERVER_DATE_FORMAT),
1641+ 'budget_tot_price': 100000000,
1642+ }
1643+
1644+
1645 requisition_id = logistic_requisition.create(self, req)
1646 logistic_requisition.add_line(self, requisition_id,
1647 agr_line)
1648 logistic_requisition.add_line(self, requisition_id,
1649+ product_line)
1650+ logistic_requisition.add_line(self, requisition_id,
1651 other_line)
1652 self.requisition = self.requisition_model.browse(self.cr, self.uid, requisition_id)
1653
1654
1655=== modified file 'framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py'
1656--- framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py 2013-12-16 12:07:22 +0000
1657+++ framework_agreement_sourcing/tests/test_agreement_souce_line_to_po.py 2014-05-07 09:53:02 +0000
1658@@ -29,6 +29,7 @@
1659 cr, uid = self.cr, self.uid
1660 lines = self.requisition.line_ids
1661 agr_line = None
1662+ self.wiz_model = self.registry('logistic.requisition.source.create.agr.po')
1663 for line in lines:
1664 if line.product_id == self.cheap_on_low_agreement.product_id:
1665 agr_line = line
1666@@ -36,26 +37,39 @@
1667 self.assertTrue(agr_line)
1668 agr_line.write({'requested_qty': 400})
1669 agr_line.refresh()
1670- source_ids = self.requisition_line_model._generate_source_line(cr, uid, agr_line)
1671- self.assertTrue(len(source_ids) == 1)
1672- self.source_line = self.source_line_model.browse(cr, uid, source_ids[0])
1673+ source_ids = []
1674+ for line in lines:
1675+ if (line.product_id.id == self.product_id or
1676+ line.product_id.type == 'service'):
1677+ lid = self.requisition_line_model._generate_source_line(cr, uid, line)
1678+ source_ids += lid
1679+ self.assertTrue(len(source_ids) == 2)
1680+ self.source_lines = self.source_line_model.browse(cr, uid, source_ids)
1681+ self.lta_source = next(x for x in self.source_lines
1682+ if x.procurement_method == 'fw_agreement')
1683+ self.other_source = next(x for x in self.source_lines
1684+ if x.procurement_method == 'other')
1685
1686 def test_01_transform_source_to_agreement(self):
1687 """Test transformation of an agreement source line into PO"""
1688 cr, uid = self.cr, self.uid
1689- self.assertTrue(self.source_line)
1690- plist = self.source_line.framework_agreement_id.supplier_id.property_product_pricelist_purchase
1691- self.source_line.write({'purchase_pricelist_id': plist.id})
1692- self.source_line.refresh()
1693- po_id = self.source_line_model._make_po_from_source_line(cr, uid,
1694- self.source_line)
1695+ self.assertTrue(self.lta_source)
1696+ self.lta_source.refresh()
1697+ active_ids = [x.id for x in self.source_lines]
1698+ wiz_id = self.wiz_model.create(self.cr, self.uid, {},
1699+ context={'active_ids': active_ids})
1700+
1701+ wiz = self.wiz_model.browse(self.cr, self.uid, wiz_id)
1702+ po_id = wiz.action_create_agreement_po_requisition(
1703+ context={'active_ids': active_ids}
1704+ )['res_id']
1705 self.assertTrue(po_id)
1706- supplier = self.source_line.framework_agreement_id.supplier_id
1707- add = self.source_line.requisition_id.consignee_shipping_id
1708- consignee = self.source_line.requisition_id.consignee_id
1709+ supplier = self.lta_source.framework_agreement_id.supplier_id
1710+ add = self.lta_source.requisition_id.consignee_shipping_id
1711+ consignee = self.lta_source.requisition_id.consignee_id
1712 po = self.registry('purchase.order').browse(cr, uid, po_id)
1713- date_order = self.source_line.requisition_id.date
1714- date_delivery = self.source_line.requisition_id.date_delivery
1715+ date_order = self.lta_source.requisition_id.date
1716+ date_delivery = self.lta_source.requisition_id.date_delivery
1717 self.assertEqual(po.partner_id, supplier)
1718 self.assertEqual(po.pricelist_id, supplier.property_product_pricelist_purchase)
1719 self.assertEqual(po.date_order, date_order)
1720@@ -63,12 +77,23 @@
1721 self.assertEqual(po.consignee_id, consignee)
1722 self.assertEqual(po.state, 'draftpo')
1723
1724- self.assertEqual(len(po.order_line), 1)
1725- po_line = po.order_line[0]
1726- self.assertEqual(po_line.product_qty, self.source_line.proposed_qty)
1727- self.assertEqual(po_line.product_id, self.source_line.proposed_product_id)
1728- self.assertEqual(po_line.product_qty, self.source_line.proposed_qty)
1729- self.assertEqual(po_line.product_uom, self.source_line.proposed_uom_id)
1730- self.assertEqual(po_line.price_unit, 50.0)
1731- self.assertEqual(po_line.lr_source_line_id, self.source_line)
1732+ self.assertEqual(len(po.order_line), 2)
1733+
1734+ po_line = next(x for x in po.order_line
1735+ if x.product_id == self.lta_source.framework_agreement_id.product_id)
1736+ self.assertEqual(po_line.product_qty, self.lta_source.proposed_qty)
1737+ self.assertEqual(po_line.product_id, self.lta_source.proposed_product_id)
1738+ self.assertEqual(po_line.product_qty, self.lta_source.proposed_qty)
1739+ self.assertEqual(po_line.product_uom, self.lta_source.proposed_uom_id)
1740+ self.assertAlmostEqual(po_line.price_unit, 50.0)
1741+ self.assertEqual(po_line.lr_source_line_id, self.lta_source)
1742 self.assertEqual(po_line.date_planned, date_delivery)
1743+
1744+ po_line = next(x for x in po.order_line
1745+ if x.product_id == self.other_source.proposed_product_id)
1746+ self.assertEqual(po_line.product_qty, self.other_source.proposed_qty)
1747+ self.assertEqual(po_line.product_id, self.other_source.proposed_product_id)
1748+ self.assertEqual(po_line.product_qty, self.other_source.proposed_qty)
1749+ self.assertEqual(po_line.product_uom, self.other_source.proposed_uom_id)
1750+ self.assertAlmostEqual(po_line.price_unit, 1.0)
1751+ self.assertEqual(po_line.lr_source_line_id, self.other_source)
1752
1753=== modified file 'framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py'
1754--- framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py 2013-11-21 11:15:49 +0000
1755+++ framework_agreement_sourcing/tests/test_logistic_order_line_to_source_line.py 2014-05-07 09:53:02 +0000
1756@@ -40,7 +40,7 @@
1757 self.assertTrue(len(to_validate_ids) == 1)
1758 to_validate = self.source_line_model.browse(cr, uid, to_validate_ids[0])
1759 self.assertEqual(to_validate.procurement_method, AGR_PROC)
1760- self.assertEqual(to_validate.unit_cost, 0.0)
1761+ self.assertAlmostEqual(to_validate.unit_cost, 0.0)
1762 self.assertEqual(to_validate.proposed_qty, 400)
1763
1764 def test_02_enough_qty_on_high_agr(self):
1765@@ -59,7 +59,7 @@
1766 self.assertTrue(len(to_validate_ids) == 1)
1767 to_validate = self.source_line_model.browse(cr, uid, to_validate_ids[0])
1768 self.assertEqual(to_validate.procurement_method, AGR_PROC)
1769- self.assertEqual(to_validate.unit_cost, 0.0)
1770+ self.assertAlmostEqual(to_validate.unit_cost, 0.0)
1771 self.assertEqual(to_validate.proposed_qty, 1500)
1772
1773 def test_03_not_enough_qty_on_high_agreement(self):
1774@@ -85,7 +85,7 @@
1775 self.assertTrue(high_line, msg="High agreement was not used")
1776 self.assertEqual(high_line.procurement_method, AGR_PROC)
1777 self.assertEqual(high_line.proposed_qty, 2000)
1778- self.assertEqual(high_line.unit_cost, 0.0)
1779+ self.assertAlmostEqual(high_line.unit_cost, 0.0)
1780
1781 # low_line
1782 low_line = next((x for x in to_validates
1783@@ -93,10 +93,13 @@
1784 self.assertTrue(low_line, msg="Low agreement was not used")
1785 self.assertEqual(low_line.procurement_method, AGR_PROC)
1786 self.assertEqual(low_line.proposed_qty, 400)
1787- self.assertEqual(low_line.unit_cost, 0.0)
1788+ self.assertAlmostEqual(low_line.unit_cost, 0.0)
1789
1790 def test_03_not_enough_qty_on_all_agreemenst(self):
1791- """Test that we """
1792+ """Test that we have generate correct line when not enough qty on all agreements
1793+
1794+ That means last source line must be of type other or procurement
1795+ """
1796 cr, uid = self.cr, self.uid
1797 lines = self.requisition.line_ids
1798 agr_line = None
1799@@ -118,7 +121,7 @@
1800 self.assertTrue(high_line, msg="High agreement was not used")
1801 self.assertEqual(high_line.procurement_method, AGR_PROC)
1802 self.assertEqual(high_line.proposed_qty, 2000)
1803- self.assertEqual(high_line.unit_cost, 0.0)
1804+ self.assertAlmostEqual(high_line.unit_cost, 0.0)
1805
1806 # low_line
1807 low_line = next((x for x in to_validates
1808@@ -126,7 +129,7 @@
1809 self.assertTrue(low_line, msg="Low agreement was not used")
1810 self.assertEqual(low_line.procurement_method, AGR_PROC)
1811 self.assertEqual(low_line.proposed_qty, 1200)
1812- self.assertEqual(low_line.unit_cost, 0.0)
1813+ self.assertAlmostEqual(low_line.unit_cost, 0.0)
1814
1815 # Tender line
1816 tender_line = next((x for x in to_validates
1817
1818=== removed file 'framework_agreement_sourcing/touch'
1819=== modified file 'framework_agreement_sourcing/view/requisition_view.xml'
1820--- framework_agreement_sourcing/view/requisition_view.xml 2013-12-16 11:11:44 +0000
1821+++ framework_agreement_sourcing/view/requisition_view.xml 2014-05-07 09:53:02 +0000
1822@@ -12,108 +12,58 @@
1823 domain="[('draft', '=', False)]"
1824 attrs="{'required': [('procurement_method', '=', 'fw_agreement')],
1825 'invisible': [('procurement_method', '!=', 'fw_agreement')]}"
1826- on_change="onchange_agreement(framework_agreement_id, requisition_line_id, proposed_qty, proposed_product_id, purchase_pricelist_id, context)"/>/>
1827- <field name="pricelist_id"
1828- invisible="1"/>
1829- <field name="purchase_pricelist_id"
1830- attrs="{'required': [('procurement_method', '=', 'fw_agreement')],
1831- 'invisible': [('procurement_method', '!=', 'fw_agreement')]}"
1832- on_change="onchange_pricelist(framework_agreement_id, requisition_line_id, proposed_qty, proposed_product_id, purchase_pricelist_id, context)"
1833- domain="[('type', '=', 'purchase')]"/>
1834+ on_change="onchange_agreement(framework_agreement_id, requisition_line_id, proposed_qty, proposed_product_id, context)"/>
1835+ <field name="framework_agreement_po_id"
1836+ readonly="1"
1837+ attrs="{'invisible': [('procurement_method', 'not in', ['fw_agreement','other'])]}"
1838+
1839+ />
1840
1841 <field name="supplier_id"
1842 invisible="1"/>
1843 </field>
1844 <field name="proposed_uom_id"
1845 position="attributes">
1846- <attribute name="attrs">{'invisible': [('procurement_method', '=', 'fw_agreement')]}</attribute>
1847- </field>
1848- <field name="unit_cost"
1849- position="attributes">
1850- <attribute name="attrs">{'invisible': [('procurement_method', '=', 'fw_agreement')]}</attribute>
1851- </field>
1852- <field name="total_cost"
1853- position="attributes">
1854- <attribute name="attrs">{'invisible': [('procurement_method', '=', 'fw_agreement')]}</attribute>
1855- </field>
1856- <field name="price_is"
1857- position="attributes">
1858- <attribute name="attrs">{'invisible': [('procurement_method', '=', 'fw_agreement')]}</attribute>
1859- </field>
1860- </field>
1861- </record>
1862-
1863- <record id="add_hide_button_create_bids" model="ir.ui.view">
1864- <field name="name">hidde button</field>
1865- <field name="model">logistic.requisition.source</field>
1866- <field name="inherit_id" ref="logistic_requisition.view_logistic_requisition_source_form"/>
1867- <field name="priority" eval="10"/>
1868- <field name="arch" type="xml">
1869- <button position="replace">
1870- </button>
1871- </field>
1872- </record>
1873-
1874-
1875- <record id="add_create_po_button" model="ir.ui.view">
1876- <field name="name">add create po button</field>
1877- <field name="model">logistic.requisition.source</field>
1878- <field name="inherit_id" ref="logistic_requisition.view_logistic_requisition_source_form"/>
1879- <field name="arch" type="xml">
1880- <sheet position="before">
1881- <header>
1882- <button name="action_create_agreement_po_requisition"
1883- context="{}"
1884- string="Create Draft PO"
1885- type="object"
1886- attrs="{'invisible': [('procurement_method', '!=', 'fw_agreement')]}"/>
1887- <button name="action_create_po_requisition"
1888- string="Call for Bids"
1889- type="object"
1890- attrs="{'invisible': ['|', ('po_requisition_id', '!=', False), ('procurement_method', '!=', 'procurement')]}"
1891- />
1892- </header>
1893- </sheet>
1894+ <attribute name="attrs">{'invisible': [('procurement_method', '=', 'fw_agreement')]}</attribute>
1895+ </field>
1896+ <field name="unit_cost"
1897+ position="attributes">
1898+ <attribute name="attrs">{'invisible': [('procurement_method', '=', 'fw_agreement')]}</attribute>
1899+ </field>
1900+ <field name="total_cost"
1901+ position="attributes">
1902+ <attribute name="attrs">{'invisible': [('procurement_method', '=', 'fw_agreement')]}</attribute>
1903+ </field>
1904+ <field name="price_is"
1905+ position="attributes">
1906+ <attribute name="attrs">{'invisible': [('procurement_method', '=', 'fw_agreement')]}</attribute>
1907+ </field>
1908 </field>
1909 </record>
1910
1911 <record id="addd_agreement_source_line_onchange" model="ir.ui.view">
1912- <field name="name">addd agreement source line onchange</field>
1913+ <field name="name">ad agreement source line onchange</field>
1914 <field name="model">logistic.requisition.source</field>
1915 <field name="inherit_id" ref="logistic_requisition.view_logistic_requisition_source_form"/>
1916 <field name="arch" type="xml">
1917 <data>
1918 <field name="procurement_method"
1919 position="attributes">
1920- <attribute name="on_change">onchange_sourcing_method(procurement_method, requisition_line_id, proposed_product_id, purchase_pricelist_id, proposed_qty)</attribute>
1921+ <attribute name="on_change">onchange_sourcing_method(procurement_method, requisition_line_id, proposed_product_id, proposed_qty)</attribute>
1922 </field>
1923
1924 <field name="proposed_qty"
1925 position="attributes">
1926- <attribute name="on_change">onchange_quantity(procurement_method, requisition_line_id, proposed_qty, proposed_product_id, purchase_pricelist_id)</attribute>
1927+ <attribute name="on_change">onchange_quantity(procurement_method, requisition_line_id, proposed_qty, proposed_product_id)</attribute>
1928 </field>
1929 <field name="proposed_product_id"
1930 position="attributes">
1931- <attribute name="on_change">onchange_product_id(procurement_method, requisition_line_id, proposed_product_id, proposed_qty, purchase_pricelist_id)</attribute>
1932+ <attribute name="on_change">onchange_product_id(procurement_method, requisition_line_id, proposed_product_id, proposed_qty)</attribute>
1933 </field>
1934
1935 </data>
1936 </field>
1937 </record>
1938
1939-
1940-<!-- Deactivate button on tree to ensure choose of the sourcing method before calling action -->
1941- <record id="hide_button_on_soure_line in req line tree" model="ir.ui.view">
1942- <field name="name">hide button on soure line in req line tree</field>
1943- <field name="model">logistic.requisition.line</field>
1944- <field name="inherit_id" ref="logistic_requisition.view_logistic_requisition_line_form" />
1945- <field name="arch" type="xml">
1946- <button name="action_create_po_requisition" position="attributes">
1947- <attribute name="attrs">{}</attribute>
1948- <attribute name="invisible">1</attribute>
1949- </button>
1950- </field>
1951- </record>
1952-
1953 </data>
1954 </openerp>
1955
1956=== added directory 'framework_agreement_sourcing/wizard'
1957=== added file 'framework_agreement_sourcing/wizard/__init__.py'
1958--- framework_agreement_sourcing/wizard/__init__.py 1970-01-01 00:00:00 +0000
1959+++ framework_agreement_sourcing/wizard/__init__.py 2014-05-07 09:53:02 +0000
1960@@ -0,0 +1,21 @@
1961+# -*- coding: utf-8 -*-
1962+##############################################################################
1963+#
1964+# Author: joel Grand-Guillaume
1965+# Copyright 2013 Camptocamp SA
1966+#
1967+# This program is free software: you can redistribute it and/or modify
1968+# it under the terms of the GNU Affero General Public License as
1969+# published by the Free Software Foundation, either version 3 of the
1970+# License, or (at your option) any later version.
1971+#
1972+# This program is distributed in the hope that it will be useful,
1973+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1974+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1975+# GNU Affero General Public License for more details.
1976+#
1977+# You should have received a copy of the GNU Affero General Public License
1978+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1979+#
1980+##############################################################################
1981+from . import logistic_requisition_source_create_po
1982
1983=== added file 'framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py'
1984--- framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py 1970-01-01 00:00:00 +0000
1985+++ framework_agreement_sourcing/wizard/logistic_requisition_source_create_po.py 2014-05-07 09:53:02 +0000
1986@@ -0,0 +1,103 @@
1987+# -*- coding: utf-8 -*-
1988+##############################################################################
1989+#
1990+# Author: Nicolas Bessi
1991+# Copyright 2013 Camptocamp SA
1992+#
1993+# This program is free software: you can redistribute it and/or modify
1994+# it under the terms of the GNU Affero General Public License as
1995+# published by the Free Software Foundation, either version 3 of the
1996+# License, or (at your option) any later version.
1997+#
1998+# This program is distributed in the hope that it will be useful,
1999+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2000+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2001+# GNU Affero General Public License for more details.
2002+#
2003+# You should have received a copy of the GNU Affero General Public License
2004+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2005+#
2006+##############################################################################
2007+
2008+from openerp.osv import orm, fields
2009+from openerp.tools.translate import _
2010+
2011+class logistic_requisition_source_po_creator(orm.TransientModel):
2012+
2013+ _name = 'logistic.requisition.source.create.agr.po'
2014+
2015+ _columns = {
2016+ 'pricelist_id': fields.many2one('product.pricelist',
2017+ string='Pricelist / Currency',
2018+ required=True),
2019+ 'framework_currency_ids': fields.many2many('framework.agreement.pricelist',
2020+ rel='framework_agr_id_po_create_rel',
2021+ string='Available Currency',
2022+ readonly=True)
2023+ }
2024+
2025+ def default_get(self, cr, uid, fields_list, context=None):
2026+ """ Take the pricelist of the lrs by default. Show the
2027+ available choice for the user.
2028+ """
2029+ if context is None:
2030+ context = {}
2031+ defaults = super(logistic_requisition_source_po_creator, self).\
2032+ default_get(cr, uid, fields_list, context=context)
2033+ line_obj = self.pool.get('logistic.requisition.source')
2034+ fmwk_price_obj = self.pool.get('framework.agreement.pricelist')
2035+ line_ids = context['active_ids']
2036+ pricelist_id = None
2037+ line = next((x for x in line_obj.browse(cr, uid, line_ids, context=context)
2038+ if x.framework_agreement_id), None)
2039+ if not line:
2040+ raise orm.except_orm(_('No sourcing line with agreement selected'),
2041+ _('Please correct selection'))
2042+
2043+ pricelist_id = line_obj._get_purchase_pricelist_from_currency(
2044+ cr,
2045+ uid,
2046+ line.requisition_id.pricelist_id.currency_id.id,
2047+ context=context
2048+ )
2049+ defaults['pricelist_id'] = pricelist_id
2050+
2051+ frwk_ids = fmwk_price_obj.search(
2052+ cr, uid,
2053+ [('framework_agreement_id', '=', line.framework_agreement_id.id)],
2054+ context=context
2055+ )
2056+ defaults['framework_currency_ids'] = frwk_ids
2057+ return defaults
2058+
2059+ def _make_purchase_order(self, cr, uid, pricelist, source_ids, context=None):
2060+ """Create PO from source line ids"""
2061+ lr_model = self.pool['logistic.requisition.source']
2062+ po_id = lr_model.make_purchase_order(cr, uid, source_ids,
2063+ pricelist, context=context)
2064+ return po_id
2065+
2066+ def action_create_agreement_po_requisition(self, cr, uid, ids, context=None):
2067+ """ Implement buttons that create PO from selected source lines"""
2068+ act_obj = self.pool['ir.actions.act_window']
2069+ source_ids = context['active_ids']
2070+ form = self.browse(cr, uid, ids, context=context)[0]
2071+ pricelist=form.pricelist_id
2072+
2073+ available_currency = [x.currency_id for x in form.framework_currency_ids]
2074+ if available_currency and pricelist.currency_id not in available_currency:
2075+ raise orm.except_orm(_('User Error'), _(
2076+ 'You must chose a pricelist that is in the same currency '
2077+ 'than one of the available in the framework agreement.'))
2078+ po_id = self._make_purchase_order(cr, uid, pricelist, source_ids,
2079+ context=context)
2080+ # TODO : update LRS price from PO depending on the chosen currency
2081+
2082+ res = act_obj.for_xml_id(cr, uid,
2083+ 'purchase', 'purchase_rfq', context=context)
2084+ res.update({'domain': [('id', '=', po_id)],
2085+ 'res_id': po_id,
2086+ 'context': '{}',
2087+ 'search_view_id': False,
2088+ })
2089+ return res
2090
2091=== added file 'framework_agreement_sourcing/wizard/logistic_requisition_source_create_po_view.xml'
2092--- framework_agreement_sourcing/wizard/logistic_requisition_source_create_po_view.xml 1970-01-01 00:00:00 +0000
2093+++ framework_agreement_sourcing/wizard/logistic_requisition_source_create_po_view.xml 2014-05-07 09:53:02 +0000
2094@@ -0,0 +1,52 @@
2095+<?xml version="1.0" encoding="utf-8"?>
2096+<openerp>
2097+ <data>
2098+
2099+ <record id="view_create_agr_po_from_source" model="ir.ui.view">
2100+ <field name="name">Create Purchase Order From Requisition Source</field>
2101+ <field name="model">logistic.requisition.source.create.agr.po</field>
2102+ <field name="arch" type="xml">
2103+ <form string="Create Purchase Order" version="7.0">
2104+ <separator string="Which pricelist / currency you want ?"/>
2105+ <label string="You can only chose a pricelist with a currency that is included
2106+ in the framewrok agreement you have chosen." colspan="4"/>
2107+ <field name="framework_currency_ids"/>
2108+ <field name="pricelist_id" domain="[('type','=','purchase')]"/>
2109+
2110+ <group>
2111+ <separator string="Are you sure you want to create a Purchase Order from those lines ?"/>
2112+ <label string="
2113+ Please note that: &#10; &#10;
2114+ Requisition will only be created if: &#10;
2115+ * Lines belong to the same company &#10;
2116+ * There is only one agreement line in selection &#10;
2117+ * Products are define on all selected lines &#10;
2118+ * Non agreement line are of type other &#10;
2119+ &#10; &#10;
2120+ " colspan="4"/>
2121+ </group>
2122+ <footer>
2123+ <button name="action_create_agreement_po_requisition"
2124+ string="Create Purchase Order"
2125+ type="object" class="oe_highlight"/>
2126+ or
2127+ <button string="Cancel"
2128+ class="oe_link"
2129+ special="cancel" />
2130+ </footer>
2131+ </form>
2132+ </field>
2133+ </record>
2134+
2135+ <act_window
2136+ name="Create Agreement Purchase Order"
2137+ res_model="logistic.requisition.source.create.agr.po"
2138+ src_model="logistic.requisition.source"
2139+ view_mode="form"
2140+ target="new"
2141+ multi="True"
2142+ key2="client_action_multi"
2143+ id="action_view_create_agr_po_from_source"/>
2144+
2145+ </data>
2146+</openerp>
2147
2148=== modified file 'logistic_requisition/__openerp__.py'
2149--- logistic_requisition/__openerp__.py 2014-03-17 09:29:28 +0000
2150+++ logistic_requisition/__openerp__.py 2014-05-07 09:53:02 +0000
2151@@ -31,8 +31,38 @@
2152 This module allows you to manage your Logistic Requisitions.
2153 ============================================================
2154
2155-A Logistic requisition express a need that is requested somewhere.
2156-
2157+A Logistic requisition express a need that is requested somewhere. It allows to
2158+manage the sourcing of the needs before making a cost estimate to the requestor.
2159+
2160+This invert the logic that is in standard in OpenERP in the way that the sourcing
2161+of the procuremnt is made before the order confirmation and we built the link incase
2162+of validation. In standard, th SO confirmation generate the procurement then it
2163+generate the needed procurement.
2164+
2165+The sourcing can be of various type:
2166+
2167+ * Warehouse dispatch: You will deliver the requested goods from one of your
2168+ stock location
2169+ * Procurement : You will go for tender to chose the best supplier for the
2170+ requiredgoods
2171+ * Framework agreement : You will use the existing Framework agreement
2172+ * Other : Nothing of those choices. In that case, the line can be selected
2173+and included in either a PO or a tender
2174+
2175+The simple process is the following:
2176+
2177+ * LR are recorded as the to represent the need of the customer/requestor
2178+ * LR are confirm and sourced of different way (dispatch, tender, ..)
2179+ * If sourced from tender, you need to go all along the tendering process (CBA).
2180+ Once you chose one bid, the system will automatically put back the prices
2181+ information on the sourcing line of the LR.
2182+ * You can create a cost estimate from sourced LR lines for your
2183+ resquestor/customer
2184+ * If the requestor accept the cost estimate, his validation will automatically:
2185+ * Create the link between the chosen winning bid and the line sourced this way.
2186+ A new draft PO will be generatedand managed as drop shipping.
2187+ * Lines sourced as a dispatch will create a delivery order.
2188+ * Lines sourced a LTA will create a PO of type LTA
2189 """,
2190 "depends": ["transport_plan",
2191 "purchase",
2192
2193=== modified file 'logistic_requisition/i18n/en_US.po'
2194--- logistic_requisition/i18n/en_US.po 2013-08-29 09:53:01 +0000
2195+++ logistic_requisition/i18n/en_US.po 2014-05-07 09:53:02 +0000
2196@@ -6,8 +6,8 @@
2197 msgstr ""
2198 "Project-Id-Version: OpenERP Server 7.0\n"
2199 "Report-Msgid-Bugs-To: \n"
2200-"POT-Creation-Date: 2013-08-29 09:51+0000\n"
2201-"PO-Revision-Date: 2013-08-29 09:51+0000\n"
2202+"POT-Creation-Date: 2014-02-04 13:11+0000\n"
2203+"PO-Revision-Date: 2014-02-04 13:11+0000\n"
2204 "Last-Translator: <>\n"
2205 "Language-Team: \n"
2206 "MIME-Version: 1.0\n"
2207@@ -21,14 +21,14 @@
2208 msgstr "Logistic Specialist"
2209
2210 #. module: logistic_requisition
2211-#: field:logistic.requisition.source,offer_ids:0
2212-msgid "Sales Quotation Lines"
2213-msgstr "Sales Quotation Lines"
2214+#: field:logistic.requisition.line,amount_total:0
2215+msgid "Total Amount"
2216+msgstr "Total Amount"
2217
2218 #. module: logistic_requisition
2219-#: field:logistic.requisition,finance_officer_id:0
2220-msgid "Finance Officer"
2221-msgstr "Finance Officer"
2222+#: view:logistic.requisition.line:0
2223+msgid "View Stock"
2224+msgstr "View Stock"
2225
2226 #. module: logistic_requisition
2227 #: view:logistic.requisition:0
2228@@ -49,6 +49,11 @@
2229 msgstr "Shipping / Transport"
2230
2231 #. module: logistic_requisition
2232+#: report:addons/logistic_requisition/report/logistic_requisition.mako:140
2233+msgid "Preferred transport"
2234+msgstr "Preferred transport"
2235+
2236+#. module: logistic_requisition
2237 #: model:ir.actions.act_window,name:logistic_requisition.act_window_requisition_source_transport
2238 #: model:ir.actions.act_window,name:logistic_requisition.action_requisition_source_transport
2239 msgid "Create Transport Plan"
2240@@ -70,10 +75,20 @@
2241 msgstr "View Lines"
2242
2243 #. module: logistic_requisition
2244-#: selection:logistic.requisition.source,price_is:0
2245-#: selection:sale.order.line,price_is:0
2246-msgid "Fixed"
2247-msgstr "Fixed"
2248+#: report:addons/logistic_requisition/report/logistic_requisition.mako:119
2249+msgid "Consignee address:"
2250+msgstr "Consignee address:"
2251+
2252+#. module: logistic_requisition
2253+#: code:addons/logistic_requisition/model/logistic_requisition.py:634
2254+#, python-format
2255+msgid "This new requisition concerns %s and is due for %s."
2256+msgstr "This new requisition concerns %s and is due for %s."
2257+
2258+#. module: logistic_requisition
2259+#: report:addons/logistic_requisition/report/logistic_requisition.mako:139
2260+msgid "Desired delivery date"
2261+msgstr "Desired delivery date"
2262
2263 #. module: logistic_requisition
2264 #: field:logistic.requisition,message_unread:0
2265@@ -93,6 +108,11 @@
2266 msgstr "Company"
2267
2268 #. module: logistic_requisition
2269+#: report:addons/logistic_requisition/report/logistic_requisition.mako:149
2270+msgid "No"
2271+msgstr "No"
2272+
2273+#. module: logistic_requisition
2274 #: selection:logistic.requisition.source,procurement_method:0
2275 msgid "Framework Agreement"
2276 msgstr "Framework Agreement"
2277@@ -114,15 +134,11 @@
2278 msgstr "Just for Quotation"
2279
2280 #. module: logistic_requisition
2281-#: view:logistic.requisition:0
2282-#: view:logistic.requisition.line:0
2283-msgid "Requestor is External or National Societe"
2284-msgstr "Requestor is External or National Societe"
2285-
2286-#. module: logistic_requisition
2287+#: code:addons/logistic_requisition/wizard/transport_plan.py:154
2288 #: model:ir.model,name:logistic_requisition.model_transport_plan
2289 #: view:logistic.requisition.source:0
2290 #: field:logistic.requisition.source,transport_plan_id:0
2291+#, python-format
2292 msgid "Transport Plan"
2293 msgstr "Transport Plan"
2294
2295@@ -138,9 +154,14 @@
2296 msgstr "Delivery Address"
2297
2298 #. module: logistic_requisition
2299-#: field:logistic.requisition.line,budget_unit_price:0
2300-msgid "Budget Unit Price"
2301-msgstr "Budget Unit Price"
2302+#: help:logistic.requisition.line.assign,logistic_user_id:0
2303+msgid "Logistic Specialist in charge of the Logistic Requisition Line"
2304+msgstr "Logistic Specialist in charge of the Logistic Requisition Line"
2305+
2306+#. module: logistic_requisition
2307+#: report:addons/logistic_requisition/report/logistic_requisition.mako:163
2308+msgid "UoM"
2309+msgstr "UoM"
2310
2311 #. module: logistic_requisition
2312 #: view:logistic.requisition:0
2313@@ -149,6 +170,12 @@
2314 msgstr "Business Unit Officer"
2315
2316 #. module: logistic_requisition
2317+#: code:addons/logistic_requisition/wizard/cost_estimate.py:262
2318+#, python-format
2319+msgid "The cost estimate cannot be created, because no lines are sourced."
2320+msgstr "The cost estimate cannot be created, because no lines are sourced."
2321+
2322+#. module: logistic_requisition
2323 #: view:logistic.requisition:0
2324 #: field:logistic.requisition.line,note:0
2325 msgid "Notes"
2326@@ -162,9 +189,9 @@
2327 msgstr "Messages"
2328
2329 #. module: logistic_requisition
2330-#: constraint:logistic.requisition.source:0
2331-msgid "The total cost cannot be more than the total budget."
2332-msgstr "The total cost cannot be more than the total budget."
2333+#: view:logistic.requisition.line:0
2334+msgid "Total Proposed"
2335+msgstr "Total Proposed"
2336
2337 #. module: logistic_requisition
2338 #: model:ir.model,name:logistic_requisition.model_purchase_order
2339@@ -172,12 +199,19 @@
2340 msgstr "Purchase Order"
2341
2342 #. module: logistic_requisition
2343+#: report:addons/logistic_requisition/report/logistic_requisition.mako:142
2344 #: view:logistic.requisition:0
2345 #: field:logistic.requisition,analytic_id:0
2346 msgid "Project"
2347 msgstr "Project"
2348
2349 #. module: logistic_requisition
2350+#: code:addons/logistic_requisition/model/logistic_requisition.py:522
2351+#, python-format
2352+msgid "Please create source ressource using various source line actions"
2353+msgstr "Please create source ressource using various source line actions"
2354+
2355+#. module: logistic_requisition
2356 #: help:logistic.requisition.source,date_eta:0
2357 msgid "Estimated Date of Arrival"
2358 msgstr "Estimated Date of Arrival"
2359@@ -202,11 +236,10 @@
2360 " sourced logistic requisition lines."
2361
2362 #. module: logistic_requisition
2363-#: selection:logistic.requisition,requester_type:0
2364-#: selection:logistic.requisition.line,requester_type:0
2365-#: selection:res.partner,requester_type:0
2366-msgid "External Organization"
2367-msgstr "External Organization"
2368+#: selection:logistic.requisition.source,price_is:0
2369+#: selection:sale.order.line,price_is:0
2370+msgid "Fixed"
2371+msgstr "Fixed"
2372
2373 #. module: logistic_requisition
2374 #: help:logistic.requisition,message_unread:0
2375@@ -221,9 +254,28 @@
2376 msgstr "Incoterm Place"
2377
2378 #. module: logistic_requisition
2379-#: field:logistic.requisition,date_budget_holder:0
2380-msgid "Budget Holder Validation Date"
2381-msgstr "Budget Holder Validation Date"
2382+#: code:addons/logistic_requisition/model/purchase.py:174
2383+#: code:addons/logistic_requisition/model/purchase.py:194
2384+#, python-format
2385+msgid "UserError"
2386+msgstr "UserError"
2387+
2388+#. module: logistic_requisition
2389+#: field:logistic.requisition.source,unit_cost:0
2390+msgid "Unit Cost"
2391+msgstr "Unit Cost"
2392+
2393+#. module: logistic_requisition
2394+#: code:addons/logistic_requisition/model/logistic_requisition.py:588
2395+#, python-format
2396+msgid "Prices for location"
2397+msgstr "Prices for location"
2398+
2399+#. module: logistic_requisition
2400+#: code:addons/logistic_requisition/model/logistic_requisition.py:1067
2401+#, python-format
2402+msgid "The sourcing lines do not have the same delivery address."
2403+msgstr "The sourcing lines do not have the same delivery address."
2404
2405 #. module: logistic_requisition
2406 #: field:logistic.requisition,name:0
2407@@ -244,11 +296,6 @@
2408 msgstr "Desired Delivery Date"
2409
2410 #. module: logistic_requisition
2411-#: view:logistic.requisition.line:0
2412-msgid "View Stock"
2413-msgstr "View Stock"
2414-
2415-#. module: logistic_requisition
2416 #: field:logistic.requisition,consignee_id:0
2417 msgid "Consignee"
2418 msgstr "Consignee"
2419@@ -293,19 +340,17 @@
2420 msgstr "Partner"
2421
2422 #. module: logistic_requisition
2423+#: code:addons/logistic_requisition/model/purchase.py:178
2424+#, python-format
2425+msgid "You cannot change the informations because this PO line is already linked to a Logistic Requsition Line %s marked as sourced or quoted."
2426+msgstr "You cannot change the informations because this PO line is already linked to a Logistic Requsition Line %s marked as sourced or quoted."
2427+
2428+#. module: logistic_requisition
2429 #: model:ir.model,name:logistic_requisition.model_sale_order
2430 msgid "Sales Order"
2431 msgstr "Sales Order"
2432
2433 #. module: logistic_requisition
2434-#: view:logistic.requisition:0
2435-#: field:logistic.requisition,amount_total:0
2436-#: view:logistic.requisition.line:0
2437-#: view:logistic.requisition.source:0
2438-msgid "Total Budget"
2439-msgstr "Total Budget"
2440-
2441-#. module: logistic_requisition
2442 #: help:logistic.requisition,incoterm_id:0
2443 msgid "International Commercial Terms are a series of predefined commercial terms used in international transactions."
2444 msgstr "International Commercial Terms are a series of predefined commercial terms used in international transactions."
2445@@ -365,6 +410,11 @@
2446 msgstr "State"
2447
2448 #. module: logistic_requisition
2449+#: view:logistic.requisition.source.create.requisition:0
2450+msgid "Which pricelist / currency you want ?"
2451+msgstr "Which pricelist / currency you want ?"
2452+
2453+#. module: logistic_requisition
2454 #: field:logistic.requisition,message_follower_ids:0
2455 #: field:logistic.requisition.line,message_follower_ids:0
2456 #: field:logistic.requisition.source,message_follower_ids:0
2457@@ -393,17 +443,13 @@
2458 msgstr "Unassigned Requisition"
2459
2460 #. module: logistic_requisition
2461-#: selection:logistic.requisition,requester_type:0
2462-#: selection:logistic.requisition.line,requester_type:0
2463-#: selection:res.partner,requester_type:0
2464-msgid "National Society"
2465-msgstr "National Society"
2466-
2467-#. module: logistic_requisition
2468+#: code:addons/logistic_requisition/model/logistic_requisition.py:1146
2469+#: code:addons/logistic_requisition/wizard/logistic_line_create_requisition.py:63
2470 #: model:ir.model,name:logistic_requisition.model_purchase_requisition
2471 #: view:logistic.requisition.line:0
2472 #: view:logistic.requisition.source:0
2473 #: field:logistic.requisition.source,po_requisition_id:0
2474+#, python-format
2475 msgid "Purchase Requisition"
2476 msgstr "Call for Bids"
2477
2478@@ -418,14 +464,9 @@
2479 msgstr "Skipped"
2480
2481 #. module: logistic_requisition
2482-#: field:logistic.requisition.source,selected_po_id:0
2483-msgid "Selected Purchase Order"
2484-msgstr "Selected Purchase Order"
2485-
2486-#. module: logistic_requisition
2487-#: constraint:logistic.requisition.source:0
2488-msgid "A purchase requisition cannot be linked to lines of different logistics requisitions."
2489-msgstr "A call for bids cannot be linked to lines of different logistics requisitions."
2490+#: help:logistic.requisition.line,logistic_user_id:0
2491+msgid "User in charge of the Logistic Requisition Line"
2492+msgstr "User in charge of the Logistic Requisition Line"
2493
2494 #. module: logistic_requisition
2495 #: model:logistic.requisition.cancel.reason,name:logistic_requisition.cancel_reason_other_provider
2496@@ -443,9 +484,27 @@
2497 msgstr "Skipped Lines"
2498
2499 #. module: logistic_requisition
2500-#: view:logistic.requisition:0
2501-msgid "View Sourcing Lines"
2502-msgstr "View Sourcing Lines"
2503+#: field:logistic.requisition.source,selected_bid_id:0
2504+msgid "Selected Bid"
2505+msgstr "Selected Bid"
2506+
2507+#. module: logistic_requisition
2508+#: code:addons/logistic_requisition/model/logistic_requisition.py:566
2509+#, python-format
2510+msgid "Stock by Location"
2511+msgstr "Stock by Location"
2512+
2513+#. module: logistic_requisition
2514+#: code:addons/logistic_requisition/model/logistic_requisition.py:1092
2515+#, python-format
2516+msgid "The logistic requisition sourcing line %s is already linked to a Purchase Requisition."
2517+msgstr "The logistic requisition sourcing line %s is already linked to a Purchase Requisition."
2518+
2519+#. module: logistic_requisition
2520+#: code:addons/logistic_requisition/wizard/cost_estimate.py:219
2521+#, python-format
2522+msgid "Cannot create a cost estimate because:"
2523+msgstr "Cannot create a cost estimate because:"
2524
2525 #. module: logistic_requisition
2526 #: field:logistic.requisition.source,price_is:0
2527@@ -459,6 +518,12 @@
2528 msgstr "Reset to Draft"
2529
2530 #. module: logistic_requisition
2531+#: view:logistic.requisition:0
2532+#: view:logistic.requisition.line:0
2533+msgid "Show cost estimate only"
2534+msgstr "Show cost estimate only"
2535+
2536+#. module: logistic_requisition
2537 #: view:logistic.requisition.cost.estimate:0
2538 msgid "The lines in the Skipped section will be ignored\n"
2539 " because they are not sourced or are already linked\n"
2540@@ -468,11 +533,22 @@
2541 " to a cost estimate."
2542
2543 #. module: logistic_requisition
2544+#: field:logistic.requisition,pricelist_id:0
2545+msgid "Pricelist"
2546+msgstr "Pricelist"
2547+
2548+#. module: logistic_requisition
2549 #: field:logistic.requisition.source,dispatch_location_id:0
2550 msgid "Dispatch From"
2551 msgstr "Dispatch From"
2552
2553 #. module: logistic_requisition
2554+#: code:addons/logistic_requisition/model/logistic_requisition.py:1113
2555+#, python-format
2556+msgid "There should be at least one selectedline with procurement method Procurement"
2557+msgstr "There should be at least one selectedline with procurement method Procurement"
2558+
2559+#. module: logistic_requisition
2560 #: view:logistic.requisition:0
2561 #: field:logistic.requisition.line,logistic_user_id:0
2562 msgid "Assigned To"
2563@@ -489,10 +565,25 @@
2564 msgstr "draft,confirmed,exception"
2565
2566 #. module: logistic_requisition
2567-#: view:logistic.requisition:0
2568-#: view:logistic.requisition.line:0
2569-msgid "Show cost estimate only"
2570-msgstr "Show cost estimate only"
2571+#: field:logistic.requisition.source,transport_applicable:0
2572+msgid "Transport Applicable"
2573+msgstr "Transport Applicable"
2574+
2575+#. module: logistic_requisition
2576+#: field:logistic.requisition.source,default_source_address:0
2577+msgid "Default source"
2578+msgstr "Default source"
2579+
2580+#. module: logistic_requisition
2581+#: report:addons/logistic_requisition/report/logistic_requisition.mako:141
2582+msgid "Cost estimate only"
2583+msgstr "Cost estimate only"
2584+
2585+#. module: logistic_requisition
2586+#: code:addons/logistic_requisition/model/purchase.py:198
2587+#, python-format
2588+msgid "You cannot delete this PO line because it is already linked to a Logistic Requsition Line %s marked as sourced or quoted."
2589+msgstr "You cannot delete this PO line because it is already linked to a Logistic Requsition Line %s marked as sourced or quoted."
2590
2591 #. module: logistic_requisition
2592 #: view:logistic.requisition:0
2593@@ -521,6 +612,11 @@
2594 msgstr "Logistic Requisition Reference must be unique!"
2595
2596 #. module: logistic_requisition
2597+#: report:addons/logistic_requisition/report/logistic_requisition.mako:192
2598+msgid "Signature"
2599+msgstr "Signature"
2600+
2601+#. module: logistic_requisition
2602 #: view:logistic.requisition.line:0
2603 msgid "Country:"
2604 msgstr "Country:"
2605@@ -531,14 +627,21 @@
2606 msgstr "Your assigned Requisition"
2607
2608 #. module: logistic_requisition
2609+#: code:addons/logistic_requisition/wizard/cost_estimate.py:196
2610+#, python-format
2611+msgid "Sourcing %s: no account code has been stored"
2612+msgstr "Sourcing %s: no account code has been stored"
2613+
2614+#. module: logistic_requisition
2615 #: field:logistic.requisition.source,proposed_qty:0
2616 msgid "Proposed Qty"
2617 msgstr "Proposed Qty"
2618
2619 #. module: logistic_requisition
2620-#: field:purchase.order.line,po_line_from_bid_ids:0
2621-msgid "Lines generated by the bid"
2622-msgstr "Lines generated by the bid"
2623+#: selection:logistic.requisition.source,price_is:0
2624+#: selection:sale.order.line,price_is:0
2625+msgid "Estimated"
2626+msgstr "Estimated"
2627
2628 #. module: logistic_requisition
2629 #: model:ir.actions.act_window,name:logistic_requisition.action_requisition_line_assign
2630@@ -552,19 +655,32 @@
2631 msgstr "Purchase Cancel Reasons"
2632
2633 #. module: logistic_requisition
2634+#: code:addons/logistic_requisition/model/logistic_requisition.py:1045
2635+#, python-format
2636+msgid "The lines are not assigned to the same User."
2637+msgstr "The lines are not assigned to the same User."
2638+
2639+#. module: logistic_requisition
2640 #: constraint:logistic.requisition.cost.estimate:0
2641 msgid "All the lines should belong to the same requisition."
2642 msgstr "All the lines should belong to the same requisition."
2643
2644 #. module: logistic_requisition
2645+#: code:addons/logistic_requisition/model/logistic_requisition.py:1118
2646+#, python-format
2647+msgid "Selected line procurement method should be procurement or other"
2648+msgstr "Selected line procurement method should be procurement or other"
2649+
2650+#. module: logistic_requisition
2651 #: view:logistic.requisition:0
2652 msgid "Delivery Date"
2653 msgstr "Delivery Date"
2654
2655 #. module: logistic_requisition
2656-#: field:logistic.requisition,budget_holder_id:0
2657-msgid "Budget Holder"
2658-msgstr "Budget Holder"
2659+#: model:ir.actions.act_window,name:logistic_requisition.action_logistic_requisition_cancel
2660+#: view:logistic.requisition.cancel:0
2661+msgid "Reason for the cancellation"
2662+msgstr "Reason for the cancellation"
2663
2664 #. module: logistic_requisition
2665 #: constraint:logistic.requisition.source:0
2666@@ -573,7 +689,6 @@
2667
2668 #. module: logistic_requisition
2669 #: view:logistic.requisition.source:0
2670-#: field:purchase.requisition,logistic_requisition_source_ids:0
2671 msgid "Logistic Requisition Sourcing Lines"
2672 msgstr "Logistic Requisition Sourcing Lines"
2673
2674@@ -583,8 +698,11 @@
2675 msgstr "Line's State"
2676
2677 #. module: logistic_requisition
2678+#: view:logistic.requisition:0
2679 #: field:logistic.requisition,currency_id:0
2680+#: view:logistic.requisition.line:0
2681 #: field:logistic.requisition.line,currency_id:0
2682+#: field:logistic.requisition.source,currency_id:0
2683 msgid "Currency"
2684 msgstr "Currency"
2685
2686@@ -600,36 +718,53 @@
2687 msgstr "Incoterm Place of Delivery. International Commercial Terms are a series of predefined commercial terms used in international transactions."
2688
2689 #. module: logistic_requisition
2690+#: code:addons/logistic_requisition/wizard/cost_estimate.py:191
2691+#, python-format
2692+msgid "Sourcing %s: no quantity has been proposed"
2693+msgstr "Sourcing %s: no quantity has been proposed"
2694+
2695+#. module: logistic_requisition
2696 #: model:ir.actions.act_window,name:logistic_requisition.action_logistic_requisition
2697 #: model:ir.ui.menu,name:logistic_requisition.menu_logistic_requisition
2698 msgid "Requisitions"
2699 msgstr "Requisitions"
2700
2701 #. module: logistic_requisition
2702-#: field:logistic.requisition,date_finance_officer:0
2703-msgid "Finance Officer Validation Date"
2704-msgstr "Finance Officer Validation Date"
2705-
2706-#. module: logistic_requisition
2707-#: view:logistic.requisition:0
2708-#: view:logistic.requisition.line:0
2709-msgid "Internal (Federation)"
2710-msgstr "Internal (Federation)"
2711-
2712-#. module: logistic_requisition
2713-#: field:logistic.requisition.source,transport_applicable:0
2714-msgid "Transport Applicable"
2715-msgstr "Transport Applicable"
2716-
2717-#. module: logistic_requisition
2718-#: field:logistic.requisition.source,purchase_requisition_line_ids:0
2719-msgid "Purchase Requisition Lines"
2720-msgstr "Call for Bids Lines"
2721+#: report:addons/logistic_requisition/report/logistic_requisition.mako:149
2722+msgid "Yes"
2723+msgstr "Yes"
2724+
2725+#. module: logistic_requisition
2726+#: code:addons/logistic_requisition/model/logistic_requisition.py:1115
2727+#: code:addons/logistic_requisition/model/logistic_requisition.py:1120
2728+#, python-format
2729+msgid "Please correct selection"
2730+msgstr "Please correct selection"
2731+
2732+#. module: logistic_requisition
2733+#: field:logistic.requisition.source,offer_ids:0
2734+msgid "Sales Quotation Lines"
2735+msgstr "Sales Quotation Lines"
2736+
2737+#. module: logistic_requisition
2738+#: constraint:logistic.requisition.source:0
2739+msgid "A purchase requisition cannot be linked to lines of different logistics requisitions."
2740+msgstr "A call for bids cannot be linked to lines of different logistics requisitions."
2741+
2742+#. module: logistic_requisition
2743+#: report:addons/logistic_requisition/report/logistic_requisition.mako:136
2744+msgid "Logistic requisition"
2745+msgstr "Logistic requisition"
2746+
2747+#. module: logistic_requisition
2748+#: report:addons/logistic_requisition/report/logistic_requisition.mako:190
2749+msgid "Requesting entity"
2750+msgstr "Requesting entity"
2751
2752 #. module: logistic_requisition
2753 #: model:ir.model,name:logistic_requisition.model_purchase_order_line
2754-#: field:logistic.requisition.source,bid_line_id:0
2755 #: field:logistic.requisition.source,purchase_line_id:0
2756+#: field:logistic.requisition.source,selected_bid_line_id:0
2757 msgid "Purchase Order Line"
2758 msgstr "Purchase Order Line"
2759
2760@@ -644,6 +779,12 @@
2761 msgstr "Assigned Specialist"
2762
2763 #. module: logistic_requisition
2764+#: code:addons/logistic_requisition/model/logistic_requisition.py:521
2765+#, python-format
2766+msgid "line %s is not sourced"
2767+msgstr "line %s is not sourced"
2768+
2769+#. module: logistic_requisition
2770 #: model:ir.model,name:logistic_requisition.model_logistic_requisition_source_transport_plan
2771 msgid "Create a transport plan for logistic requisition source lines"
2772 msgstr "Create a transport plan for logistic requisition source lines"
2773@@ -703,18 +844,13 @@
2774 msgstr "Activity Code"
2775
2776 #. module: logistic_requisition
2777+#: field:purchase.requisition.line,logistic_requisition_source_ids:0
2778 #: view:transport.plan:0
2779 #: field:transport.plan,logistic_requisition_source_ids:0
2780 msgid "Logistic Requisition Source Lines"
2781 msgstr "Logistic Requisition Source Lines"
2782
2783 #. module: logistic_requisition
2784-#: view:logistic.requisition:0
2785-#: view:logistic.requisition.line:0
2786-msgid "External (NS, Others)"
2787-msgstr "External (NS, Others)"
2788-
2789-#. module: logistic_requisition
2790 #: field:logistic.requisition.source.transport.plan,transport_estimated_cost:0
2791 msgid "Transportation Estimated Costs"
2792 msgstr "Transportation Estimated Costs"
2793@@ -750,16 +886,6 @@
2794 msgstr "offers"
2795
2796 #. module: logistic_requisition
2797-#: field:purchase.requisition.line,logistic_requisition_source_id:0
2798-msgid "Logistic Requisition Source Line"
2799-msgstr "Logistic Requisition Source Line"
2800-
2801-#. module: logistic_requisition
2802-#: view:logistic.requisition:0
2803-msgid "Validation"
2804-msgstr "Validation"
2805-
2806-#. module: logistic_requisition
2807 #: help:logistic.requisition.source.transport.plan,date_eta:0
2808 msgid "Estimated Date of Arrival if not set requisition ETA will be used"
2809 msgstr "Estimated Date of Arrival if not set requisition ETA will be used"
2810@@ -772,9 +898,15 @@
2811 msgstr "Is a Follower"
2812
2813 #. module: logistic_requisition
2814-#: view:logistic.requisition:0
2815-msgid " validated on "
2816-msgstr " validated on "
2817+#: code:addons/logistic_requisition/model/sale_order.py:45
2818+#, python-format
2819+msgid "The logistic requisition line %s has no purchase order line."
2820+msgstr "The logistic requisition line %s has no purchase order line."
2821+
2822+#. module: logistic_requisition
2823+#: report:addons/logistic_requisition/report/logistic_requisition.mako:187
2824+msgid "Approval"
2825+msgstr "Approval"
2826
2827 #. module: logistic_requisition
2828 #: help:logistic.requisition.source,date_etd:0
2829@@ -788,6 +920,11 @@
2830 msgstr "Create Call for Bids From Requisition Source"
2831
2832 #. module: logistic_requisition
2833+#: help:logistic.requisition,pricelist_id:0
2834+msgid "Pricelist that represent the currency for current logistic request."
2835+msgstr "Pricelist that represent the currency for current logistic request."
2836+
2837+#. module: logistic_requisition
2838 #: model:ir.model,name:logistic_requisition.model_stock_incoterms
2839 msgid "Incoterms"
2840 msgstr "Incoterms"
2841@@ -813,7 +950,6 @@
2842
2843 #. module: logistic_requisition
2844 #: view:logistic.requisition:0
2845-#: field:logistic.requisition,partner_id:0
2846 msgid "Requesting Entity"
2847 msgstr "Requesting Entity"
2848
2849@@ -848,6 +984,17 @@
2850 msgstr "View Prices"
2851
2852 #. module: logistic_requisition
2853+#: code:addons/logistic_requisition/model/logistic_requisition.py:1044
2854+#: code:addons/logistic_requisition/model/logistic_requisition.py:1052
2855+#: code:addons/logistic_requisition/model/logistic_requisition.py:1059
2856+#: code:addons/logistic_requisition/model/logistic_requisition.py:1066
2857+#: code:addons/logistic_requisition/model/sale_order.py:44
2858+#: code:addons/logistic_requisition/wizard/cost_estimate.py:261
2859+#, python-format
2860+msgid "Error"
2861+msgstr "Error"
2862+
2863+#. module: logistic_requisition
2864 #: model:logistic.requisition.cancel.reason,name:logistic_requisition.cancel_reason_no_service_needed
2865 msgid "No service needed anymore"
2866 msgstr "No service needed anymore"
2867@@ -859,11 +1006,7 @@
2868 msgstr "Assign"
2869
2870 #. module: logistic_requisition
2871-#: field:logistic.requisition.source,unit_cost:0
2872-msgid "Unit Cost"
2873-msgstr "Unit Cost"
2874-
2875-#. module: logistic_requisition
2876+#: report:addons/logistic_requisition/report/logistic_requisition.mako:162
2877 #: view:logistic.requisition:0
2878 #: field:logistic.requisition.line,requested_qty:0
2879 msgid "Quantity"
2880@@ -891,12 +1034,9 @@
2881 msgstr "Line Sourced"
2882
2883 #. module: logistic_requisition
2884-#: view:logistic.requisition:0
2885-#: field:logistic.requisition,requester_type:0
2886-#: view:logistic.requisition.line:0
2887-#: field:logistic.requisition.line,requester_type:0
2888-msgid "Type of Requestor"
2889-msgstr "Type of Requestor"
2890+#: report:addons/logistic_requisition/report/logistic_requisition.mako:160
2891+msgid "Number"
2892+msgstr "Number"
2893
2894 #. module: logistic_requisition
2895 #: view:logistic.requisition.source.create.requisition:0
2896@@ -904,6 +1044,12 @@
2897 msgstr "Create Requisition"
2898
2899 #. module: logistic_requisition
2900+#: code:addons/logistic_requisition/model/logistic_requisition.py:1091
2901+#, python-format
2902+msgid "Existing"
2903+msgstr "Existing"
2904+
2905+#. module: logistic_requisition
2906 #: view:logistic.requisition.line:0
2907 #: selection:logistic.requisition.line,state:0
2908 #: selection:logistic.requisition.source,state:0
2909@@ -911,9 +1057,10 @@
2910 msgstr "Assigned"
2911
2912 #. module: logistic_requisition
2913-#: field:logistic.requisition.line,budget_tot_price:0
2914-msgid "Budget Total Price"
2915-msgstr "Budget Total Price"
2916+#: view:logistic.requisition.line:0
2917+#: view:logistic.requisition.source:0
2918+msgid "Total Budget"
2919+msgstr "Total Budget"
2920
2921 #. module: logistic_requisition
2922 #: view:logistic.requisition:0
2923@@ -947,16 +1094,9 @@
2924 msgstr "Create Cost Estimate"
2925
2926 #. module: logistic_requisition
2927-#: selection:logistic.requisition.source,price_is:0
2928-#: selection:sale.order.line,price_is:0
2929-msgid "Estimated"
2930-msgstr "Estimated"
2931-
2932-#. module: logistic_requisition
2933-#: model:ir.actions.act_window,name:logistic_requisition.action_logistic_requisition_cancel
2934-#: view:logistic.requisition.cancel:0
2935-msgid "Reason for the cancellation"
2936-msgstr "Reason for the cancellation"
2937+#: field:purchase.order.line,po_line_from_bid_ids:0
2938+msgid "Lines generated by the bid"
2939+msgstr "Lines generated by the bid"
2940
2941 #. module: logistic_requisition
2942 #: field:logistic.requisition.line,name:0
2943@@ -979,18 +1119,16 @@
2944 msgstr "Your assigned Requisition Line"
2945
2946 #. module: logistic_requisition
2947-#: selection:logistic.requisition,requester_type:0
2948-#: selection:logistic.requisition.line,requester_type:0
2949-#: selection:res.partner,requester_type:0
2950-msgid "Federation (internal)"
2951-msgstr "Federation (internal)"
2952-
2953-#. module: logistic_requisition
2954 #: view:logistic.requisition.line:0
2955 msgid "Req. Date:"
2956 msgstr "Req. Date:"
2957
2958 #. module: logistic_requisition
2959+#: report:addons/logistic_requisition/report/logistic_requisition.mako:182
2960+msgid "General Remarks"
2961+msgstr "General Remarks"
2962+
2963+#. module: logistic_requisition
2964 #: view:logistic.requisition:0
2965 #: field:logistic.requisition,cost_estimate_only:0
2966 #: view:logistic.requisition.line:0
2967@@ -1014,9 +1152,9 @@
2968 msgstr "Supplier Address"
2969
2970 #. module: logistic_requisition
2971-#: field:res.partner,requester_type:0
2972-msgid "Requester Type"
2973-msgstr "Requester Type"
2974+#: selection:logistic.requisition.source,procurement_method:0
2975+msgid "Other"
2976+msgstr "Other"
2977
2978 #. module: logistic_requisition
2979 #: model:ir.model,name:logistic_requisition.model_logistic_requisition_line
2980@@ -1042,6 +1180,7 @@
2981
2982 #. module: logistic_requisition
2983 #: model:ir.model,name:logistic_requisition.model_purchase_requisition_line
2984+#: field:logistic.requisition.source,purchase_requisition_line_id:0
2985 msgid "Purchase Requisition Line"
2986 msgstr "Call for Bids Line"
2987
2988@@ -1058,6 +1197,7 @@
2989 msgstr "Product"
2990
2991 #. module: logistic_requisition
2992+#: report:addons/logistic_requisition/report/logistic_requisition.mako:161
2993 #: field:logistic.requisition.line,description:0
2994 msgid "Description"
2995 msgstr "Description"
2996@@ -1069,10 +1209,10 @@
2997 msgstr "Procurement"
2998
2999 #. module: logistic_requisition
3000-#: view:logistic.requisition:0
3001-#: view:logistic.requisition.line:0
3002-msgid "Requestor is the Federation"
3003-msgstr "Requestor is the Federation"
3004+#: code:addons/logistic_requisition/model/logistic_requisition.py:1053
3005+#, python-format
3006+msgid "The sourcing lines do not belong to the same company."
3007+msgstr "The sourcing lines do not belong to the same company."
3008
3009 #. module: logistic_requisition
3010 #: help:transport.plan,product_id:0
3011@@ -1080,6 +1220,12 @@
3012 msgstr "Product used for the transport, will be used in the cost estimate"
3013
3014 #. module: logistic_requisition
3015+#: code:addons/logistic_requisition/model/logistic_requisition.py:1097
3016+#, python-format
3017+msgid "The sourcing line %d does not have any product defined, please choose one."
3018+msgstr "The sourcing line %d does not have any product defined, please choose one."
3019+
3020+#. module: logistic_requisition
3021 #: field:logistic.requisition.source.transport.plan,transport_mode_id:0
3022 msgid "Transport by"
3023 msgstr "Transport by"
3024@@ -1090,9 +1236,15 @@
3025 msgstr "Cancellation reason:"
3026
3027 #. module: logistic_requisition
3028-#: help:logistic.requisition.line,logistic_user_id:0
3029-msgid "User in charge of the Logistic Requisition Line"
3030-msgstr "User in charge of the Logistic Requisition Line"
3031+#: code:addons/logistic_requisition/model/logistic_requisition.py:632
3032+#, python-format
3033+msgid "Logistic Requisition Line %s Assigned"
3034+msgstr "Logistic Requisition Line %s Assigned"
3035+
3036+#. module: logistic_requisition
3037+#: report:addons/logistic_requisition/report/logistic_requisition.mako:191
3038+msgid "Requested date"
3039+msgstr "Requested date"
3040
3041 #. module: logistic_requisition
3042 #: view:logistic.requisition.line:0
3043@@ -1100,9 +1252,9 @@
3044 msgstr "My Requisition Line"
3045
3046 #. module: logistic_requisition
3047-#: field:logistic.requisition,allowed_budget:0
3048-msgid "Allowed Budget"
3049-msgstr "Allowed Budget"
3050+#: field:logistic.requisition,partner_id:0
3051+msgid "Customer"
3052+msgstr "Customer"
3053
3054 #. module: logistic_requisition
3055 #: model:ir.actions.act_window,name:logistic_requisition.action_logistic_requisition_source
3056@@ -1110,11 +1262,6 @@
3057 msgstr "Requisitions Sourcing Lines"
3058
3059 #. module: logistic_requisition
3060-#: help:logistic.requisition.line.assign,logistic_user_id:0
3061-msgid "Logistic Specialist in charge of the Logistic Requisition Line"
3062-msgstr "Logistic Specialist in charge of the Logistic Requisition Line"
3063-
3064-#. module: logistic_requisition
3065 #: field:logistic.requisition,line_ids:0
3066 msgid "Products to Purchase"
3067 msgstr "Products to Purchase"
3068@@ -1125,6 +1272,7 @@
3069 msgstr "Mobilization Officer or Logistic Coordinator in charge of the Logistic Requisition"
3070
3071 #. module: logistic_requisition
3072+#: report:addons/logistic_requisition/report/logistic_requisition.mako:143
3073 #: view:logistic.requisition:0
3074 #: field:logistic.requisition,country_id:0
3075 #: view:logistic.requisition.line:0
3076@@ -1133,8 +1281,11 @@
3077 msgstr "Country"
3078
3079 #. module: logistic_requisition
3080+#: code:addons/logistic_requisition/model/logistic_requisition.py:693
3081+#: code:addons/logistic_requisition/wizard/cost_estimate.py:293
3082 #: view:logistic.requisition.cost.estimate:0
3083 #: field:logistic.requisition.line,cost_estimate_id:0
3084+#, python-format
3085 msgid "Cost Estimate"
3086 msgstr "Cost Estimate"
3087
3088@@ -1154,17 +1305,13 @@
3089 msgstr "Product UoM"
3090
3091 #. module: logistic_requisition
3092+#: report:addons/logistic_requisition/report/logistic_requisition.mako:144
3093 #: view:logistic.requisition:0
3094 #: field:logistic.requisition,date:0
3095 msgid "Requisition Date"
3096 msgstr "Requisition Date"
3097
3098 #. module: logistic_requisition
3099-#: view:logistic.requisition.line:0
3100-msgid "Total Proposed"
3101-msgstr "Total Proposed"
3102-
3103-#. module: logistic_requisition
3104 #: view:logistic.requisition.cancel:0
3105 msgid "Choose the reason for the cancellation of the\n"
3106 " logistic requisition."
3107@@ -1172,6 +1319,11 @@
3108 " logistic requisition."
3109
3110 #. module: logistic_requisition
3111+#: field:logistic.requisition.source,proposed_product_id:0
3112+msgid "Proposed Product"
3113+msgstr "Proposed Product"
3114+
3115+#. module: logistic_requisition
3116 #: view:logistic.requisition.line.assign:0
3117 msgid "Select the assignee"
3118 msgstr "Select the assignee"
3119@@ -1179,6 +1331,7 @@
3120 #. module: logistic_requisition
3121 #: model:ir.model,name:logistic_requisition.model_logistic_requisition_source
3122 #: view:logistic.requisition.source:0
3123+#: field:purchase.order.line,lr_source_line_id:0
3124 msgid "Logistic Requisition Source"
3125 msgstr "Logistic Requisition Source"
3126
3127@@ -1197,6 +1350,11 @@
3128 msgstr "Messages and communication history"
3129
3130 #. module: logistic_requisition
3131+#: report:addons/logistic_requisition/report/logistic_requisition.mako:102
3132+msgid "Shipping address:"
3133+msgstr "Shipping address:"
3134+
3135+#. module: logistic_requisition
3136 #: view:logistic.requisition.source.create.requisition:0
3137 msgid " Please note that: \n"
3138 " \n"
3139@@ -1224,7 +1382,13 @@
3140 msgstr "Sourced"
3141
3142 #. module: logistic_requisition
3143+#: report:addons/logistic_requisition/report/logistic_requisition.mako:178
3144+msgid "Delivery Remarks"
3145+msgstr "Delivery Remarks"
3146+
3147+#. module: logistic_requisition
3148 #: field:logistic.requisition.line,account_code:0
3149+#: field:sale.order.line,account_code:0
3150 msgid "Account Code"
3151 msgstr "Account Code"
3152
3153@@ -1234,6 +1398,17 @@
3154 msgstr "Generated from bid"
3155
3156 #. module: logistic_requisition
3157+#: field:logistic.requisition.source.create.requisition,pricelist_id:0
3158+msgid "Pricelist / Currency"
3159+msgstr "Pricelist / Currency"
3160+
3161+#. module: logistic_requisition
3162+#: code:addons/logistic_requisition/model/logistic_requisition.py:1060
3163+#, python-format
3164+msgid "The sourcing lines do not have the same consignee."
3165+msgstr "The sourcing lines do not have the same consignee."
3166+
3167+#. module: logistic_requisition
3168 #: view:logistic.requisition.cancel:0
3169 #: view:logistic.requisition.cost.estimate:0
3170 #: view:logistic.requisition.line.assign:0
3171@@ -1243,7 +1418,24 @@
3172 msgstr "or"
3173
3174 #. module: logistic_requisition
3175+#: view:logistic.requisition:0
3176+msgid "View Sourcing Lines"
3177+msgstr "View Sourcing Lines"
3178+
3179+#. module: logistic_requisition
3180+#: code:addons/logistic_requisition/model/logistic_requisition.py:1096
3181+#, python-format
3182+msgid "Missing information"
3183+msgstr "Missing information"
3184+
3185+#. module: logistic_requisition
3186 #: view:logistic.requisition.line:0
3187 msgid "Open Cost Estimate"
3188 msgstr "Open Cost Estimate"
3189
3190+#. module: logistic_requisition
3191+#: code:addons/logistic_requisition/wizard/cost_estimate.py:105
3192+#, python-format
3193+msgid "Transport from %s to %s by %s (Ref. %s)"
3194+msgstr "Transport from %s to %s by %s (Ref. %s)"
3195+
3196
3197=== modified file 'logistic_requisition/i18n/logistic_requisition.pot'
3198--- logistic_requisition/i18n/logistic_requisition.pot 2013-08-29 09:53:01 +0000
3199+++ logistic_requisition/i18n/logistic_requisition.pot 2014-05-07 09:53:02 +0000
3200@@ -1,13 +1,13 @@
3201 # Translation of OpenERP Server.
3202 # This file contains the translation of the following modules:
3203-# * logistic_requisition
3204+# * logistic_requisition
3205 #
3206 msgid ""
3207 msgstr ""
3208 "Project-Id-Version: OpenERP Server 7.0\n"
3209 "Report-Msgid-Bugs-To: \n"
3210-"POT-Creation-Date: 2013-08-29 09:50+0000\n"
3211-"PO-Revision-Date: 2013-08-29 09:50+0000\n"
3212+"POT-Creation-Date: 2014-02-04 13:09+0000\n"
3213+"PO-Revision-Date: 2014-02-04 13:09+0000\n"
3214 "Last-Translator: <>\n"
3215 "Language-Team: \n"
3216 "MIME-Version: 1.0\n"
3217@@ -21,13 +21,13 @@
3218 msgstr ""
3219
3220 #. module: logistic_requisition
3221-#: field:logistic.requisition.source,offer_ids:0
3222-msgid "Sales Quotation Lines"
3223+#: field:logistic.requisition.line,amount_total:0
3224+msgid "Total Amount"
3225 msgstr ""
3226
3227 #. module: logistic_requisition
3228-#: field:logistic.requisition,finance_officer_id:0
3229-msgid "Finance Officer"
3230+#: view:logistic.requisition.line:0
3231+msgid "View Stock"
3232 msgstr ""
3233
3234 #. module: logistic_requisition
3235@@ -49,6 +49,11 @@
3236 msgstr ""
3237
3238 #. module: logistic_requisition
3239+#: report:addons/logistic_requisition/report/logistic_requisition.mako:140
3240+msgid "Preferred transport"
3241+msgstr ""
3242+
3243+#. module: logistic_requisition
3244 #: model:ir.actions.act_window,name:logistic_requisition.act_window_requisition_source_transport
3245 #: model:ir.actions.act_window,name:logistic_requisition.action_requisition_source_transport
3246 msgid "Create Transport Plan"
3247@@ -70,9 +75,19 @@
3248 msgstr ""
3249
3250 #. module: logistic_requisition
3251-#: selection:logistic.requisition.source,price_is:0
3252-#: selection:sale.order.line,price_is:0
3253-msgid "Fixed"
3254+#: report:addons/logistic_requisition/report/logistic_requisition.mako:119
3255+msgid "Consignee address:"
3256+msgstr ""
3257+
3258+#. module: logistic_requisition
3259+#: code:addons/logistic_requisition/model/logistic_requisition.py:634
3260+#, python-format
3261+msgid "This new requisition concerns %s and is due for %s."
3262+msgstr ""
3263+
3264+#. module: logistic_requisition
3265+#: report:addons/logistic_requisition/report/logistic_requisition.mako:139
3266+msgid "Desired delivery date"
3267 msgstr ""
3268
3269 #. module: logistic_requisition
3270@@ -93,6 +108,11 @@
3271 msgstr ""
3272
3273 #. module: logistic_requisition
3274+#: report:addons/logistic_requisition/report/logistic_requisition.mako:149
3275+msgid "No"
3276+msgstr ""
3277+
3278+#. module: logistic_requisition
3279 #: selection:logistic.requisition.source,procurement_method:0
3280 msgid "Framework Agreement"
3281 msgstr ""
3282@@ -114,15 +134,11 @@
3283 msgstr ""
3284
3285 #. module: logistic_requisition
3286-#: view:logistic.requisition:0
3287-#: view:logistic.requisition.line:0
3288-msgid "Requestor is External or National Societe"
3289-msgstr ""
3290-
3291-#. module: logistic_requisition
3292+#: code:addons/logistic_requisition/wizard/transport_plan.py:154
3293 #: model:ir.model,name:logistic_requisition.model_transport_plan
3294 #: view:logistic.requisition.source:0
3295 #: field:logistic.requisition.source,transport_plan_id:0
3296+#, python-format
3297 msgid "Transport Plan"
3298 msgstr ""
3299
3300@@ -138,8 +154,13 @@
3301 msgstr ""
3302
3303 #. module: logistic_requisition
3304-#: field:logistic.requisition.line,budget_unit_price:0
3305-msgid "Budget Unit Price"
3306+#: help:logistic.requisition.line.assign,logistic_user_id:0
3307+msgid "Logistic Specialist in charge of the Logistic Requisition Line"
3308+msgstr ""
3309+
3310+#. module: logistic_requisition
3311+#: report:addons/logistic_requisition/report/logistic_requisition.mako:163
3312+msgid "UoM"
3313 msgstr ""
3314
3315 #. module: logistic_requisition
3316@@ -149,6 +170,12 @@
3317 msgstr ""
3318
3319 #. module: logistic_requisition
3320+#: code:addons/logistic_requisition/wizard/cost_estimate.py:262
3321+#, python-format
3322+msgid "The cost estimate cannot be created, because no lines are sourced."
3323+msgstr ""
3324+
3325+#. module: logistic_requisition
3326 #: view:logistic.requisition:0
3327 #: field:logistic.requisition.line,note:0
3328 msgid "Notes"
3329@@ -162,8 +189,8 @@
3330 msgstr ""
3331
3332 #. module: logistic_requisition
3333-#: constraint:logistic.requisition.source:0
3334-msgid "The total cost cannot be more than the total budget."
3335+#: view:logistic.requisition.line:0
3336+msgid "Total Proposed"
3337 msgstr ""
3338
3339 #. module: logistic_requisition
3340@@ -172,12 +199,19 @@
3341 msgstr ""
3342
3343 #. module: logistic_requisition
3344+#: report:addons/logistic_requisition/report/logistic_requisition.mako:142
3345 #: view:logistic.requisition:0
3346 #: field:logistic.requisition,analytic_id:0
3347 msgid "Project"
3348 msgstr ""
3349
3350 #. module: logistic_requisition
3351+#: code:addons/logistic_requisition/model/logistic_requisition.py:522
3352+#, python-format
3353+msgid "Please create source ressource using various source line actions"
3354+msgstr ""
3355+
3356+#. module: logistic_requisition
3357 #: help:logistic.requisition.source,date_eta:0
3358 msgid "Estimated Date of Arrival"
3359 msgstr ""
3360@@ -201,10 +235,9 @@
3361 msgstr ""
3362
3363 #. module: logistic_requisition
3364-#: selection:logistic.requisition,requester_type:0
3365-#: selection:logistic.requisition.line,requester_type:0
3366-#: selection:res.partner,requester_type:0
3367-msgid "External Organization"
3368+#: selection:logistic.requisition.source,price_is:0
3369+#: selection:sale.order.line,price_is:0
3370+msgid "Fixed"
3371 msgstr ""
3372
3373 #. module: logistic_requisition
3374@@ -220,8 +253,27 @@
3375 msgstr ""
3376
3377 #. module: logistic_requisition
3378-#: field:logistic.requisition,date_budget_holder:0
3379-msgid "Budget Holder Validation Date"
3380+#: code:addons/logistic_requisition/model/purchase.py:174
3381+#: code:addons/logistic_requisition/model/purchase.py:194
3382+#, python-format
3383+msgid "UserError"
3384+msgstr ""
3385+
3386+#. module: logistic_requisition
3387+#: field:logistic.requisition.source,unit_cost:0
3388+msgid "Unit Cost"
3389+msgstr ""
3390+
3391+#. module: logistic_requisition
3392+#: code:addons/logistic_requisition/model/logistic_requisition.py:588
3393+#, python-format
3394+msgid "Prices for location"
3395+msgstr ""
3396+
3397+#. module: logistic_requisition
3398+#: code:addons/logistic_requisition/model/logistic_requisition.py:1067
3399+#, python-format
3400+msgid "The sourcing lines do not have the same delivery address."
3401 msgstr ""
3402
3403 #. module: logistic_requisition
3404@@ -243,11 +295,6 @@
3405 msgstr ""
3406
3407 #. module: logistic_requisition
3408-#: view:logistic.requisition.line:0
3409-msgid "View Stock"
3410-msgstr ""
3411-
3412-#. module: logistic_requisition
3413 #: field:logistic.requisition,consignee_id:0
3414 msgid "Consignee"
3415 msgstr ""
3416@@ -292,19 +339,17 @@
3417 msgstr ""
3418
3419 #. module: logistic_requisition
3420+#: code:addons/logistic_requisition/model/purchase.py:178
3421+#, python-format
3422+msgid "You cannot change the informations because this PO line is already linked to a Logistic Requsition Line %s marked as sourced or quoted."
3423+msgstr ""
3424+
3425+#. module: logistic_requisition
3426 #: model:ir.model,name:logistic_requisition.model_sale_order
3427 msgid "Sales Order"
3428 msgstr ""
3429
3430 #. module: logistic_requisition
3431-#: view:logistic.requisition:0
3432-#: field:logistic.requisition,amount_total:0
3433-#: view:logistic.requisition.line:0
3434-#: view:logistic.requisition.source:0
3435-msgid "Total Budget"
3436-msgstr ""
3437-
3438-#. module: logistic_requisition
3439 #: help:logistic.requisition,incoterm_id:0
3440 msgid "International Commercial Terms are a series of predefined commercial terms used in international transactions."
3441 msgstr ""
3442@@ -364,6 +409,11 @@
3443 msgstr ""
3444
3445 #. module: logistic_requisition
3446+#: view:logistic.requisition.source.create.requisition:0
3447+msgid "Which pricelist / currency you want ?"
3448+msgstr ""
3449+
3450+#. module: logistic_requisition
3451 #: field:logistic.requisition,message_follower_ids:0
3452 #: field:logistic.requisition.line,message_follower_ids:0
3453 #: field:logistic.requisition.source,message_follower_ids:0
3454@@ -392,17 +442,13 @@
3455 msgstr ""
3456
3457 #. module: logistic_requisition
3458-#: selection:logistic.requisition,requester_type:0
3459-#: selection:logistic.requisition.line,requester_type:0
3460-#: selection:res.partner,requester_type:0
3461-msgid "National Society"
3462-msgstr ""
3463-
3464-#. module: logistic_requisition
3465+#: code:addons/logistic_requisition/model/logistic_requisition.py:1146
3466+#: code:addons/logistic_requisition/wizard/logistic_line_create_requisition.py:63
3467 #: model:ir.model,name:logistic_requisition.model_purchase_requisition
3468 #: view:logistic.requisition.line:0
3469 #: view:logistic.requisition.source:0
3470 #: field:logistic.requisition.source,po_requisition_id:0
3471+#, python-format
3472 msgid "Purchase Requisition"
3473 msgstr ""
3474
3475@@ -417,13 +463,8 @@
3476 msgstr ""
3477
3478 #. module: logistic_requisition
3479-#: field:logistic.requisition.source,selected_po_id:0
3480-msgid "Selected Purchase Order"
3481-msgstr ""
3482-
3483-#. module: logistic_requisition
3484-#: constraint:logistic.requisition.source:0
3485-msgid "A purchase requisition cannot be linked to lines of different logistics requisitions."
3486+#: help:logistic.requisition.line,logistic_user_id:0
3487+msgid "User in charge of the Logistic Requisition Line"
3488 msgstr ""
3489
3490 #. module: logistic_requisition
3491@@ -442,8 +483,26 @@
3492 msgstr ""
3493
3494 #. module: logistic_requisition
3495-#: view:logistic.requisition:0
3496-msgid "View Sourcing Lines"
3497+#: field:logistic.requisition.source,selected_bid_id:0
3498+msgid "Selected Bid"
3499+msgstr ""
3500+
3501+#. module: logistic_requisition
3502+#: code:addons/logistic_requisition/model/logistic_requisition.py:566
3503+#, python-format
3504+msgid "Stock by Location"
3505+msgstr ""
3506+
3507+#. module: logistic_requisition
3508+#: code:addons/logistic_requisition/model/logistic_requisition.py:1092
3509+#, python-format
3510+msgid "The logistic requisition sourcing line %s is already linked to a Purchase Requisition."
3511+msgstr ""
3512+
3513+#. module: logistic_requisition
3514+#: code:addons/logistic_requisition/wizard/cost_estimate.py:219
3515+#, python-format
3516+msgid "Cannot create a cost estimate because:"
3517 msgstr ""
3518
3519 #. module: logistic_requisition
3520@@ -458,6 +517,12 @@
3521 msgstr ""
3522
3523 #. module: logistic_requisition
3524+#: view:logistic.requisition:0
3525+#: view:logistic.requisition.line:0
3526+msgid "Show cost estimate only"
3527+msgstr ""
3528+
3529+#. module: logistic_requisition
3530 #: view:logistic.requisition.cost.estimate:0
3531 msgid "The lines in the Skipped section will be ignored\n"
3532 " because they are not sourced or are already linked\n"
3533@@ -465,11 +530,22 @@
3534 msgstr ""
3535
3536 #. module: logistic_requisition
3537+#: field:logistic.requisition,pricelist_id:0
3538+msgid "Pricelist"
3539+msgstr ""
3540+
3541+#. module: logistic_requisition
3542 #: field:logistic.requisition.source,dispatch_location_id:0
3543 msgid "Dispatch From"
3544 msgstr ""
3545
3546 #. module: logistic_requisition
3547+#: code:addons/logistic_requisition/model/logistic_requisition.py:1113
3548+#, python-format
3549+msgid "There should be at least one selectedline with procurement method Procurement"
3550+msgstr ""
3551+
3552+#. module: logistic_requisition
3553 #: view:logistic.requisition:0
3554 #: field:logistic.requisition.line,logistic_user_id:0
3555 msgid "Assigned To"
3556@@ -486,9 +562,24 @@
3557 msgstr ""
3558
3559 #. module: logistic_requisition
3560-#: view:logistic.requisition:0
3561-#: view:logistic.requisition.line:0
3562-msgid "Show cost estimate only"
3563+#: field:logistic.requisition.source,transport_applicable:0
3564+msgid "Transport Applicable"
3565+msgstr ""
3566+
3567+#. module: logistic_requisition
3568+#: field:logistic.requisition.source,default_source_address:0
3569+msgid "Default source"
3570+msgstr ""
3571+
3572+#. module: logistic_requisition
3573+#: report:addons/logistic_requisition/report/logistic_requisition.mako:141
3574+msgid "Cost estimate only"
3575+msgstr ""
3576+
3577+#. module: logistic_requisition
3578+#: code:addons/logistic_requisition/model/purchase.py:198
3579+#, python-format
3580+msgid "You cannot delete this PO line because it is already linked to a Logistic Requsition Line %s marked as sourced or quoted."
3581 msgstr ""
3582
3583 #. module: logistic_requisition
3584@@ -518,6 +609,11 @@
3585 msgstr ""
3586
3587 #. module: logistic_requisition
3588+#: report:addons/logistic_requisition/report/logistic_requisition.mako:192
3589+msgid "Signature"
3590+msgstr ""
3591+
3592+#. module: logistic_requisition
3593 #: view:logistic.requisition.line:0
3594 msgid "Country:"
3595 msgstr ""
3596@@ -528,13 +624,20 @@
3597 msgstr ""
3598
3599 #. module: logistic_requisition
3600+#: code:addons/logistic_requisition/wizard/cost_estimate.py:196
3601+#, python-format
3602+msgid "Sourcing %s: no account code has been stored"
3603+msgstr ""
3604+
3605+#. module: logistic_requisition
3606 #: field:logistic.requisition.source,proposed_qty:0
3607 msgid "Proposed Qty"
3608 msgstr ""
3609
3610 #. module: logistic_requisition
3611-#: field:purchase.order.line,po_line_from_bid_ids:0
3612-msgid "Lines generated by the bid"
3613+#: selection:logistic.requisition.source,price_is:0
3614+#: selection:sale.order.line,price_is:0
3615+msgid "Estimated"
3616 msgstr ""
3617
3618 #. module: logistic_requisition
3619@@ -549,18 +652,31 @@
3620 msgstr ""
3621
3622 #. module: logistic_requisition
3623+#: code:addons/logistic_requisition/model/logistic_requisition.py:1045
3624+#, python-format
3625+msgid "The lines are not assigned to the same User."
3626+msgstr ""
3627+
3628+#. module: logistic_requisition
3629 #: constraint:logistic.requisition.cost.estimate:0
3630 msgid "All the lines should belong to the same requisition."
3631 msgstr ""
3632
3633 #. module: logistic_requisition
3634+#: code:addons/logistic_requisition/model/logistic_requisition.py:1118
3635+#, python-format
3636+msgid "Selected line procurement method should be procurement or other"
3637+msgstr ""
3638+
3639+#. module: logistic_requisition
3640 #: view:logistic.requisition:0
3641 msgid "Delivery Date"
3642 msgstr ""
3643
3644 #. module: logistic_requisition
3645-#: field:logistic.requisition,budget_holder_id:0
3646-msgid "Budget Holder"
3647+#: model:ir.actions.act_window,name:logistic_requisition.action_logistic_requisition_cancel
3648+#: view:logistic.requisition.cancel:0
3649+msgid "Reason for the cancellation"
3650 msgstr ""
3651
3652 #. module: logistic_requisition
3653@@ -570,7 +686,6 @@
3654
3655 #. module: logistic_requisition
3656 #: view:logistic.requisition.source:0
3657-#: field:purchase.requisition,logistic_requisition_source_ids:0
3658 msgid "Logistic Requisition Sourcing Lines"
3659 msgstr ""
3660
3661@@ -580,8 +695,11 @@
3662 msgstr ""
3663
3664 #. module: logistic_requisition
3665+#: view:logistic.requisition:0
3666 #: field:logistic.requisition,currency_id:0
3667+#: view:logistic.requisition.line:0
3668 #: field:logistic.requisition.line,currency_id:0
3669+#: field:logistic.requisition.source,currency_id:0
3670 msgid "Currency"
3671 msgstr ""
3672
3673@@ -597,36 +715,53 @@
3674 msgstr ""
3675
3676 #. module: logistic_requisition
3677+#: code:addons/logistic_requisition/wizard/cost_estimate.py:191
3678+#, python-format
3679+msgid "Sourcing %s: no quantity has been proposed"
3680+msgstr ""
3681+
3682+#. module: logistic_requisition
3683 #: model:ir.actions.act_window,name:logistic_requisition.action_logistic_requisition
3684 #: model:ir.ui.menu,name:logistic_requisition.menu_logistic_requisition
3685 msgid "Requisitions"
3686 msgstr ""
3687
3688 #. module: logistic_requisition
3689-#: field:logistic.requisition,date_finance_officer:0
3690-msgid "Finance Officer Validation Date"
3691-msgstr ""
3692-
3693-#. module: logistic_requisition
3694-#: view:logistic.requisition:0
3695-#: view:logistic.requisition.line:0
3696-msgid "Internal (Federation)"
3697-msgstr ""
3698-
3699-#. module: logistic_requisition
3700-#: field:logistic.requisition.source,transport_applicable:0
3701-msgid "Transport Applicable"
3702-msgstr ""
3703-
3704-#. module: logistic_requisition
3705-#: field:logistic.requisition.source,purchase_requisition_line_ids:0
3706-msgid "Purchase Requisition Lines"
3707+#: report:addons/logistic_requisition/report/logistic_requisition.mako:149
3708+msgid "Yes"
3709+msgstr ""
3710+
3711+#. module: logistic_requisition
3712+#: code:addons/logistic_requisition/model/logistic_requisition.py:1115
3713+#: code:addons/logistic_requisition/model/logistic_requisition.py:1120
3714+#, python-format
3715+msgid "Please correct selection"
3716+msgstr ""
3717+
3718+#. module: logistic_requisition
3719+#: field:logistic.requisition.source,offer_ids:0
3720+msgid "Sales Quotation Lines"
3721+msgstr ""
3722+
3723+#. module: logistic_requisition
3724+#: constraint:logistic.requisition.source:0
3725+msgid "A call for bids cannot be linked to lines of different logistics requisitions."
3726+msgstr ""
3727+
3728+#. module: logistic_requisition
3729+#: report:addons/logistic_requisition/report/logistic_requisition.mako:136
3730+msgid "Logistic requisition"
3731+msgstr ""
3732+
3733+#. module: logistic_requisition
3734+#: report:addons/logistic_requisition/report/logistic_requisition.mako:190
3735+msgid "Requesting entity"
3736 msgstr ""
3737
3738 #. module: logistic_requisition
3739 #: model:ir.model,name:logistic_requisition.model_purchase_order_line
3740-#: field:logistic.requisition.source,bid_line_id:0
3741 #: field:logistic.requisition.source,purchase_line_id:0
3742+#: field:logistic.requisition.source,selected_bid_line_id:0
3743 msgid "Purchase Order Line"
3744 msgstr ""
3745
3746@@ -641,6 +776,12 @@
3747 msgstr ""
3748
3749 #. module: logistic_requisition
3750+#: code:addons/logistic_requisition/model/logistic_requisition.py:521
3751+#, python-format
3752+msgid "line %s is not sourced"
3753+msgstr ""
3754+
3755+#. module: logistic_requisition
3756 #: model:ir.model,name:logistic_requisition.model_logistic_requisition_source_transport_plan
3757 msgid "Create a transport plan for logistic requisition source lines"
3758 msgstr ""
3759@@ -695,18 +836,13 @@
3760 msgstr ""
3761
3762 #. module: logistic_requisition
3763+#: field:purchase.requisition.line,logistic_requisition_source_ids:0
3764 #: view:transport.plan:0
3765 #: field:transport.plan,logistic_requisition_source_ids:0
3766 msgid "Logistic Requisition Source Lines"
3767 msgstr ""
3768
3769 #. module: logistic_requisition
3770-#: view:logistic.requisition:0
3771-#: view:logistic.requisition.line:0
3772-msgid "External (NS, Others)"
3773-msgstr ""
3774-
3775-#. module: logistic_requisition
3776 #: field:logistic.requisition.source.transport.plan,transport_estimated_cost:0
3777 msgid "Transportation Estimated Costs"
3778 msgstr ""
3779@@ -742,16 +878,6 @@
3780 msgstr ""
3781
3782 #. module: logistic_requisition
3783-#: field:purchase.requisition.line,logistic_requisition_source_id:0
3784-msgid "Logistic Requisition Source Line"
3785-msgstr ""
3786-
3787-#. module: logistic_requisition
3788-#: view:logistic.requisition:0
3789-msgid "Validation"
3790-msgstr ""
3791-
3792-#. module: logistic_requisition
3793 #: help:logistic.requisition.source.transport.plan,date_eta:0
3794 msgid "Estimated Date of Arrival if not set requisition ETA will be used"
3795 msgstr ""
3796@@ -764,8 +890,14 @@
3797 msgstr ""
3798
3799 #. module: logistic_requisition
3800-#: view:logistic.requisition:0
3801-msgid " validated on "
3802+#: code:addons/logistic_requisition/model/sale_order.py:45
3803+#, python-format
3804+msgid "The logistic requisition line %s has no purchase order line."
3805+msgstr ""
3806+
3807+#. module: logistic_requisition
3808+#: report:addons/logistic_requisition/report/logistic_requisition.mako:187
3809+msgid "Approval"
3810 msgstr ""
3811
3812 #. module: logistic_requisition
3813@@ -780,6 +912,11 @@
3814 msgstr ""
3815
3816 #. module: logistic_requisition
3817+#: help:logistic.requisition,pricelist_id:0
3818+msgid "Pricelist that represent the currency for current logistic request."
3819+msgstr ""
3820+
3821+#. module: logistic_requisition
3822 #: model:ir.model,name:logistic_requisition.model_stock_incoterms
3823 msgid "Incoterms"
3824 msgstr ""
3825@@ -805,7 +942,6 @@
3826
3827 #. module: logistic_requisition
3828 #: view:logistic.requisition:0
3829-#: field:logistic.requisition,partner_id:0
3830 msgid "Requesting Entity"
3831 msgstr ""
3832
3833@@ -840,6 +976,17 @@
3834 msgstr ""
3835
3836 #. module: logistic_requisition
3837+#: code:addons/logistic_requisition/model/logistic_requisition.py:1044
3838+#: code:addons/logistic_requisition/model/logistic_requisition.py:1052
3839+#: code:addons/logistic_requisition/model/logistic_requisition.py:1059
3840+#: code:addons/logistic_requisition/model/logistic_requisition.py:1066
3841+#: code:addons/logistic_requisition/model/sale_order.py:44
3842+#: code:addons/logistic_requisition/wizard/cost_estimate.py:261
3843+#, python-format
3844+msgid "Error"
3845+msgstr ""
3846+
3847+#. module: logistic_requisition
3848 #: model:logistic.requisition.cancel.reason,name:logistic_requisition.cancel_reason_no_service_needed
3849 msgid "No service needed anymore"
3850 msgstr ""
3851@@ -851,11 +998,7 @@
3852 msgstr ""
3853
3854 #. module: logistic_requisition
3855-#: field:logistic.requisition.source,unit_cost:0
3856-msgid "Unit Cost"
3857-msgstr ""
3858-
3859-#. module: logistic_requisition
3860+#: report:addons/logistic_requisition/report/logistic_requisition.mako:162
3861 #: view:logistic.requisition:0
3862 #: field:logistic.requisition.line,requested_qty:0
3863 msgid "Quantity"
3864@@ -883,11 +1026,8 @@
3865 msgstr ""
3866
3867 #. module: logistic_requisition
3868-#: view:logistic.requisition:0
3869-#: field:logistic.requisition,requester_type:0
3870-#: view:logistic.requisition.line:0
3871-#: field:logistic.requisition.line,requester_type:0
3872-msgid "Type of Requestor"
3873+#: report:addons/logistic_requisition/report/logistic_requisition.mako:160
3874+msgid "Number"
3875 msgstr ""
3876
3877 #. module: logistic_requisition
3878@@ -896,6 +1036,12 @@
3879 msgstr ""
3880
3881 #. module: logistic_requisition
3882+#: code:addons/logistic_requisition/model/logistic_requisition.py:1091
3883+#, python-format
3884+msgid "Existing"
3885+msgstr ""
3886+
3887+#. module: logistic_requisition
3888 #: view:logistic.requisition.line:0
3889 #: selection:logistic.requisition.line,state:0
3890 #: selection:logistic.requisition.source,state:0
3891@@ -903,8 +1049,9 @@
3892 msgstr ""
3893
3894 #. module: logistic_requisition
3895-#: field:logistic.requisition.line,budget_tot_price:0
3896-msgid "Budget Total Price"
3897+#: view:logistic.requisition.line:0
3898+#: view:logistic.requisition.source:0
3899+msgid "Total Budget"
3900 msgstr ""
3901
3902 #. module: logistic_requisition
3903@@ -939,15 +1086,8 @@
3904 msgstr ""
3905
3906 #. module: logistic_requisition
3907-#: selection:logistic.requisition.source,price_is:0
3908-#: selection:sale.order.line,price_is:0
3909-msgid "Estimated"
3910-msgstr ""
3911-
3912-#. module: logistic_requisition
3913-#: model:ir.actions.act_window,name:logistic_requisition.action_logistic_requisition_cancel
3914-#: view:logistic.requisition.cancel:0
3915-msgid "Reason for the cancellation"
3916+#: field:purchase.order.line,po_line_from_bid_ids:0
3917+msgid "Lines generated by the bid"
3918 msgstr ""
3919
3920 #. module: logistic_requisition
3921@@ -971,18 +1111,16 @@
3922 msgstr ""
3923
3924 #. module: logistic_requisition
3925-#: selection:logistic.requisition,requester_type:0
3926-#: selection:logistic.requisition.line,requester_type:0
3927-#: selection:res.partner,requester_type:0
3928-msgid "Federation (internal)"
3929-msgstr ""
3930-
3931-#. module: logistic_requisition
3932 #: view:logistic.requisition.line:0
3933 msgid "Req. Date:"
3934 msgstr ""
3935
3936 #. module: logistic_requisition
3937+#: report:addons/logistic_requisition/report/logistic_requisition.mako:182
3938+msgid "General Remarks"
3939+msgstr ""
3940+
3941+#. module: logistic_requisition
3942 #: view:logistic.requisition:0
3943 #: field:logistic.requisition,cost_estimate_only:0
3944 #: view:logistic.requisition.line:0
3945@@ -1006,8 +1144,8 @@
3946 msgstr ""
3947
3948 #. module: logistic_requisition
3949-#: field:res.partner,requester_type:0
3950-msgid "Requester Type"
3951+#: selection:logistic.requisition.source,procurement_method:0
3952+msgid "Other"
3953 msgstr ""
3954
3955 #. module: logistic_requisition
3956@@ -1034,6 +1172,7 @@
3957
3958 #. module: logistic_requisition
3959 #: model:ir.model,name:logistic_requisition.model_purchase_requisition_line
3960+#: field:logistic.requisition.source,purchase_requisition_line_id:0
3961 msgid "Purchase Requisition Line"
3962 msgstr ""
3963
3964@@ -1050,6 +1189,7 @@
3965 msgstr ""
3966
3967 #. module: logistic_requisition
3968+#: report:addons/logistic_requisition/report/logistic_requisition.mako:161
3969 #: field:logistic.requisition.line,description:0
3970 msgid "Description"
3971 msgstr ""
3972@@ -1061,9 +1201,9 @@
3973 msgstr ""
3974
3975 #. module: logistic_requisition
3976-#: view:logistic.requisition:0
3977-#: view:logistic.requisition.line:0
3978-msgid "Requestor is the Federation"
3979+#: code:addons/logistic_requisition/model/logistic_requisition.py:1053
3980+#, python-format
3981+msgid "The sourcing lines do not belong to the same company."
3982 msgstr ""
3983
3984 #. module: logistic_requisition
3985@@ -1072,6 +1212,12 @@
3986 msgstr ""
3987
3988 #. module: logistic_requisition
3989+#: code:addons/logistic_requisition/model/logistic_requisition.py:1097
3990+#, python-format
3991+msgid "The sourcing line %d does not have any product defined, please choose one."
3992+msgstr ""
3993+
3994+#. module: logistic_requisition
3995 #: field:logistic.requisition.source.transport.plan,transport_mode_id:0
3996 msgid "Transport by"
3997 msgstr ""
3998@@ -1082,8 +1228,14 @@
3999 msgstr ""
4000
4001 #. module: logistic_requisition
4002-#: help:logistic.requisition.line,logistic_user_id:0
4003-msgid "User in charge of the Logistic Requisition Line"
4004+#: code:addons/logistic_requisition/model/logistic_requisition.py:632
4005+#, python-format
4006+msgid "Logistic Requisition Line %s Assigned"
4007+msgstr ""
4008+
4009+#. module: logistic_requisition
4010+#: report:addons/logistic_requisition/report/logistic_requisition.mako:191
4011+msgid "Requested date"
4012 msgstr ""
4013
4014 #. module: logistic_requisition
4015@@ -1092,8 +1244,8 @@
4016 msgstr ""
4017
4018 #. module: logistic_requisition
4019-#: field:logistic.requisition,allowed_budget:0
4020-msgid "Allowed Budget"
4021+#: field:logistic.requisition,partner_id:0
4022+msgid "Customer"
4023 msgstr ""
4024
4025 #. module: logistic_requisition
4026@@ -1102,11 +1254,6 @@
4027 msgstr ""
4028
4029 #. module: logistic_requisition
4030-#: help:logistic.requisition.line.assign,logistic_user_id:0
4031-msgid "Logistic Specialist in charge of the Logistic Requisition Line"
4032-msgstr ""
4033-
4034-#. module: logistic_requisition
4035 #: field:logistic.requisition,line_ids:0
4036 msgid "Products to Purchase"
4037 msgstr ""
4038@@ -1117,6 +1264,7 @@
4039 msgstr ""
4040
4041 #. module: logistic_requisition
4042+#: report:addons/logistic_requisition/report/logistic_requisition.mako:143
4043 #: view:logistic.requisition:0
4044 #: field:logistic.requisition,country_id:0
4045 #: view:logistic.requisition.line:0
4046@@ -1125,8 +1273,11 @@
4047 msgstr ""
4048
4049 #. module: logistic_requisition
4050+#: code:addons/logistic_requisition/model/logistic_requisition.py:693
4051+#: code:addons/logistic_requisition/wizard/cost_estimate.py:293
4052 #: view:logistic.requisition.cost.estimate:0
4053 #: field:logistic.requisition.line,cost_estimate_id:0
4054+#, python-format
4055 msgid "Cost Estimate"
4056 msgstr ""
4057
4058@@ -1146,23 +1297,24 @@
4059 msgstr ""
4060
4061 #. module: logistic_requisition
4062+#: report:addons/logistic_requisition/report/logistic_requisition.mako:144
4063 #: view:logistic.requisition:0
4064 #: field:logistic.requisition,date:0
4065 msgid "Requisition Date"
4066 msgstr ""
4067
4068 #. module: logistic_requisition
4069-#: view:logistic.requisition.line:0
4070-msgid "Total Proposed"
4071-msgstr ""
4072-
4073-#. module: logistic_requisition
4074 #: view:logistic.requisition.cancel:0
4075 msgid "Choose the reason for the cancellation of the\n"
4076 " logistic requisition."
4077 msgstr ""
4078
4079 #. module: logistic_requisition
4080+#: field:logistic.requisition.source,proposed_product_id:0
4081+msgid "Proposed Product"
4082+msgstr ""
4083+
4084+#. module: logistic_requisition
4085 #: view:logistic.requisition.line.assign:0
4086 msgid "Select the assignee"
4087 msgstr ""
4088@@ -1170,6 +1322,7 @@
4089 #. module: logistic_requisition
4090 #: model:ir.model,name:logistic_requisition.model_logistic_requisition_source
4091 #: view:logistic.requisition.source:0
4092+#: field:purchase.order.line,lr_source_line_id:0
4093 msgid "Logistic Requisition Source"
4094 msgstr ""
4095
4096@@ -1188,6 +1341,11 @@
4097 msgstr ""
4098
4099 #. module: logistic_requisition
4100+#: report:addons/logistic_requisition/report/logistic_requisition.mako:102
4101+msgid "Shipping address:"
4102+msgstr ""
4103+
4104+#. module: logistic_requisition
4105 #: view:logistic.requisition.source.create.requisition:0
4106 msgid " Please note that: \n"
4107 " \n"
4108@@ -1208,7 +1366,13 @@
4109 msgstr ""
4110
4111 #. module: logistic_requisition
4112+#: report:addons/logistic_requisition/report/logistic_requisition.mako:178
4113+msgid "Delivery Remarks"
4114+msgstr ""
4115+
4116+#. module: logistic_requisition
4117 #: field:logistic.requisition.line,account_code:0
4118+#: field:sale.order.line,account_code:0
4119 msgid "Account Code"
4120 msgstr ""
4121
4122@@ -1218,6 +1382,17 @@
4123 msgstr ""
4124
4125 #. module: logistic_requisition
4126+#: field:logistic.requisition.source.create.requisition,pricelist_id:0
4127+msgid "Pricelist / Currency"
4128+msgstr ""
4129+
4130+#. module: logistic_requisition
4131+#: code:addons/logistic_requisition/model/logistic_requisition.py:1060
4132+#, python-format
4133+msgid "The sourcing lines do not have the same consignee."
4134+msgstr ""
4135+
4136+#. module: logistic_requisition
4137 #: view:logistic.requisition.cancel:0
4138 #: view:logistic.requisition.cost.estimate:0
4139 #: view:logistic.requisition.line.assign:0
4140@@ -1227,7 +1402,24 @@
4141 msgstr ""
4142
4143 #. module: logistic_requisition
4144+#: view:logistic.requisition:0
4145+msgid "View Sourcing Lines"
4146+msgstr ""
4147+
4148+#. module: logistic_requisition
4149+#: code:addons/logistic_requisition/model/logistic_requisition.py:1096
4150+#, python-format
4151+msgid "Missing information"
4152+msgstr ""
4153+
4154+#. module: logistic_requisition
4155 #: view:logistic.requisition.line:0
4156 msgid "Open Cost Estimate"
4157 msgstr ""
4158
4159+#. module: logistic_requisition
4160+#: code:addons/logistic_requisition/wizard/cost_estimate.py:105
4161+#, python-format
4162+msgid "Transport from %s to %s by %s (Ref. %s)"
4163+msgstr ""
4164+
4165
4166=== modified file 'logistic_requisition/model/logistic_requisition.py'
4167--- logistic_requisition/model/logistic_requisition.py 2014-01-30 16:26:37 +0000
4168+++ logistic_requisition/model/logistic_requisition.py 2014-05-07 09:53:02 +0000
4169@@ -158,40 +158,22 @@
4170 readonly=True,
4171 required=True
4172 ),
4173- 'amount_total': fields.function(
4174- lambda self, *args, **kwargs: self._get_amount(*args, **kwargs),
4175- digits_compute=dp.get_precision('Account'),
4176- string='Total Budget',
4177- store={
4178- 'logistic.requisition': (
4179- lambda self, cr, uid, ids, c=None: ids,
4180- ['line_ids'], 20),
4181- 'logistic.requisition.line': (
4182- lambda self, *a, **kw: self._store_get_requisition_ids(*a, **kw),
4183- ['requested_qty', 'budget_unit_price', 'budget_tot_price', 'requisition_id'], 20),
4184- }),
4185 'sourced': fields.function(
4186 lambda self, *args, **kwargs: self._get_sourced(*args, **kwargs),
4187 string='Sourced',
4188 type='float'
4189 ),
4190- 'allowed_budget': fields.boolean('Allowed Budget'),
4191- 'currency_id': fields.related('company_id',
4192+ 'pricelist_id': fields.many2one('product.pricelist',
4193+ 'Pricelist',
4194+ required=True,
4195+ states=REQ_STATES,
4196+ help="Pricelist that represent the currency for current logistic request."),
4197+ 'currency_id': fields.related('pricelist_id',
4198 'currency_id',
4199 type='many2one',
4200 relation='res.currency',
4201 string='Currency',
4202 readonly=True),
4203- 'budget_holder_id': fields.many2one(
4204- 'res.users',
4205- string='Budget Holder'),
4206- 'date_budget_holder': fields.datetime(
4207- 'Budget Holder Validation Date'),
4208- 'finance_officer_id': fields.many2one(
4209- 'res.users',
4210- string='Finance Officer'),
4211- 'date_finance_officer': fields.datetime(
4212- 'Finance Officer Validation Date'),
4213 'cancel_reason_id': fields.many2one(
4214 'logistic.requisition.cancel.reason',
4215 string='Reason for Cancellation',
4216@@ -214,13 +196,6 @@
4217 'Logistic Requisition Reference must be unique!'),
4218 ]
4219
4220- def _get_amount(self, cr, uid, ids, name, args, context=None):
4221- res = {}
4222- for requisition in self.browse(cr, uid, ids, context=context):
4223- res[requisition.id] = sum(line.budget_tot_price for line
4224- in requisition.line_ids)
4225- return res
4226-
4227 def _get_sourced(self, cr, uid, ids, name, args, context=None):
4228 res = {}
4229 for requisition in self.browse(cr, uid, ids, context=context):
4230@@ -268,10 +243,6 @@
4231 line_obj = self.pool.get('logistic.requisition.line')
4232 line_obj._do_draft(cr, uid, line_ids, context=context)
4233 vals = {'state': 'draft',
4234- 'budget_holder_id': False,
4235- 'date_budget_holder': False,
4236- 'finance_officer_id': False,
4237- 'date_finance_officer': False,
4238 'cancel_reason_id': False,
4239 }
4240 self.write(cr, uid, ids, vals, context=context)
4241@@ -296,13 +267,24 @@
4242 default.update({
4243 'state': 'draft',
4244 'name': '/',
4245- 'budget_holder_id': False,
4246- 'date_budget_holder': False,
4247- 'finance_officer_id': False,
4248- 'date_finance_officer': False,
4249 })
4250 return super(logistic_requisition, self).copy(cr, uid, id, default=default, context=context)
4251
4252+ def onchange_partner_id(self, cr, uid, ids, part, context=None):
4253+ """We take the pricelist of the chosen partner"""
4254+ values = {'pricelist_id': False}
4255+ if not part:
4256+ return {'value': values}
4257+
4258+ part = self.pool.get('res.partner').browse(cr, uid, part,
4259+ context=context)
4260+ pricelist = part.property_product_pricelist
4261+ pricelist = pricelist.id if pricelist else False
4262+ values = {}
4263+ if pricelist:
4264+ values['pricelist_id'] = pricelist
4265+ return {'value': values}
4266+
4267 def onchange_consignee_id(self, cr, uid, ids, consignee_id, context=None):
4268 values = {'consignee_shipping_id': False}
4269 if not consignee_id:
4270@@ -425,13 +407,9 @@
4271 'Product UoM',
4272 states=REQUEST_STATES,
4273 required=True),
4274- 'budget_tot_price': fields.float(
4275- 'Budget Total Price',
4276- states=REQUEST_STATES,
4277- digits_compute=dp.get_precision('Account')),
4278- 'budget_unit_price': fields.function(
4279- lambda self, *args, **kwargs: self._get_unit_amount_line(*args, **kwargs),
4280- string='Budget Unit Price',
4281+ 'amount_total': fields.function(
4282+ lambda self, *args, **kwargs: self._get_total_cost(*args, **kwargs),
4283+ string='Total Amount',
4284 type="float",
4285 digits_compute=dp.get_precision('Account'),
4286 store=True),
4287@@ -572,11 +550,13 @@
4288 context=context, load='_classic_write')
4289 return list(set([x['requisition_id'] for x in reqs]))
4290
4291- def _get_unit_amount_line(self, cr, uid, ids, prop, unknow_none, unknow_dict, context=None):
4292+ def _get_total_cost(self, cr, uid, ids, name, args, context=None):
4293 res = {}
4294+ for i in ids:
4295+ res[i] = 0.0
4296 for line in self.browse(cr, uid, ids, context=context):
4297- price = line.budget_tot_price / line.requested_qty
4298- res[line.id] = price
4299+ for source_line in line.source_ids:
4300+ res[line.id] += source_line.total_cost
4301 return res
4302
4303 def view_stock_by_location(self, cr, uid, ids, context=None):
4304@@ -749,25 +729,6 @@
4305 'quoted': [('readonly', True)]
4306 }
4307
4308- def _purchase_line_id(self, cr, uid, ids, field_name, arg, context=None):
4309- """ For each line, returns the generated purchase line from the
4310- purchase requisition.
4311- """
4312- result = {}
4313- for line in self.browse(cr, uid, ids, context=context):
4314- result[line.id] = False
4315- bid_line = line.bid_line_id
4316- if not bid_line:
4317- continue
4318- po_lines = bid_line.po_line_from_bid_ids
4319- if not po_lines:
4320- continue
4321- assert len(po_lines) == 1, (
4322- "We should not have several purchase order lines "
4323- "for a logistic requisition line")
4324- result[line.id] = po_lines[0].id if po_lines else False
4325- return result
4326-
4327 def _default_source_address(self, cr, uid, ids, field_name, arg, context=None):
4328 """Return the default source address depending of the procurment method"""
4329 res = {}
4330@@ -818,6 +779,7 @@
4331 [('procurement', 'Procurement'),
4332 ('wh_dispatch', 'Warehouse Dispatch'),
4333 ('fw_agreement', 'Framework Agreement'),
4334+ ('other', 'Other'),
4335 ],
4336 string='Procurement Method',
4337 required=True,
4338@@ -859,6 +821,12 @@
4339 type='float',
4340 digits_compute=dp.get_precision('Account'),
4341 store=True),
4342+ 'currency_id': fields.related('requisition_id',
4343+ 'currency_id',
4344+ type='many2one',
4345+ relation='res.currency',
4346+ string='Currency',
4347+ readonly=True),
4348 'transport_applicable': fields.boolean(
4349 'Transport Applicable',
4350 states=SOURCED_STATES),
4351@@ -928,6 +896,8 @@
4352 'transport_applicable': False,
4353 'price_is': 'fixed',
4354 'name': '/',
4355+ 'procurement_method': 'other',
4356+ 'proposed_qty': 1
4357 }
4358 _constraints = [
4359 (lambda self, *a, **kw: self._check_transport_plan(*a, **kw),
4360@@ -938,9 +908,6 @@
4361 "A transport plan cannot be linked to lines of different "
4362 "logistic requisitions.",
4363 ['transport_plan_id', 'requisition_id']),
4364- (lambda self, *a, **kw: self._check_source_lines_total_amount(*a, **kw),
4365- 'The total cost cannot be more than the total budget.',
4366- ['proposed_qty', 'unit_cost', 'requisition_line_id']),
4367 (lambda self, *a, **kw: self._check_purchase_requisition_unique(*a, **kw),
4368 "A call for bids cannot be linked to lines of different "
4369 "logistics requisitions.",
4370@@ -955,10 +922,16 @@
4371 return False
4372 return True
4373
4374+ def _is_sourced_other(self, cr, uid, source, context=None):
4375+ """Predicate function to test if line on other
4376+ method are sourced"""
4377+ return self._is_sourced_procurement(cr, uid, source,
4378+ context=context)
4379+
4380 def _is_sourced_wh_dispatch(self, cr, uid, source, context=None):
4381- """Predicate function to test if line on warehouse
4382- method are sourced"""
4383- return True
4384+ """Predicate function to test if line on warehouse
4385+ method are sourced"""
4386+ return True
4387
4388 def _is_sourced(self, cr, uid, source_id, context=None):
4389 """ check if line is source using predicate function
4390@@ -1011,32 +984,32 @@
4391 return False
4392 return True
4393
4394- def _check_source_lines_total_amount(self, cr, uid, ids, context=None):
4395- for source in self.browse(cr, uid, ids, context=context):
4396- line = source.requisition_line_id
4397- total = sum(source.unit_cost * source.proposed_qty
4398- for source in line.source_ids)
4399- if total > line.budget_tot_price:
4400- return False
4401- return True
4402-
4403 def _get_purchase_line_id(self, cr, uid, ids, field_name, arg, context=None):
4404 """ For each line, returns the generated purchase line from the
4405 purchase requisition.
4406 """
4407 result = {}
4408+ po_line_model = self.pool['purchase.order.line']
4409+ po_lines = None
4410 for line in self.browse(cr, uid, ids, context=context):
4411 result[line.id] = False
4412- bid_line = line.selected_bid_line_id
4413- if not bid_line:
4414- continue
4415- po_lines = bid_line.po_line_from_bid_ids
4416- if not po_lines:
4417- continue
4418+ if line.selected_bid_line_id:
4419+ bid_line = line.selected_bid_line_id
4420+ if not bid_line:
4421+ continue
4422+ po_lines = [x.id for x in bid_line.po_line_from_bid_ids]
4423+ if not po_lines:
4424+ continue
4425+ else:
4426+ po_lines = po_line_model.search(cr, uid,
4427+ [('lr_source_line_id', '=', line.id),
4428+ ('state', '!=', 'cancel')],
4429+ context=context)
4430 assert len(po_lines) == 1, (
4431 "We should not have several purchase order lines "
4432 "for a logistic requisition line")
4433- result[line.id] = po_lines[0].id if po_lines else False
4434+ result[line.id] = po_lines[0] if po_lines else False
4435+
4436 return result
4437
4438 def create(self, cr, uid, vals, context=None):
4439@@ -1046,7 +1019,18 @@
4440 return super(logistic_requisition_source, self).create(cr, uid, vals,
4441 context=context)
4442
4443- def _prepare_po_requisition(self, cr, uid, sources, purch_req_lines, context=None):
4444+ def _get_purchase_pricelist_from_currency(self, cr, uid, currency_id, context=None):
4445+ """ This method will look for a pricelist of type 'purchase' using
4446+ the same currency than than the given one.
4447+ return : ID of product.pricelist type Integer
4448+ """
4449+ pricelist_obj = self.pool.get('product.pricelist')
4450+ pricelist_id = pricelist_obj.search(cr, uid,
4451+ [('currency_id','=',currency_id),('type','=','purchase')], limit=1)
4452+ return pricelist_id[0]
4453+
4454+ def _prepare_po_requisition(self, cr, uid, sources, purch_req_lines,
4455+ pricelist=None, context=None):
4456 company_id = None
4457 user_id = None
4458 consignee_id = None
4459@@ -1084,6 +1068,14 @@
4460 _('Error'),
4461 _('The sourcing lines do not have the '
4462 'same delivery address.'))
4463+ line_pricelist_id = self._get_purchase_pricelist_from_currency(
4464+ cr,
4465+ uid,
4466+ line.requisition_id.pricelist_id.currency_id.id,
4467+ context=context
4468+ )
4469+ if pricelist is None:
4470+ pricelist = line_pricelist_id
4471 return {'user_id': user_id or uid,
4472 'company_id': company_id,
4473 'consignee_id': consignee_id,
4474@@ -1092,6 +1084,8 @@
4475 'origin': ", ".join(origin),
4476 'req_incoterm_id': line.requisition_id.incoterm_id.id,
4477 'req_incoterm_address': line.requisition_id.incoterm_address,
4478+ 'pricelist_id': pricelist,
4479+ 'schedule_date': line.requisition_id.date_delivery,
4480 }
4481
4482 def _prepare_po_requisition_line(self, cr, uid, line, context=None):
4483@@ -1113,17 +1107,27 @@
4484 'logistic_requisition_source_ids': [(4, line.id)],
4485 }
4486
4487- def _action_create_po_requisition(self, cr, uid, ids, context=None):
4488+ def _action_create_po_requisition(self, cr, uid, ids, pricelist=None, context=None):
4489 purch_req_obj = self.pool.get('purchase.requisition')
4490 purch_req_lines = []
4491 lines = self.browse(cr, uid, ids, context=context)
4492+ if not next((x for x in lines
4493+ if x.procurement_method == 'procurement'), None):
4494+ raise orm.except_orm(_('There should be at least one selected'
4495+ ' line with procurement method Procurement'),
4496+ _('Please correct selection'))
4497 for line in lines:
4498+ if line.procurement_method not in ('other', 'procurement'):
4499+ raise orm.except_orm(_('Selected line procurement method should'
4500+ ' be procurement or other'),
4501+ _('Please correct selection'))
4502 vals = self._prepare_po_requisition_line(cr, uid, line,
4503 context=context)
4504 purch_req_lines.append(vals)
4505 vals = self._prepare_po_requisition(cr, uid,
4506 lines,
4507 purch_req_lines,
4508+ pricelist=pricelist,
4509 context=context)
4510 purch_req_id = purch_req_obj.create(cr, uid, vals, context=context)
4511 self.write(cr, uid, ids,
4512@@ -1131,8 +1135,10 @@
4513 context=context)
4514 return purch_req_id
4515
4516- def action_create_po_requisition(self, cr, uid, ids, context=None):
4517- self._action_create_po_requisition(cr, uid, ids, context=context)
4518+ def action_create_po_requisition(self, cr, uid, ids,
4519+ pricelist=None, context=None):
4520+ self._action_create_po_requisition(cr, uid, ids,
4521+ pricelist=pricelist, context=context)
4522 return self.action_open_po_requisition(cr, uid, ids, context=context)
4523
4524 def action_open_po_requisition(self, cr, uid, ids, context=None):
4525
4526=== modified file 'logistic_requisition/model/purchase.py'
4527--- logistic_requisition/model/purchase.py 2014-01-22 12:08:36 +0000
4528+++ logistic_requisition/model/purchase.py 2014-05-07 09:53:02 +0000
4529@@ -21,6 +21,7 @@
4530
4531 from openerp.osv import orm, fields
4532 from openerp import netsvc
4533+from openerp.tools.translate import _
4534
4535
4536 class purchase_order(orm.Model):
4537@@ -36,10 +37,11 @@
4538 """
4539 wf_service = netsvc.LocalService("workflow")
4540 proc_obj = self.pool.get('procurement.order')
4541- # Proc product of type service should be confirm at this
4542+ # Proc product of type service should be confirm at this
4543 # stage, otherwise, when picking of related PO is created
4544 # then done, it stay blocked at running stage
4545- proc_ids = proc_obj.search(cr, uid, [('purchase_id','in', ids)], context=context)
4546+ proc_ids = proc_obj.search(cr, uid, [('purchase_id', 'in', ids)],
4547+ context=context)
4548 for proc in proc_obj.browse(cr, uid, proc_ids, context=context):
4549 if proc.product_id.type == 'service':
4550 wf_service.trg_validate(uid, 'procurement.order',
4551@@ -74,7 +76,7 @@
4552 and sale_line.sale_flow == 'direct_delivery'):
4553 continue
4554 procurement = sale_line.procurement_id
4555- if not procurement.move_id:
4556+ if procurement and not procurement.move_id:
4557 # the procurement for the sales and purchase is the same!
4558 # So when the move will be done, the sales order and the
4559 # purchase order will be shipped at the same time
4560@@ -107,3 +109,93 @@
4561 'Lines generated by the bid',
4562 readonly=True),
4563 }
4564+
4565+ def _prepare_lrs_update_from_po_line(self, cr, uid, vals,
4566+ po_line, context=None):
4567+ """ Take the vals dict from po line and return a vals dict for LRS
4568+
4569+ :param dict vals: value of to be written in new po line
4570+ :param browse_record po_line: purchase.order.line
4571+ :returns dict : vals to be written on logistic.requisition.source
4572+
4573+ """
4574+ lrs_vals = {}
4575+ if vals.get('product_qty'):
4576+ lrs_vals['proposed_qty'] = vals.get('product_qty')
4577+ if vals.get('product_id'):
4578+ lrs_vals['proposed_product_id'] = vals.get('product_id')
4579+ if vals.get('product_uom'):
4580+ lrs_vals['proposed_uom_id'] = vals.get('product_uom')
4581+ if vals.get('price_unit'):
4582+ currency_obj = self.pool['res.currency']
4583+ to_curr = po_line.lr_source_line_id.requisition_id.currency_id.id
4584+ from_curr = po_line.order_id.pricelist_id.currency_id.id
4585+ price = currency_obj.compute(cr, uid, from_curr, to_curr,
4586+ vals.get('price_unit'), False)
4587+ lrs_vals['unit_cost'] = price
4588+ if vals.get('date_planned'):
4589+ if po_line.lr_source_line_id.transport_applicable:
4590+ if pr_bid_line.order_id.transport == 'included':
4591+ lrs_vals['date_etd'] = False
4592+ lrs_vals['date_eta'] = vals.get('date_planned')
4593+
4594+ else:
4595+ lrs_vals['date_etd'] = vals.get('date_planned')
4596+ lrs_vals['date_eta'] = False
4597+ else:
4598+ lrs_vals['date_etd'] = vals.get('date_planned')
4599+ lrs_vals['date_eta'] = vals.get('date_planned')
4600+ return lrs_vals
4601+
4602+ def write(self, cr, uid, ids, vals, context=None):
4603+ """ Here we implement something to allow the update of LRS when some
4604+ information are changed in PO line. It should be possible to do it when :
4605+ PO is still in draft
4606+ LRL is not marked as sourced
4607+ Once done, nobody should be able to change the PO line infos
4608+ """
4609+ if context is None:
4610+ context = {}
4611+ if not ids:
4612+ return True
4613+ #We have to enforce list as it is called by function_inv
4614+ if not isinstance(ids, list):
4615+ ids = [ids]
4616+ if (vals.get('product_qty') or vals.get('product_id')
4617+ or vals.get('product_uom')
4618+ or vals.get('price_unit')
4619+ or vals.get('date_planned')):
4620+ lrs_obj = self.pool.get('logistic.requisition.source')
4621+ for line in self.browse(cr, uid, ids, context=context):
4622+ if line.lr_source_line_id:
4623+ if (line.lr_source_line_id.requisition_line_id in
4624+ ('sourced', 'quoted')):
4625+ raise osv.except_osv(
4626+ _('UserError'),
4627+ _(
4628+ "You cannot change the informations because this PO line "
4629+ "is already linked to a Logistic Requsition Line %s marked "
4630+ "as sourced or quoted." % (line.lr_source_line_id.name)
4631+ )
4632+ )
4633+ else:
4634+ lrs_vals = self._prepare_lrs_update_from_po_line(cr,
4635+ uid, vals, line, context=context)
4636+ lrs_obj.write(cr, uid, [line.lr_source_line_id.id],
4637+ lrs_vals, context=context)
4638+ return super(purchase_order_line, self).write(cr, uid, ids, vals,
4639+ context=context)
4640+ def unlink(self, cr, uid, ids, context=None):
4641+ for line in self.browse(cr, uid, ids, context=context):
4642+ if line.lr_source_line_id:
4643+ if (line.lr_source_line_id.requisition_line_id in
4644+ ('sourced', 'quoted')):
4645+ raise osv.except_osv(
4646+ _('UserError'),
4647+ _(
4648+ "You cannot delete this PO line because it is "
4649+ "already linked to a Logistic Requsition Line %s marked "
4650+ "as sourced or quoted." % (line.lr_source_line_id.name)
4651+ )
4652+ )
4653+ return super(purchase_order_line, self).unlink(cr, uid, ids, context=context)
4654
4655=== modified file 'logistic_requisition/model/purchase_requisition.py'
4656--- logistic_requisition/model/purchase_requisition.py 2013-11-01 09:05:44 +0000
4657+++ logistic_requisition/model/purchase_requisition.py 2014-05-07 09:53:02 +0000
4658@@ -31,6 +31,7 @@
4659 For each selected bid line, we ensure there is a corresponding source
4660 (one2one relation) and we update the source data with the bid line data.
4661 """
4662+ currency_obj = self.pool['res.currency']
4663 if isinstance(id, (tuple, list)):
4664 assert len(id) == 1, (
4665 "_split_requisition_source_lines() accepts only 1 ID, "
4666@@ -43,16 +44,24 @@
4667 # this call for bid line has been added manually
4668 continue
4669 source = pr_line.logistic_requisition_source_ids[0]
4670+ has_requisition = source.requisition_id
4671+ if not has_requisition:
4672+ continue
4673+ to_curr = source.requisition_id.currency_id.id
4674 set_sources = set()
4675 # Look for po lines of this purchase_requisition line
4676 for pr_bid_line in pr_line.purchase_line_ids:
4677+ # Compute from bid currency to LRS currency
4678+ from_curr = pr_bid_line.order_id.pricelist_id.currency_id.id
4679+ price = currency_obj.compute(cr, uid, from_curr, to_curr,
4680+ pr_bid_line.price_unit, False)
4681 vals = {
4682 'price_is': 'fixed',
4683 'proposed_qty': pr_bid_line.quantity_bid,
4684 'proposed_product_id': pr_bid_line.product_id.id,
4685 'proposed_uom_id': pr_bid_line.product_uom.id,
4686 'selected_bid_line_id': pr_bid_line.id,
4687- 'unit_cost': pr_bid_line.price_unit,
4688+ 'unit_cost': price,
4689 #FIXME: we need to take care of the scheduled date
4690 # set eta or etd depending if transport is included
4691 }
4692@@ -119,19 +128,6 @@
4693 vals['from_bid_line_id'] = line.id
4694 return vals
4695
4696- #FIXME: we should not do that, the location must be known from the beginning of the RFQ-Bid process
4697- #def _prepare_purchase_order(self, cr, uid, requisition, supplier, context=None):
4698- # vals = super(purchase_requisition, self)._prepare_purchase_order(
4699- # cr, uid, requisition, supplier, context=context)
4700- # if requisition.logistic_requisition_source_ids:
4701- # # comes from a logistic.requisition -> generate direct
4702- # # delivery purchases, so we put the location customer
4703- # # of the first consignee_id (same consignee on all lines)
4704- # source = requisition.logistic_requisition_source_ids[0]
4705- # req = source.requisition_id
4706- # vals['location_id'] = req.consignee_id.property_stock_customer.id
4707- # return vals
4708-
4709
4710 class purchase_requisition_line(orm.Model):
4711 _inherit = 'purchase.requisition.line'
4712
4713=== modified file 'logistic_requisition/report/logistic_requisition.mako'
4714--- logistic_requisition/report/logistic_requisition.mako 2013-08-14 14:26:08 +0000
4715+++ logistic_requisition/report/logistic_requisition.mako 2014-05-07 09:53:02 +0000
4716@@ -197,29 +197,6 @@
4717 <td>&nbsp;</td>
4718 </tr>
4719 </table>
4720- <p><b>${_("Budget")}</b></p>
4721- <p>${_("Budget limit:")} ${formatLang(requisition.allowed_budget)}</p>
4722- <table class="basic_table" width="100%">
4723- <tr>
4724- <td style="font-weight:bold;width:40%">${_("Budget/financial holder")}</td>
4725- <td style="font-weight:bold;width:30%">${_("Validation date")}</td>
4726- <td style="font-weight:bold;">${_("Signature")}</td>
4727- </tr>
4728- %if requisition.budget_holder_id:
4729- <tr>
4730- <td>${requisition.budget_holder_id.name}</td>
4731- <td>${requisition.date_budget_holder if requisition.date_budget_holder else 'N/A'}</td>
4732- <td>&nbsp;</td>
4733- </tr>
4734- %endif
4735- %if requisition.finance_officer_id:
4736- <tr>
4737- <td>${requisition.finance_officer_id.name}</td>
4738- <td>${requisition.date_finance_officer if requisition.date_finance_officer else 'N/A'}</td>
4739- <td>&nbsp;</td>
4740- </tr>
4741- %endif
4742- </table>
4743 <p style="page-break-after: always"/>
4744 %endfor
4745 </body>
4746
4747=== modified file 'logistic_requisition/security/ir.model.access.csv'
4748--- logistic_requisition/security/ir.model.access.csv 2013-08-06 14:04:56 +0000
4749+++ logistic_requisition/security/ir.model.access.csv 2014-05-07 09:53:02 +0000
4750@@ -3,3 +3,5 @@
4751 access_logistic_requisition_line_purchase_user,logistic.requisition.line,model_logistic_requisition_line,purchase.group_purchase_user,1,1,1,1
4752 access_logreq_cancel_reason_user,access_logistic_requisition_cancel_reason user,model_logistic_requisition_cancel_reason,purchase.group_purchase_user,1,0,0,0
4753 access_logreq_cancel_reason_manager,access_logistic_requisition_cancel_reason manager,model_logistic_requisition_cancel_reason,purchase.group_purchase_manager,1,1,1,1
4754+access_log_cost_create_user,logistic.requisition.cost.estimate,model_logistic_requisition_cost_estimate,base.group_sale_salesman,1,1,1,1
4755+access_log_cost_create_manager,logistic.requisition.cost.estimate,model_logistic_requisition_cost_estimate,base.group_sale_manager,1,1,1,1
4756
4757=== modified file 'logistic_requisition/test/line_assigned.yml'
4758--- logistic_requisition/test/line_assigned.yml 2013-08-26 18:20:48 +0000
4759+++ logistic_requisition/test/line_assigned.yml 2014-05-07 09:53:02 +0000
4760@@ -6,6 +6,7 @@
4761 consignee_id: base.res_partner_3
4762 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4763 user_id: base.user_demo
4764+ pricelist_id: product.list0
4765 -
4766 And I add a line with an assignee
4767 -
4768@@ -14,7 +15,6 @@
4769 product_id: product.product_product_7
4770 requested_qty: 100
4771 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4772- budget_tot_price: 1000
4773 logistic_user_id: base.user_demo
4774 -
4775 And I add a line without assignee
4776@@ -24,7 +24,6 @@
4777 product_id: product.product_product_8
4778 requested_qty: 100
4779 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4780- budget_tot_price: 1000
4781 -
4782 When I confirm the logistic requisition
4783 -
4784
4785=== modified file 'logistic_requisition/test/logistic_requisition_report_test.yml'
4786--- logistic_requisition/test/logistic_requisition_report_test.yml 2013-08-27 14:33:41 +0000
4787+++ logistic_requisition/test/logistic_requisition_report_test.yml 2014-05-07 09:53:02 +0000
4788@@ -8,11 +8,11 @@
4789 consignee_id: base.res_partner_3
4790 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4791 user_id: base.user_demo
4792+ pricelist_id: product.list0
4793 line_ids:
4794 - product_id: product.product_product_7
4795 requested_qty: 100
4796 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4797- budget_tot_price: 1000
4798 logistic_user_id: base.user_demo
4799 account_code: 'Shazam!'
4800 -
4801
4802=== modified file 'logistic_requisition/test/requisition_cancel_reason.yml'
4803--- logistic_requisition/test/requisition_cancel_reason.yml 2013-08-06 14:04:56 +0000
4804+++ logistic_requisition/test/requisition_cancel_reason.yml 2014-05-07 09:53:02 +0000
4805@@ -12,6 +12,7 @@
4806 consignee_id: base.res_partner_3
4807 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4808 user_id: base.user_demo
4809+ pricelist_id: product.list0
4810 -
4811 When I cancel it with the wizard asking for the reason
4812 -
4813
4814=== modified file 'logistic_requisition/test/requisition_create_cost_estimate.yml'
4815--- logistic_requisition/test/requisition_create_cost_estimate.yml 2013-11-01 11:17:26 +0000
4816+++ logistic_requisition/test/requisition_create_cost_estimate.yml 2014-05-07 09:53:02 +0000
4817@@ -9,6 +9,7 @@
4818 incoterm_id: stock.incoterm_FCA
4819 incoterm_address: incoterm address as text
4820 analytic_id: account.analytic_consultancy
4821+ pricelist_id: product.list0
4822 -
4823 And I add a line 1
4824 -
4825@@ -18,7 +19,6 @@
4826 requested_qty: 100
4827 requested_uom_id: product.product_uom_unit
4828 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4829- budget_tot_price: 1000
4830 logistic_user_id: base.user_demo
4831 -
4832 And I add a source line to the line 1
4833@@ -42,7 +42,6 @@
4834 requested_qty: 100
4835 requested_uom_id: product.product_uom_unit
4836 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4837- budget_tot_price: 1000
4838 logistic_user_id: base.user_demo
4839 -
4840 And I add a source line to the line 2
4841@@ -88,8 +87,6 @@
4842 try:
4843 self.cost_estimate(cr, uid, wizard_id)
4844 except orm.except_orm as err:
4845- assert 'NO_BUDGET_VALID' in err.error_codes, (
4846- 'Expected an error because the budget holder is missing')
4847 assert 'NO_ACCOUNT_CODE' in err.error_codes, (
4848 'Expected an error because the account code is missing')
4849 else:
4850@@ -97,9 +94,6 @@
4851 -
4852 I set some data to fulfill the business rules
4853 -
4854- !record {model: logistic.requisition, id: logistic_requisition_cost_estimate_01}:
4855- budget_holder_id: base.user_demo
4856--
4857 !record {model: logistic.requisition.line, id: logistic_requisition_line_cost_estimate_01}:
4858 account_code: 'XXXX'
4859 -
4860
4861=== modified file 'logistic_requisition/test/transport_plan.yml'
4862--- logistic_requisition/test/transport_plan.yml 2013-11-01 11:17:26 +0000
4863+++ logistic_requisition/test/transport_plan.yml 2014-05-07 09:53:02 +0000
4864@@ -23,6 +23,7 @@
4865 consignee_id: base.res_partner_3
4866 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4867 user_id: base.user_demo
4868+ pricelist_id: product.list0
4869 -
4870 And I add a line 1
4871 -
4872@@ -31,7 +32,6 @@
4873 product_id: product.product_product_7
4874 requested_qty: 100
4875 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4876- budget_tot_price: 1000
4877 logistic_user_id: base.user_demo
4878 -
4879 And I add a source line 1
4880@@ -52,7 +52,6 @@
4881 product_id: product.product_product_8
4882 requested_qty: 100
4883 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4884- budget_tot_price: 1000
4885 logistic_user_id: base.user_demo
4886 -
4887 And I add a source line 2
4888@@ -93,6 +92,7 @@
4889 consignee_id: base.res_partner_3
4890 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4891 user_id: base.user_demo
4892+ pricelist_id: product.list0
4893 -
4894 With a line
4895 -
4896@@ -101,7 +101,6 @@
4897 product_id: product.product_product_7
4898 requested_qty: 100
4899 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4900- budget_tot_price: 1000
4901 logistic_user_id: base.user_demo
4902 -
4903 And I add a source line
4904
4905=== modified file 'logistic_requisition/test/transport_plan_from_lr_line_wizard.yml'
4906--- logistic_requisition/test/transport_plan_from_lr_line_wizard.yml 2013-11-01 11:17:26 +0000
4907+++ logistic_requisition/test/transport_plan_from_lr_line_wizard.yml 2014-05-07 09:53:02 +0000
4908@@ -7,6 +7,7 @@
4909 consignee_id: base.res_partner_3
4910 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4911 user_id: base.user_demo
4912+ pricelist_id: product.list0
4913 -
4914 And I add a first line with an assignee
4915 -
4916@@ -15,7 +16,6 @@
4917 product_id: product.product_product_7
4918 requested_qty: 100
4919 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4920- budget_tot_price: 1000
4921 logistic_user_id: base.user_demo
4922 -
4923 And I add a first source line
4924@@ -34,7 +34,6 @@
4925 product_id: product.product_product_8
4926 requested_qty: 100
4927 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4928- budget_tot_price: 1000
4929 logistic_user_id: base.user_demo
4930 -
4931 And I add a second source line
4932
4933=== modified file 'logistic_requisition/test/transport_plan_to_cost_estimate.yml'
4934--- logistic_requisition/test/transport_plan_to_cost_estimate.yml 2013-11-01 11:17:26 +0000
4935+++ logistic_requisition/test/transport_plan_to_cost_estimate.yml 2014-05-07 09:53:02 +0000
4936@@ -27,8 +27,7 @@
4937 consignee_id: base.res_partner_3
4938 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4939 user_id: base.user_demo
4940- budget_holder_id: base.user_demo
4941- finance_officer_id: base.user_demo
4942+ pricelist_id: product.list0
4943 -
4944 And I add a line 1
4945 -
4946@@ -37,7 +36,6 @@
4947 product_id: product.product_product_7
4948 requested_qty: 100
4949 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4950- budget_tot_price: 1000
4951 logistic_user_id: base.user_demo
4952 account_code: 'XXXX'
4953 -
4954@@ -60,7 +58,6 @@
4955 product_id: product.product_product_8
4956 requested_qty: 100
4957 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4958- budget_tot_price: 1000
4959 logistic_user_id: base.user_demo
4960 account_code: 'YYYY'
4961 -
4962@@ -83,7 +80,6 @@
4963 product_id: product.product_product_8
4964 requested_qty: 100
4965 date_delivery: !eval "time.strftime('%Y-%m-%d')"
4966- budget_tot_price: 1000
4967 logistic_user_id: base.user_demo
4968 account_code: 'ZZZZ'
4969 -
4970
4971=== modified file 'logistic_requisition/tests/__init__.py'
4972--- logistic_requisition/tests/__init__.py 2013-08-27 14:13:33 +0000
4973+++ logistic_requisition/tests/__init__.py 2014-05-07 09:53:02 +0000
4974@@ -22,6 +22,7 @@
4975 from . import test_sale_order_from_lr_confirm
4976 from . import test_mto_workflow
4977 from . import transport_plan_date
4978+from . import test_mutlicurrency_update_po_line
4979
4980
4981 fast_suite = [
4982@@ -32,4 +33,5 @@
4983 test_sale_order_from_lr_confirm,
4984 test_mto_workflow,
4985 transport_plan_date,
4986+ test_mutlicurrency_update_po_line,
4987 ]
4988
4989=== modified file 'logistic_requisition/tests/logistic_requisition.py'
4990--- logistic_requisition/tests/logistic_requisition.py 2013-11-01 11:17:26 +0000
4991+++ logistic_requisition/tests/logistic_requisition.py 2014-05-07 09:53:02 +0000
4992@@ -43,20 +43,6 @@
4993 log_req_obj.onchange_consignee_id(
4994 cr, uid, [], vals.get('consignee_id'))['value']
4995 )
4996- vals.update(
4997- log_req_obj.onchange_validate(
4998- cr, uid, [],
4999- vals.get('budget_holder_id'),
5000- False,
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches