<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:

def save(self, *args, **kwargs):
        '''
        This custom save method ensures that an expense is not attributed to multiple categories.
        It also ensures that the series and event properties are always associated with any
        type of expense of that series or event.
        '''
        # Set the approval and payment dates if they have just been approved/paid.
        if not hasattr(self,'__paid') or not hasattr(self,'__approved'):
            if self.approved and not self.approvalDate:
                self.approvalDate = timezone.now()
            if self.paid and not self.paymentDate:
                self.paymentDate = timezone.now()
        else:
            if self.approved and not self.approvalDate and not self.__approvalDate:
                self.approvalDate = timezone.now()
            if self.paid and not self.paymentDate and not self.__paymentDate:
                self.paymentDate = timezone.now()

        # Fill out the series and event properties to permit easy calculation of
        # revenues and expenses by series or by event.
        if self.expenseRule and not self.payTo:
            this_loc = getattr(self.expenseRule,'location',None)
            this_member = getattr(self.expenseRule,'location',None)

            if this_loc:
                self.payTo = TransactionParty.objects.get_or_create(
                    location=this_loc,
                    defaults={'name': this_loc.name}
                )[0]
            elif this_member:
                self.payTo = TransactionParty.objects.get_or_create(
                    staffMember=this_member,
                    defaults={
                        'name': this_member.fullName,
                        'user': getattr(this_member,'userAccount',None)
                    }
                )[0]

        # Set the accrual date.  The method for events ensures that the accrualDate month
        # is the same as the reported month of the series/event by accruing to the end date of the last
        # class or occurrence in that month.
        if not self.accrualDate:
            if self.event and self.event.month:
                self.accrualDate = self.event.eventoccurrence_set.order_by('endTime').filter(**{'endTime__month': self.event.month}).last().endTime
            elif self.submissionDate:
                self.accrualDate = self.submissionDate
            else:
                self.submissionDate = timezone.now()
                self.accrualDate = self.submissionDate

        # Set the total for hourly work
        if self.hours and not self.wageRate and not self.total and not getattr(getattr(self,'payTo',None),'location',None) and self.category:
            self.wageRate = self.category.defaultRate
        elif self.hours and not self.wageRate and not self.total and getattr(getattr(self,'payTo',None),'location',None):
            self.wageRate = self.payTo.location.rentalRate

        if self.hours and self.wageRate and not self.total:
            self.total = self.hours * self.wageRate

        super(ExpenseItem, self).save(*args, **kwargs)
        self.__approved = self.approved
        self.__paid = self.paid
        self.__approvalDate = self.approvalDate
        self.__paymentDate = self.paymentDate

        # If a file is attached, ensure that it is not public, and that it is saved in the 'Expense Receipts' folder
        if self.attachment:
            try:
                self.attachment.folder = Folder.objects.get(name=_('Expense Receipts'))
            except ObjectDoesNotExist:
                pass
            self.attachment.is_public = False
            self.attachment.save()