aboutsummaryrefslogtreecommitdiffstats
path: root/servo/models/shipments.py
diff options
context:
space:
mode:
authorFilipp Lepalaan <filipp@mac.com>2015-08-04 10:11:24 +0300
committerFilipp Lepalaan <filipp@mac.com>2015-08-04 10:11:24 +0300
commit63b0fc6269b38edf7234b9f151b80d81f614c0a3 (patch)
tree555de3068f33f8dddb4619349bbea7d9b7c822fd /servo/models/shipments.py
downloadServo-63b0fc6269b38edf7234b9f151b80d81f614c0a3.tar.gz
Servo-63b0fc6269b38edf7234b9f151b80d81f614c0a3.tar.bz2
Servo-63b0fc6269b38edf7234b9f151b80d81f614c0a3.zip
Initial commit
First public commit
Diffstat (limited to 'servo/models/shipments.py')
-rw-r--r--servo/models/shipments.py212
1 files changed, 212 insertions, 0 deletions
diff --git a/servo/models/shipments.py b/servo/models/shipments.py
new file mode 100644
index 0000000..2330f0d
--- /dev/null
+++ b/servo/models/shipments.py
@@ -0,0 +1,212 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2013, First Party Software
+# All rights reserved.
+
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+import gsxws
+
+from django.db import models
+
+from django.conf import settings
+from django.utils import timezone
+from django.core.files import File
+from django.utils.translation import ugettext_lazy as _
+
+from servo.models import Location
+
+
+class Shipment(models.Model):
+ """
+ Bulk returns
+ """
+ RETURN_DOA = 1 # Dead On Arrival
+ RETURN_GPR = 2 # Good Part Return
+ RETURN_CTS = 3 # Convert to stock
+
+ location = models.ForeignKey(Location, editable=False)
+
+ ship_to = models.CharField(
+ default='',
+ max_length=10,
+ editable=False,
+ )
+
+ return_id = models.CharField(
+ null=True,
+ unique=True,
+ max_length=10,
+ editable=False,
+ help_text="The return ID returned by GSX"
+ )
+
+ tracking_id = models.CharField(
+ blank=True,
+ default='',
+ max_length=30,
+ verbose_name=_('Tracking ID'),
+ help_text="Carrier's tracking ID"
+ )
+
+ tracking_url = models.URLField(
+ null=True,
+ editable=False,
+ help_text="The tracking URL returned by GSX"
+ )
+
+ packing_list = models.FileField(
+ null=True,
+ editable=False,
+ upload_to='returns',
+ help_text="The PDF returned by GSX"
+ )
+
+ carrier = models.CharField(
+ blank=True,
+ default='',
+ max_length=18,
+ choices=gsxws.CARRIERS,
+ verbose_name=_('carrier')
+ )
+
+ created_at = models.DateTimeField(auto_now=True, editable=False)
+
+ created_by = models.ForeignKey(
+ settings.AUTH_USER_MODEL,
+ null=True,
+ editable=False,
+ on_delete=models.SET_NULL,
+ related_name="created_shipments"
+ )
+
+ dispatched_at = models.DateTimeField(null=True, editable=False)
+
+ dispatched_by = models.ForeignKey(
+ settings.AUTH_USER_MODEL,
+ null=True,
+ editable=False,
+ related_name='dispatched_shipments'
+ )
+
+ width = models.PositiveIntegerField(
+ null=True,
+ blank=True,
+ verbose_name=_('width')
+ )
+
+ height = models.PositiveIntegerField(
+ null=True,
+ blank=True,
+ verbose_name=_('height')
+ )
+
+ length = models.PositiveIntegerField(
+ null=True,
+ blank=True,
+ verbose_name=_('length')
+ )
+
+ weight = models.PositiveIntegerField(
+ null=True,
+ blank=True,
+ verbose_name=_('weight')
+ )
+
+ @classmethod
+ def get_current(cls, user, location, ship_to):
+ try:
+ shipment = cls.objects.get(dispatched_at=None,
+ location=location,
+ ship_to=ship_to)
+ except cls.DoesNotExist:
+ shipment = cls.objects.create(created_by=user,
+ location=location,
+ ship_to=ship_to)
+
+ return shipment
+
+ def toggle_part(self, part):
+ part.registered_for_return = not part.registered_for_return
+ part.save()
+
+ if part.registered_for_return:
+ self.servicepart_set.add(part)
+ else:
+ self.servicepart_set.remove(part)
+
+ def verify(self):
+ """
+ Verifies this shipment with GSX
+ """
+ pass
+
+ def register_bulk_return(self, user):
+ """
+ Registers bulk return with GSX
+ """
+ parts = [] # Array of outbound parts in GSX format
+
+ gsx_act = self.location.gsx_accounts.get(ship_to=self.ship_to)
+ gsx_act.connect(user)
+
+ for p in self.servicepart_set.all().order_by('box_number'):
+ parts.append(p.to_gsx())
+
+ ret = gsxws.Return(shipToCode=self.ship_to)
+
+ ret.notes = ""
+ ret.width = self.width
+ ret.length = self.length
+ ret.height = self.height
+ ret.carrierCode = self.carrier
+ ret.trackingNumber = self.tracking_id
+ ret.estimatedTotalWeight = self.weight
+
+ result = ret.register_parts(parts)
+ ret.bulkReturnOrder = parts
+ self.dispatched_by = user
+ self.dispatched_at = timezone.now()
+ self.return_id = result.bulkReturnId
+ self.tracking_url = result.trackingURL
+
+ self.save()
+
+ filename = "bulk_return_%s.pdf" % self.return_id
+ self.packing_list.save(filename, File(open(result.packingList)))
+
+ def get_absolute_url(self):
+ return "/products/shipments/returns/%d/" % self.pk
+
+ def save(self, *args, **kwargs):
+ if not self.pk:
+ self.location = self.created_by.location
+
+ super(Shipment, self).save(*args, **kwargs)
+
+ def __unicode__(self):
+ return u'Shipment #%s from %s' % (self.pk, self.location.title)
+
+ class Meta:
+ app_label = "servo"
+ get_latest_by = 'id'
+ ordering = ('-dispatched_at',)