def save (self, user):
        location = Village.objects.get (id = self.cleaned_data ['locationid'])
        citizen = get_or_create_citizen (self.cleaned_data ['yourmobile'],
                                         self.cleaned_data ['yourname'])

        complaint_base = ComplaintType.objects.get (id = self.cleaned_data ['categoryid'])
        department = complaint_base.department
        officials = department.official_set.all ()
        if officials.count () > 0:
            assignto = officials [0]
        else:
            assignto = None

        cpl = Complaint.objects.create (complainttype = complaint_base,
                                        complaintno = None,
                                        description = self.cleaned_data ['description'],
                                        department  = department,
                                        curstate = STATUS_NEW,
                                        filedby = citizen,
                                        logdate = self.cleaned_data ['logdate'],
                                        location = location,
                                        original = None,
                                        creator = user,
                                        assignto = assignto,
                                        gender = self.cleaned_data ['gender'],
                                        community = self.cleaned_data ['community'])
        update_complaint_sequence (cpl)

        ComplaintClosureMetric.objects.create (complaintno = cpl.complaintno)

        accept_cpl = cpl.clone (user)
        accept_cpl.curstate = STATUS_ACK
        accept_cpl.save ()

        queue_complaint_ack_official_sms (accept_cpl)

        message = None
        ct = cpl.complainttype
        if ct.defsmsack != None and len (ct.defsmsack.strip ()) != 0:
            message = ct.defsmsack

        if message == None:
            if ct.defsmsnew != None and len (ct.defsmsnew.strip ()) != 0:
                message = ct.defsmsnew

        if message != None:
            queue_complaint_update_sms (cpl.filedby.mobile, message, cpl)

        return accept_cpl
    def save (self, user):
        complaint = Complaint.objects.get (complaintno = self.cleaned_data ['complaintno'], latest = True)

        newver = complaint.clone (user)

        newver.curstate = ComplaintStatus.objects.get (id = self.cleaned_data ['newstatus'])
        newver.description = self.cleaned_data ['comment']

        if self.cleaned_data ['revlocationid'] != None:
            newver.location = Village.objects.get (id = self.cleaned_data ['revlocationid'])

        if self.cleaned_data ['revcategoryid'] != None:
            assignto = None
            complaint_base = ComplaintType.objects.get (id = self.cleaned_data ['revcategoryid'])
            department = complaint_base.department
            officials = department.official_set.all ()
            if officials.count () > 0:
                assignto = officials [0]
            else:
                assignto = None

            newver.complainttype = ComplaintType.objects.get (id = self.cleaned_data ['revcategoryid'])
            newver.department = newver.complainttype.department
            newver.assignto = assignto
            newver.gender = self.cleaned_data ['gender']
            newver.community = self.cleaned_data ['community']
        newver.save ()

        # Update the "original" issue if the new status is ACK state since the
        # issue has been made actionable
        if complaint.curstate == STATUS_NEW and newver.curstate == STATUS_ACK:
            original = newver.original
            original.complainttype = newver.complainttype
            original.location = newver.location
            original.department = newver.complainttype.department
            original.assignto = newver.assignto
            original.gender = newver.gender
            original.community = newver.community
            original.save ()

        if newver.curstate == STATUS_CLOSED:
            now_time = datetime.now ()
            ccms = ComplaintClosureMetric.objects.filter (complaintno = newver.complaintno)
            origs = Complaint.objects.filter (complaintno = newver.complaintno, curstate = STATUS_NEW).order_by ('created')
            if ccms.count () == 1:
                if origs.count () == 1:
                    orig = origs [0]
                    ccm = ccms [0]
                    ccm.closed = now_time
                    period = now_time - orig.created
                    ccm.period = period.days + ((period.seconds * 1.0) / (3600 * 24))
                    ccm.save ()
                else:
                    debug ("Multiple complaint objects with status_new for complaint : " + newver.complaintno)
                    debug ("... Doing nothing")
            else:
                debug ("Multiple complaint closure metrics exist for this complaint : " + newver.complaintno)
                debug ("... Doing nothing")


        if newver.curstate == STATUS_ACK:
            message = newver.complainttype.defsmsack
        elif newver.curstate == STATUS_OPEN:
            message = newver.complainttype.defsmsopen
        elif newver.curstate == STATUS_RESOLVED:
            message = newver.complainttype.defsmsres
        elif newver.curstate == STATUS_CLOSED:
            message = newver.complainttype.defsmsclo
        elif newver.curstate == STATUS_REOPEN:
            message = newver.complainttype.defsmsnew
        else:
            message = None

        if message != None:
            queue_complaint_update_sms (newver.filedby.mobile, message, newver)
        else:
            debug ("[%s]{%s}: " % (newver.complaintno, str (newver.curstate)) +
                   "Message is empty -- not queueing >> from forms.py: issuemgr")

        if (newver.curstate == STATUS_ACK):
            queue_complaint_ack_official_sms (newver)

        return newver