django-logic icon indicating copy to clipboard operation
django-logic copied to clipboard

How to call transition from 2 statefields

Open zenners opened this issue 2 years ago • 1 comments

Hello, love the design of this package thinking of integrating it with our exisitng app.

I tried following your example of having 2 state fields in a model

process.py

class ApprovalProc(BaseProcess):
    transitions = [
        Transition(action_name='approve', sources=['pending', 'awaiting_seller'], target='approved'),
        Transition(action_name='schedule', sources=['approved'], target='scheduled'),
        Transition(action_name='reject', sources=['pending', 'awaiting_seller'], target='rejected'),
        Transition(action_name='await_seller', sources=['pending'], target='awaiting_seller'),
        Transition(action_name='cancel', sources=['pending', 'approved'], target='cancelled'),
        # Action(action_name='update', side_effects=[]),
    ]
class AuctionProc(BaseProcess):
     transitions = [
        Transition(action_name='start', sources=['not_started', 'on_hold'], target='ongoing'),
        Transition(action_name='pause', sources=['ongoing',], target='on_hold'),
        Transition(action_name='end', sources=['ongoing',], target='ended'),
        Transition(action_name='void', sources=['not_started', 'on_hold', 'ongoing', 'ended'], target='voided'),

        # Action(action_name='update', side_effects=[update_data]),
    ]
ListingProcess = ProcessManager.bind_state_fields(listing_status=ApprovalProc,auction_status=AuctionProc )

class Listing(ListingProcess, models.Model):
    listing_status = models.CharField(choices=ApprovalProc.states, default='pending', max_length=100, blank=True)
    auction_status = models.CharField(choices=AuctionProc.states, default='not_started', max_length=100, blank=True)

When i try to play around with in the shell

l = Listing.objects.first()
l.process.approve()

I get this error

django_logic.exceptions.TransitionNotAllowed: Process class <class 'listings.process.AuctionProc'> has no transition with action name approve

transitions from the AuctionProc get called without any errors. So how do I call the other process?

zenners avatar Sep 23 '22 07:09 zenners

if i

l.process.state_fields

I get this, not sure if the bind state fields function is getting both of the declarations

functools.partial(<bound method Process._get_transition_method of <listings.process.AuctionProc object at 0x7fbd93a395b0>>, 'state_fields')

zenners avatar Sep 23 '22 07:09 zenners

@zenners sorry for late reply 😃 Since you have more than one process class related to the same model, it needs to define different process name. For example:

class ApprovalProc(BaseProcess):
    transitions = [
        Transition(action_name='approve', sources=['pending', 'awaiting_seller'], target='approved'),
        Transition(action_name='schedule', sources=['approved'], target='scheduled'),
        Transition(action_name='reject', sources=['pending', 'awaiting_seller'], target='rejected'),
        Transition(action_name='await_seller', sources=['pending'], target='awaiting_seller'),
        Transition(action_name='cancel', sources=['pending', 'approved'], target='cancelled'),
        # Action(action_name='update', side_effects=[]),
    ]
class AuctionProc(BaseProcess):
     process_name = "auction_process"
     transitions = [
        Transition(action_name='start', sources=['not_started', 'on_hold'], target='ongoing'),
        Transition(action_name='pause', sources=['ongoing',], target='on_hold'),
        Transition(action_name='end', sources=['ongoing',], target='ended'),
        Transition(action_name='void', sources=['not_started', 'on_hold', 'ongoing', 'ended'], target='voided'),

        # Action(action_name='update', side_effects=[update_data]),
    ]
ListingProcess = ProcessManager.bind_state_fields(listing_status=ApprovalProc,auction_status=AuctionProc )

Then, you will be able to do the following:

l.process.approve()
l.auction_process.start()

emil-balashov avatar Aug 02 '23 06:08 emil-balashov