Conditions | 27 |
Total Lines | 119 |
Lines | 0 |
Ratio | 0 % |
Changes | 2 | ||
Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like ajaxSampleAdd.ajax_submit() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | # -*- coding: utf-8 -*- |
||
254 | def ajax_submit(self): |
||
255 | """Submit & create the Samples |
||
256 | """ |
||
257 | |||
258 | # Get Sample required fields (including extended fields) |
||
259 | fields = self.get_obj_fields() |
||
260 | |||
261 | # extract records from request |
||
262 | records = self.get_records() |
||
263 | |||
264 | fielderrors = {} |
||
265 | errors = {"message": "", "fielderrors": {}} |
||
266 | |||
267 | attachments = {} |
||
268 | valid_records = [] |
||
269 | |||
270 | # Validate required fields |
||
271 | for n, record in enumerate(records): |
||
272 | |||
273 | # Process UID fields first and set their values to the linked field |
||
274 | uid_fields = filter(lambda f: f.endswith("_uid"), record) |
||
275 | for field in uid_fields: |
||
276 | name = field.replace("_uid", "") |
||
277 | value = record.get(field) |
||
278 | if "," in value: |
||
279 | value = value.split(",") |
||
280 | record[name] = value |
||
281 | |||
282 | # Extract file uploads (fields ending with _file) |
||
283 | # These files will be added later as attachments |
||
284 | file_fields = filter(lambda f: f.endswith("_file"), record) |
||
285 | attachments[n] = map(lambda f: record.pop(f), file_fields) |
||
286 | |||
287 | # Required fields and their values |
||
288 | required_keys = [field.getName() for field in fields if field.required] |
||
289 | required_values = [record.get(key) for key in required_keys] |
||
290 | required_fields = dict(zip(required_keys, required_values)) |
||
291 | |||
292 | # Client field is required but hidden in the sample Add form. We |
||
293 | # remove |
||
294 | # it therefore from the list of required fields to let empty |
||
295 | # columns pass the required check below. |
||
296 | if record.get("Client", False): |
||
297 | required_fields.pop('Client', None) |
||
298 | |||
299 | # None of the required fields are filled, skip this record |
||
300 | if not any(required_fields.values()): |
||
301 | continue |
||
302 | |||
303 | # Missing required fields |
||
304 | missing = [f for f in required_fields if not record.get(f, None)] |
||
305 | |||
306 | # If there are required fields missing, flag an error |
||
307 | for field in missing: |
||
308 | fieldname = "{}-{}".format(field, n) |
||
309 | msg = _("Field '{}' is required".format(field)) |
||
310 | fielderrors[fieldname] = msg |
||
311 | |||
312 | # Process valid record |
||
313 | valid_record = dict() |
||
314 | for fieldname, fieldvalue in record.iteritems(): |
||
315 | # clean empty |
||
316 | if fieldvalue in ['', None]: |
||
317 | continue |
||
318 | valid_record[fieldname] = fieldvalue |
||
319 | |||
320 | # append the valid record to the list of valid records |
||
321 | valid_records.append(valid_record) |
||
322 | |||
323 | # return immediately with an error response if some field checks failed |
||
324 | if fielderrors: |
||
325 | errors["fielderrors"] = fielderrors |
||
326 | return {'errors': errors} |
||
327 | |||
328 | # Process Form |
||
329 | samples = [] |
||
330 | for n, record in enumerate(valid_records): |
||
331 | client_uid = record.get("Client") |
||
332 | client = self.get_object_by_uid(client_uid) |
||
333 | |||
334 | if not client: |
||
335 | raise RuntimeError("No client found") |
||
336 | |||
337 | # Create the Sample |
||
338 | try: |
||
339 | sample = create_sample(client, self.request, record) |
||
340 | except (KeyError, RuntimeError) as e: |
||
341 | errors["message"] = e.message |
||
342 | return {"errors": errors} |
||
343 | samples.append(sample.Title()) |
||
344 | |||
345 | level = "info" |
||
346 | if len(samples) == 0: |
||
347 | message = _('No Sample could be created.') |
||
348 | level = "error" |
||
349 | elif len(samples) > 1: |
||
350 | message = _('Samples ${samples} were successfully created.', |
||
351 | mapping={'Samples': safe_unicode(', '.join(samples))}) |
||
352 | else: |
||
353 | message = _('Analysis request ${Sample} was successfully created.', |
||
354 | mapping={'Sample': safe_unicode(samples[0])}) |
||
355 | |||
356 | # Display a portal message |
||
357 | self.context.plone_utils.addPortalMessage(message, level) |
||
358 | |||
359 | bika_setup = api.get_bika_setup() |
||
360 | auto_print = bika_setup.getAutoPrintStickers() |
||
361 | |||
362 | # https://github.com/bikalabs/bika.lims/pull/2153 |
||
363 | new_samples = [a for a in samples if a[-1] == '1'] |
||
364 | |||
365 | if 'register' in auto_print and new_samples: |
||
366 | return { |
||
367 | 'success': message, |
||
368 | 'stickers': new_samples, |
||
369 | 'stickertemplate': self.context.bika_setup.getAutoStickerTemplate() |
||
370 | } |
||
371 | else: |
||
372 | return {'success': message} |
||
373 |