2025-08-05 17:24:52 +03:30
/ *
* Hesabix Admin JavaScript
*
* @ package Hesabix
* @ author Mohammad Rezai
* @ author URI https : //pirouz.xyz
* @ since 1.0 . 0
* /
jQuery ( function ( $ ) {
'use strict' ;
const HesabixAdmin = {
jalaliMonths : [ 'فروردین' , 'اردیبهشت' , 'خرداد' , 'تیر' , 'مرداد' , 'شهریور' , 'مهر' , 'آبان' , 'آذر' , 'دی' , 'بهمن' , 'اسفند' ] ,
gregorianToJalali : function ( gy , gm , gd ) {
const g _d _m = [ 0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334 ] ;
let jy = ( gy <= 1600 ) ? 0 : 979 ;
gy -= ( gy <= 1600 ) ? 621 : 1600 ;
let gy2 = ( gm > 2 ) ? ( gy + 1 ) : gy ;
let days = ( 365 * gy ) + parseInt ( ( gy2 + 3 ) / 4 ) - parseInt ( ( gy2 + 99 ) / 100 ) + parseInt ( ( gy2 + 399 ) / 400 ) - 80 + gd + g _d _m [ gm - 1 ] ;
jy += 33 * parseInt ( days / 12053 ) ;
days %= 12053 ;
jy += 4 * parseInt ( days / 1461 ) ;
days %= 1461 ;
jy += parseInt ( ( days - 1 ) / 365 ) ;
if ( days > 365 ) days = ( days - 1 ) % 365 ;
let jm = ( days < 186 ) ? 1 + parseInt ( days / 31 ) : 7 + parseInt ( ( days - 186 ) / 30 ) ;
let jd = 1 + ( ( days < 186 ) ? ( days % 31 ) : ( ( days - 186 ) % 30 ) ) ;
return [ jy , jm , jd ] ;
} ,
jalaliToGregorian : function ( jy , jm , jd ) {
let gy = ( jy <= 979 ) ? 621 : 1600 ;
jy -= ( jy <= 979 ) ? 0 : 979 ;
let gy2 = ( jm > 2 ) ? ( jy + 1 ) : jy ;
let days = ( 365 * jy ) + parseInt ( ( jy + 3 ) / 4 ) - parseInt ( ( jy + 99 ) / 100 ) + parseInt ( ( jy + 399 ) / 400 ) + 80 + jd + ( ( jm < 7 ) ? ( jm - 1 ) * 31 : ( ( jm - 7 ) * 30 ) + 186 ) ;
gy += 400 * parseInt ( days / 146097 ) ;
days %= 146097 ;
if ( days > 36524 ) {
gy += 100 * parseInt ( -- days / 36524 ) ;
days %= 36524 ;
if ( days >= 365 ) days ++ ;
}
gy += 4 * parseInt ( days / 1461 ) ;
days %= 1461 ;
if ( days > 365 ) {
gy += parseInt ( ( days - 1 ) / 365 ) ;
days = ( days - 1 ) % 365 ;
}
let gd = days + 1 ;
let sal _a = [ 0 , 31 , ( ( gy % 4 == 0 && gy % 100 != 0 ) || ( gy % 400 == 0 ) ) ? 29 : 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ] ;
let gm ;
for ( gm = 0 ; gm < 13 && gd > sal _a [ gm ] ; gm ++ ) gd -= sal _a [ gm ] ;
return [ gy , gm , gd ] ;
} ,
formatJalaliDate : function ( date ) {
const jalali = this . gregorianToJalali ( date . getFullYear ( ) , date . getMonth ( ) + 1 , date . getDate ( ) ) ;
const monthName = this . jalaliMonths [ jalali [ 1 ] - 1 ] ;
return ` ${ jalali [ 2 ] } ${ monthName } ${ jalali [ 0 ] } ` ;
} ,
formatJalaliDateShort : function ( date ) {
const jalali = this . gregorianToJalali ( date . getFullYear ( ) , date . getMonth ( ) + 1 , date . getDate ( ) ) ;
return ` ${ jalali [ 0 ] } / ${ String ( jalali [ 1 ] ) . padStart ( 2 , '0' ) } / ${ String ( jalali [ 2 ] ) . padStart ( 2 , '0' ) } ` ;
} ,
jalaliDateToGregorian : function ( jalaliString ) {
const parts = jalaliString . split ( '/' ) ;
if ( parts . length !== 3 ) return null ;
const jy = parseInt ( parts [ 0 ] ) ;
const jm = parseInt ( parts [ 1 ] ) ;
const jd = parseInt ( parts [ 2 ] ) ;
if ( isNaN ( jy ) || isNaN ( jm ) || isNaN ( jd ) ) return null ;
const gregorian = this . jalaliToGregorian ( jy , jm , jd ) ;
return new Date ( gregorian [ 0 ] , gregorian [ 1 ] - 1 , gregorian [ 2 ] ) ;
} ,
init : function ( ) {
this . initHomeStats ( ) ;
this . initUpdateChecker ( ) ;
this . initExportImport ( ) ;
this . initSyncOperations ( ) ;
this . initProductOperations ( ) ;
this . initSettingsOperations ( ) ;
this . initApiOperations ( ) ;
this . initTabSystem ( ) ;
this . initStatusSelector ( ) ;
this . initFreightSwitch ( ) ;
this . initCustomApiAddress ( ) ;
} ,
initHomeStats : function ( ) {
if ( $ ( '#hesabix-stats-container' ) . length > 0 ) {
this . loadHomeStats ( ) ;
}
} ,
initUpdateChecker : function ( ) {
if ( document . querySelectorAll ( '#hesabix-check-update' ) . length > 0 ) {
setTimeout ( ( ) => this . checkHesabixUpdate ( ) , 1000 ) ;
}
} ,
loadHomeStats : function ( ) {
const $iconContainer = $ ( '#hesabix-home-connection-card .hesabix-feature-icon' ) ;
$iconContainer . find ( 'svg' ) . remove ( ) ;
if ( $iconContainer . find ( '.hesabix-spinner-small' ) . length === 0 ) {
$iconContainer . append ( '<span class="hesabix-spinner-small" style="display:inline-block;vertical-align:middle;"></span>' ) ;
}
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : {
action : 'admin_get_home_stats' ,
nonce : hesabix _ajax . nonce
} ,
success : ( response ) => {
if ( response . success ) {
this . renderStats ( response . data ) ;
} else {
this . showStatsError ( ) ;
}
} ,
error : ( ) => this . showStatsError ( )
} ) ;
} ,
renderStats : function ( data ) {
$ ( '#hesabix-home-products-count' ) . text ( data . products _count ) ;
$ ( '#hesabix-home-products-label' ) . text ( data . products _label ) ;
$ ( '#hesabix-home-customers-count' ) . text ( data . customers _count ) ;
$ ( '#hesabix-home-customers-label' ) . text ( data . customers _label ) ;
$ ( '#hesabix-home-orders-count' ) . text ( data . orders _count ) ;
$ ( '#hesabix-home-orders-label' ) . text ( data . orders _label ) ;
const $iconContainer = $ ( '#hesabix-home-connection-card .hesabix-feature-icon' ) ;
$iconContainer . find ( '.hesabix-spinner-small' ) . remove ( ) ;
if ( $iconContainer . find ( 'svg' ) . length === 0 ) {
$iconContainer . append ( '<svg width="40" height="40" viewBox="0 0 24 24" fill="currentColor"><path id="hesabix-home-connection-icon" d="" /></svg>' ) ;
}
const connectionClass = data . is _connected ? 'connected' : 'not-connected' ;
$ ( '#hesabix-home-connection-card' ) . removeClass ( 'connected not-connected' ) . addClass ( connectionClass ) ;
const connectionIcon = data . is _connected ?
'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z' :
'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z' ;
$ ( '#hesabix-home-connection-icon' ) . attr ( 'd' , connectionIcon ) ;
$ ( '#hesabix-home-connection-text' ) . text ( data . connected _text ) ;
$ ( '#hesabix-home-status-label' ) . text ( data . status _label ) ;
} ,
showStatsError : function ( ) {
$ ( '#hesabix-home-products-count' ) . html ( '<span style="color:#dc3545">خطا</span>' ) ;
$ ( '#hesabix-home-products-label' ) . text ( 'محصولات' ) ;
$ ( '#hesabix-home-customers-count' ) . html ( '<span style="color:#dc3545">خطا</span>' ) ;
$ ( '#hesabix-home-customers-label' ) . text ( 'مشتریان' ) ;
$ ( '#hesabix-home-orders-count' ) . html ( '<span style="color:#dc3545">خطا</span>' ) ;
$ ( '#hesabix-home-orders-label' ) . text ( 'سفارشات' ) ;
$ ( '#hesabix-home-connection-card' ) . removeClass ( 'connected not-connected' ) ;
$ ( '#hesabix-home-connection-icon' ) . attr ( 'd' , '' ) ;
$ ( '#hesabix-home-connection-text' ) . html ( '<span style="color:#dc3545">خطا</span>' ) ;
$ ( '#hesabix-home-status-label' ) . text ( 'وضعیت اتصال' ) ;
} ,
checkHesabixUpdate : function ( ) {
const updateButtons = document . querySelectorAll ( '#hesabix-check-update' ) ;
updateButtons . forEach ( el => {
const btn = $ ( el ) ;
btn . prop ( 'disabled' , true ) ;
btn . find ( '.update-text' ) . hide ( ) ;
btn . find ( '.update-loading' ) . show ( ) ;
} ) ;
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : {
action : 'admin_check_for_updates' ,
nonce : hesabix _ajax . nonce
} ,
success : ( response ) => {
if ( response . success ) {
this . showUpdateResult ( response . data ) ;
} else {
this . showUpdateError ( response . message ) ;
}
} ,
error : ( ) => this . showUpdateError ( 'خطا در بررسی بروزرسانی' ) ,
complete : ( ) => {
updateButtons . forEach ( el => {
const btn = $ ( el ) ;
btn . prop ( 'disabled' , false ) ;
btn . find ( '.update-text' ) . show ( ) ;
btn . find ( '.update-loading' ) . hide ( ) ;
} ) ;
}
} ) ;
} ,
showUpdateResult : function ( data ) {
const updateButtons = document . querySelectorAll ( '#hesabix-check-update' ) ;
updateButtons . forEach ( el => {
const btn = $ ( el ) ;
if ( data . is _update _available ) {
btn . removeClass ( 'hesabix-update-badge' ) . addClass ( 'hesabix-badge warning' ) ;
btn . html ( `
< span class = "update-text" >
< svg width = "14" height = "14" viewBox = "0 0 24 24" fill = "currentColor" style = "margin-left: 5px;" >
< path d = "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" / >
< / s v g >
نسخه جدید $ { data . latest _version } موجود است
< / s p a n >
` );
btn . attr ( 'onclick' , ` window.open(' ${ data . download _url } ', '_blank') ` ) ;
this . showUpdateNotification ( data ) ;
} else {
btn . removeClass ( 'hesabix-update-badge' ) . addClass ( 'hesabix-badge status' ) ;
btn . html ( `
< span class = "update-text" >
< svg width = "14" height = "14" viewBox = "0 0 24 24" fill = "currentColor" style = "margin-left: 5px;" >
< path d = "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" / >
< / s v g >
نسخه فعلی بروز است
< / s p a n >
` );
btn . removeAttr ( 'onclick' ) ;
}
} ) ;
} ,
showUpdateError : function ( message ) {
const updateButtons = document . querySelectorAll ( '#hesabix-check-update' ) ;
updateButtons . forEach ( el => {
const btn = $ ( el ) ;
btn . removeClass ( 'hesabix-update-badge' ) . addClass ( 'hesabix-badge danger' ) ;
btn . html ( `
< span class = "update-text" >
< svg width = "14" height = "14" viewBox = "0 0 24 24" fill = "currentColor" style = "margin-left: 5px;" >
< path d = "M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z" / >
< / s v g >
$ { message }
< / s p a n >
` );
btn . removeAttr ( 'onclick' ) ;
} ) ;
} ,
showUpdateNotification : function ( data ) {
const notification = $ ( `
< div class = "hesabix-update-notification" style = "
position : fixed ;
top : 20 px ;
right : 20 px ;
background : white ;
border - radius : 10 px ;
padding : 20 px ;
box - shadow : 0 4 px 20 px rgba ( 0 , 0 , 0 , 0.15 ) ;
z - index : 9999 ;
max - width : 400 px ;
border - left : 4 px solid # ffc107 ;
" >
< div style = "display: flex; align-items: center; justify-content: space-between; margin-bottom: 15px;" >
< h4 style = "margin: 0; color: #333;" > نسخه جدید موجود است ! < / h 4 >
< button class = "hesabix-notification-close" style = "
background : none ;
border : none ;
font - size : 18 px ;
cursor : pointer ;
color : # 666 ;
" > & times ; < / b u t t o n >
< / d i v >
< p style = "margin: 0 0 15px 0; color: #666;" >
نسخه $ { data . latest _version } از پلاگین حسابیکس منتشر شده است .
نسخه فعلی شما : $ { data . current _version }
< / p >
< div style = "display: flex; gap: 10px;" >
< button onclick = "window.open('${data.download_url}', '_blank')" class = "hesabix-btn hesabix-btn-warning" style = "flex: 1;" >
دانلود نسخه جدید
< / b u t t o n >
< button class = "hesabix-notification-close hesabix-btn hesabix-btn-secondary" style = "flex: 1;" >
بستن
< / b u t t o n >
< / d i v >
< / d i v >
` );
notification . find ( '.hesabix-notification-close' ) . on ( 'click' , ( ) => {
notification . fadeOut ( ( ) => notification . remove ( ) ) ;
} ) ;
$ ( 'body' ) . append ( notification ) ;
setTimeout ( ( ) => {
notification . fadeOut ( ( ) => notification . remove ( ) ) ;
} , 10000 ) ;
} ,
initExportImport : function ( ) {
this . initExportProducts ( ) ;
this . initImportProducts ( ) ;
this . initExportOpeningQuantity ( ) ;
this . initExportCustomers ( ) ;
} ,
initExportProducts : function ( ) {
$ ( '#hesabix_export_products' ) . submit ( ( e ) => {
e . preventDefault ( ) ;
const $btn = $ ( '#hesabix-export-product-submit' ) ;
$btn . attr ( 'disabled' , 'disabled' ) . removeClass ( 'button-primary' )
. html ( '<i class="ofwc-spinner"></i> خروج محصولات...' ) ;
$ ( '#exportProductsProgress' ) . show ( ) ;
$ ( '#exportProductsProgressBar' ) . css ( 'width' , '0%' ) . attr ( 'aria-valuenow' , 0 ) ;
this . exportProducts ( 1 , 1 , 1 , 0 ) ;
} ) ;
} ,
exportProducts : function ( batch , totalBatch , total , updateCount ) {
$ . post ( ajaxurl , {
action : 'adminExportProducts' ,
batch : batch ,
totalBatch : totalBatch ,
total : total ,
updateCount : updateCount
} , ( response ) => {
if ( response !== 'failed' ) {
const res = JSON . parse ( response ) ;
res . batch = parseInt ( res . batch ) ;
if ( res . batch < res . totalBatch ) {
const progress = Math . round ( ( res . batch * 100 ) / res . totalBatch ) ;
$ ( '#exportProductsProgressBar' ) . css ( 'width' , progress + '%' ) . attr ( 'aria-valuenow' , progress ) ;
this . exportProducts ( res . batch + 1 , res . totalBatch , res . total , res . updateCount ) ;
} else {
$ ( '#exportProductsProgressBar' ) . css ( 'width' , '100%' ) . attr ( 'aria-valuenow' , 100 ) ;
setTimeout ( ( ) => top . location . replace ( res . redirectUrl ) , 1000 ) ;
}
} else {
alert ( 'خطا در استخراج محصولات' ) ;
}
} ) ;
} ,
initImportProducts : function ( ) {
$ ( '#hesabix_import_products' ) . submit ( ( e ) => {
e . preventDefault ( ) ;
const $btn = $ ( '#hesabix-import-product-submit' ) ;
$btn . attr ( 'disabled' , 'disabled' ) . removeClass ( 'button-primary' )
. html ( '<i class="ofwc-spinner"></i> در حال ورود کالاها از حسابیکس, لطفاً صبر کنید...' ) ;
$ ( '#importProductsProgress' ) . show ( ) ;
$ ( '#importProductsProgressBar' ) . css ( 'width' , '0%' ) . attr ( 'aria-valuenow' , 0 ) ;
this . importProducts ( 1 , 1 , 1 , 0 ) ;
} ) ;
} ,
importProducts : function ( batch , totalBatch , total , updateCount ) {
$ . post ( ajaxurl , {
action : 'adminImportProducts' ,
batch : batch ,
totalBatch : totalBatch ,
total : total ,
updateCount : updateCount
} , ( response ) => {
if ( response !== 'failed' ) {
const res = JSON . parse ( response ) ;
res . batch = parseInt ( res . batch ) ;
if ( res . batch < res . totalBatch ) {
const progress = Math . round ( ( res . batch * 100 ) / res . totalBatch ) ;
$ ( '#importProductsProgressBar' ) . css ( 'width' , progress + '%' ) . attr ( 'aria-valuenow' , progress ) ;
this . importProducts ( res . batch + 1 , res . totalBatch , res . total , res . updateCount ) ;
} else {
$ ( '#importProductsProgressBar' ) . css ( 'width' , '100%' ) . attr ( 'aria-valuenow' , 100 ) ;
setTimeout ( ( ) => top . location . replace ( res . redirectUrl ) , 1000 ) ;
}
} else {
alert ( 'خطا در وارد کردن محصولات' ) ;
}
} ) ;
} ,
initExportOpeningQuantity : function ( ) {
$ ( '#hesabix_export_products_opening_quantity' ) . submit ( ( e ) => {
e . preventDefault ( ) ;
const $btn = $ ( '#hesabix-export-product-opening-quantity-submit' ) ;
$btn . attr ( 'disabled' , 'disabled' ) . removeClass ( 'button-primary' )
. html ( '<i class="ofwc-spinner"></i> استخراج موجودی اول دوره...' ) ;
$ ( '#exportProductsOpeningQuantityProgress' ) . show ( ) ;
$ ( '#exportProductsOpeningQuantityProgressBar' ) . css ( 'width' , '0%' ) . attr ( 'aria-valuenow' , 0 ) ;
this . exportProductsOpeningQuantity ( 1 , 1 , 1 ) ;
} ) ;
} ,
exportProductsOpeningQuantity : function ( batch , totalBatch , total ) {
$ . post ( ajaxurl , {
action : 'adminExportProductsOpeningQuantity' ,
batch : batch ,
totalBatch : totalBatch ,
total : total
} , ( response ) => {
if ( response !== 'failed' ) {
const res = JSON . parse ( response ) ;
res . batch = parseInt ( res . batch ) ;
if ( res . batch < res . totalBatch ) {
const progress = Math . round ( ( res . batch * 100 ) / res . totalBatch ) ;
$ ( '#exportProductsOpeningQuantityProgressBar' ) . css ( 'width' , progress + '%' ) . attr ( 'aria-valuenow' , progress ) ;
this . exportProductsOpeningQuantity ( res . batch + 1 , res . totalBatch , res . total ) ;
} else {
$ ( '#exportProductsOpeningQuantityProgressBar' ) . css ( 'width' , '100%' ) . attr ( 'aria-valuenow' , 100 ) ;
setTimeout ( ( ) => top . location . replace ( res . redirectUrl ) , 1000 ) ;
}
} else {
alert ( 'خطا در استخراج موجودی اول دوره' ) ;
}
} ) ;
} ,
initExportCustomers : function ( ) {
$ ( '#hesabix_export_customers' ) . submit ( ( e ) => {
e . preventDefault ( ) ;
const $btn = $ ( '#hesabix-export-customer-submit' ) ;
$btn . attr ( 'disabled' , 'disabled' ) . removeClass ( 'button-primary' )
. html ( '<i class="ofwc-spinner"></i> خروجی مشتریان، لطفاً صبر کنید...' ) ;
$ ( '#exportCustomersProgress' ) . show ( ) ;
$ ( '#exportCustomersProgressBar' ) . css ( 'width' , '0%' ) . attr ( 'aria-valuenow' , 0 ) ;
this . exportCustomers ( 1 , 1 , 1 , 0 ) ;
} ) ;
} ,
exportCustomers : function ( batch , totalBatch , total , updateCount ) {
$ . post ( ajaxurl , {
action : 'adminExportCustomers' ,
batch : batch ,
totalBatch : totalBatch ,
total : total ,
updateCount : updateCount
} , ( response ) => {
if ( response !== 'failed' ) {
const res = JSON . parse ( response ) ;
res . batch = parseInt ( res . batch ) ;
if ( res . batch < res . totalBatch ) {
const progress = Math . round ( ( res . batch * 100 ) / res . totalBatch ) ;
$ ( '#exportCustomersProgressBar' ) . css ( 'width' , progress + '%' ) . attr ( 'aria-valuenow' , progress ) ;
this . exportCustomers ( res . batch + 1 , res . totalBatch , res . total , res . updateCount ) ;
} else {
$ ( '#exportCustomersProgressBar' ) . css ( 'width' , '100%' ) . attr ( 'aria-valuenow' , 100 ) ;
setTimeout ( ( ) => top . location . replace ( res . redirectUrl ) , 1000 ) ;
}
} else {
alert ( 'خطا در استخراج مشتریان' ) ;
}
} ) ;
} ,
initSyncOperations : function ( ) {
this . initSyncChanges ( ) ;
this . initSyncProducts ( ) ;
this . initSyncOrders ( ) ;
this . initUpdateCustomers ( ) ;
this . initUpdateProducts ( ) ;
this . initUpdateWcProducts ( ) ;
this . initUpdateProductsWithFilter ( ) ;
} ,
initSyncChanges : function ( ) {
$ ( '#hesabix_sync_changes' ) . submit ( ( e ) => {
e . preventDefault ( ) ;
const $btn = $ ( '#hesabix-sync-changes-submit' ) ;
const $btnText = $btn . find ( '.sync-changes-text' ) ;
let $btnLoading = $btn . find ( '.sync-changes-loading' ) ;
if ( $btnLoading . length === 0 ) {
$btn . append ( '<span class="sync-changes-loading" style="display:inline-block;vertical-align:middle;margin-right:6px;"><span class="hesabix-spinner-small" style="display:inline-block;vertical-align:middle;"></span></span>' ) ;
$btnLoading = $btn . find ( '.sync-changes-loading' ) ;
}
$btn . attr ( 'disabled' , 'disabled' ) ;
$btnText . hide ( ) ;
$btnLoading . show ( ) ;
$ ( '#hesabix-sync-overlay' ) . fadeIn ( 300 ) ;
$ . post ( ajaxurl , { action : 'adminSyncChanges' } , ( ) => {
$ ( '#hesabix-sync-overlay' ) . fadeOut ( 300 ) ;
$btn . removeAttr ( 'disabled' ) ;
$btnLoading . hide ( ) ;
$btnText . show ( ) ;
this . loadSyncStats ( ) ;
this . showSyncMessage ( 'success' , 'همگامسازی تغییرات با موفقیت انجام شد.' ) ;
} ) ;
} ) ;
} ,
initSyncProducts : function ( ) {
$ ( '#hesabix_sync_products' ) . submit ( ( e ) => {
e . preventDefault ( ) ;
const $btn = $ ( '#hesabix-sync-products-submit' ) ;
const $btnText = $btn . find ( '.sync-products-text' ) ;
let $btnLoading = $btn . find ( '.sync-products-loading' ) ;
if ( $btnLoading . length === 0 ) {
$btn . append ( '<span class="sync-products-loading" style="display:inline-block;vertical-align:middle;margin-right:6px;"><span class="hesabix-spinner-small" style="display:inline-block;vertical-align:middle;"></span></span>' ) ;
$btnLoading = $btn . find ( '.sync-products-loading' ) ;
}
$btn . attr ( 'disabled' , 'disabled' ) ;
$btnText . hide ( ) ;
$btnLoading . show ( ) ;
$ ( '#hesabix-sync-overlay' ) . fadeIn ( 300 ) ;
$ . post ( ajaxurl , {
action : 'admin_sync_products' ,
batch : 1 ,
totalBatch : 1 ,
total : 1 ,
nonce : hesabix _ajax . nonce
} , ( response ) => {
if ( typeof response === 'string' ) {
try { response = JSON . parse ( response ) ; } catch ( e ) { }
}
$ ( '#hesabix-sync-overlay' ) . fadeOut ( 300 ) ;
$btn . removeAttr ( 'disabled' ) ;
$btnLoading . hide ( ) ;
$btnText . show ( ) ;
this . loadSyncStats ( ) ;
if ( response && response . success ) {
this . showSyncMessage ( 'success' , response . message || 'همگامسازی قیمت و موجودی با موفقیت انجام شد.' ) ;
} else {
this . showSyncMessage ( 'error' , ( response && response . message ) ? response . message : 'خطا در همگامسازی قیمت و موجودی' ) ;
}
} ) ;
} ) ;
} ,
initSyncOrders : function ( ) {
$ ( '#hesabix_sync_orders' ) . submit ( ( e ) => {
e . preventDefault ( ) ;
const $btn = $ ( '#hesabix-sync-orders-submit' ) ;
const $btnText = $btn . find ( '.sync-orders-text' ) ;
let $btnLoading = $btn . find ( '.sync-orders-loading' ) ;
if ( $btnLoading . length === 0 ) {
$btn . append ( '<span class="sync-orders-loading" style="display:inline-block;vertical-align:middle;margin-right:6px;"><span class="hesabix-spinner-small" style="display:inline-block;vertical-align:middle;"></span></span>' ) ;
$btnLoading = $btn . find ( '.sync-orders-loading' ) ;
}
$btn . attr ( 'disabled' , 'disabled' ) ;
$btnText . hide ( ) ;
$btnLoading . show ( ) ;
$ ( '#hesabix-sync-overlay' ) . fadeIn ( 300 ) ;
const date = $ ( '#hesabix_sync_order_date' ) . val ( ) ;
const endDate = $ ( '#hesabix_sync_order_end_date' ) . val ( ) ;
$ . post ( ajaxurl , {
action : 'admin_sync_orders' ,
date : date ,
endDate : endDate ,
batch : 1 ,
totalBatch : 1 ,
total : 1 ,
updateCount : 0
} , ( response ) => {
if ( typeof response === 'string' ) {
try { response = JSON . parse ( response ) ; } catch ( e ) { }
}
$ ( '#hesabix-sync-overlay' ) . fadeOut ( 300 ) ;
$btn . removeAttr ( 'disabled' ) ;
$btnLoading . hide ( ) ;
$btnText . show ( ) ;
this . loadSyncStats ( ) ;
if ( response && response . success ) {
this . showSyncMessage ( 'success' , response . message || 'همگامسازی سفارشات با موفقیت انجام شد.' ) ;
} else {
this . showSyncMessage ( 'error' , ( response && response . message ) ? response . message : 'خطا در همگامسازی سفارشات' ) ;
}
} ) ;
} ) ;
} ,
initUpdateCustomers : function ( ) {
$ ( '#hesabix_update_customers' ) . submit ( ( e ) => {
e . preventDefault ( ) ;
const $btn = $ ( '#hesabix-update-customers-submit' ) ;
const $btnText = $btn . find ( '.update-customers-text' ) ;
let $btnLoading = $btn . find ( '.update-customers-loading' ) ;
if ( $btnLoading . length === 0 ) {
$btn . append ( '<span class="update-customers-loading" style="display:inline-block;vertical-align:middle;margin-right:6px;"><span class="hesabix-spinner-small" style="display:inline-block;vertical-align:middle;"></span></span>' ) ;
$btnLoading = $btn . find ( '.update-customers-loading' ) ;
}
$btn . attr ( 'disabled' , 'disabled' ) ;
$btnText . hide ( ) ;
$btnLoading . show ( ) ;
$ ( '#hesabix-sync-overlay' ) . fadeIn ( 300 ) ;
$ . post ( ajaxurl , {
action : 'hesabix_update_customers' ,
nonce : hesabix _ajax . nonce
} , ( response ) => {
if ( typeof response === 'string' ) {
try { response = JSON . parse ( response ) ; } catch ( e ) { }
}
$ ( '#hesabix-sync-overlay' ) . fadeOut ( 300 ) ;
$btn . removeAttr ( 'disabled' ) ;
$btnLoading . hide ( ) ;
$btnText . show ( ) ;
this . loadSyncStats ( ) ;
if ( response && response . success ) {
this . showSyncMessage ( 'success' , response . data . message || 'بروزرسانی مشتریان حسابیکس با موفقیت انجام شد.' ) ;
} else {
this . showSyncMessage ( 'error' , ( response && response . data && response . data . message ) ? response . data . message : 'خطا در بروزرسانی مشتریان حسابیکس' ) ;
}
} ) ;
} ) ;
} ,
initUpdateProducts : function ( ) {
$ ( '#hesabix_update_products' ) . submit ( ( e ) => {
e . preventDefault ( ) ;
const $btn = $ ( '#hesabix-update-products-submit' ) ;
const $btnText = $btn . find ( '.update-products-text' ) ;
let $btnLoading = $btn . find ( '.update-products-loading' ) ;
if ( $btnLoading . length === 0 ) {
$btn . append ( '<span class="update-products-loading" style="display:inline-block;vertical-align:middle;margin-right:6px;"><span class="hesabix-spinner-small" style="display:inline-block;vertical-align:middle;"></span></span>' ) ;
$btnLoading = $btn . find ( '.update-products-loading' ) ;
}
$btn . attr ( 'disabled' , 'disabled' ) ;
$btnText . hide ( ) ;
$ ( '#hesabix-sync-overlay' ) . fadeIn ( 300 ) ;
$ ( '#updateProductsProgress' ) . show ( ) ;
$ ( '#updateProductsProgressBar' ) . css ( 'width' , '0%' ) . attr ( 'aria-valuenow' , 0 ) ;
this . updateProductsAjax ( 1 , 1 , 1 ) ;
} ) ;
} ,
initUpdateWcProducts : function ( ) {
$ ( '#hesabix_update_wc_products' ) . submit ( ( e ) => {
e . preventDefault ( ) ;
const $btn = $ ( '#hesabix-update-wc-products-submit' ) ;
const $btnText = $btn . find ( '.update-wc-products-text' ) ;
let $btnLoading = $btn . find ( '.update-wc-products-loading' ) ;
if ( $btnLoading . length === 0 ) {
$btn . append ( '<span class="update-wc-products-loading" style="display:inline-block;vertical-align:middle;margin-right:6px;"><span class="hesabix-spinner-small" style="display:inline-block;vertical-align:middle;"></span></span>' ) ;
$btnLoading = $btn . find ( '.update-wc-products-loading' ) ;
}
$btn . attr ( 'disabled' , 'disabled' ) ;
$btnText . hide ( ) ;
$ ( '#hesabix-sync-overlay' ) . fadeIn ( 300 ) ;
$ ( '#updateWcProductsProgress' ) . show ( ) ;
$ ( '#updateWcProductsProgressBar' ) . css ( 'width' , '0%' ) . attr ( 'aria-valuenow' , 0 ) ;
this . updateWcProductsAjax ( 1 , 1 , 1 ) ;
} ) ;
} ,
updateWcProductsAjax : function ( batch , totalBatch , total ) {
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : {
action : 'admin_update_wc_products' ,
nonce : hesabix _ajax . nonce ,
batch : batch ,
totalBatch : totalBatch ,
total : total
} ,
success : ( response ) => {
if ( typeof response === 'string' ) {
try { response = JSON . parse ( response ) ; } catch ( e ) { }
}
if ( response && response . success ) {
this . loadSyncStats ( ) ;
$ ( '#hesabix-sync-overlay' ) . fadeOut ( 300 ) ;
this . showSyncMessage ( 'success' , response . message || 'بروزرسانی محصولات ووکامرس با موفقیت انجام شد.' ) ;
} else {
$ ( '#hesabix-sync-overlay' ) . fadeOut ( 300 ) ;
this . showSyncMessage ( 'error' , ( response && response . message ) ? response . message : 'خطا در بروزرسانی محصولات ووکامرس' ) ;
}
const $btn = $ ( '#hesabix-update-wc-products-submit' ) ;
const $btnText = $btn . find ( '.update-wc-products-text' ) ;
const $btnLoading = $btn . find ( '.update-wc-products-loading' ) ;
$btn . removeAttr ( 'disabled' ) ;
$btnLoading . hide ( ) ;
$btnText . show ( ) ;
$ ( '#updateWcProductsProgress' ) . hide ( ) ;
} ,
error : ( response ) => console . log ( response )
} ) ;
} ,
updateProductsAjax : function ( batch , totalBatch , total ) {
$ . post ( ajaxurl , {
action : 'admin_update_products' ,
batch : batch ,
totalBatch : totalBatch ,
total : total
} , ( response ) => {
if ( typeof response === 'string' ) {
try { response = JSON . parse ( response ) ; } catch ( e ) { }
}
if ( response && response . success ) {
this . loadSyncStats ( ) ;
$ ( '#hesabix-sync-overlay' ) . fadeOut ( 300 ) ;
this . showSyncMessage ( 'success' , response . message || 'بروزرسانی محصولات با موفقیت انجام شد.' ) ;
} else {
$ ( '#hesabix-sync-overlay' ) . fadeOut ( 300 ) ;
this . showSyncMessage ( 'error' , ( response && response . message ) ? response . message : 'خطا در بروزرسانی محصولات' ) ;
}
const $btn = $ ( '#hesabix-update-products-submit' ) ;
const $btnText = $btn . find ( '.update-products-text' ) ;
const $btnLoading = $btn . find ( '.update-products-loading' ) ;
$btn . removeAttr ( 'disabled' ) ;
$btnLoading . hide ( ) ;
$btnText . show ( ) ;
$ ( '#updateProductsProgress' ) . hide ( ) ;
} ) ;
} ,
initUpdateProductsWithFilter : function ( ) {
$ ( '#hesabix_update_products_with_filter' ) . submit ( ( e ) => {
e . preventDefault ( ) ;
const submitButton = $ ( '#hesabix-update-products-with-filter-submit' ) ;
const offset = document . getElementById ( "hesabix-update-products-offset" ) . value ;
const rpp = document . getElementById ( "hesabix-update-products-rpp" ) . value ;
submitButton . removeClass ( 'button-primary' )
. html ( '<i class="ofwc-spinner"></i> بروزرسانی محصولات لطفا صبر کنید...' )
. attr ( 'disabled' , 'disabled' ) ;
this . updateProductsWithFilter ( offset , rpp ) ;
} ) ;
} ,
updateProductsWithFilter : function ( offset , rpp ) {
if ( offset && rpp ) {
$ . post ( ajaxurl , {
action : 'adminUpdateProductsWithFilter' ,
offset : offset ,
rpp : rpp
} , ( response ) => {
if ( response !== 'failed' ) {
const res = JSON . parse ( response ) ;
if ( ! res . error ) {
top . location . replace ( res . redirectUrl ) ;
}
} else {
alert ( 'خطا در بروزرسانی محصولات' ) ;
}
} ) ;
} else {
alert ( 'فیلد ه ا را به درستی وارد نمایید' ) ;
const submitButton = $ ( '#hesabix-update-products-with-filter-submit' ) ;
submitButton . addClass ( 'button-primary' )
. html ( 'بروزرسانی محصولات در حسابیکس بر اساس فروشگاه در بازه ID مشخص شده' )
. removeAttr ( 'disabled' ) ;
}
} ,
showSyncMessage : function ( type , message ) {
$ ( '.hesabix-sync-message' ) . remove ( ) ;
const messageClass = type === 'success' ? 'hesabix-alert-success' : 'hesabix-alert-danger' ;
const messageHtml = '<div class="hesabix-sync-message hesabix-alert ' + messageClass + ' hesabix-fade-in" style="margin-bottom:18px;margin-top:18px;">' +
'<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" style="vertical-align: middle; margin-left: 8px;">' +
'<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />' +
'</svg>' + message + '</div>' ;
const $title = $ ( ".hesabix-tab-page-title:contains('همگامسازی اطلاعات')" ) ;
if ( $title . length ) {
$title . before ( messageHtml ) ;
$ ( 'html, body' ) . animate ( { scrollTop : $title . offset ( ) . top - 300 } , 500 ) ;
} else {
$ ( 'body' ) . prepend ( messageHtml ) ;
$ ( 'html, body' ) . animate ( { scrollTop : 0 } , 500 ) ;
}
} ,
loadSyncStats : function ( ) {
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : {
action : 'hesabix_get_sync_stats_ajax' ,
nonce : hesabix _ajax . nonce
} ,
success : ( response ) => {
if ( response . success && response . data ) {
$ ( '#sync-store-products-count' ) . html ( response . data . storeProductsCount ) ;
$ ( '#sync-hesabix-products-count' ) . html ( response . data . hesabixProductsCount ) ;
$ ( '#sync-linked-products-count' ) . html ( response . data . linkedProductsCount ) ;
} else {
$ ( '#sync-store-products-count, #sync-hesabix-products-count, #sync-linked-products-count' ) . html ( 'ارور' ) ;
}
} ,
error : ( ) => {
$ ( '#sync-store-products-count, #sync-hesabix-products-count, #sync-linked-products-count' ) . html ( 'ارور' ) ;
}
} ) ;
} ,
initProductOperations : function ( ) {
this . initInvoiceSubmission ( ) ;
this . initProductItemOperations ( ) ;
this . initPluginDataOperations ( ) ;
} ,
initInvoiceSubmission : function ( ) {
$ ( ".btn-submit-invoice" ) . on ( "click" , function ( ) {
const orderId = $ ( this ) . attr ( "data-order-id" ) ;
const btnEl = $ ( '.btn-submit-invoice[data-order-id=' + orderId + ']' ) ;
btnEl . attr ( 'aria-disabled' , true ) . addClass ( 'disabled' ) . html ( 'ثبت فاکتور...' ) ;
HesabixAdmin . submitInvoice ( orderId ) ;
} ) ;
} ,
submitInvoice : function ( orderId ) {
$ . post ( ajaxurl , {
action : 'adminSubmitInvoice' ,
orderId : orderId
} , ( response ) => {
if ( response !== 'failed' ) {
location . reload ( ) ;
} else {
alert ( 'خطا در ثبت فاکتور' ) ;
}
} ) ;
} ,
initProductItemOperations : function ( ) {
$ ( ".hesabix-item-save" ) . on ( 'click' , function ( ) {
const productId = $ ( "#panel_product_data_hesabix" ) . data ( 'product-id' ) ;
const attributeId = $ ( this ) . data ( 'id' ) ;
const code = $ ( "#hesabix-item-" + attributeId ) . val ( ) ;
$ . post ( ajaxurl , {
action : 'adminChangeProductCode' ,
productId : productId ,
attributeId : attributeId ,
code : code
} , ( response ) => {
$ ( this ) . prop ( 'disabled' , false ) ;
if ( response !== 'failed' ) {
const res = JSON . parse ( response ) ;
alert ( res . error ? res . message : 'کد کالای متصل با موفقیت تغییر کرد.' ) ;
if ( productId === attributeId ) {
$ ( "#hesabix_hesabix_item_code_0" ) . val ( code ) ;
} else {
$ ( "#hesabix_hesabix_item_code_" + attributeId ) . val ( code ) ;
}
} else {
alert ( 'خطا در هنگام تغییر کد کالای متصل.' ) ;
}
} ) ;
$ ( this ) . prop ( 'disabled' , true ) ;
} ) ;
$ ( ".hesabix-item-delete-link" ) . on ( 'click' , function ( ) {
const productId = $ ( "#panel_product_data_hesabix" ) . data ( 'product-id' ) ;
const attributeId = $ ( this ) . data ( 'id' ) ;
$ . post ( ajaxurl , {
action : 'adminDeleteProductLink' ,
productId : productId ,
attributeId : attributeId
} , ( response ) => {
$ ( this ) . prop ( 'disabled' , false ) ;
if ( response !== 'failed' ) {
const res = JSON . parse ( response ) ;
$ ( "#hesabix-item-" + attributeId ) . val ( '' ) ;
if ( productId === attributeId ) {
$ ( "#hesabix_hesabix_item_code_0" ) . val ( '' ) ;
} else {
$ ( "#hesabix_hesabix_item_code_" + attributeId ) . val ( '' ) ;
}
setTimeout ( ( ) => {
alert ( res . error ? res . message : 'ارتباط محصول با موفقیت حذف شد' ) ;
} , 100 ) ;
} else {
alert ( 'خطا در هنگام حذف ارتباط' ) ;
}
} ) ;
$ ( this ) . prop ( 'disabled' , true ) ;
} ) ;
$ ( ".hesabix-item-update" ) . on ( 'click' , function ( ) {
const productId = $ ( "#panel_product_data_hesabix" ) . data ( 'product-id' ) ;
const attributeId = $ ( this ) . data ( 'id' ) ;
$ . post ( ajaxurl , {
action : 'adminUpdateProduct' ,
productId : productId ,
attributeId : attributeId
} , ( response ) => {
$ ( this ) . prop ( 'disabled' , false ) ;
if ( response !== 'failed' ) {
const res = JSON . parse ( response ) ;
if ( res . newPrice != null ) {
$ ( "#hesabix-item-price-" + attributeId ) . text ( res . newPrice ) ;
}
if ( res . newQuantity != null ) {
$ ( "#hesabix-item-quantity-" + attributeId ) . text ( res . newQuantity ) ;
}
if ( res . error ) {
alert ( res . message ) ;
}
} else {
alert ( 'خطا در هنگام بروزرسانی محصول' ) ;
}
} ) ;
$ ( this ) . prop ( 'disabled' , true ) ;
} ) ;
$ ( "#hesabix-item-save-all" ) . on ( 'click' , function ( ) {
const productId = $ ( "#panel_product_data_hesabix" ) . data ( 'product-id' ) ;
const itemsCode = $ ( ".hesabix-item-code" ) ;
const itemsData = [ ] ;
for ( let i = 0 ; i < itemsCode . length ; i ++ ) {
const item = itemsCode [ i ] ;
const attributeId = $ ( item ) . data ( 'id' ) ;
const code = $ ( item ) . val ( ) ;
itemsData . push ( { attributeId : attributeId , code : code } ) ;
}
$ . post ( ajaxurl , {
action : 'adminChangeProductsCode' ,
productId : productId ,
itemsData : itemsData
} , ( response ) => {
$ ( this ) . prop ( 'disabled' , false ) ;
if ( response !== 'failed' ) {
const res = JSON . parse ( response ) ;
alert ( res . error ? res . message : 'کد کالاهای متصل با موفقیت تغییر کرد.' ) ;
location . reload ( ) ;
} else {
alert ( 'خطا در هنگام تغییر کد کالاهای متصل' ) ;
}
} ) ;
$ ( this ) . prop ( 'disabled' , true ) ;
} ) ;
$ ( "#hesabix-item-delete-link-all" ) . on ( 'click' , function ( ) {
const productId = $ ( "#panel_product_data_hesabix" ) . data ( 'product-id' ) ;
$ . post ( ajaxurl , {
action : 'adminDeleteProductsLink' ,
productId : productId
} , ( response ) => {
$ ( this ) . prop ( 'disabled' , false ) ;
if ( response !== 'failed' ) {
const res = JSON . parse ( response ) ;
const itemsCode = $ ( ".hesabix-item-code" ) ;
for ( let i = 0 ; i < itemsCode . length ; i ++ ) {
const item = itemsCode [ i ] ;
$ ( item ) . val ( '' ) ;
}
$ ( '[id^="hesabix_hesabix_item_code_"]' ) . val ( '' ) ;
setTimeout ( ( ) => {
alert ( res . error ? res . message : 'ارتباط محصولات با موفقیت حذف شد.' ) ;
} , 100 ) ;
} else {
alert ( 'خطا در هنگام حذف ارتباط' ) ;
}
} ) ;
$ ( this ) . prop ( 'disabled' , true ) ;
} ) ;
$ ( "#hesabix-item-update-all" ) . on ( 'click' , function ( ) {
const productId = $ ( "#panel_product_data_hesabix" ) . data ( 'product-id' ) ;
$ . post ( ajaxurl , {
action : 'adminUpdateProductAndVariations' ,
productId : productId
} , ( response ) => {
$ ( this ) . prop ( 'disabled' , false ) ;
if ( response !== 'failed' ) {
const res = JSON . parse ( response ) ;
if ( res . error ) {
alert ( res . message ) ;
return ;
}
for ( let i = 0 ; i < res . newData . length ; i ++ ) {
if ( res . newData [ i ] . newPrice != null ) {
$ ( "#hesabix-item-price-" + res . newData [ i ] . attributeId ) . text ( res . newData [ i ] . newPrice ) ;
}
if ( res . newData [ i ] . newQuantity != null ) {
$ ( "#hesabix-item-quantity-" + res . newData [ i ] . attributeId ) . text ( res . newData [ i ] . newQuantity ) ;
}
}
} else {
alert ( 'خطا در هنگام بروزرسانی محصول' ) ;
}
} ) ;
$ ( this ) . prop ( 'disabled' , true ) ;
} ) ;
} ,
initPluginDataOperations : function ( ) {
$ ( '#hesabix-clear-plugin-data' ) . click ( function ( ) {
if ( confirm ( 'هشدار: با انجام این عملیات کلیه اطلاعات افزونه شامل روابط بین کالاها، مشتریان و فاکتور ه ا و همینطور تنظیمات افزونه حذف می گردد. آیا از انجام این عملیات مطمئن هستید؟' ) ) {
$ ( this ) . addClass ( 'disabled' ) . html ( 'حذف دیتای افزونه...' ) ;
$ . post ( ajaxurl , { action : 'adminClearPluginData' } , ( response ) => {
$ ( this ) . removeClass ( 'disabled' ) . html ( 'حذف دیتای افزونه' ) ;
if ( response !== 'failed' ) {
alert ( 'دیتای افزونه با موفقیت حذف شد.' ) ;
} else {
alert ( 'خطا در هنگام حذف دیتای افزونه.' ) ;
}
} ) ;
}
} ) ;
$ ( '#hesabix-install-plugin-data' ) . click ( function ( ) {
if ( confirm ( 'با انجام این عملیات جدول افزونه در دیتابیس وردپرس ایجاد و تنظیمات پیش فرض افزونه تنظیم می گردد. آیا از انجام این عملیات مطمئن هستید؟' ) ) {
$ ( this ) . addClass ( 'disabled' ) . html ( 'نصب دیتای افزونه...' ) ;
$ . post ( ajaxurl , { action : 'adminInstallPluginData' } , ( response ) => {
$ ( this ) . removeClass ( 'disabled' ) . html ( 'نصب دیتای افزونه' ) ;
if ( response !== 'failed' ) {
alert ( 'دیتای افزونه با موفقیت نصب شد.' ) ;
} else {
alert ( 'خطا در هنگام نصب دیتای افزونه.' ) ;
}
} ) ;
}
} ) ;
} ,
initSettingsOperations : function ( ) {
this . initApiKeyChange ( ) ;
this . initAdditionalFields ( ) ;
} ,
initApiKeyChange : function ( ) {
let oldApiKey = '' ;
$ ( "#changeBusinessWarning" ) . hide ( ) ;
$ ( "#hesabix_account_api" ) . focusin ( function ( ) {
oldApiKey = $ ( "#hesabix_account_api" ) . val ( ) ;
} ) ;
$ ( "#hesabix_account_api" ) . focusout ( function ( ) {
const newApiKey = $ ( "#hesabix_account_api" ) . val ( ) ;
if ( oldApiKey != '' && oldApiKey != newApiKey ) {
$ ( "#changeBusinessWarning" ) . show ( ) ;
}
} ) ;
} ,
initAdditionalFields : function ( ) {
const radio = $ ( 'input:radio[name="addFieldsRadio"]' ) ;
const radioChecked = $ ( 'input:radio[name="addFieldsRadio"]:checked' ) ;
const textInput = $ ( '.contact_text_input' ) ;
if ( radioChecked . val ( ) === '2' ) {
textInput . prop ( "disabled" , false ) ;
} else {
textInput . prop ( "disabled" , true ) ;
}
$ ( radio ) . on ( 'click' , function ( ) {
if ( $ ( this ) . val ( ) === '2' ) {
textInput . prop ( "disabled" , false ) ;
} else {
textInput . prop ( "disabled" , true ) ;
}
} ) ;
} ,
initApiOperations : function ( ) {
$ ( document ) . ready ( ( ) => {
$ ( document ) . on ( 'click' , '#save-api-settings' , ( e ) => {
e . preventDefault ( ) ;
this . saveApiSettings ( ) ;
} ) ;
$ ( document ) . on ( 'click' , '#test-connection' , ( e ) => {
e . preventDefault ( ) ;
this . testApiConnection ( ) ;
} ) ;
$ ( '#hesabix_api_form' ) . on ( 'submit' , ( e ) => {
e . preventDefault ( ) ;
this . saveApiSettings ( ) ;
} ) ;
} ) ;
} ,
saveApiSettings : function ( ) {
const saveBtn = $ ( '#save-api-settings' ) ;
const originalText = saveBtn . html ( ) ;
saveBtn . addClass ( 'loading' ) . prop ( 'disabled' , true ) ;
const formData = {
2025-08-11 07:25:23 +03:30
action : 'admin_save_api_settings' ,
2025-08-05 17:24:52 +03:30
nonce : hesabix _ajax . nonce ,
api _key : $ ( '#hesabix_account_api' ) . val ( ) ,
api _address : $ ( '#hesabix_api_address' ) . val ( ) ,
custom _api _address : $ ( '#hesabix_custom_api_address' ) . val ( )
} ;
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : formData ,
success : ( response ) => {
if ( response . success ) {
this . showMessage ( 'success' , response . data . message ) ;
} else {
this . showMessage ( 'error' , response . data . message || 'خطا در ذخیره تنظیمات' ) ;
}
} ,
error : ( ) => this . showMessage ( 'error' , 'خطا در ارتباط با سرور' ) ,
complete : ( ) => {
saveBtn . removeClass ( 'loading' ) . prop ( 'disabled' , false ) . html ( originalText ) ;
}
} ) ;
} ,
testApiConnection : function ( ) {
const testBtn = $ ( '#test-connection' ) ;
const originalText = testBtn . html ( ) ;
testBtn . addClass ( 'loading' ) . prop ( 'disabled' , true ) ;
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : {
2025-08-11 07:25:23 +03:30
action : 'admin_test_api_connection' ,
2025-08-05 17:24:52 +03:30
nonce : hesabix _ajax . nonce
} ,
success : ( response ) => {
if ( response . success ) {
this . showMessage ( 'success' , response . data . message ) ;
} else {
this . showMessage ( 'error' , response . data . message || 'خطا در بررسی اتصال' ) ;
}
} ,
error : ( ) => this . showMessage ( 'error' , 'خطا در ارتباط با سرور' ) ,
complete : ( ) => {
testBtn . removeClass ( 'loading' ) . prop ( 'disabled' , false ) . html ( originalText ) ;
}
} ) ;
} ,
showMessage : function ( type , message ) {
$ ( '.hesabix-message' ) . remove ( ) ;
const messageClass = type === 'success' ? 'hesabix-alert-success' : 'hesabix-alert-danger' ;
const messageHtml = `
< div class = "hesabix-message hesabix-alert ${messageClass}" >
< div class = "hesabix-alert-content" >
< span > $ { message } < / s p a n >
< / d i v >
< / d i v >
` ;
const form = $ ( '#hesabix_api_form' ) ;
if ( form . length > 0 ) {
form . before ( messageHtml ) ;
} else {
$ ( '.hesabix-admin' ) . prepend ( messageHtml ) ;
}
} ,
initTabSystem : function ( ) {
const $tabs = $ ( '.hesabix-tab' ) ;
const $tabContent = $ ( '.hesabix-tab-content' ) ;
$tabs . on ( 'click' , ( e ) => {
e . preventDefault ( ) ;
const $tab = $ ( e . currentTarget ) ;
const tabName = $tab . attr ( 'data-tab' ) ;
if ( ! $tab . hasClass ( 'active' ) ) {
$tabContent . html ( '<div class="hesabix-stats-loading"><div class="hesabix-spinner"></div><p>در حال بارگذاری...</p></div>' ) ;
$tabs . removeClass ( 'active' ) ;
$tab . addClass ( 'active' ) ;
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : {
action : 'hesabix_load_tab_content' ,
tab : tabName ,
nonce : hesabix _ajax . nonce
} ,
success : ( response ) => {
if ( response . success ) {
$tabContent . html ( response . data . content ) ;
this . initStatusSelector ( ) ;
this . initFreightSwitch ( ) ;
if ( tabName === 'api' ) {
this . initCustomApiAddress ( ) ;
}
$ ( document ) . trigger ( 'hesabix_content_loaded' ) ;
this . initTabSpecificFunctions ( tabName ) ;
} else {
$tabContent . html ( '<div class="hesabix-alert hesabix-alert-danger">خطا در بارگذاری محتوا</div>' ) ;
}
} ,
error : ( ) => {
$tabContent . html ( '<div class="hesabix-alert hesabix-alert-danger">خطا در بارگذاری محتوا</div>' ) ;
}
} ) ;
}
} ) ;
} ,
initTabSpecificFunctions : function ( tabName ) {
switch ( tabName ) {
case 'home' :
this . loadHomeStats ( ) ;
break ;
case 'sync' :
this . loadSyncStats ( ) ;
this . initDateRangeSelector ( ) ;
this . initSyncProducts ( ) ;
this . initSyncOrders ( ) ;
this . initUpdateCustomers ( ) ;
this . initUpdateProducts ( ) ;
this . initUpdateWcProducts ( ) ;
break ;
case 'extra' :
this . initSaveExtraSettings ( ) ;
break ;
case 'catalog' :
this . initSaveCatalogSettings ( ) ;
break ;
case 'invoice' :
this . initSaveInvoiceSettings ( ) ;
break ;
case 'customers' :
this . initSaveCustomersSettings ( ) ;
this . initSaveCustomersFields ( ) ;
break ;
case 'logs' :
this . initLogAjax ( ) ;
break ;
}
} ,
initStatusSelector : function ( ) {
$ ( '.hesabix-status-selector' ) . each ( function ( ) {
const $container = $ ( this ) ;
const $grid = $container . find ( '.hesabix-status-grid' ) ;
const $hiddenInput = $container . find ( 'input[type="hidden"]' ) ;
function updateHiddenInput ( ) {
const selectedValues = [ ] ;
$grid . find ( '.hesabix-status-item.selected input[type="checkbox"]' ) . each ( function ( ) {
selectedValues . push ( $ ( this ) . val ( ) ) ;
} ) ;
$hiddenInput . val ( selectedValues . join ( ',' ) ) ;
}
$grid . on ( 'click' , '.hesabix-status-item' , function ( e ) {
e . preventDefault ( ) ;
const $item = $ ( this ) ;
const $checkbox = $item . find ( 'input[type="checkbox"]' ) ;
if ( $item . hasClass ( 'selected' ) ) {
$item . removeClass ( 'selected' ) ;
$checkbox . prop ( 'checked' , false ) ;
} else {
$grid . find ( '.hesabix-status-item.selected' ) . removeClass ( 'selected' ) ;
$grid . find ( 'input[type="checkbox"]' ) . prop ( 'checked' , false ) ;
$item . addClass ( 'selected' ) ;
$checkbox . prop ( 'checked' , true ) ;
}
updateHiddenInput ( ) ;
} ) ;
updateHiddenInput ( ) ;
} ) ;
} ,
initFreightSwitch : function ( ) {
const $freightOptions = $ ( '.hesabix-freight-option' ) ;
let $freightCodeField = $ ( 'tr.hesabix-freight-code-field' ) ;
if ( $freightCodeField . length === 0 ) {
$freightCodeField = $ ( '#hesabix_invoice_freight_code' ) . closest ( 'tr' ) ;
}
if ( $freightCodeField . length === 0 ) {
$freightCodeField = $ ( 'tr' ) . filter ( function ( ) {
return $ ( this ) . find ( '#hesabix_invoice_freight_code' ) . length > 0 ;
} ) ;
}
$freightOptions . on ( 'click' , function ( ) {
const $option = $ ( this ) ;
const value = $option . data ( 'value' ) ;
$freightOptions . removeClass ( 'active' ) ;
$option . addClass ( 'active' ) ;
$ ( '#hesabix_invoice_freight' ) . val ( value ) ;
const valueStr = String ( value ) ;
if ( valueStr === '1' ) {
$freightCodeField . removeClass ( 'hidden' ) . addClass ( 'required-field' ) . css ( 'display' , 'table-row' ) ;
} else {
$freightCodeField . addClass ( 'hidden' ) . removeClass ( 'required-field' ) . css ( 'display' , 'none' ) ;
}
$option . animate ( { scale : 0.95 } , 100 ) . animate ( { scale : 1 } , 100 ) ;
} ) ;
const initialValue = $ ( '#hesabix_invoice_freight' ) . val ( ) ;
const initialValueStr = String ( initialValue ) ;
if ( initialValueStr === '1' ) {
$freightCodeField . removeClass ( 'hidden' ) . addClass ( 'required-field' ) . css ( 'display' , 'table-row' ) ;
} else {
$freightCodeField . addClass ( 'hidden' ) . removeClass ( 'required-field' ) . css ( 'display' , 'none' ) ;
}
} ,
initCustomApiAddress : function ( ) {
const apiAddressSelect = $ ( '#hesabix_api_address' ) ;
const customAddressField = $ ( '.custom-api-address-field' ) ;
function toggleCustomField ( ) {
const selectedValue = apiAddressSelect . val ( ) ;
if ( selectedValue === 'custom' ) {
customAddressField . addClass ( 'show' ) ;
} else {
customAddressField . removeClass ( 'show' ) ;
}
}
toggleCustomField ( ) ;
apiAddressSelect . on ( 'change' , toggleCustomField ) ;
} ,
initSaveExtraSettings : function ( ) {
$ ( '#ajax-save-extra-settings' ) . on ( 'click' , ( e ) => {
e . preventDefault ( ) ;
const form = $ ( '#hesabix_extra_form' ) ;
const formData = form . serialize ( ) ;
const $btn = $ ( '#ajax-save-extra-settings' ) ;
$btn . addClass ( 'loading' ) . prop ( 'disabled' , true ) ;
$ ( '#extra-settings-message' ) . hide ( ) ;
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : formData + '&action=hesabix_save_extra_settings_ajax&nonce=' + hesabix _ajax . nonce ,
success : ( response ) => {
$btn . removeClass ( 'loading' ) . prop ( 'disabled' , false ) ;
const msg = response . success ?
'<div class="hesabix-alert hesabix-alert-success" style="margin-bottom:16px;">تنظیمات با موفقیت ذخیره شد.</div>' :
'<div class="hesabix-alert hesabix-alert-danger" style="margin-bottom:16px;">خطا در ذخیره تنظیمات!</div>' ;
$ ( '#extra-settings-message' ) . html ( msg ) . fadeIn ( ) ;
$ ( 'html, body' ) . animate ( { scrollTop : $ ( '#extra-settings-message' ) . offset ( ) . top } , 500 ) ;
} ,
error : ( ) => {
$btn . removeClass ( 'loading' ) . prop ( 'disabled' , false ) ;
const msg = '<div class="hesabix-alert hesabix-alert-danger" style="margin-bottom:16px;">خطا در ذخیره تنظیمات!</div>' ;
$ ( '#extra-settings-message' ) . html ( msg ) . fadeIn ( ) ;
$ ( 'html, body' ) . animate ( { scrollTop : $ ( '#extra-settings-message' ) . offset ( ) . top } , 500 ) ;
}
} ) ;
} ) ;
} ,
initSaveCatalogSettings : function ( ) {
$ ( '#ajax-save-catalog-settings' ) . on ( 'click' , ( e ) => {
e . preventDefault ( ) ;
const form = $ ( '#hesabix_catalog_form' ) ;
const formData = form . serialize ( ) ;
const $btn = $ ( '#ajax-save-catalog-settings' ) ;
$btn . addClass ( 'loading' ) . prop ( 'disabled' , true ) ;
$ ( '#catalog-settings-message' ) . hide ( ) ;
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : formData + '&action=hesabix_save_catalog_settings_ajax&nonce=' + hesabix _ajax . nonce ,
success : ( response ) => {
$btn . removeClass ( 'loading' ) . prop ( 'disabled' , false ) ;
const msg = response . success ?
'<div class="hesabix-alert hesabix-alert-success" style="margin-bottom:16px;">تنظیمات با موفقیت ذخیره شد.</div>' :
'<div class="hesabix-alert hesabix-alert-danger" style="margin-bottom:16px;">خطا در ذخیره تنظیمات!</div>' ;
$ ( '#catalog-settings-message' ) . html ( msg ) . fadeIn ( ) ;
$ ( 'html, body' ) . animate ( { scrollTop : 0 } , 500 ) ;
} ,
error : ( ) => {
$btn . removeClass ( 'loading' ) . prop ( 'disabled' , false ) ;
const msg = '<div class="hesabix-alert hesabix-alert-danger" style="margin-bottom:16px;">خطا در ذخیره تنظیمات!</div>' ;
$ ( '#catalog-settings-message' ) . html ( msg ) . fadeIn ( ) ;
$ ( 'html, body' ) . animate ( { scrollTop : 0 } , 500 ) ;
}
} ) ;
} ) ;
} ,
initSaveInvoiceSettings : function ( ) {
$ ( '#ajax-save-invoice-settings' ) . on ( 'click' , ( e ) => {
e . preventDefault ( ) ;
const form = $ ( '#hesabix_invoice_form' ) ;
const formData = form . serialize ( ) ;
const $btn = $ ( '#ajax-save-invoice-settings' ) ;
$btn . addClass ( 'loading' ) . prop ( 'disabled' , true ) ;
$ ( '#invoice-settings-message' ) . hide ( ) ;
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : formData + '&action=hesabix_save_invoice_settings_ajax&nonce=' + hesabix _ajax . nonce ,
success : ( response ) => {
$btn . removeClass ( 'loading' ) . prop ( 'disabled' , false ) ;
const msg = response . success ?
'<div class="hesabix-alert hesabix-alert-success" style="margin-bottom:16px;">تنظیمات با موفقیت ذخیره شد.</div>' :
'<div class="hesabix-alert hesabix-alert-danger" style="margin-bottom:16px;">خطا در ذخیره تنظیمات!</div>' ;
$ ( '#invoice-settings-message' ) . html ( msg ) . fadeIn ( ) ;
$ ( 'html, body' ) . animate ( { scrollTop : $ ( '#invoice-settings-message' ) . offset ( ) . top } , 500 ) ;
} ,
error : ( ) => {
$btn . removeClass ( 'loading' ) . prop ( 'disabled' , false ) ;
const msg = '<div class="hesabix-alert hesabix-alert-danger" style="margin-bottom:16px;">خطا در ذخیره تنظیمات!</div>' ;
$ ( '#invoice-settings-message' ) . html ( msg ) . fadeIn ( ) ;
$ ( 'html, body' ) . animate ( { scrollTop : $ ( '#invoice-settings-message' ) . offset ( ) . top } , 500 ) ;
}
} ) ;
} ) ;
} ,
initSaveCustomersSettings : function ( ) {
$ ( '#ajax-save-customers-settings' ) . on ( 'click' , ( e ) => {
e . preventDefault ( ) ;
const form = $ ( '#hesabix_customers_form' ) ;
const formData = form . serialize ( ) ;
const $btn = $ ( '#ajax-save-customers-settings' ) ;
$btn . addClass ( 'loading' ) . prop ( 'disabled' , true ) ;
$ ( '#customers-settings-message' ) . hide ( ) ;
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : formData + '&action=hesabix_save_customers_settings_ajax&nonce=' + hesabix _ajax . nonce ,
success : ( response ) => {
$btn . removeClass ( 'loading' ) . prop ( 'disabled' , false ) ;
const msg = response . success ?
'<div class="hesabix-alert hesabix-alert-success" style="margin-bottom:16px;">تنظیمات با موفقیت ذخیره شد.</div>' :
'<div class="hesabix-alert hesabix-alert-danger" style="margin-bottom:16px;">خطا در ذخیره تنظیمات!</div>' ;
$ ( '#customers-settings-message' ) . html ( msg ) . fadeIn ( ) ;
$ ( 'html, body' ) . animate ( { scrollTop : 0 } , 500 ) ;
} ,
error : ( ) => {
$btn . removeClass ( 'loading' ) . prop ( 'disabled' , false ) ;
const msg = '<div class="hesabix-alert hesabix-alert-danger" style="margin-bottom:16px;">خطا در ذخیره تنظیمات!</div>' ;
$ ( '#customers-settings-message' ) . html ( msg ) . fadeIn ( ) ;
$ ( 'html, body' ) . animate ( { scrollTop : 0 } , 500 ) ;
}
} ) ;
} ) ;
} ,
initSaveCustomersFields : function ( ) {
$ ( 'input[name="addFieldsRadio"]' ) . on ( 'change' , function ( ) {
const selectedValue = $ ( this ) . val ( ) ;
const $fieldsTable = $ ( '.hesabix-table-container' ) ;
const $fieldInputs = $fieldsTable . find ( 'input[type="checkbox"], input[type="text"]' ) ;
if ( selectedValue === '2' ) {
$fieldInputs . prop ( 'disabled' , true ) ;
$fieldsTable . addClass ( 'disabled-fields' ) ;
} else {
$fieldInputs . prop ( 'disabled' , false ) ;
$fieldsTable . removeClass ( 'disabled-fields' ) ;
}
} ) ;
const currentSelection = $ ( 'input[name="addFieldsRadio"]:checked' ) . val ( ) ;
if ( currentSelection === '2' ) {
const $fieldsTable = $ ( '.hesabix-table-container' ) ;
const $fieldInputs = $fieldsTable . find ( 'input[type="checkbox"], input[type="text"]' ) ;
$fieldInputs . prop ( 'disabled' , true ) ;
$fieldsTable . addClass ( 'disabled-fields' ) ;
}
$ ( '#ajax-save-customers-fields' ) . on ( 'click' , ( e ) => {
e . preventDefault ( ) ;
const formData = new FormData ( ) ;
const radioValue = $ ( 'input[name="addFieldsRadio"]:checked' ) . val ( ) ;
formData . append ( 'addFieldsRadio' , radioValue ) ;
const nationalCodeCheck = $ ( '#nationalCodeCheck' ) . is ( ':checked' ) ? 'yes' : 'no' ;
const nationalCodeRequired = $ ( '#nationalCodeRequired' ) . is ( ':checked' ) ? 'yes' : 'no' ;
const nationalCode = $ ( '#nationalCode' ) . val ( ) ;
formData . append ( 'nationalCodeCheck' , nationalCodeCheck ) ;
formData . append ( 'nationalCodeRequired' , nationalCodeRequired ) ;
formData . append ( 'nationalCode' , nationalCode ) ;
const economicCodeCheck = $ ( '#economicCodeCheck' ) . is ( ':checked' ) ? 'yes' : 'no' ;
const economicCodeRequired = $ ( '#economicCodeRequired' ) . is ( ':checked' ) ? 'yes' : 'no' ;
const economicCode = $ ( '#economicCode' ) . val ( ) ;
formData . append ( 'economicCodeCheck' , economicCodeCheck ) ;
formData . append ( 'economicCodeRequired' , economicCodeRequired ) ;
formData . append ( 'economicCode' , economicCode ) ;
const registrationNumberCheck = $ ( '#registrationNumberCheck' ) . is ( ':checked' ) ? 'yes' : 'no' ;
const registrationNumberRequired = $ ( '#registrationNumberRequired' ) . is ( ':checked' ) ? 'yes' : 'no' ;
const registrationNumber = $ ( '#registrationNumber' ) . val ( ) ;
formData . append ( 'registrationNumberCheck' , registrationNumberCheck ) ;
formData . append ( 'registrationNumberRequired' , registrationNumberRequired ) ;
formData . append ( 'registrationNumber' , registrationNumber ) ;
const websiteCheck = $ ( '#websiteCheck' ) . is ( ':checked' ) ? 'yes' : 'no' ;
const websiteRequired = $ ( '#websiteRequired' ) . is ( ':checked' ) ? 'yes' : 'no' ;
const website = $ ( '#website' ) . val ( ) ;
formData . append ( 'websiteCheck' , websiteCheck ) ;
formData . append ( 'websiteRequired' , websiteRequired ) ;
formData . append ( 'website' , website ) ;
formData . append ( 'action' , 'hesabix_save_customers_fields_ajax' ) ;
formData . append ( 'nonce' , hesabix _ajax . nonce ) ;
const $btn = $ ( '#ajax-save-customers-fields' ) ;
$btn . addClass ( 'loading' ) . prop ( 'disabled' , true ) ;
$ ( '#customers-fields-message' ) . hide ( ) ;
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : formData ,
processData : false ,
contentType : false ,
success : ( response ) => {
$btn . removeClass ( 'loading' ) . prop ( 'disabled' , false ) ;
const msg = response . success ?
'<div class="hesabix-alert hesabix-alert-success" style="margin-bottom:16px;">فیلدهای اضافی با موفقیت ذخیره شد.</div>' :
'<div class="hesabix-alert hesabix-alert-danger" style="margin-bottom:16px;">خطا در ذخیره فیلدهای اضافی!</div>' ;
$ ( '#customers-fields-message' ) . html ( msg ) . fadeIn ( ) ;
$ ( 'html, body' ) . animate ( { scrollTop : 0 } , 500 ) ;
} ,
error : ( ) => {
$btn . removeClass ( 'loading' ) . prop ( 'disabled' , false ) ;
const msg = '<div class="hesabix-alert hesabix-alert-danger" style="margin-bottom:16px;">خطا در ذخیره فیلدهای اضافی!</div>' ;
$ ( '#customers-fields-message' ) . html ( msg ) . fadeIn ( ) ;
$ ( 'html, body' ) . animate ( { scrollTop : 0 } , 500 ) ;
}
} ) ;
} ) ;
} ,
initLogAjax : function ( ) {
this . initGetLogFile ( ) ;
this . initDeleteLogFile ( ) ;
this . initDeleteAllLogs ( ) ;
} ,
initGetLogFile : function ( ) {
$ ( '#get-log-file' ) . on ( 'click' , ( e ) => {
e . preventDefault ( ) ;
const $btn = $ ( e . currentTarget ) ;
const originalText = $btn . html ( ) ;
$btn . prop ( 'disabled' , true ) . html ( 'در حال بارگذاری...' ) ;
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : {
action : 'hesabix_get_log_file_ajax' ,
nonce : hesabix _ajax . nonce
} ,
success : ( response ) => {
if ( response . success ) {
$ ( '#log-content' ) . html ( response . data . content ) ;
$ ( '#log-modal' ) . show ( ) ;
} else {
alert ( 'خطا در بارگذاری فایل لاگ' ) ;
}
} ,
error : ( ) => alert ( 'خطا در بارگذاری فایل لاگ' ) ,
complete : ( ) => {
$btn . prop ( 'disabled' , false ) . html ( originalText ) ;
}
} ) ;
} ) ;
} ,
initDeleteLogFile : function ( ) {
$ ( '#delete-log-file' ) . on ( 'click' , ( e ) => {
e . preventDefault ( ) ;
if ( confirm ( 'آیا از حذف فایل لاگ اطمینان دارید؟' ) ) {
const $btn = $ ( e . currentTarget ) ;
const originalText = $btn . html ( ) ;
$btn . prop ( 'disabled' , true ) . html ( 'در حال حذف...' ) ;
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : {
action : 'hesabix_delete_log_file_ajax' ,
nonce : hesabix _ajax . nonce
} ,
success : ( response ) => {
if ( response . success ) {
alert ( 'فایل لاگ با موفقیت حذف شد' ) ;
location . reload ( ) ;
} else {
alert ( 'خطا در حذف فایل لاگ' ) ;
}
} ,
error : ( ) => alert ( 'خطا در حذف فایل لاگ' ) ,
complete : ( ) => {
$btn . prop ( 'disabled' , false ) . html ( originalText ) ;
}
} ) ;
}
} ) ;
} ,
initDeleteAllLogs : function ( ) {
$ ( '#delete-all-logs' ) . on ( 'click' , ( e ) => {
e . preventDefault ( ) ;
if ( confirm ( 'آیا از حذف تمام فایلهای لاگ اطمینان دارید؟' ) ) {
const $btn = $ ( e . currentTarget ) ;
const originalText = $btn . html ( ) ;
$btn . prop ( 'disabled' , true ) . html ( 'در حال حذف...' ) ;
$ . ajax ( {
url : ajaxurl ,
type : 'POST' ,
data : {
action : 'hesabix_delete_all_logs_ajax' ,
nonce : hesabix _ajax . nonce
} ,
success : ( response ) => {
if ( response . success ) {
alert ( 'تمام فایلهای لاگ با موفقیت حذف شدند' ) ;
location . reload ( ) ;
} else {
alert ( 'خطا در حذف فایلهای لاگ' ) ;
}
} ,
error : ( ) => alert ( 'خطا در حذف فایلهای لاگ' ) ,
complete : ( ) => {
$btn . prop ( 'disabled' , false ) . html ( originalText ) ;
}
} ) ;
}
} ) ;
} ,
initDateRangeSelector : function ( ) {
const $form = $ ( '#hesabix_sync_orders' ) ;
const $presetBtns = $ ( '.hesabix-date-preset-btn' ) ;
const $customContainer = $ ( '.hesabix-date-range-container' ) ;
const $selectedRange = $ ( '.hesabix-selected-range' ) ;
const $rangeDisplay = $ ( '#hesabix-range-display' ) ;
const $submitBtn = $ ( '#hesabix-sync-orders-submit' ) ;
const $startDate = $ ( '#hesabix_sync_order_date' ) ;
const $endDate = $ ( '#hesabix_sync_order_end_date' ) ;
const $startDateJalali = $ ( '#hesabix_sync_order_date_jalali' ) ;
const $endDateJalali = $ ( '#hesabix_sync_order_end_date_jalali' ) ;
const $validationMsg = $ ( '.hesabix-date-validation-message' ) ;
if ( $startDate . length === 0 || $endDate . length === 0 ) return ;
this . setPresetRange ( 7 ) ;
$presetBtns . filter ( '[data-days="7"]' ) . addClass ( 'active' ) ;
$presetBtns . on ( 'click' , ( e ) => {
e . preventDefault ( ) ;
const $btn = $ ( e . currentTarget ) ;
$presetBtns . removeClass ( 'active' ) ;
$btn . addClass ( 'active' ) ;
if ( $btn . data ( 'custom' ) ) {
this . showCustomRange ( ) ;
} else {
const days = parseInt ( $btn . data ( 'days' ) ) ;
this . setPresetRange ( days ) ;
this . hideCustomRange ( ) ;
}
} ) ;
$startDateJalali . add ( $endDateJalali ) . on ( 'input' , ( e ) => {
const $input = $ ( e . target ) ;
const value = $input . val ( ) ;
if ( value . length === 10 && /^\d{4}\/\d{2}\/\d{2}$/ . test ( value ) ) {
const gregorianDate = this . jalaliDateToGregorian ( value ) ;
if ( gregorianDate ) {
const isStartDate = $input . attr ( 'id' ) . includes ( 'start' ) ;
const targetInput = isStartDate ? $startDate : $endDate ;
targetInput . val ( this . formatDateForInput ( gregorianDate ) ) ;
this . validateDateRange ( ) ;
this . updateRangeDisplay ( ) ;
}
}
} ) ;
$startDateJalali . add ( $endDateJalali ) . on ( 'blur' , ( e ) => {
const $input = $ ( e . target ) ;
const value = $input . val ( ) ;
if ( value && ! /^\d{4}\/\d{2}\/\d{2}$/ . test ( value ) ) {
$input . addClass ( 'error' ) ;
} else {
$input . removeClass ( 'error' ) ;
}
} ) ;
$form . on ( 'submit' , ( e ) => {
if ( ! this . validateDateRange ( ) ) {
e . preventDefault ( ) ;
alert ( 'Please select a valid date range before synchronizing orders.' ) ;
return false ;
}
} ) ;
setTimeout ( ( ) => {
this . updateRangeDisplay ( ) ;
this . showSelectedRange ( ) ;
} , 100 ) ;
} ,
setPresetRange : function ( days ) {
const $startDate = $ ( '#hesabix_sync_order_date' ) ;
const $endDate = $ ( '#hesabix_sync_order_end_date' ) ;
const $startDateJalali = $ ( '#hesabix_sync_order_date_jalali' ) ;
const $endDateJalali = $ ( '#hesabix_sync_order_end_date_jalali' ) ;
const endDate = new Date ( ) ;
const startDate = new Date ( ) ;
startDate . setDate ( endDate . getDate ( ) - days ) ;
$startDate . val ( this . formatDateForInput ( startDate ) ) ;
$endDate . val ( this . formatDateForInput ( endDate ) ) ;
$startDateJalali . val ( this . formatJalaliDateShort ( startDate ) ) ;
$endDateJalali . val ( this . formatJalaliDateShort ( endDate ) ) ;
this . updateRangeDisplay ( ) ;
this . enableSubmitButton ( ) ;
this . showSelectedRange ( ) ;
} ,
showCustomRange : function ( ) {
$ ( '.hesabix-date-range-container' ) . slideDown ( 300 ) ;
$ ( '#hesabix_sync_order_date' ) . focus ( ) ;
this . validateDateRange ( ) ;
} ,
hideCustomRange : function ( ) {
$ ( '.hesabix-date-range-container' ) . slideUp ( 300 ) ;
this . clearValidation ( ) ;
} ,
validateDateRange : function ( ) {
const $startDate = $ ( '#hesabix_sync_order_date' ) ;
const $endDate = $ ( '#hesabix_sync_order_end_date' ) ;
const $startDateJalali = $ ( '#hesabix_sync_order_date_jalali' ) ;
const $endDateJalali = $ ( '#hesabix_sync_order_end_date_jalali' ) ;
const $validationMsg = $ ( '.hesabix-date-validation-message' ) ;
const $submitBtn = $ ( '#hesabix-sync-orders-submit' ) ;
const $selectedRange = $ ( '.hesabix-selected-range' ) ;
const startVal = $startDate . val ( ) ;
const endVal = $endDate . val ( ) ;
if ( ! startVal || ! endVal ) {
this . disableSubmitButton ( ) ;
this . hideSelectedRange ( ) ;
return false ;
}
const startDate = new Date ( startVal ) ;
const endDate = new Date ( endVal ) ;
if ( startDate >= endDate ) {
this . showValidationError ( ) ;
this . disableSubmitButton ( ) ;
this . hideSelectedRange ( ) ;
return false ;
}
this . clearValidation ( ) ;
this . enableSubmitButton ( ) ;
this . showSelectedRange ( ) ;
return true ;
} ,
showValidationError : function ( ) {
const $startDate = $ ( '#hesabix_sync_order_date' ) ;
const $endDate = $ ( '#hesabix_sync_order_end_date' ) ;
const $startDateJalali = $ ( '#hesabix_sync_order_date_jalali' ) ;
const $endDateJalali = $ ( '#hesabix_sync_order_end_date_jalali' ) ;
const $validationMsg = $ ( '.hesabix-date-validation-message' ) ;
$startDate . add ( $endDate ) . addClass ( 'error' ) ;
$startDateJalali . add ( $endDateJalali ) . addClass ( 'error' ) ;
$validationMsg . slideDown ( 200 ) ;
} ,
clearValidation : function ( ) {
const $startDate = $ ( '#hesabix_sync_order_date' ) ;
const $endDate = $ ( '#hesabix_sync_order_end_date' ) ;
const $startDateJalali = $ ( '#hesabix_sync_order_date_jalali' ) ;
const $endDateJalali = $ ( '#hesabix_sync_order_end_date_jalali' ) ;
const $validationMsg = $ ( '.hesabix-date-validation-message' ) ;
$startDate . add ( $endDate ) . removeClass ( 'error' ) ;
$startDateJalali . add ( $endDateJalali ) . removeClass ( 'error' ) ;
$validationMsg . slideUp ( 200 ) ;
} ,
updateRangeDisplay : function ( ) {
const $startDate = $ ( '#hesabix_sync_order_date' ) ;
const $endDate = $ ( '#hesabix_sync_order_end_date' ) ;
const $rangeDisplay = $ ( '#hesabix-range-display' ) ;
const startVal = $startDate . val ( ) ;
const endVal = $endDate . val ( ) ;
if ( startVal && endVal ) {
const startDate = new Date ( startVal ) ;
const endDate = new Date ( endVal ) ;
if ( startDate < endDate ) {
const formattedStart = this . formatDateForDisplay ( startDate ) ;
const formattedEnd = this . formatDateForDisplay ( endDate ) ;
const daysDiff = Math . ceil ( ( endDate - startDate ) / ( 1000 * 60 * 60 * 24 ) ) ;
$rangeDisplay . html ( ` ${ formattedStart } - ${ formattedEnd } <span style="font-weight: normal; opacity: 0.8;">( ${ daysDiff } روز)</span> ` ) ;
}
}
} ,
showSelectedRange : function ( ) {
const $selectedRange = $ ( '.hesabix-selected-range' ) ;
if ( ! $selectedRange . is ( ':visible' ) ) {
$selectedRange . slideDown ( 300 ) ;
}
} ,
hideSelectedRange : function ( ) {
$ ( '.hesabix-selected-range' ) . slideUp ( 300 ) ;
} ,
enableSubmitButton : function ( ) {
$ ( '#hesabix-sync-orders-submit' ) . prop ( 'disabled' , false ) . removeClass ( 'disabled' ) ;
} ,
disableSubmitButton : function ( ) {
$ ( '#hesabix-sync-orders-submit' ) . prop ( 'disabled' , true ) . addClass ( 'disabled' ) ;
} ,
formatDateForInput : function ( date ) {
return date . getFullYear ( ) + '-' +
String ( date . getMonth ( ) + 1 ) . padStart ( 2 , '0' ) + '-' +
String ( date . getDate ( ) ) . padStart ( 2 , '0' ) ;
} ,
formatDateForDisplay : function ( date ) {
return this . formatJalaliDate ( date ) ;
}
} ;
window . loadHomeStats = HesabixAdmin . loadHomeStats . bind ( HesabixAdmin ) ;
window . checkHesabixUpdate = HesabixAdmin . checkHesabixUpdate . bind ( HesabixAdmin ) ;
window . loadSyncStats = HesabixAdmin . loadSyncStats . bind ( HesabixAdmin ) ;
window . hesabix _load _tab _content = HesabixAdmin . initTabSystem . bind ( HesabixAdmin ) ;
HesabixAdmin . init ( ) ;
} ) ;
function hesabixTutorialJumpTo ( time ) {
const vidEl = document . getElementById ( 'hesabix-tutorial-video' ) ;
vidEl . play ( ) ;
vidEl . pause ( ) ;
vidEl . currentTime = time ;
vidEl . play ( ) ;
}