Пример #1
0
def check_mail():
    """Checks IMAP box for incoming mail"""
    uid = Configuration.conf('imap_act')

    if empty(uid):
        raise ConfigurationError('Incoming message user not configured')

    counter = 0
    user = User.objects.get(pk=uid)
    server = Configuration.get_imap_server()
    typ, data = server.search(None, "UnSeen")

    for num in data[0].split():
        #logging.debug("** Processing message %s" % num)
        typ, data = server.fetch(num, "(RFC822)")
        # parsestr() seems to return an email.message?
        msg = Parser().parsestr(data[0][1])
        Note.from_email(msg, user)
        #server.copy(num, 'servo')
        server.store(num, '+FLAGS', '\\Seen')
        counter += 1

    server.close()
    server.logout()

    return '%d messages processed' % counter
Пример #2
0
    def __init__(self, *args, **kwargs):

        super(DeviceForm, self).__init__(*args, **kwargs)

        if Configuration.false('checkin_require_password'):
            self.fields['password'].required = False

        if Configuration.true('checkin_require_condition'):
            self.fields['condition'].required = True

        if kwargs.get('instance'):
            prod = gsxws.Product('')
            prod.description = self.instance.description

            if prod.is_ios:
                self.fields['password'].label = _('Passcode')

            if not prod.is_ios:
                del (self.fields['imei'])

            if not prod.is_mac:
                del (self.fields['username'])

        if Configuration.true('checkin_password'):
            self.fields['password'].widget = forms.TextInput(
                attrs={'class': 'span12'})
Пример #3
0
def init_session(request):
    """
    Initialize the session for the check-in interface.

    Only run for GET requests
    """
    if not request.user.is_authenticated():
        request.session.flush()

    if not Configuration.checkin_enabled():
        raise ConfigurationError(_('Check-in interface not enabled'))

    # initialize locale
    init_locale(request)

    # set test cookie
    request.session.set_test_cookie()

    # initialize vars
    request.session['checkin_device'] = None
    request.session['checkin_customer'] = None

    user = User.get_checkin_user()
    location = user.location

    if not request.session.get('company_name'):
        request.session['company_name'] = Configuration.conf('company_name')

    if request.user.is_authenticated():

        # these are our fallback defaults
        user = request.user
        location = user.location

        try:
            location_id = request.GET['l']
        except KeyError:
            # not given - try session, then default to user's location
            location_id = request.session.get('checkin_location', location.pk)
        finally:
            location = get_object_or_404(Location, pk=location_id)

        try:
            user_id = request.GET['u']
        except KeyError:
            # not given - default to session, then auth user
            user_id = request.session.get('checkin_user', user.pk)

        user = get_object_or_404(User, pk=user_id)
        request.session['checkin_locations'] = Location.get_checkin_list()

        checkin_users = User.get_checkin_group()
        queryset = checkin_users.filter(location=location)
        request.session['checkin_users'] = User.serialize(queryset)

    request.session['checkin_user'] = user.pk
    request.session['checkin_location'] = location.pk
    request.session['checkin_user_name'] = user.get_name()
    request.session['checkin_location_name'] = location.title
Пример #4
0
    def get_amount_stocked(self, user):
        """
        Returns the amount of this product in the same location as the user.
        Caches the result for faster access later.
        """
        amount = 0
        track_inventory = Configuration.track_inventory()

        if not track_inventory:
            return 0

        if self.part_type == "SERVICE" or not self.pk:
            return 0

        cache_key = "product_%d_amount_stocked" % self.pk

        if cache.get(cache_key):
            return cache.get(cache_key)

        location = user.get_location()

        try:
            inventory = Inventory.objects.get(product=self, location=location)
            amount = inventory.amount_stocked
        except Inventory.DoesNotExist:
            pass

        cache.set(cache_key, amount)
        return amount
Пример #5
0
    def get_amount_stocked(self, user):
        """
        Returns the amount of this product in the same location as the user.
        Caches the result for faster access later.
        """
        amount = 0
        track_inventory = Configuration.track_inventory()

        if not track_inventory:
            return 0

        if self.part_type == "SERVICE" or not self.pk:
            return 0

        cache_key = "product_%d_amount_stocked" % self.pk

        if cache.get(cache_key):
            return cache.get(cache_key)

        location = user.get_location()

        try:
            inventory = Inventory.objects.get(product=self, location=location)
            amount = inventory.amount_stocked
        except Inventory.DoesNotExist:
            pass

        cache.set(cache_key, amount)
        return amount
Пример #6
0
def status(request):
    """
    Status checking through the checkin
    """
    title = _('Repair Status')

    if request.GET.get('code'):
        timeline = []
        form = StatusCheckForm(request.GET)
        if form.is_valid():
            code = form.cleaned_data['code']
            try:
                order = Order.objects.get(code=code)
                status_description = order.get_status_description()
                if Configuration.conf('checkin_timeline'):
                    timeline = order.orderstatus_set.all()
                if order.status is None:
                    order.status_name = _(u'Waiting to be processed')
            except Order.DoesNotExist:
                messages.error(request, _(u'Order %s not found') % code)
            return render(request, "checkin/status-show.html", locals())
    else:
        form = StatusCheckForm()

    return render(request, "checkin/status.html", locals())
Пример #7
0
def get_checkin_locations(user):
    from servo.models import User
    if user.is_authenticated():
        return user.locations.all()
    else:
        user_id = Configuration.conf('checkin_user')
        return User.objects.get(pk=user_id).locations.all()
Пример #8
0
    def handle(self, *args, **options):
        uid = Configuration.conf('imap_act')

        if uid in [None, '']:
            return

        user = User.objects.get(pk=uid)
        tz = timezone.get_current_timezone()
        
        for i in Escalation.objects.exclude(Q(escalation_id='') | Q(status='C')):
            i.gsx_account.connect(i.created_by)
            r = i.get_escalation().lookup()
            aware = timezone.make_aware(r.lastModifiedTimestamp, tz)

            if aware < i.updated_at: # hasn't been updated
                continue

            try:
                parent = i.note_set.latest()
            except Note.DoesNotExist:
                continue

            bodies = [n.body for n in i.note_set.all()]

            for x in r.escalationNotes.iterchildren():
                if x.text in bodies: # skip notes we already have
                    continue

                note = Note(created_by=user, escalation=i, body=x.text)
                parent.add_reply(note)
                note.save()

            i.updated_at = timezone.now()
            i.status = r.escalationStatus
            i.save()
Пример #9
0
    def track_inventory(self):
        if not Configuration.track_inventory():
            return False

        if self.part_type == "SERVICE":
            return False

        return True
Пример #10
0
def get_checkin_locations(user):
    """Return possible checkin location choices for this user."""
    from servo.models import User
    if user.is_authenticated():
        return user.locations.enabled()
    else:
        user_id = Configuration.conf('checkin_user')
        return User.objects.get(pk=user_id).locations.enabled()
Пример #11
0
def get_checkin_locations(user):
    """Return possible checkin location choices for this user."""
    from servo.models import User
    if user.is_authenticated():
        return user.locations.enabled()
    else:
        user_id = Configuration.conf('checkin_user')
        return User.objects.get(pk=user_id).locations.enabled()
Пример #12
0
    def track_inventory(self):
        if not Configuration.track_inventory():
            return False

        if self.part_type == "SERVICE":
            return False

        return True
Пример #13
0
def print_invoice(request, pk):
    from servo.models import Configuration

    invoice = get_object_or_404(Invoice, pk=pk)
    template = invoice.order.get_print_template("receipt")

    title = _("Receipt #%d") % invoice.pk
    conf = Configuration.conf()
    order = invoice.order

    return render(request, template, locals())
Пример #14
0
def print_invoice(request, pk):
    from servo.models import Configuration

    invoice = get_object_or_404(Invoice, pk=pk)
    template = invoice.order.get_print_template("receipt")

    title = _("Receipt #%d") % invoice.pk
    conf = Configuration.conf()
    order = invoice.order

    return render(request, template, locals())
Пример #15
0
    def handle(self, *args, **options):
        uid = Configuration.conf('imap_act')

        if uid == '':
            raise ValueError('Incoming message user not configured')

        user = User.objects.get(pk=uid)
        server = Configuration.get_imap_server()
        typ, data = server.search(None, "UnSeen")

        for num in data[0].split():
            #logging.debug("** Processing message %s" % num)
            typ, data = server.fetch(num, "(RFC822)")
            # parsestr() seems to return an email.message?
            msg = Parser().parsestr(data[0][1])
            Note.from_email(msg, user)
            #server.copy(num, 'servo')
            server.store(num, '+FLAGS', '\\Seen')

        server.close()
        server.logout()
Пример #16
0
    def handle(self, *args, **options):
        uid = Configuration.conf('imap_act')

        if uid == '':
            raise ValueError('Incoming message user not configured')

        user = User.objects.get(pk=uid)
        server = Configuration.get_imap_server()
        typ, data = server.search(None, "UnSeen")

        for num in data[0].split():
            #logging.debug("** Processing message %s" % num)
            typ, data = server.fetch(num, "(RFC822)")
            # parsestr() seems to return an email.message?
            msg = Parser().parsestr(data[0][1])
            Note.from_email(msg, user)
            #server.copy(num, 'servo')
            server.store(num, '+FLAGS', '\\Seen')

        server.close()
        server.logout()
Пример #17
0
    def __init__(self, *args, **kwargs):

        super(DeviceForm, self).__init__(*args, **kwargs)

        if Configuration.false('checkin_require_password'):
            self.fields['password'].required = False

        if Configuration.true('checkin_require_condition'):
            self.fields['condition'].required = True

        if kwargs.get('instance'):
            prod = gsxws.Product('')
            prod.description = self.instance.description

            if prod.is_ios:
                self.fields['password'].label = _('Passcode')

            if not prod.is_ios:
                del(self.fields['imei'])
            if not prod.is_mac:
                del(self.fields['username'])
            
        if Configuration.true('checkin_password'):
            self.fields['password'].widget = forms.TextInput(attrs={'class': 'span12'})
Пример #18
0
    def sell(self, amount, location):
        """
        Deduct product from inventory with specified location
        """
        track_inventory = Configuration.track_inventory()

        if self.part_type == "SERVICE" or not track_inventory:
            return

        try:
            inventory = Inventory.objects.get(product=self, location=location)
            inventory.amount_stocked = inventory.amount_stocked - amount
            inventory.save()
        except Inventory.DoesNotExist:
            raise ValueError(_(u"Product %s not found in inventory.") % self.code)
Пример #19
0
    def __init__(self, *args, **kwargs):

        super(DeviceForm, self).__init__(*args, **kwargs)

        if Configuration.false("checkin_require_password"):
            self.fields["password"].required = False

        if Configuration.true("checkin_require_condition"):
            self.fields["condition"].required = True

        if kwargs.get("instance"):
            prod = gsxws.Product("")
            prod.description = self.instance.description

            if prod.is_ios:
                self.fields["password"].label = _("Passcode")

            if not prod.is_ios:
                del (self.fields["imei"])
            if not prod.is_mac:
                del (self.fields["username"])

        if Configuration.true("checkin_password"):
            self.fields["password"].widget = forms.TextInput(attrs={"class": "span12"})
Пример #20
0
def init_session(request):
    # initialize some basic vars
    if not request.user.is_authenticated():
        request.session.flush()

    # initialize locale
    init_locale(request)

    request.session['checkin_device']   = None
    request.session['checkin_customer'] = None

    user = User.get_checkin_user()
    location = user.location

    if not request.session.get('company_name'):
        request.session['company_name'] = Configuration.conf('company_name')

    if request.user.is_authenticated():

        # these are our fallback defaults
        user = request.user
        location = user.location

        try:
            location_id = request.GET['l']
        except KeyError:
            # not given - try session, then default to user's location
            location_id = request.session.get('checkin_location', location.pk)
        finally:
            location = get_object_or_404(Location, pk=location_id)

        try:
            user_id = request.GET['u']
        except KeyError:
            # not given - default to session, then auth user
            user_id = request.session.get('checkin_user', user.pk)
        
        user = get_object_or_404(User, pk=user_id)
        request.session['checkin_locations'] = Location.get_checkin_list()

        checkin_users = User.get_checkin_group()
        queryset = checkin_users.filter(location=location)
        request.session['checkin_users'] = User.serialize(queryset)
    
    request.session['checkin_user'] = user.pk
    request.session['checkin_location'] = location.pk
    request.session['checkin_user_name'] = user.get_name()
    request.session['checkin_location_name'] = location.title
Пример #21
0
    def calculate_price(self, price, shipping=0.0):
        """
        Calculates price and returns it w/ and w/o tax
        """
        conf = Configuration.conf()
        shipping = shipping or 0.0

        if not isinstance(shipping, Decimal):
            shipping = Decimal(shipping)

        margin = get_margin(price)
        vat = Decimal(conf.get("pct_vat", 0.0))

        # TWOPLACES = Decimal(10) ** -2  # same as Decimal('0.01')
        # @TODO: make rounding configurable!
        wo_tax = ((price * 100) / (100 - margin) + shipping).to_integral_exact(rounding=ROUND_CEILING)
        with_tax = (wo_tax * (vat + 100) / 100).to_integral_exact(rounding=ROUND_CEILING)

        return wo_tax, with_tax
Пример #22
0
    def calculate_price(self, price, shipping=0.0):
        """
        Calculates price and returns it w/ and w/o tax
        """
        conf = Configuration.conf()
        shipping = shipping or 0.0

        if not isinstance(shipping, Decimal):
            shipping = Decimal(shipping)

        margin = get_margin(price)
        vat = Decimal(conf.get("pct_vat", 0.0))

        # TWOPLACES = Decimal(10) ** -2  # same as Decimal('0.01')
        # @TODO: make rounding configurable!
        wo_tax = ((price*100)/(100-margin)+shipping).to_integral_exact(rounding=ROUND_CEILING)
        with_tax = (wo_tax*(vat+100)/100).to_integral_exact(rounding=ROUND_CEILING)

        return wo_tax, with_tax
Пример #23
0
    def handle(self, *args, **options):
        # get local user to create notes as
        uid = Configuration.conf('imap_act')

        if empty(uid):
            raise ConfigurationError('Incoming message user not defined')

        user = User.objects.get(pk=uid)
        tz = timezone.get_current_timezone()

        for i in Escalation.objects.exclude(
                Q(escalation_id='') | Q(status='C')):
            # connect per-user since the escalations can be under different ship-tos
            try:
                i.gsx_account.connect(i.created_by)
            except Exception:
                continue  # skip auth errors so we don't get stuck

            r = i.get_escalation().lookup()
            aware = timezone.make_aware(r.lastModifiedTimestamp, tz)

            if aware < i.updated_at:  # hasn't been updated
                continue

            try:
                parent = i.note_set.latest()
            except Note.DoesNotExist:
                continue

            bodies = [n.body for n in i.note_set.all()]

            for x in r.escalationNotes.iterchildren():
                if x.text in bodies:  # skip notes we already have
                    continue

                note = Note(created_by=user, escalation=i, body=x.text)
                parent.add_reply(note)
                note.save()

            i.updated_at = timezone.now()
            i.status = r.escalationStatus
            i.save()
Пример #24
0
def reset_session(request):

    # initialize some basic vars
    if not request.user.is_authenticated():
        request.session.flush()

    # initialize locale
    init_locale(request)

    request.session['checkin_device'] = None
    request.session['checkin_customer'] = None

    if not request.session.get('company_name'):
        request.session['company_name'] = Configuration.conf('company_name')

    if request.user.is_authenticated():

        if request.GET.get('u'):
            user = User.objects.get(pk=request.GET['u'])
        else:
            user = request.user

        if request.GET.get('l'):
            location = Location.objects.get(pk=request.GET['l'])
        else:
            location = user.location

        checkin_users = User.get_checkin_group()
        request.session['checkin_users'] = User.get_checkin_group_list()
        request.session['checkin_locations'] = request.user.get_location_list()

        queryset = checkin_users.filter(location=location)
        request.session['checkin_users'] = User.serialize(queryset)

    else:
        user = User.get_checkin_user()
        location = user.location
    
    request.session['checkin_user'] = user.pk
    request.session['checkin_location'] = location.pk
    request.session['checkin_user_name'] = user.get_name()
    request.session['checkin_location_name'] = location.title
Пример #25
0
    def handle(self, *args, **options):
        # get local user to create notes as
        uid = Configuration.conf('imap_act')
        
        if empty(uid):
            raise ConfigurationError('Incoming message user not defined')

        user = User.objects.get(pk=uid)
        tz = timezone.get_current_timezone()
        
        for i in Escalation.objects.exclude(Q(escalation_id='') | Q(status='C')):
            # connect per-user since the escalations can be under different ship-tos
            try:
                i.gsx_account.connect(i.created_by)
            except Exception:
                continue # skip auth errors so we don't get stuck

            r = i.get_escalation().lookup()
            aware = timezone.make_aware(r.lastModifiedTimestamp, tz)

            if aware < i.updated_at: # hasn't been updated
                continue

            try:
                parent = i.note_set.latest()
            except Note.DoesNotExist:
                continue

            bodies = [n.body for n in i.note_set.all()]

            for x in r.escalationNotes.iterchildren():
                if x.text in bodies: # skip notes we already have
                    continue

                note = Note(created_by=user, escalation=i, body=x.text)
                parent.add_reply(note)
                note.save()

            i.updated_at = timezone.now()
            i.status = r.escalationStatus
            i.save()
Пример #26
0
def status(request):
    """Check service order status through the checkin."""
    title = _('Repair Status')

    if request.GET.get('code'):
        timeline = []
        form = StatusCheckForm(request.GET)
        if form.is_valid():
            code = form.cleaned_data['code']
            try:
                order = Order.objects.get(code=code)
                status_description = order.get_status_description()
                if Configuration.conf('checkin_timeline'):
                    timeline = order.orderstatus_set.all()
                if order.status is None:
                    order.status_name = _(u'Waiting to be processed')
            except Order.DoesNotExist:
                messages.error(request, _(u'Order %s not found') % code)
            return render(request, "checkin/status-show.html", locals())
    else:
        form = StatusCheckForm()

    return render(request, "checkin/status.html", locals())
Пример #27
0
def default_vat():
    conf = Configuration.conf()
    return conf.get("pct_vat", 0.0)
Пример #28
0
    def from_gsx(cls, part):
        """
        Creates a Servo Product from GSX partDetail.
        We don't do GSX lookups here since we can't
        determine the correct GSX Account at this point.
        """
        conf = Configuration.conf()

        try:
            shipping = Decimal(conf.get("shipping_cost"))
        except TypeError:
            shipping = Decimal(0.0)

        part_number = part.originalPartNumber or part.partNumber
        product = Product(code=part_number)
        product.title = part.partDescription

        if part.originalPartNumber:
            product.subst_code = part.partNumber

        if part.stockPrice and not product.fixed_price:
            # calculate stock price
            purchase_sp = part.stockPrice or 0.0
            purchase_sp = Decimal(purchase_sp)
            sp, vat_sp  = product.calculate_price(purchase_sp, shipping)
            product.pct_margin_stock  = get_margin(purchase_sp)
            product.price_notax_stock = sp
            product.price_sales_stock = vat_sp
            # @TODO: make rounding configurable
            product.price_purchase_stock = purchase_sp.to_integral_exact(
                rounding=ROUND_CEILING
            )

        try:
            # calculate exchange price
            purchase_ep = part.exchangePrice or 0.0
            purchase_ep = Decimal(purchase_ep)

            if purchase_ep > 0 and not product.fixed_price:
                ep, vat_ep = product.calculate_price(purchase_ep, shipping)
                product.price_notax_exchange = ep
                product.price_sales_exchange = vat_ep
                product.pct_margin_exchange = Configuration.get_margin(purchase_ep)
                # @TODO: make rounding configurable
                product.price_purchase_exchange = purchase_ep.to_integral_exact(
                    rounding=ROUND_CEILING
                )
        except AttributeError:
            pass  # Not all parts have exchange prices

        product.brand = "Apple"
        product.shipping = shipping
        product.warranty_period = 3

        product.labour_tier = part.laborTier
        product.part_type = part.partType.upper()

        # EEE and componentCode are sometimes missing
        if part.eeeCode:
            product.eee_code = str(part.eeeCode).strip()
        if part.componentCode:
            product.component_code = str(part.componentCode).strip()

        product.is_serialized = part.isSerialized
        return product
Пример #29
0
def index(request):
    """
    Render the checkin homepage.

    @FIXME: would be nice to break this into smaller chunks...
    """
    if request.method == 'GET':
        try:
            init_session(request)
        except ConfigurationError as e:
            error = {'message': e}
            return render(request, 'checkin/error.html', error)

    title = _('Service Order Check-In')
    dcat = request.GET.get('d', 'mac')
    dmap = {
        'mac': _('Mac'),
        'iphone': _('iPhone'),
        'ipad': _('iPad'),
        'ipod': _('iPod'),
        'acc': _('Apple Accessory'),
        'beats': _('Beats Products'),
        'other': _('Other Devices'),
    }

    issue_form = IssueForm()
    device = Device(description=dmap[dcat])

    if dcat in ('mac', 'iphone', 'ipad', 'ipod'):
        sn_form = AppleSerialNumberForm()
    else:
        sn_form = SerialNumberForm()

    tags = Tag.objects.filter(type="order")
    device_form = DeviceForm(instance=device)
    customer_form = CustomerForm(request)

    if request.method == 'POST':

        if not request.session.test_cookie_worked():
            error = {
                'message': _('Please enable cookies to use this application.')
            }
            return render(request, 'checkin/error.html', error)
        else:
            request.session.delete_test_cookie()

        sn_form = SerialNumberForm(request.POST)
        issue_form = IssueForm(request.POST, request.FILES)
        customer_form = CustomerForm(request, request.POST)
        device_form = DeviceForm(request.POST, request.FILES)

        if device_form.is_valid() and issue_form.is_valid(
        ) and customer_form.is_valid():

            user = get_object_or_404(User, pk=request.session['checkin_user'])

            idata = issue_form.cleaned_data
            ddata = device_form.cleaned_data
            cdata = customer_form.cleaned_data
            customer_id = request.session.get('checkin_customer')

            if customer_id:
                customer = get_object_or_404(Customer, pk=customer_id)
            else:
                customer = Customer()

            name = u'{0} {1}'.format(cdata['fname'], cdata['lname'])

            if len(cdata['company']):
                name += ', ' + cdata['company']

            customer.name = name
            customer.city = cdata['city']
            customer.phone = cdata['phone']
            customer.email = cdata['email']
            customer.phone = cdata['phone']
            customer.zip_code = cdata['postal_code']
            customer.street_address = cdata['address']
            customer.save()

            order = Order(customer=customer, created_by=user)
            order.location_id = request.session['checkin_location']
            order.checkin_location = cdata['checkin_location']
            order.checkout_location = cdata['checkout_location']

            order.save()
            order.check_in(user)

            try:
                device = get_device(request, ddata['sn'])
            except GsxError as e:
                pass

            device.username = ddata['username']
            device.password = ddata['password']
            device.description = ddata['description']
            device.purchased_on = ddata['purchased_on']
            device.purchase_country = ddata['purchase_country']
            device.save()

            order.add_device(device, user)

            note = Note(created_by=user, body=idata['issue_description'])
            note.is_reported = True
            note.order = order
            note.save()

            # Proof of purchase was supplied
            if ddata.get('pop'):
                f = {'content_type': Attachment.get_content_type('note').pk}
                f['object_id'] = note.pk
                a = AttachmentForm(f, {'content': ddata['pop']})
                a.save()

            if request.POST.get('tags'):
                order.set_tags(request.POST.getlist('tags'), request.user)

            # Check checklists early for validation
            answers = []

            # @FIXME: should try to move this to a formset...
            for k, v in request.POST.items():
                if k.startswith('__cl__'):
                    answers.append('- **' + k[6:] + '**: ' + v)

            if len(answers) > 0:
                note = Note(created_by=user, body="\r\n".join(answers))

                if Configuration.true('checkin_report_checklist'):
                    note.is_reported = True

                note.order = order
                note.save()

            # mark down internal notes (only if logged in)
            if len(idata.get('notes')):
                note = Note(created_by=user, body=idata['notes'])
                note.is_reported = False
                note.order = order
                note.save()

            # mark down condition of device
            if len(ddata.get('condition')):
                note = Note(created_by=user, body=ddata['condition'])
                note.is_reported = True
                note.order = order
                note.save()

            # mark down supplied accessories
            if len(ddata.get('accessories')):
                accs = ddata['accessories'].strip().split("\n")
                order.set_accessories(accs, device)

            redirect_to = thanks
            """
            if request.user.is_authenticated():
                if request.user.autoprint:
                    redirect_to = print_confirmation
            """
            return redirect(redirect_to, order.url_code)

    try:
        pk = Configuration.conf('checkin_checklist')
        questions = ChecklistItem.objects.filter(checklist_id=pk)
    except ValueError:
        # Checklists probably not configured
        pass

    if request.GET.get('phone'):
        return find_customer(request, request.GET['phone'])

    if request.GET.get('sn'):
        return find_device(request)

    return render(request, "checkin/newindex.html", locals())
Пример #30
0
def terms(request):
    """Show terms of service."""
    conf = Configuration.conf()
    return render(request, 'checkin/terms.html', locals())
Пример #31
0
def default_vat():
    conf = Configuration.conf()
    return conf.get("pct_vat", 0.0)
Пример #32
0
    def from_gsx(cls, part):
        """
        Creates a Servo Product from GSX partDetail.
        We don't do GSX lookups here since we can't
        determine the correct GSX Account at this point.
        """
        conf = Configuration.conf()

        try:
            shipping = Decimal(conf.get("shipping_cost"))
        except TypeError:
            shipping = Decimal(0.0)

        part_number = part.originalPartNumber or part.partNumber
        product = Product(code=part_number)
        product.title = part.partDescription

        if part.originalPartNumber:
            product.subst_code = part.partNumber

        if part.stockPrice and not product.fixed_price:
            # calculate stock price
            purchase_sp = part.stockPrice or 0.0
            purchase_sp = Decimal(purchase_sp)
            sp, vat_sp = product.calculate_price(purchase_sp, shipping)
            product.pct_margin_stock = get_margin(purchase_sp)
            product.price_notax_stock = sp
            product.price_sales_stock = vat_sp
            # @TODO: make rounding configurable
            product.price_purchase_stock = purchase_sp.to_integral_exact(rounding=ROUND_CEILING)

        try:
            # calculate exchange price
            purchase_ep = part.exchangePrice or 0.0
            purchase_ep = Decimal(purchase_ep)

            if purchase_ep > 0 and not product.fixed_price:
                ep, vat_ep = product.calculate_price(purchase_ep, shipping)
                product.price_notax_exchange = ep
                product.price_sales_exchange = vat_ep
                product.pct_margin_exchange = Configuration.get_margin(purchase_ep)
                # @TODO: make rounding configurable
                product.price_purchase_exchange = purchase_ep.to_integral_exact(rounding=ROUND_CEILING)
        except AttributeError:
            pass  # Not all parts have exchange prices

        product.brand = "Apple"
        product.shipping = shipping
        product.warranty_period = 3

        product.labour_tier = part.laborTier
        product.part_type = part.partType.upper()

        # EEE and componentCode are sometimes missing
        if part.eeeCode:
            product.eee_code = str(part.eeeCode).strip()
        if part.componentCode:
            product.component_code = str(part.componentCode).strip()

        product.is_serialized = part.isSerialized
        return product
Пример #33
0
def index(request):

    if request.method == 'GET':
        reset_session(request)
        
    title = _('Service Order Check-In')    

    dcat = request.GET.get('d', 'mac')
    dmap = {
        'mac'       : _('Mac'),
        'iphone'    : _('iPhone'),
        'ipad'      : _('iPad'),
        'ipod'      : _('iPod'),
        'acc'       : _('Apple Accessory'),
        'beats'     : _('Beats Products'),
        'other'     : _('Other Devices'),
    }

    issue_form = IssueForm()
    device = Device(description=dmap[dcat])

    if dcat in ('mac', 'iphone', 'ipad', 'ipod'):
        sn_form = AppleSerialNumberForm()
    else:
        sn_form = SerialNumberForm()

    tags = Tag.objects.filter(type="order")
    device_form = DeviceForm(instance=device)
    customer_form =  CustomerForm(request)

    if request.method == 'POST':

        sn_form = SerialNumberForm(request.POST)
        issue_form = IssueForm(request.POST, request.FILES)
        customer_form = CustomerForm(request, request.POST)
        device_form = DeviceForm(request.POST, request.FILES)

        if device_form.is_valid() and issue_form.is_valid() and customer_form.is_valid():

            user = User.objects.get(pk=request.session['checkin_user'])

            idata = issue_form.cleaned_data
            ddata = device_form.cleaned_data
            cdata = customer_form.cleaned_data

            customer_id = request.session.get('checkin_customer')
            if customer_id:
                customer = Customer.objects.get(pk=customer_id)
            else:
                customer = Customer()

            name = u'{0} {1}'.format(cdata['fname'], cdata['lname'])
            
            if len(cdata['company']):
                name += ', ' + cdata['company']

            customer.name  = name
            customer.city  = cdata['city']
            customer.phone = cdata['phone']
            customer.email = cdata['email']
            customer.phone = cdata['phone']
            customer.zip_code = cdata['postal_code']
            customer.street_address = cdata['address']
            customer.save()

            order = Order(customer=customer, created_by=user)
            order.location_id = request.session['checkin_location']
            order.checkin_location = cdata['checkin_location']
            order.checkout_location = cdata['checkout_location']

            order.save()
            order.check_in(user)

            try:
                device = get_device(request, ddata['sn'])
            except GsxError as e:
                pass

            device.username = ddata['username']
            device.password = ddata['password']
            device.description = ddata['description']
            device.purchased_on = ddata['purchased_on']
            device.purchase_country = ddata['purchase_country']
            device.save()
            
            order.add_device(device, user)

            note = Note(created_by=user, body=idata['issue_description'])
            note.is_reported = True
            note.order = order
            note.save()

            # Proof of purchase was supplied
            if ddata.get('pop'):
                f = {'content_type': Attachment.get_content_type('note').pk}
                f['object_id'] = note.pk
                a = AttachmentForm(f, {'content': ddata['pop']})
                a.save()

            if request.POST.get('tags'):
                order.set_tags(request.POST.getlist('tags'), request.user)

            # Check checklists early for validation
            answers = []

            # @FIXME: should try to move this to a formset...
            for k, v in request.POST.items():
                if k.startswith('__cl__'):
                    answers.append('- **' + k[6:] + '**: ' + v)

            if len(answers) > 0:
                note = Note(created_by=user, body="\r\n".join(answers))

                if Configuration.true('checkin_report_checklist'):
                    note.is_reported = True

                note.order = order
                note.save()

            # mark down internal notes (only if logged in)
            if len(idata.get('notes')):
                note = Note(created_by=user, body=idata['notes'])
                note.is_reported = False
                note.order = order
                note.save()

            # mark down condition of device
            if len(ddata.get('condition')):
                note = Note(created_by=user, body=ddata['condition'])
                note.is_reported = True
                note.order = order
                note.save()

            # mark down supplied accessories
            if len(ddata.get('accessories')):
                accs = ddata['accessories'].strip().split("\n")
                order.set_accessories(accs, device)

            redirect_to = thanks

            """
            if request.user.is_authenticated():
                if request.user.autoprint:
                    redirect_to = print_confirmation
            """
            return redirect(redirect_to, order.url_code)

    try:
        pk = Configuration.conf('checkin_checklist')
        questions = ChecklistItem.objects.filter(checklist_id=pk)
    except ValueError:
        # Checklists probably not configured
        pass

    if request.GET.get('phone'):

        if not request.user.is_authenticated():
            return

        results = []

        for c in Customer.objects.filter(phone=request.GET['phone']):
            title = '%s - %s' % (c.phone, c.name)
            results.append({'id': c.pk, 'name': c.name, 'title': title})

        return HttpResponse(json.dumps(results), content_type='application/json')

    if request.GET.get('sn'):

        device = Device(sn=request.GET['sn'])
        device.description = _('Other Device')
        device_form = DeviceForm(instance=device)

        try:
            apple_sn_validator(device.sn)
        except Exception as e: # not an Apple serial number
            return render(request, "checkin/device_form.html", locals())

        try:
            device = get_device(request, device.sn)
            device_form = DeviceForm(instance=device)
        except GsxError as e:
            error = e

        return render(request, "checkin/device_form.html", locals())

    return render(request, "checkin/newindex.html", locals())
Пример #34
0
def terms(request):
    conf = Configuration.conf()
    return render(request, 'checkin/terms.html', locals())