Skip to content
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

Feature: Withdraw charges #1943

Merged
merged 44 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
f598805
⚙️Update: Fields commission show condition for multipurpose use
Aunshon Jul 21, 2023
5c1da6f
Merge branch 'develop' into feat/withdraw-charges
Aunshon Jul 21, 2023
f43e4b5
✅Withdraw charger ui done. SocialFields.vue component modified and Fi…
Aunshon Jul 21, 2023
fc5fc3a
Add auto open in SocialFields.vue
Aunshon Jul 24, 2023
3fdbf00
⚡️Reset Fields.vue and SocialFields.vue component to normal component…
Aunshon Jul 25, 2023
13fe0bb
⚡️Reset Fields.vue and SocialFields.vue component to normal component…
Aunshon Jul 25, 2023
19e6e43
⚡️Redesign withdraw method and charge ui and save active withdraw and…
Aunshon Jul 25, 2023
0962450
⚡️Bring charge data to vendor dashboard frontend
Aunshon Jul 26, 2023
3368308
⚡️Revert Fields.vue
Aunshon Jul 26, 2023
e34e992
⚡️Revert Fields.vue
Aunshon Jul 26, 2023
9ebb35d
⚡️Revert Fields.vue
Aunshon Jul 26, 2023
a9c8bd3
⚡️Withdraw charge show based on active withdraw switch DONE.
Aunshon Jul 26, 2023
21a1495
⚡️Show charge and revivable amount in vendor
Aunshon Jul 27, 2023
ec98694
⚡️Save withdraw charge when request vendor.
Aunshon Jul 27, 2023
bb967cc
⚡️Show withdraw charge and receivable amount in admin and vendor dash…
Aunshon Jul 28, 2023
7720884
⚡️Test charge and show withdraw charge by ajax
Aunshon Jul 28, 2023
d0cb9c8
⚡️Withdraw charge validation on withdraw create in api and hook
Aunshon Jul 30, 2023
15f30f0
⚡️Complete test case
Aunshon Jul 31, 2023
40b7cf0
⚡️Allignment fix
Aunshon Jul 31, 2023
ca871f7
⚡️Allignment fix
Aunshon Jul 31, 2023
ab760da
⚡️Allignment fix
Aunshon Jul 31, 2023
c164834
⚡️Allignment fix
Aunshon Jul 31, 2023
4df8390
⚡️Allignment fix
Aunshon Jul 31, 2023
06c3e45
Merge branch 'develop' into feat/withdraw-charges
Aunshon Aug 3, 2023
d9b939b
⚡️Fix make withdraw request errors
Aunshon Aug 3, 2023
695b007
⚡️Move charge validation code to withdraw validator for ajax and api
Aunshon Aug 3, 2023
ac51e92
⚡️Exclude automated withdraw methods in withdraw charge setting
Aunshon Aug 3, 2023
e7785e6
⚡️rewrite get charge data function in Withdraw.php class, that now we…
Aunshon Aug 4, 2023
e2fd7cd
Pr review updated
Aunshon Sep 15, 2023
7093a4c
Merge branch 'develop' into feat/withdraw-charges
Aunshon Sep 15, 2023
d66e642
Remove get withdraw charge ajax
Aunshon Sep 19, 2023
5eb2806
Merge branch 'develop' into feat/withdraw-charges
Aunshon Oct 26, 2023
9225ec1
Fix: date when withdraw charge create.
Aunshon Nov 20, 2023
9cfa4d4
Merge branch 'develop' into feat/withdraw-charges
Aunshon Nov 20, 2023
602176d
Fix: date when withdraw charge create.
Aunshon Nov 20, 2023
52235e1
Fix withdraw create date, fix get withdraw request responses, charge …
Aunshon Nov 20, 2023
2a125d1
Fix: empty id returning when create withdraw by api.
Aunshon Nov 27, 2023
f9acbd5
Fix: format money of withdraw charge.
Aunshon Dec 6, 2023
b27dead
Fix: withdraw charge negative value
Aunshon Dec 6, 2023
3b74f0b
Merge branch 'develop' into feat/withdraw-charges
Aunshon Dec 6, 2023
88623c2
Fix: withdraw charge negative value
Aunshon Dec 6, 2023
7fae9f4
Fix: withdraw charge negative value
Aunshon Dec 6, 2023
c303166
Fix: phpcs
Aunshon Dec 11, 2023
3cbc8da
Merge branch 'develop' into feat/withdraw-charges
Aunshon Dec 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions assets/src/js/withdraw.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,38 @@
$("input[name='withdraw-schedule']").on( 'change', (e) => {
Dokan_Withdraw.handleScheduleChange( e );
});

$( "[name='withdraw_method'][id='withdraw-method']" ).on( 'change', ( e ) => {
Dokan_Withdraw.calculateWithdrawCharges();
} );

$( 'input#withdraw-amount' ).on( 'keyup', Dokan_Withdraw.debounce( Dokan_Withdraw.calculateWithdrawCharges, 500 ) );
},

debounce( func, wait, immediate ) {
var timeout;
return function () {
var context = this,
args = arguments;
var later = function () {
timeout = null;
if ( ! immediate ) func.apply( context, args );
};
var callNow = immediate && ! timeout;
clearTimeout( timeout );
timeout = setTimeout( later, wait );
if ( callNow ) func.apply( context, args );
};
},
openRequestWithdrawWindow: () => {
const withdrawTemplate = wp.template( 'withdraw-request-popup' ),
modal = $( '#dokan-withdraw-request-popup' ).iziModal( {
width : 690,
overlayColor: 'rgba(0, 0, 0, 0.8)',
headerColor : dokan.modal_header_color,
onOpening : function ( modal ) {
Dokan_Withdraw.calculateWithdrawCharges();
},
} );

modal.iziModal( 'setContent', withdrawTemplate().trim() );
Expand Down Expand Up @@ -200,6 +225,89 @@
const nextDate = $(e.target).data('next-schedule');
$( '#dokan-withdraw-next-scheduled-date').html(nextDate);
},
calculateWithdrawCharges: () => {
let charges = $( "select[name='withdraw_method'][id='withdraw-method'] option:selected" ).data();
if (
$( '#dokan-send-withdraw-request-popup-form > .dokan-alert-danger' ).length
|| ! charges
) {
return;
}

let withdrawMethod = $(
"[name='withdraw_method'][id='withdraw-method']"
).val();
let withdrawAmount = $(
"[name='withdraw_amount'][id='withdraw-amount']"
).val();
withdrawAmount = accounting.unformat(
withdrawAmount,
dokan_refund.mon_decimal_point
);
let { chargePercentage, chargeFixed } = $(
"select[name='withdraw_method'][id='withdraw-method'] option:selected"
).data();
let chargeAmount = 0;
let nonce = $( '#dokan_withdraw_charge_nonce' ).val();

$.post(
dokan.ajaxurl,
{
action: 'dokan_handle_get_withdraw_method_charge',
dokan_withdraw_charge_nonce: nonce,
method: withdrawMethod,
amount: withdrawAmount,
},
( response ) => {
let data = response.data ? response.data : {};
Dokan_Withdraw.showWithdrawChargeHtml( data );

$( '#dokan-withdraw-request-submit' ).attr(
'disabled',
! response.success
);
}
);
},

showWithdrawChargeHtml( chargeData ) {
let chargeSection = $( '#dokan-withdraw-charge-section' );
let revivableSection = $( '#dokan-withdraw-revivable-section' );

if ( ! chargeData.plain || ! chargeData.plain.charge ) {
chargeSection.hide();
revivableSection.hide();

return;
}

let chargeText = '';

if (
chargeData.plain.charge_data &&
chargeData.plain.charge_data.fixed
) {
chargeText += `${ chargeData.html.charge_data.fixed }`;
}

if (
chargeData.plain.charge_data &&
chargeData.plain.charge_data.percentage
) {
chargeText += chargeText ? ' + ' : '';
chargeText += `${ chargeData.html.charge_data.percentage }`;
chargeText += ` = ${ chargeData.html.charge }`;
}

$( '#dokan-withdraw-charge-section-text' ).html( chargeText );

$( '#dokan-withdraw-revivable-section-text' ).html(
chargeData.plain.receivable ? chargeData.html.receivable : ''
);

chargeSection.show();
revivableSection.show();
},
};

$(document).ready(function() {
Expand Down
1 change: 1 addition & 0 deletions dokan.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
* @class WeDevs_Dokan The class that holds the entire WeDevs_Dokan plugin
*
* @property WeDevs\Dokan\BackgroundProcess\Manager $bg_process Instance of WeDevs\Dokan\BackgroundProcess\Manager class
* @property WeDevs\Dokan\Withdraw\Manager $withdraw Instance of WeDevs\Dokan\Withdraw\Manager class
*/
final class WeDevs_Dokan {

Expand Down
20 changes: 19 additions & 1 deletion includes/Admin/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ public function get_settings_sections() {
'description' => __( 'Withdraw Settings, Threshold', 'dokan-lite' ),
'document_link' => 'https://wedevs.com/docs/dokan/settings/withdraw-options/',
'settings_title' => __( 'Withdraw Settings', 'dokan-lite' ),
'settings_description' => __( 'You can configure your store\'s withdrawal methods, limits, order status and more.', 'dokan-lite' ),
'settings_description' => __( 'You can configure your store\'s withdrawal methods, charges, limits, order status and more.', 'dokan-lite' ),
],
[
'id' => 'dokan_reverse_withdrawal',
Expand Down Expand Up @@ -587,6 +587,24 @@ public function get_settings_fields() {
'options' => dokan_withdraw_get_methods(),
'tooltip' => __( 'Check to add available payment methods for vendors to withdraw money.', 'dokan-lite' ),
],
'withdraw_charges' => [
'name' => 'withdraw_charges',
'label' => __( 'Withdraw Charges', 'dokan-lite' ),
'desc' => __( 'Select suitable withdraw charges for vendors', 'dokan-lite' ),
'type' => 'charges',
'options' => dokan_withdraw_get_methods(),
'chargeable_methods' => dokan_withdraw_get_chargeable_methods(),
'default' => dokan_withdraw_get_method_charges(),
'show_if' => [
'withdraw_methods' => [
'contains-any' => array_keys( dokan_withdraw_get_methods() ),
],
],
'items_show_if' => [
'key' => 'withdraw_methods',
'condition' => 'contains-key-value',
],
],
'withdraw_limit' => [
'name' => 'withdraw_limit',
'label' => __( 'Minimum Withdraw Limit', 'dokan-lite' ),
Expand Down
2 changes: 1 addition & 1 deletion includes/Assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ public function get_scripts() {
],
'dokan-script' => [
'src' => $asset_url . '/js/dokan.js',
'deps' => [ 'imgareaselect', 'customize-base', 'customize-model', 'dokan-i18n-jed', 'jquery-tiptip', 'moment', 'dokan-date-range-picker' ],
'deps' => [ 'imgareaselect', 'customize-base', 'customize-model', 'dokan-i18n-jed', 'jquery-tiptip', 'moment', 'dokan-date-range-picker', 'dokan-accounting' ],
'version' => filemtime( $asset_path . 'js/dokan.js' ),
],
'dokan-vue-vendor' => [
Expand Down
16 changes: 10 additions & 6 deletions includes/Dashboard/Templates/Withdraw.php
Original file line number Diff line number Diff line change
Expand Up @@ -434,13 +434,16 @@ public function withdraw_dashboard_layout_display() {
return;
}

/**
* @var $last_withdraw \WeDevs\Dokan\Withdraw\Withdraw[]
*/
$last_withdraw = dokan()->withdraw->get_withdraw_requests( dokan_get_current_user_id(), 1, 1 );
$payment_details = __( 'You do not have any approved withdraw yet.', 'dokan-lite' );

if ( ! empty( $last_withdraw ) ) {
$last_withdraw_amount = '<strong>' . wc_price( $last_withdraw[0]->amount ) . '</strong>';
$last_withdraw_date = '<strong><em>' . dokan_format_date( $last_withdraw[0]->date ) . '</em></strong>';
$last_withdraw_method_used = '<strong>' . dokan_withdraw_get_method_title( $last_withdraw[0]->method ) . '</strong>';
$last_withdraw_amount = '<strong>' . wc_price( $last_withdraw[0]->get_amount() ) . '</strong>';
$last_withdraw_date = '<strong><em>' . dokan_format_date( $last_withdraw[0]->get_date() ) . '</em></strong>';
$last_withdraw_method_used = '<strong>' . dokan_withdraw_get_method_title( $last_withdraw[0]->get_method() ) . '</strong>';

// translators: 1: Last formatted withdraw amount 2: Last formatted withdraw date 3: Last formatted withdraw method used.
$payment_details = sprintf( __( '%1$s on %2$s to %3$s', 'dokan-lite' ), $last_withdraw_amount, $last_withdraw_date, $last_withdraw_method_used );
Expand Down Expand Up @@ -502,9 +505,10 @@ public function withdraw_request_popup_form_content() {
$default_withdraw_method = dokan_withdraw_get_default_method( $current_user_id );
dokan_get_template_part(
'withdraw/request-form', '', array(
'amount' => NumberUtil::round( $balance, wc_get_price_decimals(), PHP_ROUND_HALF_DOWN ), // we are setting 12.3456 to 12.34 not 12.35
'withdraw_method' => $default_withdraw_method,
'payment_methods' => $payment_methods,
'amount' => NumberUtil::round( $balance, wc_get_price_decimals(), PHP_ROUND_HALF_DOWN ), // we are setting 12.3456 to 12.34 not 12.35
'withdraw_method' => $default_withdraw_method,
'payment_methods' => $payment_methods,
'withdraw_charges' => dokan_withdraw_get_method_charges(),
)
);
}
Expand Down
125 changes: 112 additions & 13 deletions includes/REST/WithdrawController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Exception;
use WeDevs\Dokan\Cache;
use WeDevs\Dokan\Withdraw\Withdraw;
use WP_Error;
use WP_REST_Controller;
use WP_REST_Request;
Expand Down Expand Up @@ -115,6 +116,43 @@ public function register_routes() {
'schema' => [ $this, 'get_public_batch_schema' ],
]
);

register_rest_route(
$this->namespace, '/' . $this->rest_base . '/charges', [
[
'methods' => WP_REST_Server::READABLE,
'callback' => [ $this, 'get_all_method_charges' ],
'permission_callback' => [ $this, 'get_items_permissions_check' ],
],
]
);

$methods = array_keys( dokan_withdraw_get_methods() );

register_rest_route(
$this->namespace, '/' . $this->rest_base . '/charge', [
[
'methods' => WP_REST_Server::READABLE,
'callback' => [ $this, 'get_method_charge' ],
'permission_callback' => [ $this, 'get_items_permissions_check' ],
'args' => [
'method' => [
'description' => __( 'Withdraw method key', 'dokan-lite' ),
'type' => 'string',
'context' => [ 'view' ],
'enum' => $methods,
'required' => true,
],
'amount' => [
'description' => __( 'Withdraw amount', 'dokan-lite' ),
'type' => 'number',
'context' => [ 'view' ],
'required' => true,
],
],
],
]
);
}

/**
Expand Down Expand Up @@ -350,29 +388,37 @@ public function create_item( $request ) {
throw new DokanException( 'dokan_rest_withdraw_error', __( 'No vendor found', 'dokan-lite' ), 404 );
}

$args = [
'user_id' => $user_id,
'amount' => $request['amount'],
'date' => current_time( 'mysql' ),
'method' => $request['method'],
'note' => $note,
'ip' => dokan_get_client_ip(),
];

if ( dokan()->withdraw->has_pending_request( $user_id ) ) {
throw new DokanException( 'dokan_rest_withdraw_error', __( 'You already have a pending withdraw request', 'dokan-lite' ), 400 );
}

$validate_request = dokan()->withdraw->is_valid_approval_request( $args );
$validate_request = dokan()->withdraw->is_valid_approval_request(
[
'user_id' => $user_id,
'amount' => $request['amount'],
'method' => $request['method'],
]
);

if ( is_wp_error( $validate_request ) ) {
throw new DokanException( 'dokan_rest_withdraw_error', $validate_request->get_error_message(), 400 );
}

$withdraw = dokan()->withdraw->create( $args );
$withdraw = new Withdraw();

if ( is_wp_error( $withdraw ) ) {
throw new DokanException( $withdraw->get_error_code(), $withdraw->get_error_message(), 400 );
$withdraw
->set_user_id( $user_id )
->set_amount( $request['amount'] )
->set_date( current_time( 'mysql' ) )
Aunshon marked this conversation as resolved.
Show resolved Hide resolved
->set_status( dokan()->withdraw->get_status_code( 'pending' ) )
->set_method( $request['method'] )
->set_ip( dokan_get_client_ip() )
->set_note( $note );

$result = $withdraw->save();

if ( is_wp_error( $result ) ) {
throw new DokanException( $result->get_error_code(), $result->get_error_message(), 400 );
}

$response = $this->prepare_item_for_response( $withdraw, $request );
Expand Down Expand Up @@ -612,11 +658,61 @@ public function batch_items( $request ) {
);
}

/**
* Get all withdraw method charges.
*
* @since DOKAN_SINCE
*
* @return WP_Error|\WP_HTTP_Response|WP_REST_Response
*/
public function get_all_method_charges() {
$all_charges = dokan_withdraw_get_method_charges();

return rest_ensure_response( $all_charges );
}

/**
* Get withdraw method charge.
*
* @since DOKAN_SINCE
*
* @return WP_Error|\WP_HTTP_Response|WP_REST_Response
*/
public function get_method_charge( $request ) {
$method = $request->get_param( 'method' );
$amount = wc_format_decimal( $request->get_param( 'amount' ) );

$withdraw = new Withdraw();

$withdraw->set_method( $method )
->set_amount( $amount )
->calculate_charge();

$response = [
'charge' => $withdraw->get_charge(),
'receivable' => $withdraw->get_receivable_amount(),
'charge_data' => $withdraw->get_charge_data(),
];

if ( $withdraw->get_receivable_amount() < 0 ) {
return new WP_Error(
'invalid-withdraw-amount',
__( 'Invalid withdraw amount. The withdraw charge is greater than the withdraw amount', 'dokan-lite' ),
$response
);
}

return rest_ensure_response( $response );
}

/**
* Prepare data for response
*
* @since 2.8.0
*
* @param $withdraw \WeDevs\Dokan\Withdraw\Withdraw
* @param $request \WP_REST_Request
*
* @return WP_REST_Response|WP_Error
*/
public function prepare_item_for_response( $withdraw, $request ) {
Expand Down Expand Up @@ -645,6 +741,9 @@ public function prepare_item_for_response( $withdraw, $request ) {
'note' => $withdraw->get_note(),
'details' => $details,
'ip' => $withdraw->get_ip(),
'charge' => $withdraw->get_charge(),
'receivable' => $withdraw->get_receivable_amount(),
'charge_data' => $withdraw->get_charge_data(),
];

$response = rest_ensure_response( $data );
Expand Down
Loading