func (plan BasePlan) MarshalYAML() (interface{}, error) {
	bz, err := codec.MarshalYAML(codec.NewProtoCodec(codectypes.NewInterfaceRegistry()), &plan)
	if err != nil {
		return nil, err
	}
	return string(bz), err
}
MarshalYAML returns the YAML representation of a Plan.
package types
import (
	"fmt"
	"strings"
	"time"
	"github.com/cosmos/cosmos-sdk/codec"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
	sdk "github.com/cosmos/cosmos-sdk/types"
	"github.com/cosmos/cosmos-sdk/types/address"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
	"github.com/gogo/protobuf/proto"
)
const (
	MaxNameLength                    int    = 140
	PrivatePlanFarmingPoolAddrPrefix string = "PrivatePlan"
	PoolAddrSplitter                 string = "|"
)
var (
	_ PlanI = (*FixedAmountPlan)(nil)
	_ PlanI = (*RatioPlan)(nil)
)
func NewBasePlan(id uint64, name string, typ PlanType, farmingPoolAddr, terminationAddr string, coinWeights sdk.DecCoins, startTime, endTime time.Time) *BasePlan {
	basePlan := &BasePlan{
		Id:                   id,
		Name:                 name,
		Type:                 typ,
		FarmingPoolAddress:   farmingPoolAddr,
		TerminationAddress:   terminationAddr,
		StakingCoinWeights:   coinWeights,
		StartTime:            startTime,
		EndTime:              endTime,
		Terminated:           false,
		LastDistributionTime: nil,
		DistributedCoins:     sdk.NewCoins(),
	}
	return basePlan
}
func (plan BasePlan) GetId() uint64 {  
	return plan.Id
}
func (plan *BasePlan) SetId(id uint64) error {  
	plan.Id = id
	return nil
}
func (plan BasePlan) GetName() string {  
	return plan.Name
}
func (plan *BasePlan) SetName(name string) error {  
	plan.Name = name
	return nil
}
func (plan BasePlan) GetType() PlanType {
	return plan.Type
}
func (plan *BasePlan) SetType(typ PlanType) error {
	plan.Type = typ
	return nil
}
func (plan BasePlan) GetFarmingPoolAddress() sdk.AccAddress {
	addr, _ := sdk.AccAddressFromBech32(plan.FarmingPoolAddress)
	return addr
}
func (plan *BasePlan) SetFarmingPoolAddress(addr sdk.AccAddress) error {
	plan.FarmingPoolAddress = addr.String()
	return nil
}
func (plan BasePlan) GetTerminationAddress() sdk.AccAddress {
	addr, _ := sdk.AccAddressFromBech32(plan.TerminationAddress)
	return addr
}
func (plan *BasePlan) SetTerminationAddress(addr sdk.AccAddress) error {
	plan.TerminationAddress = addr.String()
	return nil
}
func (plan BasePlan) GetStakingCoinWeights() sdk.DecCoins {
	return plan.StakingCoinWeights
}
func (plan *BasePlan) SetStakingCoinWeights(coinWeights sdk.DecCoins) error {
	plan.StakingCoinWeights = coinWeights
	return nil
}
func (plan BasePlan) GetStartTime() time.Time {
	return plan.StartTime
}
func (plan *BasePlan) SetStartTime(t time.Time) error {
	plan.StartTime = t
	return nil
}
func (plan BasePlan) GetEndTime() time.Time {
	return plan.EndTime
}
func (plan *BasePlan) SetEndTime(t time.Time) error {
	plan.EndTime = t
	return nil
}
func (plan *BasePlan) GetTerminated() bool {
	return plan.Terminated
}
func (plan *BasePlan) SetTerminated(terminated bool) error {
	plan.Terminated = terminated
	return nil
}
func (plan *BasePlan) GetLastDistributionTime() *time.Time {
	return plan.LastDistributionTime
}
func (plan *BasePlan) SetLastDistributionTime(t *time.Time) error {
	plan.LastDistributionTime = t
	return nil
}
func (plan *BasePlan) GetDistributedCoins() sdk.Coins {
	return plan.DistributedCoins
}
func (plan *BasePlan) SetDistributedCoins(distributedCoins sdk.Coins) error {
	plan.DistributedCoins = distributedCoins
	return nil
}
func (plan BasePlan) GetBasePlan() *BasePlan {
	return &BasePlan{
		Id:                   plan.GetId(),
		Name:                 plan.GetName(),
		Type:                 plan.GetType(),
		FarmingPoolAddress:   plan.GetFarmingPoolAddress().String(),
		TerminationAddress:   plan.GetTerminationAddress().String(),
		StakingCoinWeights:   plan.GetStakingCoinWeights(),
		StartTime:            plan.GetStartTime(),
		EndTime:              plan.GetEndTime(),
		Terminated:           plan.GetTerminated(),
		LastDistributionTime: plan.GetLastDistributionTime(),
		DistributedCoins:     plan.GetDistributedCoins(),
	}
}
func (plan BasePlan) Validate() error {
	if plan.Type != PlanTypePrivate && plan.Type != PlanTypePublic {
		return sdkerrors.Wrapf(ErrInvalidPlanType, "unknown plan type: %s", plan.Type)
	}
	if _, err := sdk.AccAddressFromBech32(plan.FarmingPoolAddress); err != nil {
		return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid farming pool address %q: %v", plan.FarmingPoolAddress, err)
	}
	if _, err := sdk.AccAddressFromBech32(plan.TerminationAddress); err != nil {
		return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid termination address %q: %v", plan.TerminationAddress, err)
	}
	if strings.Contains(plan.Name, PoolAddrSplitter) {
		return sdkerrors.Wrapf(ErrInvalidPlanName, "plan name cannot contain %s", PoolAddrSplitter)
	}
	if len(plan.Name) > MaxNameLength {
		return sdkerrors.Wrapf(ErrInvalidPlanName, "plan name cannot be longer than max length of %d", MaxNameLength)
	}
	if err := ValidateStakingCoinTotalWeights(plan.StakingCoinWeights); err != nil {
		return err
	}
	if !plan.EndTime.After(plan.StartTime) {
		return sdkerrors.Wrapf(ErrInvalidPlanEndTime, "end time %s must be greater than start time %s", plan.EndTime, plan.StartTime)
	}
	if err := plan.DistributedCoins.Validate(); err != nil {
		return sdkerrors.Wrapf(sdkerrors.ErrInvalidCoins, "invalid distributed coins: %v", err)
	}
	return nil
}
func (plan BasePlan) String() string {
	out, _ := plan.MarshalYAML()
	return out.(string)
}