Merge lp:~unifield-team/unifield-server/grouped_pi_v7_jfb into lp:~unifield-team/unifield-server/grouped_pi_v7
- grouped_pi_v7_jfb
- Merge into grouped_pi_v7
Proposed by
jftempo
Status: | Needs review |
---|---|
Proposed branch: | lp:~unifield-team/unifield-server/grouped_pi_v7_jfb |
Merge into: | lp:~unifield-team/unifield-server/grouped_pi_v7 |
Diff against target: |
501 lines (+125/-140) 5 files modified
bin/addons/msf_profile/i18n/fr_MF.po (+9/-7) bin/addons/stock/physical_inventory.py (+49/-43) bin/addons/stock/wizard/physical_inventory_generate_counting_sheet.py (+61/-90) bin/osv/orm.py (+4/-0) bin/tools/translate.py (+2/-0) |
To merge this branch: | bzr merge lp:~unifield-team/unifield-server/grouped_pi_v7_jfb |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Dev Team | Pending | ||
Review via email: mp+337846@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/addons/msf_profile/i18n/fr_MF.po' |
2 | --- bin/addons/msf_profile/i18n/fr_MF.po 2018-02-15 17:15:17 +0000 |
3 | +++ bin/addons/msf_profile/i18n/fr_MF.po 2018-02-19 10:31:32 +0000 |
4 | @@ -73157,8 +73157,8 @@ |
5 | #. module: stock |
6 | #: code:addons/stock/physical_inventory.py:759 |
7 | #, python-format |
8 | -msgid "Duplicate line (same product, batch number and expiry date)" |
9 | -msgstr "Ligne dupliquée (même produit, numéro de lot et date d'expiration)" |
10 | +msgid "Product %s, Duplicate line (same product, batch number and expiry date)" |
11 | +msgstr "Produit %s, Ligne dupliquée (même produit, numéro de lot et date d'expiration)" |
12 | |
13 | #. module: msf_budget |
14 | #: field:wizard.local.expenses,start_period_id:0 |
15 | @@ -85702,7 +85702,7 @@ |
16 | #. module: stock |
17 | #: view:physical.inventory.import.wizard:0 |
18 | msgid "Count all as 0" |
19 | -msgstr "Les calculer tous comme à 0" |
20 | +msgstr "Compter les lignes comme étant à 0" |
21 | |
22 | #. module: base |
23 | #: help:res.config.users,menu_tips:0 |
24 | @@ -100851,7 +100851,7 @@ |
25 | #: view:physical.inventory:0 |
26 | #: field:physical.inventory.counting,is_ed:0 |
27 | msgid "ED" |
28 | -msgstr "DE" |
29 | +msgstr "EXP" |
30 | |
31 | #. modules: purchase, purchase_followup |
32 | #: field:purchase.order,partner_ref:0 |
33 | @@ -106718,7 +106718,7 @@ |
34 | #. module: stock |
35 | #: field:physical.inventory.generate.counting.sheet,only_with_stock_level:0 |
36 | msgid "Only count lines with stock different than 0" |
37 | -msgstr "Commpter uniquement les produits avec un niveau de stock différent de 0." |
38 | +msgstr "Compter uniquement les produits avec un niveau de stock différent de 0." |
39 | |
40 | #. module: stock |
41 | #: code:addons/stock/physical_inventory.py:784 |
42 | @@ -106762,5 +106762,7 @@ |
43 | msgid "You cannot confirm an inventory which is %s" |
44 | msgstr "Vous ne pouvez pas confirmé un inventaire qui est %s" |
45 | |
46 | - |
47 | - |
48 | +#. module: stock |
49 | +#: view:physical.inventory:0 |
50 | +msgid "[('Hide ignored', ('ignored', '!=', True)), ('Show all', ''), ('Show ignored only', ('ignored', '=', True))]" |
51 | +msgstr "[('Cacher lignes ignorées', ('ignored', '!=', True)), ('Tout afficher', ''), ('Afficher ignorées seulement', ('ignored', '=', True))]" |
52 | |
53 | === modified file 'bin/addons/stock/physical_inventory.py' |
54 | --- bin/addons/stock/physical_inventory.py 2018-02-15 17:16:59 +0000 |
55 | +++ bin/addons/stock/physical_inventory.py 2018-02-19 10:31:32 +0000 |
56 | @@ -32,6 +32,13 @@ |
57 | _name = 'physical.inventory' |
58 | _description = 'Physical Inventory' |
59 | |
60 | + def write(self, cr, uid, ids, vals, context=None): |
61 | + if context is None: |
62 | + context = {} |
63 | + if context.get('button') in ('import_xls_discrepancy_report', 'import_counting_sheet') and '__last_update' in context: |
64 | + del context['__last_update'] |
65 | + return super(PhysicalInventory, self).write(cr, uid, ids, vals, context) |
66 | + |
67 | def _inventory_totals(self, cr, uid, ids, field_names, arg, context=None): |
68 | context = context is None and {} or context |
69 | def read_many(model, ids, columns): |
70 | @@ -236,12 +243,6 @@ |
71 | Choose to include batch numbers / expiry date or not |
72 | """ |
73 | context = context is None and {} or context |
74 | - def read_single(model, id_, column): |
75 | - return self.pool.get(model).read(cr, uid, [id_], [column], context=context)[0][column] |
76 | - def create(model, vals): |
77 | - return self.pool.get(model).create(cr, uid, vals, context=context) |
78 | - def view(module, view): |
79 | - return self.pool.get('ir.model.data').get_object_reference(cr, uid, module, view)[1] |
80 | |
81 | # Prepare values to feed the wizard with |
82 | assert len(ids) == 1 |
83 | @@ -249,12 +250,11 @@ |
84 | |
85 | # Create the wizard |
86 | wiz_model = 'physical.inventory.generate.counting.sheet' |
87 | - wiz_values = {"inventory_id": inventory_id} |
88 | - wiz_id = create(wiz_model, wiz_values) |
89 | + wiz_id = self.pool.get(wiz_model).create(cr, uid, {'inventory_id': inventory_id}, context=context) |
90 | context['wizard_id'] = wiz_id |
91 | |
92 | # Get the view reference |
93 | - view_id = view('stock', 'physical_inventory_generate_counting_sheet') |
94 | + view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'physical_inventory_generate_counting_sheet')[1] |
95 | |
96 | # Return a description of the wizard view |
97 | return {'type': 'ir.actions.act_window', |
98 | @@ -319,6 +319,7 @@ |
99 | # Create a similar dictionnary for counted quantities |
100 | counting_lines_per_product_batch_expirtydate = {} |
101 | counted_quantities = {} |
102 | + max_line_no = 0 |
103 | for line in counting_lines: |
104 | |
105 | product_batch_expirydate = (line["product_id"][0], |
106 | @@ -332,6 +333,8 @@ |
107 | "line_id": line["id"], |
108 | "line_no": line["line_no"] |
109 | } |
110 | + if line["line_no"] > max_line_no: |
111 | + max_line_no = line["line_no"] |
112 | |
113 | # Create a similar dictionnary for existing discrepancies |
114 | previous_discrepancy_line_ids = inventory["discrepancy_line_ids"] |
115 | @@ -361,11 +364,15 @@ |
116 | all_product_batch_expirydate = set().union(theoretical_quantities, |
117 | counted_quantities) |
118 | |
119 | + bn_ed_prod_ids = [x[0] for x in all_product_batch_expirydate if x[1] or x[2]] |
120 | + prod_info = {} |
121 | + for prod in self.pool.get('product.product').read(cr, uid, bn_ed_prod_ids, ['batch_management', 'perishable'], context=context): |
122 | + prod_info[prod['id']] = prod |
123 | + |
124 | # filter the case we had an entry with BN when product is not (anymore) BN mandatory: |
125 | filtered_all_product_batch_expirydate = set() |
126 | for prod_id, batch_n, exp_date in all_product_batch_expirydate: |
127 | - prod_data = self.pool.get('product.product').read(cr, uid, prod_id, ['batch_management', 'perishable']) |
128 | - if batch_n and exp_date and not prod_data['batch_management'] and not prod_data['perishable']: |
129 | + if batch_n and not prod_info[prod_id]['batch_management'] or exp_date and not prod_info[prod_id]['perishable']: |
130 | continue |
131 | else: |
132 | filtered_all_product_batch_expirydate.add((prod_id, batch_n, exp_date)) |
133 | @@ -375,7 +382,6 @@ |
134 | update_discrepancies = {} |
135 | counting_lines_with_no_discrepancy = [] |
136 | |
137 | - new_product_line_no = 0 |
138 | # For each of them, compare the theoretical and counted qty |
139 | for product_batch_expirydate in filtered_all_product_batch_expirydate: |
140 | # If the key is not known, assume 0 |
141 | @@ -384,7 +390,7 @@ |
142 | |
143 | # If no discrepancy, nothing to do |
144 | # (Use a continue to save 1 indentation level..) |
145 | - if counted_qty == theoretical_qty: |
146 | + if counted_qty == theoretical_qty or theoretical_qty == 0 and counted_qty == -1: |
147 | if product_batch_expirydate in counting_lines_per_product_batch_expirtydate: |
148 | counting_line_id = counting_lines_per_product_batch_expirtydate[product_batch_expirydate]["line_id"] |
149 | counting_lines_with_no_discrepancy.append(counting_line_id) |
150 | @@ -395,14 +401,8 @@ |
151 | this_product_batch_expirydate = counting_lines_per_product_batch_expirtydate[product_batch_expirydate] |
152 | line_no = this_product_batch_expirydate["line_no"] |
153 | else: # Otherwise, create additional line numbers starting from the total of existing lines |
154 | - new_product_line_no += 1 |
155 | - if len(counting_lines_per_product_batch_expirtydate) > 0: |
156 | - # get highest line_no |
157 | - line_no = counting_lines_per_product_batch_expirtydate[ |
158 | - sorted(counting_lines_per_product_batch_expirtydate)[-1] |
159 | - ]['line_no'] + new_product_line_no |
160 | - else: |
161 | - line_no = new_product_line_no |
162 | + max_line_no += 1 |
163 | + line_no = max_line_no |
164 | |
165 | if product_batch_expirydate in previous_discrepancies: |
166 | previous_discrepancies[product_batch_expirydate]["todelete"] = False |
167 | @@ -754,19 +754,22 @@ |
168 | |
169 | # Check quantity |
170 | quantity = row.cells[4].data |
171 | - # if quantity is integer then convert to string otherwise it will not be imported: |
172 | - if isinstance(quantity, int) and quantity == 0: |
173 | - quantity = '0' |
174 | - try: |
175 | - quantity = counting_obj.quantity_validate(cr, quantity) |
176 | - except NegativeValueError: |
177 | - add_error(_('Quantity %s is negative') % quantity, row_index, 4) |
178 | - quantity = 0.0 |
179 | - except ValueError: |
180 | - quantity = 0.0 |
181 | - add_error(_('Quantity %s is not valid') % quantity, row_index, 4) |
182 | + if quantity is not None: |
183 | + if isinstance(quantity, int) and quantity == 0: |
184 | + quantity = '0' |
185 | + try: |
186 | + quantity = counting_obj.quantity_validate(cr, quantity) |
187 | + except NegativeValueError: |
188 | + add_error(_('Quantity %s is negative') % quantity, row_index, 4) |
189 | + quantity = 0.0 |
190 | + except ValueError: |
191 | + quantity = 0.0 |
192 | + add_error(_('Quantity %s is not valid') % quantity, row_index, 4) |
193 | |
194 | - product_info = product_obj.read(cr, uid, product_id, ['batch_management', 'perishable', 'default_code', 'uom_id']) |
195 | + if product_id: |
196 | + product_info = product_obj.read(cr, uid, product_id, ['batch_management', 'perishable', 'default_code', 'uom_id']) |
197 | + else: |
198 | + product_info = {'batch_management': False, 'perishable': False, 'default_code': product_code, 'uom_id': False} |
199 | |
200 | if product_info['uom_id'] and product_uom_id and product_info['uom_id'][0] != product_uom_id: |
201 | add_error(_("""Product %s, UoM %s does not conform to that of product in stock""") % (product_info['default_code'], product_uom), row_index, 3) |
202 | @@ -774,7 +777,7 @@ |
203 | |
204 | # Check batch number |
205 | batch_name = row.cells[5].data |
206 | - if not batch_name and product_info['batch_management'] and float(quantity or 0) > 0: |
207 | + if not batch_name and product_info['batch_management'] and quantity is not None: |
208 | add_error(_('Batch number is required'), row_index, 5) |
209 | |
210 | if batch_name and not product_info['batch_management']: |
211 | @@ -797,14 +800,14 @@ |
212 | raise ValueError() |
213 | except ValueError: |
214 | add_error(_("""Expiry date %s is not valid""") % expiry_date, row_index, 6) |
215 | - if not expiry_date and product_info['perishable'] and float(quantity or 0) > 0: |
216 | + if not expiry_date and product_info['perishable'] and quantity is not None: |
217 | add_error(_('Expiry date is required'), row_index, 6) |
218 | |
219 | # Check duplicate line (Same product_id, batch_number, expirty_date) |
220 | item = '%d-%s-%s' % (product_id or -1, batch_name or '', expiry_date or '') |
221 | - if item in line_items and (batch_name or expiry_date): |
222 | - add_error(_("""Duplicate line (same product, batch number and expiry date)"""), row_index) |
223 | - else: |
224 | + if item in line_items: |
225 | + add_error(_("""Product %s, Duplicate line (same product, batch number and expiry date)""") % product_info['default_code'], row_index) |
226 | + elif quantity is not None: |
227 | line_items.append(item) |
228 | |
229 | data = { |
230 | @@ -812,10 +815,12 @@ |
231 | 'product_id': product_id, |
232 | 'batch_number': batch_name, |
233 | 'expiry_date': expiry_date, |
234 | - 'quantity': quantity, |
235 | + 'quantity': False, |
236 | 'product_uom_id': product_uom_id, |
237 | } |
238 | |
239 | + if quantity is not None: |
240 | + data['quantity'] = quantity |
241 | # Check if line exist |
242 | if line_no: |
243 | line_ids = counting_obj.search(cr, uid, [('inventory_id', '=', inventory_rec.id), ('line_no', '=', line_no)]) |
244 | @@ -829,7 +834,7 @@ |
245 | |
246 | if len(line_ids) > 0: |
247 | counting_sheet_lines.append((1, line_ids[0], data)) |
248 | - else: |
249 | + elif quantity is not None: |
250 | counting_sheet_lines.append((0, 0, data)) |
251 | |
252 | # endfor |
253 | @@ -838,7 +843,8 @@ |
254 | wizard_obj = self.pool.get('physical.inventory.import.wizard') |
255 | if counting_sheet_errors: |
256 | # Errors found, open message box for exlain |
257 | - self.write(cr, uid, ids, {'file_to_import': False}, context=context) |
258 | + #self.write(cr, uid, ids, {'file_to_import': False}, context=context) |
259 | + cr.execute('update physical_inventory set file_to_import=NULL where id=%s', (ids[0], )) |
260 | if counting_sheet_warnings: |
261 | counting_sheet_errors.append("\n%s" % _("Warning")) |
262 | counting_sheet_errors += counting_sheet_warnings |
263 | @@ -922,7 +928,8 @@ |
264 | wizard_obj = self.pool.get('physical.inventory.import.wizard') |
265 | if discrepancy_report_errors: |
266 | # Errors found, open message box for exlain |
267 | - self.write(cr, uid, ids, {'file_to_import2': False}, context=context) |
268 | + #self.write(cr, uid, ids, {'file_to_import2': False}, context=context) |
269 | + cr.execute('update physical_inventory set file_to_import2=NULL where id=%s', (ids[0], )) |
270 | result = wizard_obj.message_box(cr, uid, title=_('Importation errors'), |
271 | message='\n'.join(discrepancy_report_errors)) |
272 | else: |
273 | @@ -1170,7 +1177,6 @@ |
274 | self.infolog(cr, uid, _("The Physical inventory id:%s (%s) has been cancelled") % (inv.id, inv.name)) |
275 | return {} |
276 | |
277 | - |
278 | PhysicalInventory() |
279 | |
280 | |
281 | |
282 | === modified file 'bin/addons/stock/wizard/physical_inventory_generate_counting_sheet.py' |
283 | --- bin/addons/stock/wizard/physical_inventory_generate_counting_sheet.py 2018-02-15 17:06:51 +0000 |
284 | +++ bin/addons/stock/wizard/physical_inventory_generate_counting_sheet.py 2018-02-19 10:31:32 +0000 |
285 | @@ -59,46 +59,51 @@ |
286 | location_id = inventory["location_id"][0] |
287 | product_ids = inventory["product_ids"] |
288 | |
289 | - bn_and_eds = self.get_BN_and_ED_for_products_at_location(cr, uid, location_id, product_ids, only_with_stock_level, context=context) |
290 | + bn_and_eds = self.get_BN_and_ED_for_products_at_location(cr, uid, location_id, product_ids, context=context) |
291 | |
292 | # Prepare the inventory lines to be created |
293 | |
294 | inventory_counting_lines_to_create = [] |
295 | - current_prodlot_id = False |
296 | - for product in self.pool.get('product.product').browse(cr, uid, product_ids, context=context): |
297 | - bn_and_eds_for_this_product = bn_and_eds[product.id] |
298 | + for product_id in bn_and_eds.keys(): |
299 | + bn_and_eds_for_this_product = bn_and_eds[product_id] |
300 | # If no bn / ed related to this product, create a single inventory |
301 | # line |
302 | - if not product.batch_management and not product.perishable: |
303 | - if only_with_stock_level and not self.not_zero_stock_on_location(cr, uid, location_id, product.id, |
304 | - current_prodlot_id, context=context): |
305 | + if bn_and_eds[product_id] == (False, False, False): |
306 | + if only_with_stock_level and not self.not_zero_stock_on_location(cr, uid, location_id, product_id, False, context=context): |
307 | continue |
308 | else: |
309 | values = { |
310 | "line_no": len(inventory_counting_lines_to_create) + 1, |
311 | "inventory_id": inventory_id, |
312 | - "product_id": product.id, |
313 | - "batch_number": False, |
314 | - "expiry_date": False |
315 | - } |
316 | - inventory_counting_lines_to_create.append(values) |
317 | - # Otherwise, create an inventory line for this product ~and~ for |
318 | - # each BN/ED |
319 | + "product_id": product_id, |
320 | + "batch_number": False, |
321 | + "expiry_date": False |
322 | + } |
323 | + inventory_counting_lines_to_create.append(values) |
324 | + elif not bn_and_eds[product_id]: |
325 | + # BN/ED product with no stock move in this location |
326 | + if not only_with_stock_level: |
327 | + values = { |
328 | + "line_no": len(inventory_counting_lines_to_create) + 1, |
329 | + "inventory_id": inventory_id, |
330 | + "product_id": product_id, |
331 | + "batch_number": False, |
332 | + "expiry_date": False |
333 | + } |
334 | + inventory_counting_lines_to_create.append(values) |
335 | else: |
336 | + # Otherwise, create an inventory line for this product ~and~ for |
337 | + # each BN/ED |
338 | for bn_and_ed in bn_and_eds_for_this_product: |
339 | - current_prodlot = bn_and_ed[0] if prefill_bn else False |
340 | - current_prodlot_id = \ |
341 | - self.pool.get('stock.production.lot').search(cr, uid, [('name', '=', current_prodlot)], |
342 | - context=context)[0] if prefill_bn else False |
343 | - if only_with_stock_level and not self.not_zero_stock_on_location(cr, uid, location_id, product.id, |
344 | - current_prodlot_id, context=context): |
345 | + if only_with_stock_level and not self.not_zero_stock_on_location(cr, uid, location_id, product_id, |
346 | + bn_and_ed[2], context=context): |
347 | continue |
348 | else: |
349 | values = { |
350 | "line_no": len(inventory_counting_lines_to_create) + 1, |
351 | "inventory_id": inventory_id, |
352 | - "product_id": product.id, |
353 | - "batch_number": current_prodlot, |
354 | + "product_id": product_id, |
355 | + "batch_number": bn_and_ed[0] if prefill_bn else False, |
356 | "expiry_date": bn_and_ed[1] if prefill_ed else False |
357 | } |
358 | inventory_counting_lines_to_create.append(values) |
359 | @@ -125,80 +130,46 @@ |
360 | |
361 | return {'type': 'ir.actions.act_window_close'} |
362 | |
363 | - def get_BN_and_ED_for_products_at_location(self, cr, uid, location_id, product_ids, only_with_stock_level, context=None): |
364 | - context = context if context else {} |
365 | - def read_many(model, ids, columns): |
366 | - return self.pool.get(model).read(cr, uid, ids, columns, context=context) |
367 | - |
368 | - # Add location to the copied context |
369 | - ctx = context.copy() |
370 | - ctx['location'] = location_id |
371 | - ctx['compute_child'] = True |
372 | - |
373 | - # Get the moves at location, related to these products |
374 | - moves_at_location = self.get_moves_at_location(cr, uid, location_id, context=ctx) |
375 | - |
376 | - moves_at_location_for_products = [ m for m in moves_at_location |
377 | - if m["product_id"][0] in product_ids ] |
378 | - |
379 | - # Get the production lot associated to these moves |
380 | - moves_at_location_for_products = read_many("stock.move", |
381 | - moves_at_location_for_products, |
382 | - ["product_id", |
383 | - "prodlot_id", |
384 | - "expired_date"]) |
385 | - |
386 | - # Init a dict with an empty set for each products |
387 | - BN_and_ED = { product_id:set() for product_id in product_ids } |
388 | - |
389 | - for move in moves_at_location_for_products: |
390 | - |
391 | + def get_BN_and_ED_for_products_at_location(self, cr, uid, location_id, product_ids, context=None): |
392 | + if context is None: |
393 | + context = {} |
394 | + |
395 | + |
396 | + prod_info = {} |
397 | + move_obj = self.pool.get('stock.move') |
398 | + prod_obj = self.pool.get('product.product') |
399 | + |
400 | + BN_and_ED = {} |
401 | + for prod in prod_obj.read(cr, uid, product_ids, ['batch_management', 'perishable'], context=context): |
402 | + if not prod['batch_management'] and not prod['perishable']: |
403 | + BN_and_ED[prod['id']] = (False, False, False) |
404 | + else: |
405 | + prod_info[prod['id']] = prod |
406 | + BN_and_ED[prod['id']] = set() |
407 | + |
408 | + domain = ['&', '&', '|', |
409 | + ('location_id', 'in', [location_id]), |
410 | + ('location_dest_id', 'in', [location_id]), |
411 | + ('state', '=', 'done'), |
412 | + ('product_id', 'in', prod_info.keys()), |
413 | + ('prodlot_id', '!=', False) |
414 | + ] |
415 | + |
416 | + move_ids = move_obj.search(cr, uid, domain, context=context) |
417 | + |
418 | + for move in move_obj.read(cr, uid, move_ids, ['product_id', 'prodlot_id', 'expired_date']): |
419 | product_id = move["product_id"][0] |
420 | - product_qty = self.pool.get('product.product').browse(cr, uid, product_id, fields_to_fetch=['qty_available'], |
421 | - context=ctx).qty_available |
422 | - |
423 | - batch_number = move["prodlot_id"][1] if isinstance(move["prodlot_id"], tuple) else False |
424 | - expired_date = move["expired_date"] |
425 | - |
426 | - # Dirty hack to ignore/hide internal batch numbers ("MSFBN") |
427 | - if batch_number and batch_number.startswith("MSFBN"): |
428 | + |
429 | + |
430 | + if move['prodlot_id'] and move["prodlot_id"][1].startswith("MSFBN"): |
431 | batch_number = False |
432 | + else: |
433 | + batch_number = move["prodlot_id"][1] |
434 | |
435 | - if not only_with_stock_level or (only_with_stock_level and product_qty != 0): |
436 | - BN_and_ED[product_id].add((batch_number, expired_date)) |
437 | + BN_and_ED[product_id].add((batch_number, move["expired_date"], move["prodlot_id"][0])) |
438 | |
439 | return BN_and_ED |
440 | |
441 | - # FIXME : this is copy/pasta from the other wizard ... |
442 | - # Should be factorized, probably in physical inventory, or stock somewhere. |
443 | - def get_moves_at_location(self, cr, uid, location_id, context=None): |
444 | - context = context if context else {} |
445 | - |
446 | - def read_many(model, ids, columns): |
447 | - return self.pool.get(model).read(cr, uid, ids, columns, context=context) |
448 | - |
449 | - def search(model, domain): |
450 | - return self.pool.get(model).search(cr, uid, domain, context=context) |
451 | - |
452 | - assert isinstance(location_id, int) |
453 | - |
454 | - # Get all the moves for in/out of that location |
455 | - from_or_to_location = ['&', '|', |
456 | - ('location_id', 'in', [location_id]), |
457 | - ('location_dest_id', 'in', [location_id]), |
458 | - ('state', '=', 'done')] |
459 | - |
460 | - moves_at_location_ids = search("stock.move", from_or_to_location) |
461 | - moves_at_location = read_many("stock.move", |
462 | - moves_at_location_ids, |
463 | - ["product_id", |
464 | - "date", |
465 | - "product_qty", |
466 | - "location_id", |
467 | - "location_dest_id"]) |
468 | - |
469 | - return moves_at_location |
470 | - |
471 | def not_zero_stock_on_location(self, cr, uid, location_id, product_id, prodlot_id, context=False): |
472 | ''' |
473 | Check if the product's stock on the inventory's location is != 0 |
474 | |
475 | === modified file 'bin/osv/orm.py' |
476 | --- bin/osv/orm.py 2018-01-18 18:35:04 +0000 |
477 | +++ bin/osv/orm.py 2018-02-19 10:31:32 +0000 |
478 | @@ -1472,6 +1472,10 @@ |
479 | trans = translation_obj._get_source(cr, user, context['base_model_name'], 'view', context['lang'], node.get('string')) |
480 | if trans: |
481 | node.set('string', trans) |
482 | + if node.get('filter_selector'): |
483 | + trans = translation_obj._get_source(cr, user, self._name, 'view', context['lang'], node.get('filter_selector')) |
484 | + if trans: |
485 | + node.set('filter_selector', trans) |
486 | if node.tag == 'translate': |
487 | parent = node.getparent() |
488 | source = node.text |
489 | |
490 | === modified file 'bin/tools/translate.py' |
491 | --- bin/tools/translate.py 2017-02-16 10:55:56 +0000 |
492 | +++ bin/tools/translate.py 2018-02-19 10:31:32 +0000 |
493 | @@ -561,6 +561,8 @@ |
494 | res.append(de.get('confirm').encode("utf8")) |
495 | if de.get("help"): |
496 | res.append(de.get('help').encode("utf8")) |
497 | + if de.get("filter_selector"): |
498 | + res.append(de.get('filter_selector').encode("utf8")) |
499 | if de.tag == 'translate': |
500 | text_to_translate = '' |
501 | if de.text: |