Merge branch 'feature/api-cleanup' of github.com:open-cloud/xos into feature/api-cleanup
diff --git a/xos/api/service/vbng/debug.py b/xos/api/service/vbng/debug.py
index 8a7f69e..8ecec0f 100644
--- a/xos/api/service/vbng/debug.py
+++ b/xos/api/service/vbng/debug.py
@@ -11,7 +11,7 @@
 from django.conf.urls import patterns, url
 from services.cord.models import VOLTTenant, VBNGTenant, CordSubscriberRoot
 from core.xoslib.objects.cordsubscriber import CordSubscriber
-from api.xosapi_helpers import PlusSerializerMixin, XOSViewSet
+from api.xosapi_helpers import PlusModelSerializer, XOSViewSet
 from django.shortcuts import get_object_or_404
 from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
 from xos.exceptions import *
@@ -25,7 +25,7 @@
     # rest_framework 2.x
     ReadOnlyField = serializers.Field
 
-class CordDebugIdSerializer(serializers.ModelSerializer, PlusSerializerMixin):
+class CordDebugIdSerializer(PlusModelSerializer):
     # Swagger is failing because CordDebugViewSet has neither a model nor
     # a serializer_class. Stuck this in here as a placeholder for now.
     id = ReadOnlyField()
diff --git a/xos/api/tenant/cord/subscriber.py b/xos/api/tenant/cord/subscriber.py
index 7df8410..90ccbcb 100644
--- a/xos/api/tenant/cord/subscriber.py
+++ b/xos/api/tenant/cord/subscriber.py
@@ -4,13 +4,14 @@
 from rest_framework import serializers
 from rest_framework import generics
 from rest_framework import viewsets
+from rest_framework import status
 from rest_framework.decorators import detail_route, list_route
 from rest_framework.views import APIView
 from core.models import *
 from django.forms import widgets
 from django.conf.urls import patterns, url
 from services.cord.models import VOLTTenant, VBNGTenant, CordSubscriberRoot
-from api.xosapi_helpers import PlusSerializerMixin, XOSViewSet, ReadOnlyField
+from api.xosapi_helpers import PlusModelSerializer, XOSViewSet, ReadOnlyField
 from django.shortcuts import get_object_or_404
 from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
 from xos.exceptions import *
@@ -94,7 +95,7 @@
 class IdentitySerializer(serializers.Serializer):
     account_num = serializers.CharField(required=False)
 
-class CordSubscriberSerializer(serializers.ModelSerializer, PlusSerializerMixin):
+class CordSubscriberSerializer(PlusModelSerializer):
         id = ReadOnlyField()
         humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
         features = FeatureSerializer(required=False)
@@ -114,21 +115,6 @@
         def getHumanReadableName(self, obj):
             return obj.__unicode__()
 
-        def create(self, validated_data):
-            obj = self.Meta.model(**validated_data)
-            return obj
-
-        def update(self, instance, validated_data):
-            for k in validated_data.keys():
-                v = validated_data[k]
-                if k in self.nested_fields:
-                    d = getattr(instance,k)
-                    d.update(v)
-                    setattr(instance,k,d)
-                else:
-                    setattr(instance, k, v)
-            return instance
-
 # @ensure_csrf_cookie
 class CordSubscriberViewSet(XOSViewSet):
     base_name = "subscriber"
@@ -145,8 +131,10 @@
         patterns.append( self.detail_url("identity/$", {"get": "get_identities", "put": "set_identities"}, "identities") )
         patterns.append( self.detail_url("identity/(?P<identity>[a-zA-Z0-9\-_]+)/$", {"get": "get_identity", "put": "set_identity"}, "get_identity") )
 
-        patterns.append( url(self.api_path + "subidlookup/(?P<ssid>[0-9\-]+)/$", self.as_view({"get": "ssiddetail"}), name="ssiddetail") )
-        patterns.append( url(self.api_path + "subidlookup/$", self.as_view({"get": "ssidlist"}), name="ssidlist") )
+        patterns.append( url(self.api_path + "account_num_lookup/(?P<account_num>[0-9\-]+)/$", self.as_view({"get": "account_num_detail"}), name="account_num_detail") )
+
+        patterns.append( url(self.api_path + "ssidmap/(?P<ssid>[0-9\-]+)/$", self.as_view({"get": "ssiddetail"}), name="ssiddetail") )
+        patterns.append( url(self.api_path + "ssidmap/$", self.as_view({"get": "ssidlist"}), name="ssidlist") )
 
         return patterns
 
@@ -209,6 +197,14 @@
         subscriber.save()
         return Response({identity: IdentitySerializer(subscriber.identity).data[identity]})
 
+    def account_num_detail(self, pk=None, account_num=None):
+        object_list = CordSubscriberNew.get_tenant_objects().all()
+        object_list = [x for x in object_list if x.service_specific_id == account_num]
+        if not object_list:
+            return Response("Failed to find account_num %s" % account_num, status=status.HTTP_404_NOT_FOUND)
+
+        return Response( object_list[0].id )
+
     def ssidlist(self, request):
         object_list = CordSubscriberNew.get_tenant_objects().all()
 
diff --git a/xos/api/tenant/cord/volt.py b/xos/api/tenant/cord/volt.py
index d9f08ce..e17cf26 100644
--- a/xos/api/tenant/cord/volt.py
+++ b/xos/api/tenant/cord/volt.py
@@ -8,7 +8,7 @@
 from django.forms import widgets
 from services.cord.models import VOLTTenant, VOLTService, CordSubscriberRoot
 from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
-from api.xosapi_helpers import PlusSerializerMixin, XOSViewSet, ReadOnlyField
+from api.xosapi_helpers import PlusModelSerializer, XOSViewSet, ReadOnlyField
 
 def get_default_volt_service():
     volt_services = VOLTService.get_service_objects().all()
@@ -27,7 +27,7 @@
 
     @subscriber.setter
     def subscriber(self, value):
-        self.subscriber_root = subscriber.id
+        self.subscriber_root = value # CordSubscriberRoot.get_tenant_objects().get(id=value)
 
     @property
     def related(self):
@@ -42,15 +42,16 @@
                     related["compute_node_name"] = self.vcpe.instance.node.name
         return related
 
-
-class VOLTTenantSerializer(serializers.ModelSerializer, PlusSerializerMixin):
+class VOLTTenantSerializer(PlusModelSerializer):
     id = ReadOnlyField()
-    service_specific_id = serializers.CharField()
+    service_specific_id = serializers.CharField(required=False)
     s_tag = serializers.CharField()
     c_tag = serializers.CharField()
     subscriber = serializers.PrimaryKeyRelatedField(queryset=CordSubscriberRoot.get_tenant_objects().all(), required=False)
     related = serializers.DictField(required=False)
 
+    property_fields=["subscriber"]
+
     humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
     class Meta:
         model = VOLTTenantForAPI
diff --git a/xos/api/xosapi_helpers.py b/xos/api/xosapi_helpers.py
index 75baf75..8011c11 100644
--- a/xos/api/xosapi_helpers.py
+++ b/xos/api/xosapi_helpers.py
@@ -19,7 +19,7 @@
     example, stuff related to backend fields.
 """
 
-class PlusSerializerMixin():
+class PlusModelSerializer(serializers.ModelSerializer):
     backendIcon = serializers.SerializerMethodField("getBackendIcon")
     backendHtml = serializers.SerializerMethodField("getBackendHtml")
 
@@ -35,6 +35,36 @@
     def getBackendHtml(self, obj):
         return obj.getBackendHtml()
 
+    def create(self, validated_data):
+        property_fields = getattr(self, "property_fields", [])
+        create_fields = {}
+        for k in validated_data:
+            if not k in property_fields:
+                create_fields[k] = validated_data[k]
+        obj = self.Meta.model(**create_fields)
+
+        for k in validated_data:
+            if k in property_fields:
+                setattr(obj, k, validated_data[k])
+
+        obj.caller = self.context['request'].user
+        obj.save()
+        return obj
+
+    def update(self, instance, validated_data):
+        nested_fields = getattr(self, "nested_fields", [])
+        for k in validated_data.keys():
+            v = validated_data[k]
+            if k in nested_fields:
+                d = getattr(instance,k)
+                d.update(v)
+                setattr(instance,k,d)
+            else:
+                setattr(instance, k, v)
+        instance.caller = self.context['request'].user
+        instance.save()
+        return instance
+
 class XOSViewSet(viewsets.ModelViewSet):
     api_path=""