Skip to content

How to pay with new wallet? #25

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
moecasts opened this issue May 12, 2019 · 35 comments
Closed

How to pay with new wallet? #25

moecasts opened this issue May 12, 2019 · 35 comments
Assignees
Labels
good issue Good for newcomers
Milestone

Comments

@moecasts
Copy link
Contributor

moecasts commented May 12, 2019

There are multi wallets in the app, how to pay with the right wallet?

@rez1dent3
Copy link
Member

@moecasts

new wallet:

$usd = $user->createWallet(['name' => 'USD']);
// todo deposit
$usd->pay($product);

find wallet:

$usd = $user->getWallet('usd'); // find by slug
$usd->pay($product);

Снимок экрана от 2019-05-12 21-36-03

@rez1dent3
Copy link
Member

rez1dent3 commented May 12, 2019

@moecasts I have noticed that the free is considered not true. Soon to be fixed....

@rez1dent3 rez1dent3 self-assigned this May 12, 2019
@rez1dent3 rez1dent3 added the good issue Good for newcomers label May 12, 2019
@moecasts
Copy link
Contributor Author

moecasts commented May 13, 2019

@rez1dent3 I have got that, when I pay with the user's second wallet, the product default wallet will get the money. Also, the transfer from_type will be the Wallet Class, it should be the User Class, and the transfer status is 'gift' which should be 'paid'.

@rez1dent3
Copy link
Member

@moecasts Yes, the bug is there.
Really should go into the status "paid". But the goods have to be fixed to a wallet, it works correctly.

In PR #30 I made changes to the project.

@rez1dent3
Copy link
Member

@moecasts fixes in tag 2.3.0. One migration was added.

@moecasts
Copy link
Contributor Author

@rez1dent3 I got this error after upgraded. Is that a wrong in the package?
image

@rez1dent3
Copy link
Member

@moecasts funnily... I'll try to catch it. I didn't have one of those.

@rez1dent3
Copy link
Member

@moecasts added doctrine/dbal depending. the problem should disappear... tag 2.3.1

@moecasts
Copy link
Contributor Author

@rez1dent3 Yes, I have just found that. Thank you very much!

@moecasts
Copy link
Contributor Author

moecasts commented May 13, 2019

@rez1dent3 There is a new error. And I solved it by adding that to the new migration.
Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
image

@rez1dent3
Copy link
Member

@moecasts able to reproduce...

@moecasts
Copy link
Contributor Author

@rez1dent3 Will you add this to the package?

@rez1dent3
Copy link
Member

@moecasts yes

@moecasts
Copy link
Contributor Author

@rez1dent3 Thank you very much!

@rez1dent3
Copy link
Member

@moecasts done. see the tag 2.3.2

@moecasts
Copy link
Contributor Author

@rez1dent3 There is a problem, when I pay with new wallet, the transfer's from_type and from_id is wallet class and id, it would cause that $user->paid($product) will not be work. Also, Both User and Product have two wallets. When user pay with default wallet and new wallet, only the product default will get the money. In my opinion, the same slug wallet should get the money.

image

image

image

@rez1dent3
Copy link
Member

@moecasts The user is a wallet, so when you buy a product is assigned to him. This feature is necessary for the implementation of the return (refund) of goods.

@rez1dent3
Copy link
Member

@moecasts You can inherit from Wallet and add relations.

@moecasts
Copy link
Contributor Author

@rez1dent3 I try to get the new wallet transfers, but it only return the default wallet transfers. Is it wrong?
image
image
image

@rez1dent3 rez1dent3 mentioned this issue May 13, 2019
Merged
@rez1dent3
Copy link
Member

@moecasts
Branch 2.4.x-dev

composer req bavix/laravel-wallet:2.4.x-dev

Simple:

    $user = \App\User::first();
    $user->load('wallets.transfers');

    $item = \App\Item::first();
    $usd = $user->getWallet('usd');
    $usd->pay($item);  // first 

    $user->wallet->pay($item); // payment by default wallet
    $usd->pay($item); // payment with new wallet

Result:

{
   "id":1,
   "name":"Arch Schaden",
   "email":"[email protected]",
   "email_verified_at":"2019-05-13 18:28:23",
   "created_at":"2019-05-13 18:28:23",
   "updated_at":"2019-05-13 18:28:23",
   "wallets":[
      {
         "id":1,
         "holder_type":"App\\User",
         "holder_id":1,
         "name":"Default Wallet",
         "slug":"default",
         "description":null,
         "balance":238832,
         "created_at":"2019-05-13 18:30:40",
         "updated_at":"2019-05-13 18:45:25",
         "transfers":[
            {
               "id":3,
               "from_type":"Bavix\\Wallet\\Models\\Wallet",
               "from_id":1,
               "to_type":"App\\Item",
               "to_id":1,
               "status":"paid",
               "status_last":null,
               "deposit_id":9,
               "withdraw_id":8,
               "fee":0,
               "uuid":"d52fb86e-37b8-4b5f-994c-ca1cd986bb78",
               "created_at":"2019-05-13 18:45:25",
               "updated_at":"2019-05-13 18:45:25"
            }
         ]
      },
      {
         "id":3,
         "holder_type":"App\\User",
         "holder_id":1,
         "name":"EUR",
         "slug":"eur",
         "description":null,
         "balance":716496,
         "created_at":"2019-05-13 18:30:40",
         "updated_at":"2019-05-13 18:35:43",
         "transfers":[

         ]
      },
      {
         "id":2,
         "holder_type":"App\\User",
         "holder_id":1,
         "name":"USD",
         "slug":"usd",
         "description":null,
         "balance":238832,
         "created_at":"2019-05-13 18:30:40",
         "updated_at":"2019-05-13 18:45:25",
         "transfers":[
            {
               "id":2,
               "from_type":"Bavix\\Wallet\\Models\\Wallet",
               "from_id":2,
               "to_type":"App\\Item",
               "to_id":1,
               "status":"paid",
               "status_last":null,
               "deposit_id":7,
               "withdraw_id":6,
               "fee":0,
               "uuid":"ef6b6a71-b375-4d07-b2a3-98f3b1491f96",
               "created_at":"2019-05-13 18:41:35",
               "updated_at":"2019-05-13 18:41:35"
            },
            {
               "id":4,
               "from_type":"Bavix\\Wallet\\Models\\Wallet",
               "from_id":2,
               "to_type":"App\\Item",
               "to_id":1,
               "status":"paid",
               "status_last":null,
               "deposit_id":11,
               "withdraw_id":10,
               "fee":0,
               "uuid":"52289967-76c0-4cdc-ae25-0583b12e83df",
               "created_at":"2019-05-13 18:45:25",
               "updated_at":"2019-05-13 18:45:25"
            }
         ]
      }
   ]
}

@moecasts
Copy link
Contributor Author

@rez1dent3 I found that, the $user->wallet will return the first wallet of the user but not the default wallet of user. So I think that there should be a select in the wallet relation like this:

public function wallet(): MorphOne
{
    return ($this instanceof WalletModel ? $this->holder : $this)
        ->morphOne(config('wallet.wallet.model'), 'holder')
        ->where('slug', config('wallet.wallet.default.slug'))
        ->withDefault([
            'name' => config('wallet.wallet.default.name'),
            'slug' => config('wallet.wallet.default.slug'),
            'balance' => 0,
        ]);
}

@rez1dent3
Copy link
Member

@moecasts Here the default wallet will return, you can check.

@moecasts
Copy link
Contributor Author

moecasts commented May 14, 2019

@rez1dent3 The paid function is still not work with the new wallet. I have solved by this code. Is there any help for your improvement?

public function payForPlan(Wallet $wallet, Product $product, $type = 'subscribe', bool $force = false): Transfer
{
    if (!$product->canBuy($this, $force)) {
        throw new ProductEnded(trans('wallet::errors.product_stock'));
    }

    $amount = $product->getAmountProduct($type);

    $productWallet = $product->getWallet($wallet->slug);

    if ($force) {
        return $wallet->forceTransfer(
            $productWallet,
            $amount,
            $product->getMetaProduct(),
            Transfer::STATUS_PAID
        );
    }

    return $wallet->transfer(
        $productWallet,
        $amount,
        $product->getMetaProduct(),
        Transfer::STATUS_PAID
    );
}

public function paidForPlan(Wallet $wallet, Product $product, bool $gifts = false): ?Transfer
{
    $status = [Transfer::STATUS_PAID];
    if ($gifts) {
        $status[] = Transfer::STATUS_GIFT;
    }

    $productWallet = $product->getWallet($wallet->slug);

    /**
     * @var Model $product
     * @var Transfer $query
     */
    $query = $wallet->transfers();
    return $query
        ->where('to_type', $productWallet->getMorphClass())
        ->where('to_id', $productWallet->getKey())
        ->whereIn('status', $status)
        ->orderBy('id', 'desc')
        ->first();
}

@moecasts
Copy link
Contributor Author

@rez1dent3 In my opinion, the transfers table should not have from_type and to_type columns, we can get the holder without that columns.

@rez1dent3
Copy link
Member

@moecasts Initially, the wallet was developed for yourself and without the ability to work with many wallets. Because of this, such a structure was chosen. It works for many wallets, but the goods will be assigned to the wallet.

In the next versions, I plan to implement a verification feature similar to yours, but it should be done more accurately and abstractly.

PS,
All wishes for version 3.0, you can write here #18

@moecasts
Copy link
Contributor Author

@rez1dent3 Sorry what's the meaning of the goods will be assigned to the wallet.? I can't understand it.

@rez1dent3
Copy link
Member

rez1dent3 commented May 14, 2019

@moecasts
When buying a product in the database, will be assigned to the wallet. Not per user. If you check the paid method of the wallet, the result will be TRUE.

$user->wallet->pay($item);
$user->paid($item); // false
$user->wallet->pay($item); // true

@rez1dent3
Copy link
Member

@moecasts
The peculiarity of the wallets.

At the moment there can be 2 solutions.

  1. You create a table and store the data yourself.
  2. Add a link and pull data from all wallets, then it will work.

@moecasts
Copy link
Contributor Author

@moecasts Here the default wallet will return, you can check.

I checked,it did't return the default wallet.

Code:

public function wallet(): MorphOne
{
    return ($this instanceof WalletModel ? $this->holder : $this)
        ->morphOne(config('wallet.wallet.model'), 'holder')
        // ->where('slug', config('wallet.wallet.default.slug'))
        ->withDefault([
            'name' => config('wallet.wallet.default.name'),
            'slug' => config('wallet.wallet.default.slug'),
            'balance' => 0,
        ]);
}

Result:

[
    {
        "id": 2,
        "holder_type": "App\\Models\\User",
        "holder_id": 11,
        "name": "喵粮",
        "slug": "coins",
        "description": null,
        "balance": 206004,
        "created_at": "2019-05-13 22:57:16",
        "updated_at": "2019-05-14 13:56:19"
    }
]

But the default wallet is

[
    {
        "id": 1,
        "holder_type": "App\\Models\\User",
        "holder_id": 11,
        "name": "积分",
        "slug": "points",
        "description": null,
        "balance": 53300,
        "created_at": "2019-05-13 22:57:16",
        "updated_at": "2019-05-14 13:30:14"
    }
]

Here is the data
image

@rez1dent3
Copy link
Member

@moecasts I can replace it with $this, it won't break anything. need to?

@moecasts
Copy link
Contributor Author

@rez1dent3 just need to add this code ->where('slug', config('wallet.wallet.default.slug')), the problem will be solved. That's won't break anything too.

@rez1dent3
Copy link
Member

@moecasts Okay I will try. Thank you.

@moecasts
Copy link
Contributor Author

@rez1dent3 thank you very much!

@rez1dent3
Copy link
Member

@moecasts done. branch 2.4.x-dev

rez1dent3 added a commit that referenced this issue May 14, 2019
- Add zh-CN trans. @moecasts
- Add ru trans
- Add method `holderTransfers` #25

### Changed
- optimize `getWallet` method
- optimize relations wallets

### Fixed
- fixed getting a default wallet #25 @moecasts

### Removed
- trait CanBePaid (deprecated ^2.2)
- trait CanBePaidFloat (deprecated ^2.2)
@rez1dent3
Copy link
Member

@moecasts Edits made. Use the 2.4.0 tag. Thank you.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
good issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants