示例#1
0
class FKApplication(models.Model):
    """
    Student application need to be approved by dept chair and dean.
    Test workflow for FSMKeyField
    """
    state = FSMKeyField('testapp.DbState', default='new')

    @transition(field=state, source='new', target='draft')
    def draft(self):
        pass

    @transition(field=state, source=['new', 'draft'], target='dept')
    def to_approvement(self):
        pass

    @transition(field=state, source='dept', target='dean')
    def dept_approved(self):
        pass

    @transition(field=state, source='dept', target='new')
    def dept_rejected(self):
        pass

    @transition(field=state, source='dean', target='done')
    def dean_approved(self):
        pass

    @transition(field=state, source='dean', target='dept')
    def dean_rejected(self):
        pass
示例#2
0
class FKBlogPost(models.Model):
    state = FSMKeyField(DBState,
                        default='new',
                        protected=True,
                        on_delete=models.PROTECT)

    @transition(field=state, source='new', target='published')
    def publish(self):
        pass

    @transition(field=state, source='published')
    def notify_all(self):
        pass

    @transition(field=state, source='published', target='hidden')
    def hide(self):
        pass

    @transition(field=state, source='new', target='removed')
    def remove(self):
        raise Exception('Upss')

    @transition(field=state, source=['published', 'hidden'], target='stolen')
    def steal(self):
        pass

    @transition(field=state, source='*', target='moderated')
    def moderate(self):
        pass

    class Meta:
        app_label = 'django_fsm'
示例#3
0
class Invoice(ConcurrentTransitionMixin, FsmLogMixin, TimeStampedBaseModel):
    class Transitions:
        trans_1 = [
            'New', 'Verify Invoices', 'Overrun Check', 'Print Summary',
            'Under Certification', 'Sent to Finance', 'Completed'
        ]

        trans_2 = ['*', 'Verify Invoices']

    contract = models.ForeignKey(Contract, null=True, on_delete=models.CASCADE)
    contractor = models.ForeignKey(Contractor,
                                   null=True,
                                   on_delete=models.CASCADE)
    task = models.ForeignKey(Task, null=True, on_delete=models.CASCADE)

    state = FSMKeyField(InvoiceProcess, default="New")

    region = models.CharField(max_length=100)
    invoice_no = models.CharField(max_length=100)
    invoice_type = models.CharField(max_length=100)
    payment_type = models.CharField(max_length=100)
    revenue_amount = models.DecimalField(max_digits=20,
                                         decimal_places=2,
                                         default=Decimal('0.00'))
    opex_amount = models.DecimalField(max_digits=20,
                                      decimal_places=2,
                                      default=Decimal('0.00'))
    capex_amount = models.DecimalField(max_digits=20,
                                       decimal_places=2,
                                       default=Decimal('0.00'))
    invoice_amount = models.DecimalField(max_digits=20,
                                         decimal_places=2,
                                         default=Decimal('0.00'))
    penalty = models.DecimalField(max_digits=20,
                                  decimal_places=2,
                                  default=Decimal('0.00'))
    invoice_date = models.DateTimeField(blank=True, null=True)
    invoice_cert_date = models.DateTimeField(blank=True, null=True)
    received_date = models.DateTimeField(blank=True, null=True)
    signed_date = models.DateTimeField(blank=True, null=True)
    start_date = models.DateTimeField(blank=True, null=True)
    end_date = models.DateTimeField(blank=True, null=True)
    rfs_date = models.DateTimeField(blank=True, null=True)
    reject_date = models.DateTimeField(blank=True, null=True)
    sent_finance_date = models.DateTimeField(blank=True, null=True)
    cost_center = models.CharField(max_length=100)
    expense_code = models.CharField(max_length=100)
    remarks = models.TextField(blank=True)
    description = models.TextField(blank=True)
    proj_no = models.CharField(max_length=100)
    status = models.CharField(max_length=100, default='Ongoing')

    #current_process = models.CharField(max_length=100)
    invoice_ref = models.CharField(
        max_length=100,
        unique=True)  # checks uniqueness of invoice_no over the contractor

    @property
    def state__name(self):
        return self.state

    def get_invoice_ref(self):
        return self.contractor.name + ':' + self.invoice_no

    def get_invoice_amount(self):
        return self.revenue_amount + self.opex_amount + self.capex_amount

    def save(self, *args, **kwargs):
        self.invoice_ref = self.get_invoice_ref()
        self.invoice_amount = self.get_invoice_amount()
        super(Invoice, self).save(*args, **kwargs)
        self.task.save()

    def can_print(self):
        """
        Return True if Task is not Overrun
        """
        return not self.task.is_overrun and not self.task.is_overbook

    def can_verify(self):
        allowed_task_state = [
            'Work in Progress', 'Work Completed without PCC',
            'Work Completed with PCC'
        ]
        return True if self.task.state in allowed_task_state else False

    @fsm_log_by
    @transition(field=state,
                source='*',
                target='New',
                permission='budget_mgt.change_workflow')
    def set_new(self, by=None):
        pass

    @fsm_log_by
    @transition(field=state,
                source='New',
                target='Verify Invoices',
                permission='budget_mgt.change_workflow',
                conditions=[can_verify])
    def set_verify_invoices(self, by=None):
        pass

    @fsm_log_by
    @transition(field=state,
                source='Verify Invoices',
                target='Overrun Check',
                permission='budget_mgt.change_workflow')
    def set_overrun_check(self, by=None):
        pass

    @fsm_log_by
    @transition(field=state,
                source='Overrun Check',
                target='Print Summary',
                permission='budget_mgt.change_workflow',
                conditions=[can_print])
    def set_print_summary(self, by=None):
        pass

    @fsm_log_by
    @transition(field=state,
                source='Print Summary',
                target='Under Certification',
                permission='budget_mgt.change_workflow')
    def set_under_certification(self, by=None):
        pass

    @fsm_log_by
    @transition(field=state,
                source='Under Certification',
                target='Sent to Finance',
                permission='budget_mgt.change_workflow')
    def set_sent_to_finance(self, by=None):
        pass

    @fsm_log_by
    @transition(field=state,
                source='Sent to Finance',
                target='Completed',
                permission='budget_mgt.change_workflow')
    def set_completed(self, by=None):
        pass
示例#4
0
class Task(ConcurrentTransitionMixin, FsmLogMixin, ManytoManyMixin,
           TimeStampedBaseModel):
    class Transitions:
        trans_1 = [
            'Work in Progress', 'PCC to be Issued', 'PCC Issued', 'Closed'
        ]

    contract = models.ForeignKey(Contract, null=True, on_delete=models.CASCADE)
    contractor = models.ForeignKey(Contractor,
                                   null=True,
                                   on_delete=models.CASCADE)

    state = FSMKeyField(TaskProcess, default="Work in Progress")
    state_date = models.DateTimeField(blank=True, null=True)

    status = models.CharField(max_length=100)
    task_no = models.CharField(max_length=100, unique=True)
    category = models.CharField(max_length=100)

    sicet_type = models.CharField(max_length=100, blank=True)
    section = models.CharField(max_length=100, blank=True)
    sub_section = models.CharField(max_length=100, blank=True)
    cear_title = models.TextField(blank=True)
    remarks = models.TextField(blank=True)

    modernization = models.BooleanField(default=False)

    finance_actual_expenditure = models.DecimalField(max_digits=20,
                                                     decimal_places=2,
                                                     default=Decimal('0.00'))
    transferable = models.DecimalField(max_digits=20,
                                       decimal_places=2,
                                       default=Decimal('0.00'))
    finance_remarks = models.TextField(blank=True)

    proj_no = models.CharField(max_length=100)
    year = models.CharField(max_length=100)

    total_authorize_commitment = models.DecimalField(max_digits=20,
                                                     decimal_places=2,
                                                     default=Decimal('0.00'))
    total_authorize_expenditure = models.DecimalField(max_digits=20,
                                                      decimal_places=2,
                                                      default=Decimal('0.00'))

    total_accrual = models.DecimalField(max_digits=20,
                                        decimal_places=2,
                                        default=Decimal('0.00'))
    actual_expenditure = models.DecimalField(max_digits=20,
                                             decimal_places=2,
                                             default=Decimal('0.00'))
    wip_amount = models.DecimalField(max_digits=20,
                                     decimal_places=2,
                                     default=Decimal('0.00'))
    total_pcc_amount = models.DecimalField(max_digits=20,
                                           decimal_places=2,
                                           default=Decimal('0.00'))

    tags = TaggableManager()

    def __str__(self):
        return self.task_no

    # get initial values for tags
    @property
    def initial_tags(self):
        return [i.name for i in self.tags.all()]

    @property
    def state__name(self):
        return self.state

    @property
    def is_overrun(self):
        return self.actual_expenditure > self.total_accrual

    @property
    def is_overbook(self):
        return self.total_accrual > self.total_authorize_expenditure

    @property
    def is_pcc_issued(self):
        return True if len(self.pcc_set.all()) != 0 else False

    @property
    def is_pcc_amount_ok(self):
        return self.total_pcc_amount <= self.total_authorize_expenditure

    @property
    def is_pcc_complete(self):
        pcc = self.pcc_set.order_by('-pk').first()
        return pcc.is_complete if pcc else False

    @property
    def is_within_work_criteria(self):
        if self.total_authorize_expenditure != 0:
            work_percent = self.total_pcc_amount / self.total_authorize_expenditure
            return 100 >= work_percent * 100 >= 95
        else:
            return False

    @property
    def is_expenditure_within_commitment(self):
        return True if self.total_authorize_expenditure <= self.total_authorize_commitment else False

    def get_wip_amount(self):
        return self.total_authorize_expenditure - self.total_pcc_amount

    def get_year(self):
        string = str(self.task_no)
        string = string.split('-')
        try:
            return string[-1]
        except IndexError:
            return 'invalid Task No'

    def get_region(self):
        string = str(self.task_no)
        string = string.split('-')
        try:
            return string[0]
        except IndexError:
            return 'invalid Task No'

    def get_category(self):
        string = str(self.task_no)
        string = string.split('-')
        try:
            return string[3]
        except IndexError:
            return 'invalid Task No'

    def get_total_authorize_commitment(self):
        total = self.authorizecommitment_set.all().aggregate(sum=Sum('amount'))
        return Decimal('0.00') if total['sum'] is None else total['sum']

    def get_total_authorize_expenditure(self):
        total = self.authorizeexpenditure_set.all().aggregate(
            sum=Sum('amount'))
        return Decimal('0.00') if total['sum'] is None else total['sum']

    def get_total_pcc(self):
        total = self.pcc_set.all().aggregate(sum=Sum('amount'))
        return Decimal('0.00') if total['sum'] is None else total['sum']

    def get_total_accrual(self):
        total = self.accrual_set.all().aggregate(sum=Sum('amount'))
        return Decimal('0.00') if total['sum'] is None else total['sum']

    def get_actual_expenditure(self):
        total = self.invoice_set.all().aggregate(sum=Sum('capex_amount'))
        return Decimal('0.00') if total['sum'] is None else total['sum']

    def can_complete(self):
        return not self.is_overbook and not self.is_overrun and self.is_pcc_amount_ok and \
               self.is_within_work_criteria

    def can_close(self):
        return self.can_complete() and self.is_expenditure_within_commitment

    def pcc_is_issued(self):
        return self.is_pcc_issued

    def parse_task_no(self):
        self.year = self.get_year()
        self.region = self.get_region()
        self.category = self.get_category()

    def save(self, *args, **kwargs):
        self.wip_amount = self.get_wip_amount()
        self.total_accrual = self.get_total_accrual()
        self.total_pcc_amount = self.get_total_pcc()
        self.total_authorize_commitment = self.get_total_authorize_commitment()
        self.total_authorize_expenditure = self.get_total_authorize_expenditure(
        )
        self.actual_expenditure = self.get_actual_expenditure()
        super(Task, self).save(*args, **kwargs)

    @fsm_log_by
    @transition(field=state, source='*', target='Work in Progress')
    def set_work_in_progress(self, by=None):
        pass

    @fsm_log_by
    @transition(field=state,
                source='Work in Progress',
                target='PCC to be Issued',
                conditions=[can_complete])
    def set_pcc_to_be_issued(self, by=None):
        pass

    @fsm_log_by
    @transition(field=state,
                source=['Work in Progress', 'PCC to be Issued'],
                target='PCC Issued',
                conditions=[can_complete, pcc_is_issued])
    def set_pcc_issued(self, by=None):
        pass

    @fsm_log_by
    @transition(field=state,
                source='PCC Issued',
                target='Close',
                conditions=[can_close, pcc_is_issued])
    def set_close(self, by=None):
        pass