# -*- coding: utf-8 -*- import gsxws import logging from django.contrib import messages from django.http import HttpResponse from django.utils.translation import ugettext as _ from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth.decorators import permission_required from servo.models import Order, GsxAccount, Repair, ServicePart from servo.forms import GsxCustomerForm, GsxRepairForm, GsxComponentForm, ImportForm class RepairDetails(object): def __init__(self, confirmation): repair = gsxws.Repair(confirmation).details() self.dispatch_id = repair.dispatchId self.po_number = repair.purchaseOrderNumber self.cs_code = repair.csCode self.tracking_number = repair.deliveryTrackingNumber self.notes = repair.notes self.status = repair.repairStatus self.status_description = repair.coverageStatusDescription self.parts = repair.partsInfo @permission_required("servo.change_order") def register_return(request, part_id): part = get_object_or_404(ServicePart, pk=part_id) try: part.register_for_return(request.user) messages.success(request, _(u"Part %s updated") % part.order_item.code) except Exception as e: messages.error(request, e) return redirect(part.repair.order) @permission_required("servo.change_repair") def import_repair(request, order_pk, device_pk): from servo.models import Device order = get_object_or_404(Order, pk=order_pk) device = get_object_or_404(Device, pk=device_pk) action = request.path form = ImportForm() if request.method == 'POST': form = ImportForm(request.POST) if form.is_valid(): confirmation = form.cleaned_data['confirmation'] try: repair = Repair.create_from_gsx(confirmation, order, device, request.user) messages.success(request, _('GSX repair %s imported successfully' % confirmation)) return redirect(repair) except Exception as e: messages.error(request, e) return redirect(order) return render(request, "repairs/import_repair.html", locals()) @permission_required("servo.change_order") def return_label(request, repair, part): """ Returns the return label PDF for this repair and part """ repair = get_object_or_404(Repair, pk=repair) try: repair.connect_gsx(request.user) label_data = repair.get_return_label(part) return HttpResponse(label_data, content_type="application/pdf") except gsxws.GsxError as e: messages.error(request, e) return redirect(repair.order) @permission_required("servo.change_repair") def add_part(request, repair, part): """ Adds this part to this GSX repair """ rep = get_object_or_404(Repair, pk=repair) soi = rep.order.serviceorderitem_set.get(pk=part) if request.method == "POST": try: part = rep.add_part(soi, request.user) data = {'part': part.part_number, 'repair': rep.confirmation} msg = _("Part %(part)s added to repair %(repair)s") % data messages.success(request, msg) except gsxws.GsxError as e: messages.error(request, e) return redirect(rep.order) context = {'item': soi} context['repair'] = rep context['action'] = request.path return render(request, "repairs/add_part.html", context) def remove_part(request, repair, part): rep = get_object_or_404(Repair, pk=repair) part = get_object_or_404(ServicePart, pk=part) if request.method == "POST": rep.connect_gsx(request.user) gsx_rep = rep.get_gsx_repair() orderline = part.get_repair_order_line() orderline.toDelete = True orderline.orderLineNumber = part.line_number try: gsx_rep.update({'orderLines': [orderline]}) data = {'part': part.code, 'repair': rep.confirmation} msg = _(u"Part %(part)s removed from %(repair)s") % data messages.success(request, msg) except gsxws.GsxError as e: messages.error(request, e) return redirect(rep.order) data = {'action': request.path} return render(request, "repairs/delete_part.html", data) def delete_repair(request, pk): """Delete this unsubmitted GSX repair.""" repair = get_object_or_404(Repair, pk=pk) if repair.is_submitted(): messages.error(request, _('Submitted repairs cannot be deleted')) return redirect(repair.order) if request.method == 'POST': order = repair.order repair.delete() messages.success(request, _('GSX repair deleted')) return redirect(order) context = {'action': request.path} return render(request, 'repairs/delete_repair.html', context) def check_parts_warranty(request, repair): """ Checks this (new) repair warranty status with the included device and parts """ repair = get_object_or_404(Repair, pk=repair) parts = repair.order.get_parts() try: wty = repair.warranty_status() wty_parts = wty.parts repair.acplus = wty.acPlusFlag except Exception as e: return render(request, 'search/results/gsx_error.html', {'message': e}) try: for k, v in enumerate(parts): try: parts[k].warranty_status = wty_parts[k].partWarranty except TypeError: parts[k].warranty_status = _('Unknown') except KeyError: parts[0].warranty_status = wty_parts.partWarranty context = {'parts': parts} context['checked_parts'] = [p.pk for p in repair.parts.all()] return render(request, 'repairs/check_parts.html', context) def prep_edit_view(request, repair, order=None, device=None): """ Prepares edit view for GSX repair """ context = {'order': order} if repair.submitted_at: raise ValueError(_("Submitted repairs cannot be edited")) if not order.has_parts: raise ValueError(_("Please add some parts before creating repair")) if not order.customer: raise ValueError(_("Cannot create GSX repair without valid customer data")) customer = order.customer.gsx_address(request.user.location) customer_form = GsxCustomerForm(initial=customer) context['repair'] = repair context['customer'] = customer context['title'] = repair.get_number() context['customer_form'] = customer_form context['device'] = device or repair.device context['repair_form'] = GsxRepairForm(instance=repair) if len(repair.component_data): context['component_form'] = GsxComponentForm(components=repair.component_data) return context def edit_repair(request, order_id, repair_id): """ Edits existing (non-submitted) GSX repair """ order = get_object_or_404(Order, pk=order_id) repair = get_object_or_404(Repair, pk=repair_id) if request.GET.get('c'): # looking up issue code for symptom repair.symptom_code = request.GET['c'] repair.save() choices = repair.get_issue_code_choices() return render(request, "repairs/issue_code_menu.html", locals()) repair.set_parts(order.get_parts()) try: repair.connect_gsx(request.user) repair.check_components() data = prep_edit_view(request, repair, order) except (ValueError, gsxws.GsxError) as e: messages.error(request, e) return redirect(order) if request.method == "POST": try: data = save_repair(request, data) msg = _('GSX repair saved') if 'confirm' in request.POST.keys(): repair.submit(data['customer_data']) msg = _(u"GSX repair %s created") % repair.confirmation messages.success(request, msg) return redirect("repairs-view_repair", order.pk, repair.pk) messages.success(request, msg) return redirect(order) except Exception as e: messages.error(request, e) return render(request, "orders/gsx_repair_form.html", data) def save_repair(request, context): """ Saves this GSX repair """ repair = context['repair'] customer = context['customer'] if len(repair.component_data): component_form = GsxComponentForm(request.POST, components=repair.component_data) if component_form.is_valid(): repair.component_data = component_form.json_data else: raise ValueError(_("Invalid component data")) customer_form = GsxCustomerForm(request.POST, initial=customer) repair_form = GsxRepairForm(request.POST, request.FILES, instance=repair) if customer_form.is_valid(): context['customer_data'] = customer_form.cleaned_data if repair_form.is_valid(): repair = repair_form.save(commit=False) repair.set_parts(repair_form.cleaned_data['parts']) repair.save() else: raise ValueError(repair_form.errors) else: raise ValueError(_("Invalid customer info")) context['repair_form'] = repair_form context['customer_form'] = customer_form return context def create_repair(request, order_id, device_id, type): """ Creates a GSX repair for the specified SRO and device and redirects to the repair's edit page. """ from datetime import timedelta from django.utils import timezone order = get_object_or_404(Order, pk=order_id) device = order.devices.get(pk=device_id) repair = Repair(order=order, created_by=request.user, device=device) timediff = timezone.now() - order.created_at if timediff.seconds <= 3600: repair.unit_received_at = order.created_at - timedelta(hours=1) else: repair.unit_received_at = order.created_at repair.reference = request.user.gsx_poprefix + order.code try: repair.gsx_account = GsxAccount.default(request.user, order.queue) except Exception as e: messages.error(request, e) return redirect(order) repair.repair_type = type repair.tech_id = request.user.tech_id repair.save() return redirect(edit_repair, order.pk, repair.pk) def repair_details(request, confirmation): """ Returns GSX repair details for confirmation number """ try: repair = RepairDetails(confirmation) except Exception as e: data = {'error': e} return render(request, "snippets/error_modal.html", data) data = {'repair': repair} if request.method == "POST": data = save_repair(request, data) return render(request, "repairs/get_details.html", data) def copy_repair(request, pk): """ Duplicates a local GSX repair """ repair = get_object_or_404(Repair, pk=pk) new_repair = repair.duplicate(request.user) return redirect(edit_repair, new_repair.order_id, new_repair.pk) def update_sn(request, pk, part): """ Updates the parts serial number """ part = get_object_or_404(ServicePart, pk=part) try: part.repair.connect_gsx(request.user) part.update_sn() msg = _(u'%s serial numbers updated') % part.part_number messages.success(request, msg) except Exception as e: messages.error(request, e) return redirect(part.repair.order)