Create Flow

Step 1: Extend BaseVoucherCreateConfirmFragment

The fragments first task is to confirm whether the user is happy with their Voucher. The second task is to display loading while the creation and possibly activation of the Voucher occurs. The create screen must extend the BaseVoucherLoadingFragment which does much of the heavy lifting when interacting with the rest of the create flow.

public class SimpleCreateConfirmFragment extends BaseVoucherCreateConfirmFragment {

}
class SimpleCreateConfirmFragment : BaseVoucherCreateConfirmFragment() {

}

Option 1 : Creation

Calling transformVoucher will asynchronously convert the PendingVoucher into a Voucher via the Voucher server. It can not be opened and is not considered funded until is has been activated which can happen on this screen or on the Summary Screen.

This can be achieved by calling the fragments method transformIntoVoucher() and listening for its result.

The following kotlin code would convert the PendingVoucher into a Voucher and if successful continue the flow to the summary screen.

transformIntoVoucher()
        .subscribe(new Subscriber<Voucher>() {
            @Override
            public void onCompleted() {
            }

            @Override
            public void onError(Throwable e) {
                // Error
            }

            @Override
            public void onNext(Voucher voucher) {
                forwardToSummary(voucher);
            }
        });
transformIntoVoucher()
        .subscribe(
                { voucher ->
                    forwardToSummary(voucher)
                },
                { throwable -> 
                    // Error
                })

Option 2 : Activate and Skip the Summary Screen

If you wish to activate here and skip the summary screen you can use fragment methods activateVoucher(Voucher voucher) and forwardToComplete(Voucher voucher)

The following kotlin code would convert the PendingVoucher into a Voucher then activate it and if both are successful finish the flow.

transformIntoVoucher()
        .flatMap(new Func1<Voucher, Observable<Voucher>>() {
            @Override
            public Observable<Voucher> call(Voucher voucher) {
                return activateVoucher(voucher);
            }
        })
        .subscribe(new Subscriber<Voucher>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {
                //Error
            }

            @Override
            public void onNext(Voucher voucher) {
                forwardToComplete(voucher);
            }
        });
transformIntoVoucher()
        .flatMap { voucher -> activateVoucher(voucher) }
        .subscribe(
                { voucher ->
                    forwardToComplete(voucher)
                },
                { throwable -> 
                    // Error
                })

Protected Methods

The fragment has access to the following methods:

// Allows quick access of the create configuration and all it's settings.
CreateConfiguration getCreateConfig()

// The current pending voucher built in the last screen. This can still be modified until `transformIntoVoucher()` is called.
PendingVoucher getPendingVoucher()

// This will communicate with our server to create a Voucher object from a pendingVoucher
Observable<Voucher> transformIntoVoucher()

// This will activate a Voucher, which will make the voucher live. 
Observable<Voucher> activateVoucher(Voucher voucher)

// This moves you forward in the create flow. This should be called if the activateVoucher() has not been call
void forwardToSummary(Voucher voucher)

// This finishes the create flow. This should be called if both transformIntoVoucher() and activateVoucher() is called
void forwardToComplete(Voucher voucher)
// Allows quick access of the create configuration and all it's settings.
fun getCreateConfig() : CreateConfiguration

// The current pending voucher built in the last screen. This can still be modified until `transformIntoVoucher()` is called.
fun getPendingVoucher() : PendingVoucher

// This will communicate with our server to create a Voucher object from a pendingVoucher
fun transformIntoVoucher() : Observable<Voucher>

// This will activate a Voucher, which will make the voucher live. 
fun activateVoucher(voucher: Voucher) : Observable<Voucher>

// This moves you forward in the create flow. This should be called if the activateVoucher() has not been call
fun forwardToSummary(voucher: Voucher)

// This finishes the create flow. This should be called if both transformIntoVoucher() and activateVoucher() is called
fun forwardToComplete(voucher: Voucher)

Using the Navigator

If you want to preview the gift:

getNavigator().previewGift(getActivity(), getPendingVoucher());
navigator.previewGift(activity, pendingVoucher)

Simple Example

This example shows a button that when pressed with transform the voucher and proceed to the summary screen.

SimpleVoucherConfirmFragment.kt

class SimpleVoucherConfirmFragment extends BaseVoucherCreateConfirmFragment {

    private TextView loadingText;
    private VouchrButton sendButton;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_simple_voucher_confirm, container, false);
        loadingText = view.findViewById(R.id.loadingText);
        sendButton = view.findViewById(R.id.sendButton);
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        loadingText.setText("Ready to send?");
        sendButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                loadingText.setText("Sending...");
                transformIntoVoucher()
                        .subscribe(new Subscriber<Voucher>() {
                            @Override
                            public void onCompleted() {
                            }

                            @Override
                            public void onError(Throwable e) { // Error
                                loadingText.setText("Something went wrong... Retry?");
                                sendButton.setVisibility(View.VISIBLE);
                            }

                            @Override
                            public void onNext(Voucher voucher) { // Success
                                forwardToSummary(voucher);
                            }
                        });
            }
        });
    }
}
class SimpleVoucherConfirmFragment : BaseVoucherCreateConfirmFragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_simple_voucher_confirm, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        loadingText.text = "Ready to send?"
        sendButton.setOnClickListener {
            loadingText.text = "Sending..."
            transformIntoVoucher()
                    .subscribe(
                            { voucher -> // Success
                                forwardToSummary(voucher)
                            },
                            { throwable -> // Error
                                loadingText.text = "Something went wrong... Retry?"
                                sendButton.visibility = View.VISIBLE
                            })
        }
    }
}

fragment_simple_voucher_confirm.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/loadingText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:text="Sending in progress..."
        android:textAppearance="?TextAppearance.SecondaryHeader"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.surpriise.vouchrcommon.ui.components.VouchrButton
        android:id="@+id/sendButton"
        style="?VouchrButton.Dark.Positive"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="@string/send"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/loadingText" />


</android.support.constraint.ConstraintLayout>

Step 2: Set CreateFlowController

Setup the CreateFlowController while building the CreateConfiguration. When you setup the CreateFlowController override the createConfirmScreen function and pass in your own screen that we built in step 1.

CreateConfiguration createConfiguration = new CreateConfiguration.Builder(context)
        .setCreateFlowController(new CreateFlowController.Default() {
            @Override
            public BaseVoucherCreateConfirmFragment createConfirmScreen(PendingVoucher pv, CreateConfiguration cc) {
                return new SimpleVoucherLoadingFragment();
            }
        })
        .build()

Engine.Builder engineBuilder = new Engine.Builder(VOUCHR_BASE_URL, SDK_ID);
engineBuilder.setCreateConfig(new CreateConfiguration.Builder(this).build())
engineBuilder.build().startup(this);
val createConfiguration = CreateConfiguration.Builder(context)
        .setCreateFlowController(object : CreateFlowController.Default() {
            override fun createConfirmScreen(pv: PendingVoucher, cc: CreateConfiguration): BaseVoucherCreateConfirmFragment {
                return SimpleVoucherLoadingFragment()
            }
        })
        .build()

val engineBuilder = Engine.Builder(VOUCHR_BASE_URL, SDK_ID)
engineBuilder.setCreateConfig(CreateConfiguration.Builder(this).build())
engineBuilder.build().startup(this)

More information on the CreateFlowController can be found in the JavaDocs here

Step 3: Launching the create flow

To start the create flow use the following IntentBuilder.

VoucherCreationActivity.IntentBuilder.init().start(this);
VoucherCreationActivity.IntentBuilder.init().start(this)

And depending on your theme after progressing through the flow you should see something like this

Create Loading Screen