diff --git a/cost-of-goods-for-woocommerce.php b/cost-of-goods-for-woocommerce.php index 1ff5046..26fce18 100644 --- a/cost-of-goods-for-woocommerce.php +++ b/cost-of-goods-for-woocommerce.php @@ -3,7 +3,7 @@ Plugin Name: Cost of Goods for WooCommerce Plugin URI: https://wpfactory.com/item/cost-of-goods-for-woocommerce/ Description: Save product purchase costs (cost of goods) in WooCommerce. Beautifully. -Version: 2.5.0 +Version: 2.5.1 Author: WPFactory Author URI: https://wpfactory.com Text Domain: cost-of-goods-for-woocommerce @@ -63,7 +63,8 @@ final class Alg_WC_Cost_of_Goods { * @var string * @since 1.0.0 */ - public $version = '2.5.0'; + + public $version = '2.5.1'; /** * @var Alg_WC_Cost_of_Goods The single instance of the class diff --git a/includes/alg-wc-cog-functions.php b/includes/alg-wc-cog-functions.php index a46d6f8..fc4e3ec 100644 --- a/includes/alg-wc-cog-functions.php +++ b/includes/alg-wc-cog-functions.php @@ -2,7 +2,7 @@ /** * Cost of Goods for WooCommerce - Functions * - * @version 2.4.2 + * @version 2.5.1 * @since 1.4.0 * @author WPFactory */ @@ -199,3 +199,17 @@ function alg_wc_cog_array_to_string( $arr, $args = array() ) { return implode( $args['glue'], $transformed_arr ); } } + +if ( ! function_exists( 'alg_wc_cog_get_blocked_options_message' ) ) { + /** + * alg_wc_cog_get_blocked_options_message. + * + * @version 2.5.1 + * @since 2.5.1 + * + * @return string + */ + function alg_wc_cog_get_blocked_options_message() { + return sprintf( __( 'Disabled options can be unlocked using %s', 'cost-of-goods-for-woocommerce' ), 'https://wpfactory.com/item/cost-of-goods-for-woocommerce/', __( 'Cost of Goods for WooCommerce Pro', 'cost-of-goods-for-woocommerce' ) ); + } +} diff --git a/includes/analytics/build/index.asset.php b/includes/analytics/build/index.asset.php index 2fe6c6f..927f32a 100644 --- a/includes/analytics/build/index.asset.php +++ b/includes/analytics/build/index.asset.php @@ -1 +1 @@ - array('wc-currency', 'wp-hooks', 'wp-i18n'), 'version' => 'c8a835c8dd767411a52fc60d79167167'); \ No newline at end of file + array('wc-currency', 'wp-hooks', 'wp-i18n'), 'version' => '788d1a21f794f9834f9046d4d5b938c9'); \ No newline at end of file diff --git a/includes/analytics/build/index.js b/includes/analytics/build/index.js index f7824e1..9761fbb 100644 --- a/includes/analytics/build/index.js +++ b/includes/analytics/build/index.js @@ -1 +1,674 @@ -!function(o){var t={};function e(r){if(t[r])return t[r].exports;var c=t[r]={i:r,l:!1,exports:{}};return o[r].call(c.exports,c,c.exports,e),c.l=!0,c.exports}e.m=o,e.c=t,e.d=function(o,t,r){e.o(o,t)||Object.defineProperty(o,t,{enumerable:!0,get:r})},e.r=function(o){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(o,"__esModule",{value:!0})},e.t=function(o,t){if(1&t&&(o=e(o)),8&t)return o;if(4&t&&"object"==typeof o&&o&&o.__esModule)return o;var r=Object.create(null);if(e.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:o}),2&t&&"string"!=typeof o)for(var c in o)e.d(r,c,function(t){return o[t]}.bind(null,c));return r},e.n=function(o){var t=o&&o.__esModule?function(){return o.default}:function(){return o};return e.d(t,"a",t),t},e.o=function(o,t){return Object.prototype.hasOwnProperty.call(o,t)},e.p="",e(e.s=9)}([function(o,t){o.exports=window.wp.i18n},function(o,t,e){var r=e(5),c=e(6),n=e(7),a=e(8);o.exports=function(o){return r(o)||c(o)||n(o)||a()},o.exports.default=o.exports,o.exports.__esModule=!0},function(o,t){o.exports=window.wp.hooks},function(o,t){o.exports=window.wc.currency},function(o,t){o.exports=function(o,t){(null==t||t>o.length)&&(t=o.length);for(var e=0,r=new Array(t);e arr.length) len = arr.length; + + for (var i = 0, arr2 = new Array(len); i < len; i++) { + arr2[i] = arr[i]; + } + + return arr2; +} + +module.exports = _arrayLikeToArray; +module.exports["default"] = module.exports, module.exports.__esModule = true; + +/***/ }), + +/***/ "./node_modules/@babel/runtime/helpers/arrayWithoutHoles.js": +/*!******************************************************************!*\ + !*** ./node_modules/@babel/runtime/helpers/arrayWithoutHoles.js ***! + \******************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var arrayLikeToArray = __webpack_require__(/*! ./arrayLikeToArray.js */ "./node_modules/@babel/runtime/helpers/arrayLikeToArray.js"); + +function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) return arrayLikeToArray(arr); +} + +module.exports = _arrayWithoutHoles; +module.exports["default"] = module.exports, module.exports.__esModule = true; + +/***/ }), + +/***/ "./node_modules/@babel/runtime/helpers/iterableToArray.js": +/*!****************************************************************!*\ + !*** ./node_modules/@babel/runtime/helpers/iterableToArray.js ***! + \****************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +function _iterableToArray(iter) { + if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); +} + +module.exports = _iterableToArray; +module.exports["default"] = module.exports, module.exports.__esModule = true; + +/***/ }), + +/***/ "./node_modules/@babel/runtime/helpers/nonIterableSpread.js": +/*!******************************************************************!*\ + !*** ./node_modules/@babel/runtime/helpers/nonIterableSpread.js ***! + \******************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); +} + +module.exports = _nonIterableSpread; +module.exports["default"] = module.exports, module.exports.__esModule = true; + +/***/ }), + +/***/ "./node_modules/@babel/runtime/helpers/toConsumableArray.js": +/*!******************************************************************!*\ + !*** ./node_modules/@babel/runtime/helpers/toConsumableArray.js ***! + \******************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var arrayWithoutHoles = __webpack_require__(/*! ./arrayWithoutHoles.js */ "./node_modules/@babel/runtime/helpers/arrayWithoutHoles.js"); + +var iterableToArray = __webpack_require__(/*! ./iterableToArray.js */ "./node_modules/@babel/runtime/helpers/iterableToArray.js"); + +var unsupportedIterableToArray = __webpack_require__(/*! ./unsupportedIterableToArray.js */ "./node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js"); + +var nonIterableSpread = __webpack_require__(/*! ./nonIterableSpread.js */ "./node_modules/@babel/runtime/helpers/nonIterableSpread.js"); + +function _toConsumableArray(arr) { + return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread(); +} + +module.exports = _toConsumableArray; +module.exports["default"] = module.exports, module.exports.__esModule = true; + +/***/ }), + +/***/ "./node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js": +/*!***************************************************************************!*\ + !*** ./node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js ***! + \***************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var arrayLikeToArray = __webpack_require__(/*! ./arrayLikeToArray.js */ "./node_modules/@babel/runtime/helpers/arrayLikeToArray.js"); + +function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen); +} + +module.exports = _unsupportedIterableToArray; +module.exports["default"] = module.exports, module.exports.__esModule = true; + +/***/ }), + +/***/ "./src/index.js": +/*!**********************!*\ + !*** ./src/index.js ***! + \**********************/ +/*! no exports provided */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _modules_orders__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./modules/orders */ "./src/modules/orders.js"); +/* harmony import */ var _modules_revenue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modules/revenue */ "./src/modules/revenue.js"); +/* harmony import */ var _modules_stock__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./modules/stock */ "./src/modules/stock.js"); +/* harmony import */ var _modules_products__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modules/products */ "./src/modules/products.js"); +/** + * Analytics. + * + * @version 2.5.1 + * @since 2.4.5 + * @author WPFactory + */ +// Orders. + +_modules_orders__WEBPACK_IMPORTED_MODULE_0__["default"].init(); // Revenue. + + +_modules_revenue__WEBPACK_IMPORTED_MODULE_1__["default"].init(); // Stock. + + +_modules_stock__WEBPACK_IMPORTED_MODULE_2__["default"].init(); // Products. + + +_modules_products__WEBPACK_IMPORTED_MODULE_3__["default"].init(); + +/***/ }), + +/***/ "./src/modules/orders.js": +/*!*******************************!*\ + !*** ./src/modules/orders.js ***! + \*******************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ "./node_modules/@babel/runtime/helpers/toConsumableArray.js"); +/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/hooks */ "@wordpress/hooks"); +/* harmony import */ var _wordpress_hooks__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _woocommerce_currency__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @woocommerce/currency */ "@woocommerce/currency"); +/* harmony import */ var _woocommerce_currency__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_woocommerce_currency__WEBPACK_IMPORTED_MODULE_3__); + + +/** + * Cost of Goods for WooCommerce - Analytics > Orders (WooCommerce Admin) Report. + * + * @see https://github.com/woocommerce/woocommerce-admin/blob/main/client/analytics/report/orders/config.js#L50-L62 + * + */ + + + +var storeCurrency = _woocommerce_currency__WEBPACK_IMPORTED_MODULE_3___default()(wcSettings.currency); +var orders = { + init: function init() { + // Reports table + Object(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__["addFilter"])('woocommerce_admin_report_table', 'cost-of-goods-for-woocommerce', function (reportTableData) { + if (reportTableData.endpoint !== 'orders' || !reportTableData.items || !reportTableData.items.data || !reportTableData.items.data.length || !alg_wc_cog_analytics_obj.cost_and_profit_columns_enabled_on_orders) { + return reportTableData; + } + + var newHeaders = [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(reportTableData.headers), [{ + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Cost', 'cost-of-goods-for-woocommerce'), + key: 'order_cost', + isNumeric: true //isSortable: true, + + }, { + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Profit', 'cost-of-goods-for-woocommerce'), + key: 'order_profit', + isNumeric: true //isSortable: true, + + }]); + var newRows = reportTableData.rows.map(function (row, index) { + var order = reportTableData.items.data[index]; + var newRow = [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(row), [{ + display: storeCurrency.formatAmount(order.order_cost), + value: order.order_cost, + type: 'currency' + }, { + display: storeCurrency.formatAmount(order.order_profit), + value: order.order_profit, + type: 'currency' + }]); + return newRow; + }); + reportTableData.headers = newHeaders; + reportTableData.rows = newRows; + return reportTableData; + }); // Charts + + /** + * @see https://github.com/woocommerce/woocommerce-admin/blob/main/client/analytics/report/orders/config.js#L50-L62 + */ + + Object(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__["addFilter"])('woocommerce_admin_orders_report_charts', 'cost-of-goods-for-woocommerce', function (charts) { + if (alg_wc_cog_analytics_obj.cost_and_profit_totals_enabled_on_orders) { + charts = [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(charts), [{ + key: 'costs_total', + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Costs total', 'cost-of-goods-for-woocommerce'), + type: 'currency' + }, { + key: 'profit_total', + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Profit total', 'cost-of-goods-for-woocommerce'), + type: 'currency' + }]); + } + + return charts; + }); + } +}; +/* harmony default export */ __webpack_exports__["default"] = (orders); + +/***/ }), + +/***/ "./src/modules/products.js": +/*!*********************************!*\ + !*** ./src/modules/products.js ***! + \*********************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ "./node_modules/@babel/runtime/helpers/toConsumableArray.js"); +/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/hooks */ "@wordpress/hooks"); +/* harmony import */ var _wordpress_hooks__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _woocommerce_currency__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @woocommerce/currency */ "@woocommerce/currency"); +/* harmony import */ var _woocommerce_currency__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_woocommerce_currency__WEBPACK_IMPORTED_MODULE_3__); + + +/** + * Cost of Goods for WooCommerce - Analytics > Products (WooCommerce Admin) Report. + * + */ + + + +var storeCurrency = _woocommerce_currency__WEBPACK_IMPORTED_MODULE_3___default()(wcSettings.currency); +var products = { + init: function init() { + // Reports table + Object(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__["addFilter"])('woocommerce_admin_report_table', 'cost-of-goods-for-woocommerce', function (reportTableData) { + if (reportTableData.endpoint !== 'products' || !reportTableData.items || !reportTableData.items.data || !reportTableData.items.data.length || !alg_wc_cog_analytics_obj.cost_and_profit_columns_enabled_on_products) { + return reportTableData; + } + + var newHeaders = [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(reportTableData.headers), [{ + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Cost', 'cost-of-goods-for-woocommerce'), + key: 'cost', + isNumeric: true //isSortable: true, + + }, { + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Profit', 'cost-of-goods-for-woocommerce'), + key: 'profit', + isNumeric: true //isSortable: true, + + }]); + var newRows = reportTableData.rows.map(function (row, index) { + var item = reportTableData.items.data[index]; + console.log(item); + var newRow = [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(row), [{ + display: storeCurrency.formatAmount(item.cost), + value: item.cost, + type: 'currency' + }, { + display: storeCurrency.formatAmount(item.profit), + value: item.profit, + type: 'currency' + }]); + return newRow; + }); + reportTableData.rows = newRows; + reportTableData.headers = newHeaders; + return reportTableData; + }); // Charts + + /** + * @see https://github.com/woocommerce/woocommerce-admin/blob/main/client/analytics/report/orders/config.js#L50-L62 + */ + + Object(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__["addFilter"])('woocommerce_admin_products_report_charts', 'cost-of-goods-for-woocommerce', function (charts) { + if (alg_wc_cog_analytics_obj.cost_and_profit_totals_enabled_on_products) { + charts = [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(charts), [{ + key: 'costs_total', + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Costs total', 'cost-of-goods-for-woocommerce'), + type: 'currency' + }, { + key: 'profit_total', + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Profit total', 'cost-of-goods-for-woocommerce'), + type: 'currency' + }]); + } + + return charts; + }); + } +}; +/* harmony default export */ __webpack_exports__["default"] = (products); + +/***/ }), + +/***/ "./src/modules/revenue.js": +/*!********************************!*\ + !*** ./src/modules/revenue.js ***! + \********************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ "./node_modules/@babel/runtime/helpers/toConsumableArray.js"); +/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/hooks */ "@wordpress/hooks"); +/* harmony import */ var _wordpress_hooks__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _woocommerce_currency__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @woocommerce/currency */ "@woocommerce/currency"); +/* harmony import */ var _woocommerce_currency__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_woocommerce_currency__WEBPACK_IMPORTED_MODULE_3__); + + +/** + * Cost of Goods for WooCommerce - Analytics > Revenue (WooCommerce Admin) Report. + * + */ + + + +var storeCurrency = _woocommerce_currency__WEBPACK_IMPORTED_MODULE_3___default()(wcSettings.currency); +var orders = { + init: function init() { + // Reports table + Object(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__["addFilter"])('woocommerce_admin_report_table', 'cost-of-goods-for-woocommerce', function (reportTableData) { + if (reportTableData.endpoint !== 'revenue' || !reportTableData.items || !reportTableData.items.data || !reportTableData.items.data.length || !alg_wc_cog_analytics_obj.cost_and_profit_columns_enabled_on_revenue) { + return reportTableData; + } + + var newHeaders = [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(reportTableData.headers), [{ + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Cost', 'cost-of-goods-for-woocommerce'), + key: 'costs_total', + isNumeric: true //isSortable: true, + + }, { + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Profit', 'cost-of-goods-for-woocommerce'), + key: 'profit_total', + isNumeric: true //isSortable: true, + + }]); + var newRows = reportTableData.rows.map(function (row, index) { + var item = reportTableData.items.data[index]; + var newRow = [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(row), [{ + display: storeCurrency.formatAmount(item.subtotals.costs_total), + value: item.costs_total, + type: 'currency' + }, { + display: storeCurrency.formatAmount(item.subtotals.profit_total), + value: item.profit_total, + type: 'currency' + }]); + return newRow; + }); + reportTableData.headers = newHeaders; + reportTableData.rows = newRows; + return reportTableData; + }); // Charts + + /** + * @see https://github.com/woocommerce/woocommerce-admin/blob/main/client/analytics/report/orders/config.js#L50-L62 + */ + + Object(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__["addFilter"])('woocommerce_admin_revenue_report_charts', 'cost-of-goods-for-woocommerce', function (charts) { + if (alg_wc_cog_analytics_obj.cost_and_profit_totals_enabled_on_revenue) { + charts = [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(charts), [{ + key: 'costs_total', + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Costs total', 'cost-of-goods-for-woocommerce'), + type: 'currency' + }, { + key: 'profit_total', + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Profit total', 'cost-of-goods-for-woocommerce'), + type: 'currency' + }]); + } + + return charts; + }); + } +}; +/* harmony default export */ __webpack_exports__["default"] = (orders); + +/***/ }), + +/***/ "./src/modules/stock.js": +/*!******************************!*\ + !*** ./src/modules/stock.js ***! + \******************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ "./node_modules/@babel/runtime/helpers/toConsumableArray.js"); +/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/hooks */ "@wordpress/hooks"); +/* harmony import */ var _wordpress_hooks__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n"); +/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _woocommerce_currency__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @woocommerce/currency */ "@woocommerce/currency"); +/* harmony import */ var _woocommerce_currency__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_woocommerce_currency__WEBPACK_IMPORTED_MODULE_3__); + + +/** + * Cost of Goods for WooCommerce - Analytics > Stock (WooCommerce Admin) Report. + * + */ + + + +var storeCurrency = _woocommerce_currency__WEBPACK_IMPORTED_MODULE_3___default()(wcSettings.currency); +var stock = { + init: function init() { + this.addColumns(); + this.addCOGFilter(); + }, + addCOGFilter: function addCOGFilter() { + if (alg_wc_cog_analytics_obj.filter_enabled_on_stock) { + Object(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__["addFilter"])('woocommerce_admin_stock_report_filters', 'cost-of-goods-for-woocommerce', function (obj) { + obj.push({ + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Cost of Goods filter', 'cost-of-goods-for-woocommerce'), + staticParams: ['paged', 'per_page'], + param: 'alg_cog_stock_filter', + showFilters: function showFilters() { + return true; + }, + filters: [{ + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Disabled', 'cost-of-goods-for-woocommerce'), + value: 'all' + }, { + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Products with cost', 'cost-of-goods-for-woocommerce'), + value: 'with_cost' + }] + }); + return obj; + }); + } + }, + addColumns: function addColumns() { + // Reports table + Object(_wordpress_hooks__WEBPACK_IMPORTED_MODULE_1__["addFilter"])('woocommerce_admin_report_table', 'cost-of-goods-for-woocommerce', function (reportTableData) { + if (reportTableData.endpoint !== 'stock' || !reportTableData.items || !reportTableData.items.data || !reportTableData.items.data.length) { + return reportTableData; + } + + var newHeaders = _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(reportTableData.headers); // Cost and profit + + + if (alg_wc_cog_analytics_obj.cost_and_profit_enabled_on_stock) { + newHeaders.push({ + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Cost', 'cost-of-goods-for-woocommerce'), + key: 'product_cost', + isNumeric: true //isSortable: true, + + }); + newHeaders.push({ + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Profit', 'cost-of-goods-for-woocommerce'), + key: 'product_profit', + isNumeric: true //isSortable: true, + + }); + } // Category + + + if (alg_wc_cog_analytics_obj.category_enabled_on_stock) { + newHeaders.push({ + label: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('Category', 'cost-of-goods-for-woocommerce'), + key: 'product_cat' //isSortable: true, + + }); + } + + var newRows = reportTableData.rows.map(function (row, index) { + var product = reportTableData.items.data[index]; + + var newRow = _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(row); // Cost and profit + + + if (alg_wc_cog_analytics_obj.cost_and_profit_enabled_on_stock) { + newRow.push({ + display: storeCurrency.formatAmount(product.product_cost), + value: product.product_cost, + type: 'currency' + }); + newRow.push({ + display: storeCurrency.formatAmount(product.product_profit), + value: product.product_profit, + type: 'currency' + }); + } // Category + + + if (alg_wc_cog_analytics_obj.category_enabled_on_stock) { + newRow.push({ + display: product.product_cat, + value: product.product_cat + }); + } + + return newRow; + }); + reportTableData.headers = newHeaders; + reportTableData.rows = newRows; + return reportTableData; + }); + } +}; +/* harmony default export */ __webpack_exports__["default"] = (stock); + +/***/ }), + +/***/ "@woocommerce/currency": +/*!**********************************!*\ + !*** external ["wc","currency"] ***! + \**********************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +(function() { module.exports = window["wc"]["currency"]; }()); + +/***/ }), + +/***/ "@wordpress/hooks": +/*!*******************************!*\ + !*** external ["wp","hooks"] ***! + \*******************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +(function() { module.exports = window["wp"]["hooks"]; }()); + +/***/ }), + +/***/ "@wordpress/i18n": +/*!******************************!*\ + !*** external ["wp","i18n"] ***! + \******************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +(function() { module.exports = window["wp"]["i18n"]; }()); + +/***/ }) + +/******/ }); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/includes/analytics/class-alg-wc-cog-analytics-products.php b/includes/analytics/class-alg-wc-cog-analytics-products.php new file mode 100644 index 0000000..471e252 --- /dev/null +++ b/includes/analytics/class-alg-wc-cog-analytics-products.php @@ -0,0 +1,185 @@ +prefix}wc_order_product_lookup.product_net_revenue - alg_cog_oimc.meta_value, 0)) AS profit_total"; + } + return $clauses; + } + + /** + * add_profit_to_select_products. + * + * @version 2.5.1 + * @since 2.5.1 + * + * @param $clauses + * + * @return array + */ + function add_profit_to_select_products( $clauses ) { + if ( 'yes' === get_option( 'alg_wc_cog_cost_and_profit_column_on_products_tab', 'no' ) ) { + $clauses[] = ', profit'; + } + return $clauses; + } + + /** + * add_profit_to_select_products_subquery. + * + * @version 2.5.1 + * @since 2.5.1 + * + * @param $clauses + * + * @return array + */ + function add_profit_to_select_products_subquery( $clauses ) { + if ( 'yes' === get_option( 'alg_wc_cog_cost_and_profit_column_on_products_tab', 'no' ) ) { + global $wpdb; + $clauses[] = ", SUM(IFNULL({$wpdb->prefix}wc_order_product_lookup.product_net_revenue - alg_cog_oimc.meta_value, 0)) AS profit"; + } + return $clauses; + } + + /** + * add_costs_to_join_products. + * + * @version 2.5.1 + * @since 2.5.1 + * + * @param $clauses + * + * @return array + */ + function add_costs_to_join_products( $clauses ) { + if ( 'yes' === get_option( 'alg_wc_cog_cost_and_profit_column_on_products_tab', 'no' ) ) { + global $wpdb; + $clauses[] = "LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta alg_cog_oimc ON {$wpdb->prefix}wc_order_product_lookup.order_item_id = alg_cog_oimc.order_item_id AND alg_cog_oimc.meta_key = '_alg_wc_cog_item_cost'"; + } + return $clauses; + } + + /** + * add_costs_to_select_products_subquery. + * + * @version 2.5.1 + * @since 2.5.1 + * + * @param $clauses + * + * @return array + */ + function add_costs_to_select_products_subquery( $clauses ) { + if ( 'yes' === get_option( 'alg_wc_cog_cost_and_profit_column_on_products_tab', 'no' ) ) { + $clauses[] = ', SUM(IFNULL(alg_cog_oimc.meta_value, 0)) AS cost'; + } + return $clauses; + } + + /** + * add_costs_to_select_products. + * + * @version 2.5.1 + * @since 2.5.1 + * + * @param $clauses + * + * @return array + */ + function add_costs_to_select_products( $clauses ) { + if ( 'yes' === get_option( 'alg_wc_cog_cost_and_profit_column_on_products_tab', 'no' ) ) { + $clauses[] = ', cost'; + } + return $clauses; + } + + /** + * add_analytics_localization_info. + * + * @version 2.5.1 + * @since 2.5.1 + * + * @param $info + * + * @return mixed + */ + function add_analytics_localization_info( $info ) { + $info['cost_and_profit_totals_enabled_on_products'] = 'yes' === get_option( 'alg_wc_cog_cost_and_profit_totals_on_products_tab', 'no' ); + $info['cost_and_profit_columns_enabled_on_products'] = 'yes' === get_option( 'alg_wc_cog_cost_and_profit_column_on_products_tab', 'no' ); + return $info; + } + + } + +endif; + +return new Alg_WC_Cost_of_Goods_Analytics_Products(); diff --git a/includes/analytics/class-alg-wc-cog-analytics.php b/includes/analytics/class-alg-wc-cog-analytics.php index d604526..7a61b62 100644 --- a/includes/analytics/class-alg-wc-cog-analytics.php +++ b/includes/analytics/class-alg-wc-cog-analytics.php @@ -2,7 +2,7 @@ /** * Cost of Goods for WooCommerce - Analytics Class. * - * @version 2.4.8 + * @version 2.5.1 * @since 1.7.0 * @author WPFactory */ @@ -16,7 +16,7 @@ class Alg_WC_Cost_of_Goods_Analytics { /** * Constructor. * - * @version 2.4.8 + * @version 2.5.1 * @since 1.7.0 * */ @@ -31,6 +31,9 @@ function __construct() { // Analytics > Stock. require_once('class-alg-wc-cog-analytics-stock.php'); + + // Analytics > Products. + require_once('class-alg-wc-cog-analytics-products.php'); } /** diff --git a/includes/analytics/src/index.js b/includes/analytics/src/index.js index 58c8280..6f59a78 100644 --- a/includes/analytics/src/index.js +++ b/includes/analytics/src/index.js @@ -1,7 +1,7 @@ /** * Analytics. * - * @version 2.4.5 + * @version 2.5.1 * @since 2.4.5 * @author WPFactory */ @@ -16,4 +16,8 @@ revenue.init(); // Stock. import stock from './modules/stock'; -stock.init(); \ No newline at end of file +stock.init(); + +// Products. +import products from './modules/products'; +products.init(); \ No newline at end of file diff --git a/includes/analytics/src/modules/products.js b/includes/analytics/src/modules/products.js new file mode 100644 index 0000000..7e495ab --- /dev/null +++ b/includes/analytics/src/modules/products.js @@ -0,0 +1,94 @@ +/** + * Cost of Goods for WooCommerce - Analytics > Products (WooCommerce Admin) Report. + * + */ + +import {addFilter} from '@wordpress/hooks'; +import {__} from '@wordpress/i18n'; +import CurrencyFactory from '@woocommerce/currency'; + +const storeCurrency = CurrencyFactory(wcSettings.currency); + +let products = { + init: function () { + // Reports table + addFilter( + 'woocommerce_admin_report_table', + 'cost-of-goods-for-woocommerce', + (reportTableData) => { + if ( + reportTableData.endpoint !== 'products' || + !reportTableData.items || + !reportTableData.items.data || + !reportTableData.items.data.length || + !alg_wc_cog_analytics_obj.cost_and_profit_columns_enabled_on_products + ) { + return reportTableData; + } + const newHeaders = [ + ...reportTableData.headers, + { + label: __('Cost', 'cost-of-goods-for-woocommerce'), + key: 'cost', + isNumeric: true, + //isSortable: true, + }, + { + label: __('Profit', 'cost-of-goods-for-woocommerce'), + key: 'profit', + isNumeric: true, + //isSortable: true, + }, + ]; + const newRows = reportTableData.rows.map((row, index) => { + const item = reportTableData.items.data[index]; + console.log(item); + const newRow = [ + ...row, + { + display: storeCurrency.formatAmount(item.cost), + value: item.cost, + type: 'currency' + }, + { + display: storeCurrency.formatAmount(item.profit), + value: item.profit, + type: 'currency' + }, + ]; + return newRow; + }); + reportTableData.rows = newRows; + reportTableData.headers = newHeaders; + + return reportTableData; + } + ); + // Charts + /** + * @see https://github.com/woocommerce/woocommerce-admin/blob/main/client/analytics/report/orders/config.js#L50-L62 + */ + addFilter( + 'woocommerce_admin_products_report_charts', + 'cost-of-goods-for-woocommerce', + (charts) => { + if (alg_wc_cog_analytics_obj.cost_and_profit_totals_enabled_on_products) { + charts = [...charts, + { + key: 'costs_total', + label: __('Costs total', 'cost-of-goods-for-woocommerce'), + type: 'currency' + }, + { + key: 'profit_total', + label: __('Profit total', 'cost-of-goods-for-woocommerce'), + type: 'currency' + }]; + } + return charts; + } + ); + } +}; +export default products; + diff --git a/includes/analytics/src/modules/revenue.js b/includes/analytics/src/modules/revenue.js index bff44ef..876e2ef 100644 --- a/includes/analytics/src/modules/revenue.js +++ b/includes/analytics/src/modules/revenue.js @@ -1,7 +1,5 @@ /** - * Cost of Goods for WooCommerce - Analytics > Orders (WooCommerce Admin) Report. - * - * @see https://github.com/woocommerce/woocommerce-admin/blob/main/client/analytics/report/orders/config.js#L50-L62 + * Cost of Goods for WooCommerce - Analytics > Revenue (WooCommerce Admin) Report. * */ diff --git a/includes/analytics/src/modules/stock.js b/includes/analytics/src/modules/stock.js index ee8e19c..ee80d5b 100644 --- a/includes/analytics/src/modules/stock.js +++ b/includes/analytics/src/modules/stock.js @@ -1,8 +1,6 @@ /** * Cost of Goods for WooCommerce - Analytics > Stock (WooCommerce Admin) Report. * - * @see https://github.com/woocommerce/woocommerce-admin/blob/main/client/analytics/report/orders/config.js#L50-L62 - * */ import {addFilter} from '@wordpress/hooks'; diff --git a/includes/background-process/class-alg-wc-cog-bkg-process.php b/includes/background-process/class-alg-wc-cog-bkg-process.php index 7fea7ba..b7be517 100644 --- a/includes/background-process/class-alg-wc-cog-bkg-process.php +++ b/includes/background-process/class-alg-wc-cog-bkg-process.php @@ -30,6 +30,8 @@ protected function get_logger_context() { } /** + * get_action_label. + * * @version 2.3.0 * @since 2.3.0 * @@ -104,6 +106,8 @@ protected function send_email() { } /** + * get_email_template. + * * @version 2.3.0 * @since 2.3.0 * @@ -131,6 +135,8 @@ protected function replace_variables( $from_to, $string ) { } /** + * get_email_subject. + * * @version 2.3.0 * @since 2.3.0 * @@ -143,6 +149,8 @@ protected function get_email_subject() { } /** + * get_email_heading. + * * @version 2.3.0 * @since 2.3.0 * @@ -155,7 +163,7 @@ protected function get_email_heading() { } /** - * get_email_sending_params. + * get_email_params. * * @version 2.3.0 * @since 2.3.0 @@ -188,7 +196,7 @@ public function set_email_params( $args = null ) { } /** - * init_task. + * save. * * @version 2.3.0 * @since 2.3.0 diff --git a/includes/background-process/class-alg-wc-cog-import-tool-bkg-process.php b/includes/background-process/class-alg-wc-cog-import-tool-bkg-process.php index c803ea4..7614d60 100644 --- a/includes/background-process/class-alg-wc-cog-import-tool-bkg-process.php +++ b/includes/background-process/class-alg-wc-cog-import-tool-bkg-process.php @@ -21,6 +21,8 @@ class Alg_WC_Cost_of_Goods_Import_Tool_Bkg_Process extends Alg_WC_Cost_of_Goods_ protected $action = 'alg_wc_cog_import_tool'; /** + * get_action_label. + * * @version 2.3.0 * @since 2.3.0 * @@ -31,6 +33,8 @@ protected function get_action_label() { } /** + * task. + * * @version 2.4.6 * @since 2.3.0 * diff --git a/includes/background-process/class-alg-wc-cog-recalculate-orders-bkg-process.php b/includes/background-process/class-alg-wc-cog-recalculate-orders-bkg-process.php index 57253c0..6adc4c3 100644 --- a/includes/background-process/class-alg-wc-cog-recalculate-orders-bkg-process.php +++ b/includes/background-process/class-alg-wc-cog-recalculate-orders-bkg-process.php @@ -21,6 +21,8 @@ class Alg_WC_Cost_of_Goods_Recalculate_Orders_Bkg_Process extends Alg_WC_Cost_of protected $action = 'alg_wc_cog_recalculate_orders'; /** + * get_action_label. + * * @version 2.3.0 * @since 2.3.0 * @@ -31,6 +33,8 @@ protected function get_action_label() { } /** + * task. + * * @version 2.4.9 * @since 2.3.0 * diff --git a/includes/background-process/class-alg-wc-cog-update-cost-bkg-process.php b/includes/background-process/class-alg-wc-cog-update-cost-bkg-process.php new file mode 100644 index 0000000..afd4223 --- /dev/null +++ b/includes/background-process/class-alg-wc-cog-update-cost-bkg-process.php @@ -0,0 +1,58 @@ +core->products->update_product_cost_by_percentage(array( + 'product_id' => $product_id, + 'percentage' => $percentage, + 'update_type' => $update_type, // profit | price + 'update_variations' => true + )); + return false; + } + } +endif; \ No newline at end of file diff --git a/includes/class-alg-wc-cog-core.php b/includes/class-alg-wc-cog-core.php index 98798dc..26d7a7c 100644 --- a/includes/class-alg-wc-cog-core.php +++ b/includes/class-alg-wc-cog-core.php @@ -2,117 +2,131 @@ /** * Cost of Goods for WooCommerce - Core Class * - * @version 2.3.0 + * @version 2.5.1 * @since 1.0.0 * @author WPFactory */ -if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly +if ( ! defined( 'ABSPATH' ) ) { + exit; +} // Exit if accessed directly if ( ! class_exists( 'Alg_WC_Cost_of_Goods_Core' ) ) : -class Alg_WC_Cost_of_Goods_Core { + class Alg_WC_Cost_of_Goods_Core { - /** - * Constructor. - * - * @version 2.3.0 - * @since 1.0.0 - * @todo [next] add "delete all (products and/or orders) meta" tool - * @todo [next] add option to enter costs *with taxes* - * @todo [next] add options to exclude fees, shipping etc. in order profit - * @todo [next] add reports (e.g. `calculate_all_products_profit()` etc.) - * @todo [next] admin: add all fees column(s), e.g. shipping, gateway, meta - * @todo [next] admin: rename file and class - * @todo [next] admin: customizable column position - * @todo [next] admin: customizable column title - * @todo [later] add custom cost fields - * @todo [later] add custom info fields - * @todo [maybe] `force_on_meta`: `woocommerce_process_shop_order_meta` - * @todo [maybe] add XML export - * @todo [maybe] add product profit/cost meta box - * @todo [maybe] add option to change meta keys prefix (i.e. `_alg_wc_cog`) - */ - function __construct() { - // Analytics - require_once( 'analytics/class-alg-wc-cog-analytics.php' ); - // Bulk Edit tool - $this->bulk_edit_tool = require_once( 'tools/class-alg-wc-cog-bulk-edit-tool.php' ); - // Import tool - $this->import_tool = require_once( 'tools/class-alg-wc-cog-import-tool.php' ); - // Products - $this->products = require_once( 'class-alg-wc-cog-products.php' ); - // Orders - $this->orders = require_once( 'class-alg-wc-cog-orders.php' ); - // Background process - add_action( 'plugins_loaded', array( $this, 'init_bkg_process' ), 9 ); - // Core loaded - do_action( 'alg_wc_cog_core_loaded', $this ); - } + /** + * Constructor. + * + * @version 2.5.1 + * @since 1.0.0 + * @todo [next] add "delete all (products and/or orders) meta" tool + * @todo [next] add option to enter costs *with taxes* + * @todo [next] add options to exclude fees, shipping etc. in order profit + * @todo [next] add reports (e.g. `calculate_all_products_profit()` etc.) + * @todo [next] admin: add all fees column(s), e.g. shipping, gateway, meta + * @todo [next] admin: rename file and class + * @todo [next] admin: customizable column position + * @todo [next] admin: customizable column title + * @todo [later] add custom cost fields + * @todo [later] add custom info fields + * @todo [maybe] `force_on_meta`: `woocommerce_process_shop_order_meta` + * @todo [maybe] add XML export + * @todo [maybe] add product profit/cost meta box + * @todo [maybe] add option to change meta keys prefix (i.e. `_alg_wc_cog`) + */ + function __construct() { + // Analytics + require_once( 'analytics/class-alg-wc-cog-analytics.php' ); + // Import tool + $this->import_tool = require_once( 'tools/class-alg-wc-cog-import-tool.php' ); + // Products + $this->products = require_once( 'class-alg-wc-cog-products.php' ); + // Orders + $this->orders = require_once( 'class-alg-wc-cog-orders.php' ); + // Background process + add_action( 'plugins_loaded', array( $this, 'init_bkg_process' ), 8 ); + // Bulk costs tool + add_action( 'plugins_loaded', array( $this, 'init_bulk_costs_tool' ), 9 ); + // Core loaded + do_action( 'alg_wc_cog_core_loaded', $this ); + } - /** - * get_default_shop_currency. - * - * @version 2.3.0 - * @since 2.3.0 - * @todo [now] `wc_price()` - * @todo [now] product profit and cost + multicurrency - */ - function get_default_shop_currency() { - return get_option( 'woocommerce_currency' ); - } + /** + * get_default_shop_currency. + * + * @version 2.3.0 + * @since 2.3.0 + * @todo [now] `wc_price()` + * @todo [now] product profit and cost + multicurrency + */ + function get_default_shop_currency() { + return get_option( 'woocommerce_currency' ); + } - /** - * get_default_shop_currency_symbol. - * - * @version 2.3.0 - * @since 2.3.0 - */ - function get_default_shop_currency_symbol() { - return get_woocommerce_currency_symbol( $this->get_default_shop_currency() ); - } + /** + * get_default_shop_currency_symbol. + * + * @version 2.3.0 + * @since 2.3.0 + */ + function get_default_shop_currency_symbol() { + return get_woocommerce_currency_symbol( $this->get_default_shop_currency() ); + } - /** - * init_bkg_process. - * - * @version 2.3.0 - * @since 2.3.0 - */ - function init_bkg_process() { - require_once( 'background-process/class-alg-wc-cog-bkg-process.php' ); - add_filter( 'alg_wc_cog_bkg_process_email_params', array( $this, 'change_bkg_process_email_params' ) ); - new Alg_WC_Cost_of_Goods_Bkg_Process(); - } + /** + * init_bkg_process. + * + * @version 2.5.1 + * @since 2.3.0 + */ + function init_bkg_process() { + require_once( 'background-process/class-alg-wc-cog-bkg-process.php' ); + add_filter( 'alg_wc_cog_bkg_process_email_params', array( $this, 'change_bkg_process_email_params' ) ); + new Alg_WC_Cost_of_Goods_Bkg_Process(); + } - /** - * change_bkg_process_email_params. - * - * @version 2.3.0 - * @since 2.3.0 - * - * @param $email_params - * - * @return mixed - */ - function change_bkg_process_email_params( $email_params ) { - $email_params['send_email_on_task_complete'] = 'yes' === get_option( 'alg_wc_cog_bkg_process_send_email', 'yes' ); - $email_params['send_to'] = get_option( 'alg_wc_cog_bkg_process_email_to', get_option( 'admin_email' ) ); - return $email_params; - } + /** + * init_bulk_costs_tool. + * + * @version 2.5.1 + * @since 2.5.1 + */ + function init_bulk_costs_tool(){ + // Bulk Edit tool + $this->bulk_edit_tool = require_once( 'tools/class-alg-wc-cog-bulk-edit-tool.php' ); + } - /** - * get_product_profit_html. - * - * For backward compatibility. - * - * @version 2.2.0 - * @since 2.2.0 - */ - function get_product_profit_html( $product_id, $template = '%profit% (%profit_percent%)' ) { - return $this->products->get_product_profit_html( $product_id, $template ); - } + /** + * change_bkg_process_email_params. + * + * @param $email_params + * + * @return mixed + * @version 2.3.0 + * @since 2.3.0 + * + */ + function change_bkg_process_email_params( $email_params ) { + $email_params['send_email_on_task_complete'] = 'yes' === get_option( 'alg_wc_cog_bkg_process_send_email', 'yes' ); + $email_params['send_to'] = get_option( 'alg_wc_cog_bkg_process_email_to', get_option( 'admin_email' ) ); + + return $email_params; + } -} + /** + * get_product_profit_html. + * + * For backward compatibility. + * + * @version 2.2.0 + * @since 2.2.0 + */ + function get_product_profit_html( $product_id, $template = '%profit% (%profit_percent%)' ) { + return $this->products->get_product_profit_html( $product_id, $template ); + } + + } endif; diff --git a/includes/class-alg-wc-cog-products.php b/includes/class-alg-wc-cog-products.php index c42a7b6..26bb24a 100644 --- a/includes/class-alg-wc-cog-products.php +++ b/includes/class-alg-wc-cog-products.php @@ -2,7 +2,7 @@ /** * Cost of Goods for WooCommerce - Products Class * - * @version 2.4.7 + * @version 2.5.1 * @since 2.1.0 * @author WPFactory */ @@ -47,43 +47,75 @@ function get_options() { /** * add_hooks. * - * @version 2.4.2 + * @version 2.5.1 * @since 2.1.0 */ function add_hooks() { // Cost input on admin product page (simple product) add_action( get_option( 'alg_wc_cog_product_cost_field_position', 'woocommerce_product_options_pricing' ), array( $this, 'add_cost_input' ) ); - add_action( 'woocommerce_bookings_after_display_cost', array( $this, 'add_cost_input' ) ); - add_action( 'save_post_product', array( $this, 'save_cost_input' ), PHP_INT_MAX, 2 ); + add_action( 'woocommerce_bookings_after_display_cost', array( $this, 'add_cost_input' ) ); + add_action( 'save_post_product', array( $this, 'save_cost_input' ), PHP_INT_MAX, 2 ); // Cost input on admin product page (variable product) - add_action( 'woocommerce_variation_options_pricing', array( $this, 'add_cost_input_variation' ), 10, 3 ); - add_action( 'woocommerce_save_product_variation', array( $this, 'save_cost_input_variation' ), PHP_INT_MAX, 2 ); - add_action( 'woocommerce_product_options_general_product_data', array( $this, 'add_cost_input_variable' ), PHP_INT_MAX ); + add_action( 'woocommerce_variation_options_pricing', array( $this, 'add_cost_input_variation' ), 10, 3 ); + add_action( 'woocommerce_save_product_variation', array( $this, 'save_cost_input_variation' ), PHP_INT_MAX, 2 ); + add_action( 'woocommerce_product_options_general_product_data', array( $this, 'add_cost_input_variable' ), PHP_INT_MAX ); // Products columns if ( $this->is_column_profit || $this->is_column_cost ) { - add_filter( 'manage_edit-product_columns', array( $this, 'add_product_columns' ) ); - add_action( 'manage_product_posts_custom_column', array( $this, 'render_product_columns' ), PHP_INT_MAX, 2 ); + add_filter( 'manage_edit-product_columns', array( $this, 'add_product_columns' ) ); + add_action( 'manage_product_posts_custom_column', array( $this, 'render_product_columns' ), PHP_INT_MAX, 2 ); // Make columns sortable if ( $this->is_columns_sorting ) { - add_filter( 'manage_edit-product_sortable_columns', array( $this, 'product_sortable_columns' ) ); - add_action( 'pre_get_posts', array( $this, 'product_pre_get_posts_order_by_column' ) ); + add_filter( 'manage_edit-product_sortable_columns', array( $this, 'product_sortable_columns' ) ); + add_action( 'pre_get_posts', array( $this, 'product_pre_get_posts_order_by_column' ) ); } - add_action( 'admin_head-edit.php', array( $this, 'handle_product_columns_style' ) ); + add_action( 'admin_head-edit.php', array( $this, 'handle_product_columns_style' ) ); } // Products > Export (WooCommerce) - add_filter( 'woocommerce_product_export_column_names', array( $this, 'add_export_column' ) ); - add_filter( 'woocommerce_product_export_product_default_columns', array( $this, 'add_export_column' ) ); + add_filter( 'woocommerce_product_export_column_names', array( $this, 'add_export_column' ) ); + add_filter( 'woocommerce_product_export_product_default_columns', array( $this, 'add_export_column' ) ); add_filter( 'woocommerce_product_export_product_column_alg_wc_cog_cost', array( $this, 'add_export_data' ), 10, 2 ); // Products > Import (WooCommerce) - add_filter( 'woocommerce_csv_product_import_mapping_options', array( $this, 'add_import_mapping_option' ) ); - add_filter( 'woocommerce_csv_product_import_mapping_default_columns', array( $this, 'set_import_mapping_option_default' ) ); - add_filter( 'woocommerce_product_importer_parsed_data', array( $this, 'parse_import_data' ), 10, 2 ); + add_filter( 'woocommerce_csv_product_import_mapping_options', array( $this, 'add_import_mapping_option' ) ); + add_filter( 'woocommerce_csv_product_import_mapping_default_columns', array( $this, 'set_import_mapping_option_default' ) ); + add_filter( 'woocommerce_product_importer_parsed_data', array( $this, 'parse_import_data' ), 10, 2 ); // Add product stock - add_action( 'add_meta_boxes', array( $this, 'add_product_add_stock_meta_box' ) ); - add_action( 'save_post_product', array( $this, 'save_product_add_stock' ), PHP_INT_MAX, 2 ); + add_action( 'add_meta_boxes', array( $this, 'add_product_add_stock_meta_box' ) ); + add_action( 'save_post_product', array( $this, 'save_product_add_stock' ), PHP_INT_MAX, 2 ); // Sanitize cog meta (_alg_wc_cog_cost) - add_filter( 'sanitize_post_meta_' . '_alg_wc_cog_cost', array( $this, 'sanitize_cog_meta' ) ); - + add_filter( 'sanitize_post_meta_' . '_alg_wc_cog_cost', array( $this, 'sanitize_cog_meta' ) ); + // Save profit + add_action( 'updated_post_meta', array( $this, 'save_profit_on_postmeta' ), 10, 4 ); + add_action( 'added_post_meta', array( $this, 'save_profit_on_postmeta' ), 10, 4 ); + add_action( 'deleted_post_meta', array( $this, 'save_profit_on_postmeta' ), 10, 4 ); + } + + /** + * Save profit on post meta everytime the cost or price is updated on product. + * + * @version 2.5.1 + * @since 2.5.1 + * + * @param $meta_id + * @param $post_id + * @param $meta_key + * @param $meta_value + */ + function save_profit_on_postmeta( $meta_id, $post_id, $meta_key, $meta_value ) { + if ( + in_array( $meta_key, array( + '_alg_wc_cog_cost', + '_price', + '_sale_price', + ) ) && + is_a( $product = wc_get_product( $post_id ), 'WC_Product' ) + ) { + $profit = (float) $this->get_product_profit( $post_id ); + $cost = (float) $this->get_product_cost( $post_id ); + $price = (float) $this->get_product_price( $product ); + update_post_meta( $post_id, '_alg_wc_cog_profit', $profit ); + update_post_meta( $post_id, '_alg_wc_cog_profit_percent', ( 0 != $cost ? ( $profit / $cost * 100 ) : 0 ) ); + update_post_meta( $post_id, '_alg_wc_cog_profit_margin', ( 0 != $price ? ( $profit / $price * 100 ) : 0 ) ); + } } /** @@ -786,6 +818,73 @@ function save_cost_input_variation( $variation_id, $i ) { } } + /** + * update_product_price. + * + * @version 2.5.1 + * @since 2.5.1 + * + * @param null $args + * + * @return bool + */ + function update_product_cost_by_percentage( $args = null ) { + $args = wp_parse_args( $args, array( + 'product_id' => '', + 'percentage' => 100, + 'update_type' => 'price', // profit | price + 'update_variations' => true + ) ); + $percentage = $args['percentage']; + $product_id = $args['product_id']; + $product = wc_get_product( $product_id ); + $update_variations = $args['update_variations']; + $update_type = $args['update_type']; + if ( ! is_a( $product, 'WC_Product' ) ) { + return false; + } + update_post_meta( $product->get_id(), '_alg_wc_cog_cost', $this->calculate_product_cost_by_percentage( $product->get_price(), $percentage, $update_type ) ); + if ( + $update_variations && + $product->is_type( 'variable' ) && $product instanceof WC_Product_Variable + ) { + foreach ( $product->get_available_variations() as $variation ) { + $variation_id = isset( $variation['variation_id'] ) ? $variation['variation_id'] : ''; + $display_price = isset( $variation['display_price'] ) ? $variation['display_price'] : ''; + if ( empty( $variation_id ) || empty( $display_price ) ) { + continue; + } + update_post_meta( $variation_id, '_alg_wc_cog_cost', $this->calculate_product_cost_by_percentage( $display_price, $percentage, $update_type ) ); + } + } + return true; + } + + /** + * calculate_product_cost. + * + * @version 2.5.1 + * @since 2.5.1 + * + * @param $price + * @param $percentage + * @param string $method price | profit + * + * @return float|int + */ + function calculate_product_cost_by_percentage( $price, $percentage, $method ) { + if ( empty( $price ) ) { + return 0; + } + if ( 'profit' === $method ) { + // Profit percent. + return $price / ( ( 100 + $percentage ) / 100 ); + // Profit marging. + //return $price - ( ( $price * $percentage ) / 100 ); + } + return ( $price * $percentage ) / 100; + } + } diff --git a/includes/css/alg-wc-cog-bulk-edit-tool.css b/includes/css/alg-wc-cog-bulk-edit-tool.css index c5d5f70..9a92e94 100644 --- a/includes/css/alg-wc-cog-bulk-edit-tool.css +++ b/includes/css/alg-wc-cog-bulk-edit-tool.css @@ -1,14 +1,38 @@ /** * alg-wc-cog-bulk-edit-tool.css. * - * @version 1.3.4 + * @version 2.5.1 * @since 1.3.3 */ .alg_wc_cog_bet_active_row { - background-color: #fefbcc !important; + background-color: #fefbcc !important; } .alg_wc_cog_bet_modified_row { - background-color: #dffecc !important; + background-color: #dffecc !important; } + +.alg_wc_cog_bulk_edit p.search-box { + float: left; + margin: 0; + vertical-align: top; +} + +.alg_wc_cog_bulk_edit .tablenav.top { + clear: none; + float: right; + vertical-align: top; + margin-top: 0; + margin-bottom: 10px; + padding-top: 0; +} + +.alg_wc_cog_notice { + display: none; +} + +.form-action .spinner { + float: none; + margin: -3px 0 0 10px; +} \ No newline at end of file diff --git a/includes/js/alg-wc-cog-bulk-edit-tool.js b/includes/js/alg-wc-cog-bulk-edit-tool.js index 5f7762d..d4e380e 100644 --- a/includes/js/alg-wc-cog-bulk-edit-tool.js +++ b/includes/js/alg-wc-cog-bulk-edit-tool.js @@ -1,23 +1,90 @@ /** * alg-wc-cog-bulk-edit-tool.js. * - * @version 1.3.4 + * @version 2.5.1 * @since 1.3.3 * @author WPFactory */ -jQuery( document ).ready( function() { - jQuery( ".alg_wc_cog_bet_input" ).on( "focus", function() { - jQuery( this ).closest( "tr" ).addClass( "alg_wc_cog_bet_active_row" ); - } ); - jQuery( ".alg_wc_cog_bet_input" ).on( "focusout", function() { - jQuery( this ).closest( "tr" ).removeClass( "alg_wc_cog_bet_active_row" ); - } ); - jQuery( ".alg_wc_cog_bet_input" ).on( "change", function() { - if ( jQuery( this ).attr( "initial-value" ) != jQuery( this ).val() ) { - jQuery( this ).closest( "td" ).addClass( "alg_wc_cog_bet_modified_row" ); - } else { - jQuery( this ).closest( "td" ).removeClass( "alg_wc_cog_bet_modified_row" ); - } - } ); -} ); +(function ($, window, document) { + "use strict"; + + /** + * Handle ajax form submission in bulk edit form for both by-price and by-profit. + * + * @version 2.5.1 + * @since 2.5.1 + */ + $(document).on('submit', '.bulk-edit-form.ajax-submission', function (e) { + + let bulkEditForm = $(this), + bulkEditFormType = bulkEditForm.data('type'), + bulkEditFormSpinner = bulkEditForm.find('.spinner'), + bulkEditFormNotice = $('.alg_wc_cog_notice'); + + if (confirm(algWcCog.confirmText) && typeof bulkEditFormType !== 'undefined') { + + // Showing the spinner + bulkEditFormSpinner.addClass('is-active'); + bulkEditFormNotice.removeClass('notice-success notice-error').fadeOut(100); + + $.ajax({ + type: 'POST', + context: this, + url: algWcCog.ajaxURL, + data: { + 'action': 'alg_wc_cog_update_cost', + 'form_data': bulkEditForm.serialize(), + 'update_type': bulkEditFormType, + }, + success: function (response) { + // Hiding the spinner + bulkEditFormSpinner.removeClass('is-active'); + if (response.success) { + bulkEditFormNotice.addClass('notice-success').find(' > p').html(response.data).parent().fadeIn(100); + } else { + bulkEditFormNotice.addClass('notice-error').find(' > p').html(response.data).parent().fadeIn(100); + } + bulkEditForm.find('select').val('').trigger('change'); + bulkEditForm.trigger("reset"); + + return false; + } + }); + } + + e.preventDefault(); + return false; + }); + + + /** + * Document on Ready + * + * @version 1.3.4 + * @since 1.3.3 + */ + $(document).on('ready', function () { + + let cogBetInput = $(".alg_wc_cog_bet_input"); + + cogBetInput.on("focus", function () { + $(this).closest("tr").addClass("alg_wc_cog_bet_active_row"); + }); + + cogBetInput.on("focusout", function () { + $(this).closest("tr").removeClass("alg_wc_cog_bet_active_row"); + }); + + cogBetInput.on("change", function () { + if ($(this).attr("initial-value") !== jQuery(this).val()) { + $(this).closest("td").addClass("alg_wc_cog_bet_modified_row"); + } else { + $(this).closest("td").removeClass("alg_wc_cog_bet_modified_row"); + } + }); + }); + +})(jQuery, window, document); + + diff --git a/includes/js/alg-wc-cog-bulk-edit-tool.min.js b/includes/js/alg-wc-cog-bulk-edit-tool.min.js index 8af1239..ba48b84 100644 --- a/includes/js/alg-wc-cog-bulk-edit-tool.min.js +++ b/includes/js/alg-wc-cog-bulk-edit-tool.min.js @@ -1 +1 @@ -jQuery(document).ready(function(){jQuery(".alg_wc_cog_bet_input").on("focus",function(){jQuery(this).closest("tr").addClass("alg_wc_cog_bet_active_row")});jQuery(".alg_wc_cog_bet_input").on("focusout",function(){jQuery(this).closest("tr").removeClass("alg_wc_cog_bet_active_row")});jQuery(".alg_wc_cog_bet_input").on("change",function(){if(jQuery(this).attr("initial-value")!=jQuery(this).val()){jQuery(this).closest("td").addClass("alg_wc_cog_bet_modified_row")}else{jQuery(this).closest("td").removeClass("alg_wc_cog_bet_modified_row")}})}); \ No newline at end of file +!function(t,e,a){"use strict";t(a).on("submit",".bulk-edit-form.ajax-submission",function(e){let a=t(this),s=a.data("type"),c=a.find(".spinner"),o=t(".alg_wc_cog_notice");return confirm(algWcCog.confirmText)&&void 0!==s&&(c.addClass("is-active"),o.removeClass("notice-success notice-error").fadeOut(100),t.ajax({type:"POST",context:this,url:algWcCog.ajaxURL,data:{action:"alg_wc_cog_update_cost",form_data:a.serialize(),update_type:s},success:function(t){return c.removeClass("is-active"),t.success?o.addClass("notice-success").find(" > p").html(t.data).parent().fadeIn(100):o.addClass("notice-error").find(" > p").html(t.data).parent().fadeIn(100),a.find("select").val("").trigger("change"),a.trigger("reset"),!1}})),e.preventDefault(),!1}),t(a).on("ready",function(){let e=t(".alg_wc_cog_bet_input");e.on("focus",function(){t(this).closest("tr").addClass("alg_wc_cog_bet_active_row")}),e.on("focusout",function(){t(this).closest("tr").removeClass("alg_wc_cog_bet_active_row")}),e.on("change",function(){t(this).attr("initial-value")!==jQuery(this).val()?t(this).closest("td").addClass("alg_wc_cog_bet_modified_row"):t(this).closest("td").removeClass("alg_wc_cog_bet_modified_row")})})}(jQuery,window,document); \ No newline at end of file diff --git a/includes/settings/class-alg-wc-cog-settings-tools.php b/includes/settings/class-alg-wc-cog-settings-tools.php index 6d16bd8..f3be2cb 100644 --- a/includes/settings/class-alg-wc-cog-settings-tools.php +++ b/includes/settings/class-alg-wc-cog-settings-tools.php @@ -2,7 +2,7 @@ /** * Cost of Goods for WooCommerce - Tools Section Settings * - * @version 2.4.6 + * @version 2.5.1 * @since 1.4.0 * @author WPFactory */ @@ -29,7 +29,7 @@ function __construct() { /** * get_settings. * - * @version 2.4.6 + * @version 2.5.1 * @since 1.4.0 * @todo [later] better descriptions * @todo [maybe] add "PHP time limit" option, i.e. `set_time_limit()` @@ -287,6 +287,23 @@ function get_settings() { 'checkboxgroup' => 'end', 'custom_attributes' => apply_filters( 'alg_wc_cog_settings', array( 'disabled' => 'disabled' ) ), ), + array( + 'title' => __( 'Products tab', 'cost-of-goods-for-woocommerce' ), + 'desc' => __( 'Add "Cost" and "Profit" columns', 'cost-of-goods-for-woocommerce' ), + 'id' => 'alg_wc_cog_cost_and_profit_column_on_products_tab', + 'custom_attributes' => apply_filters( 'alg_wc_cog_settings', array( 'disabled' => 'disabled' ) ), + 'default' => 'no', + 'type' => 'checkbox', + 'checkboxgroup' => 'start' + ), + array( + 'desc' => __( 'Add "Cost" and "Profit" totals to the report charts', 'cost-of-goods-for-woocommerce' ), + 'id' => 'alg_wc_cog_cost_and_profit_totals_on_products_tab', + 'default' => 'no', + 'type' => 'checkbox', + 'checkboxgroup' => 'end', + 'custom_attributes' => apply_filters( 'alg_wc_cog_settings', array( 'disabled' => 'disabled' ) ), + ), array( 'title' => __( 'Stock tab', 'cost-of-goods-for-woocommerce' ), 'desc' => __( 'Add "Cost" and "Profit" columns', 'cost-of-goods-for-woocommerce' ), @@ -306,7 +323,7 @@ function get_settings() { ), array( 'desc' => __( 'Add filter allowing to restrict the query', 'cost-of-goods-for-woocommerce' ), - 'desc_tip' => __( 'For now, allows to get only products with costs.', 'cost-of-goods-for-woocommerce' ), + 'desc_tip' => __( 'For now, it allows to get only products with costs.', 'cost-of-goods-for-woocommerce' ), 'id' => 'alg_wc_cog_filter_enabled_on_analytics_stock', 'custom_attributes' => apply_filters( 'alg_wc_cog_settings', array( 'disabled' => 'disabled' ) ), 'default' => 'no', diff --git a/includes/tools/class-alg-wc-cog-bulk-edit-tool.php b/includes/tools/class-alg-wc-cog-bulk-edit-tool.php index 02799c6..cf5584b 100644 --- a/includes/tools/class-alg-wc-cog-bulk-edit-tool.php +++ b/includes/tools/class-alg-wc-cog-bulk-edit-tool.php @@ -7,253 +7,553 @@ * @author WPFactory */ -if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly +if ( ! defined( 'ABSPATH' ) ) { + exit; +} // Exit if accessed directly if ( ! class_exists( 'Alg_WC_Cost_of_Goods_Bulk_Edit_Tool' ) ) : -class Alg_WC_Cost_of_Goods_Bulk_Edit_Tool { - - /** - * Constructor. - * - * @version 2.3.1 - * @since 1.2.0 - */ - function __construct() { - add_action( 'admin_init', array( $this, 'save_costs' ) ); - add_filter( 'woocommerce_screen_ids', array( $this, 'add_tool_to_wc_screen_ids' ) ); - add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts_and_styles' ) ); - add_action( 'admin_menu', array( $this, 'create_wp_list_tool' ) ); - add_action( 'set-screen-option', array( $this, 'set_screen_option' ), 10, 3 ); - } + class Alg_WC_Cost_of_Goods_Bulk_Edit_Tool { + + /** + * Tool page's slug. + * + * @var string + */ + private $page_slug = 'bulk-edit-costs'; + + /** + * @var Alg_WC_Cost_of_Goods_Update_Cost_Bkg_Process + */ + public $update_cost_bkg_process; - /** - * set_screen_option. - * - * @version 2.3.1 - * @since 2.3.1 - * - * @param $status - * @param $option - * @param $value - * - * @return mixed - */ - function set_screen_option( $status, $option, $value ) { - if ( 'alg_wc_cog_bulk_edit_per_page' === $option ) { - return $value; + /** + * Constructor. + * + * @version 2.5.1 + * @since 1.2.0 + */ + function __construct() { + add_action( 'admin_init', array( $this, 'save_costs' ) ); + add_filter( 'woocommerce_screen_ids', array( $this, 'add_tool_to_wc_screen_ids' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts_and_styles' ) ); + add_action( 'admin_menu', array( $this, 'create_wp_list_tool' ) ); + add_action( 'set-screen-option', array( $this, 'set_screen_option' ), 10, 3 ); + add_action( 'wp_ajax_alg_wc_cog_update_cost', array( $this, 'ajax_update_costs' ) ); + // Bkg Process + add_action( 'plugins_loaded', array( $this, 'init_bkg_process' ) ); } - return $status; - } - /** - * screen_option. - * - * @version 2.3.1 - * @since 2.3.1 - */ - function screen_option() { - $option = 'per_page'; - $args = [ - 'label' => __( 'Items per page', 'cost-of-goods-for-woocommerce' ), - 'default' => 20, - 'option' => 'alg_wc_cog_bulk_edit_per_page' - ]; - add_screen_option( $option, $args ); - require_once( 'class-alg-wc-cog-wplist-bulk-edit-tool.php' ); - $this->wp_list_bulk_edit_tool = new Alg_WC_Cost_of_Goods_WP_List_Bulk_Edit_Tool(); - } + /** + * init_bkg_process. + * + * @version 2.5.1 + * @since 2.5.1 + */ + function init_bkg_process() { + require_once( alg_wc_cog()->plugin_path() . '/includes/background-process/class-alg-wc-cog-update-cost-bkg-process.php' ); + $this->update_cost_bkg_process = new Alg_WC_Cost_of_Goods_Update_Cost_Bkg_Process(); + } + + /** + * Update costs on Ajax for bulk edit tools. + * + * @version 2.5.1 + * @since 2.5.1 + */ + function ajax_update_costs() { + $posted_data = wp_unslash( $_POST ); + $_form_data = isset( $posted_data['form_data'] ) ? $posted_data['form_data'] : ''; + $update_type = isset( $posted_data['update_type'] ) ? $posted_data['update_type'] : ''; + parse_str( $_form_data, $form_data ); + // Verify nonce + if ( isset( $form_data["_nonce_{$update_type}_val"] ) && ! wp_verify_nonce( $form_data["_nonce_{$update_type}_val"], "_nonce_{$update_type}_action" ) ) { + wp_send_json_error( esc_html__( 'Something went wrong! Please try again.', 'cost-of-goods-for-woocommerce' ) ); + } + $percentage = isset( $form_data['percentage'] ) ? sanitize_text_field( $form_data['percentage'] ) : ''; + $product_category = isset( $form_data['product_category'] ) ? $form_data['product_category'] : ''; + $product_category = is_array( $product_category ) ? $product_category : array(); + $product_category = array_map( 'esc_attr', $product_category ); + // If empty percentage do not proceed + if ( empty( $percentage ) || empty( $update_type ) ) { + wp_send_json_error( esc_html__( 'Invalid percentage or category.', 'cost-of-goods-for-woocommerce' ) ); + } + $query_args = array( + 'post_type' => 'product', + 'post_status' => 'publish', + 'posts_per_page' => '-1', + 'fields' => 'ids', + ); + if ( ! empty( $product_category ) && is_array( $product_category ) ) { + $query_args['tax_query'] = array( + array( + 'taxonomy' => 'product_cat', + 'field' => 'slug', + 'terms' => $product_category, + 'operator' => 'IN', + ) + ); + } + $posts = get_posts( $query_args ); + $bkg_process_min_amount = get_option( 'alg_wc_cog_bkg_process_min_amount', 100 ); + $perform_bkg_process = count( $posts ) >= $bkg_process_min_amount; + $message = ''; + if ( $perform_bkg_process ) { + $message = __( 'Costs are being updated via background processing.', 'cost-of-goods-for-woocommerce' ); + $message .= 'yes' === get_option( 'alg_wc_cog_bkg_process_send_email', 'yes' ) ? ' '.sprintf( __( 'An email is going to be sent to %s when the task is completed.', 'cost-of-goods-for-woocommerce' ), get_option( 'alg_wc_cog_bkg_process_email_to', get_option( 'admin_email' ) ) ) : ''; + $this->update_cost_bkg_process->cancel_process(); + foreach ( $posts as $product_id ) { + $this->update_cost_bkg_process->push_to_queue( + array( + 'product_id' => $product_id, + 'percentage' => $percentage, + 'update_type' => $update_type, + ) + ); + } + $this->update_cost_bkg_process->save()->dispatch(); + } else { + $message = __( 'Successfully changed product costs.', 'cost-of-goods-for-woocommerce' ); + foreach ( $posts as $product_id ) { + alg_wc_cog()->core->products->update_product_cost_by_percentage( array( + 'product_id' => $product_id, + 'percentage' => $percentage, + 'update_type' => $update_type, + 'update_variations' => true + ) ); + } + } + wp_send_json_success( esc_html( $message ) ); + } - /** - * create_wp_list_tool. - * - * @version 2.3.4 - * @since 2.3.1 - */ - function create_wp_list_tool() { - if ( ! apply_filters( 'alg_wc_cog_create_edit_costs_tool_validation', true ) ) { - return; + /** + * Display content for Profit Section. + * + * @version 2.5.1 + * @since 2.5.1 + */ + function display_section_profit() { + $disabled = apply_filters( 'alg_wc_cog_settings', 'disabled' ); + $blocked_text = apply_filters( 'alg_wc_cog_settings', alg_wc_cog_get_blocked_options_message() ); + ?> + + + + + + + + + + + wp_list_bulk_edit_tool->prepare_items(); - $save_button = ''; - $save_button_style2 = ''; - ?> -
-
-

- ' . __( 'Bulk edit products costs/prices/stock.', 'cost-of-goods-for-woocommerce' ) . ' ' . - sprintf( __( 'Tool\'s options can be set in "%s" %s.', 'cost-of-goods-for-woocommerce' ), - __( 'Cost of Goods for WooCommerce', 'cost-of-goods-for-woocommerce' ), - '' . - __( 'plugin settings', 'cost-of-goods-for-woocommerce' ) . ''); - ?> - wp_list_bulk_edit_tool->search_box(__('Search','cost-of-goods-for-woocommerce'), 'alg_wc_cog_search'); ?> - wp_list_bulk_edit_tool->display(); ?> - -
-
- + + + + + + + + + + + wp_list_bulk_edit_tool->prepare_items(); + $this->wp_list_bulk_edit_tool->search_box( __( 'Search', 'cost-of-goods-for-woocommerce' ), 'alg_wc_cog_search' ); + $this->wp_list_bulk_edit_tool->display(); } - $min_suffix = ( defined( 'WP_DEBUG' ) && true === WP_DEBUG ? '' : '.min' ); - wp_enqueue_style( 'alg-wc-cog-bulk-edit-tool-style', - alg_wc_cog()->plugin_url() . '/includes/css/alg-wc-cog-bulk-edit-tool' . $min_suffix . '.css', - array(), - alg_wc_cog()->version - ); - wp_enqueue_script( 'alg-wc-cog-bulk-edit-tool', - alg_wc_cog()->plugin_url() . '/includes/js/alg-wc-cog-bulk-edit-tool' . $min_suffix . '.js', - array( 'jquery' ), - alg_wc_cog()->version, - true - ); - } - /** - * add_tool_to_wc_screen_ids. - * - * for `wc_input_price` class. - * - * @version 2.3.1 - * @since 1.2.0 - */ - function add_tool_to_wc_screen_ids( $screen_ids ) { - $screen_ids[] = 'tools_page_bulk-edit-costs'; - return $screen_ids; - } + /** + * Display section navs HTML. + * + * @version 2.5.1 + * @since 2.5.1 + */ + function display_section_navs_html() { + + $tabs_nav_html = array(); + $nav_sections = $this->get_section_nav_items(); + $section = isset( $_GET['section'] ) ? sanitize_text_field( $_GET['section'] ) : key( $nav_sections ); + + foreach ( $nav_sections as $key => $tab ) { + + $label = isset( $tab['label'] ) ? $tab['label'] : ''; + $is_current = $section === $key ? 'current' : ''; + $section_url = admin_url( sprintf( 'tools.php?page=%s§ion=%s', $this->page_slug, $key ) ); - /** - * save_costs. - * - * @version 2.2.0 - * @since 1.2.0 - * @see https://wordpress.org/support/topic/you-should-add-posibility-to-edit-regular-price-and-sale-price/ - * @todo [next] prices: `$do_update_func` - * @todo [maybe] nonce etc. - * @todo [maybe] output some error on ` ! ( $product = wc_get_product( $product_id ) )`? - */ - function save_costs() { - $do_edit_prices = ( 'yes' === get_option( 'alg_wc_cog_bulk_edit_tool_edit_prices', 'no' ) ); - if ( $do_edit_prices ) { - $error_sale_price_ids = array(); + $tabs_nav_html[] = sprintf( '
  • %s
  • ', $section_url, $is_current, $label ); + } + + printf( '', implode( ' | ', $tabs_nav_html ) ); } - if ( isset( $_POST['alg_wc_cog_bulk_edit_tool_save_costs'] ) ) { - // Costs - if ( isset( $_POST['alg_wc_cog_bulk_edit_tool_costs'] )&& is_array( $_POST['alg_wc_cog_bulk_edit_tool_costs'] ) ) { - foreach ( $_POST['alg_wc_cog_bulk_edit_tool_costs'] as $product_id => $cost_value ) { - update_post_meta( sanitize_key( $product_id ), '_alg_wc_cog_cost', sanitize_text_field( $cost_value ) ); - } + + /** + * display_wp_list_tool. + * + * @version 2.5.1 + * @since 2.3.1 + */ + function display_bulk_edit_tools() { + + ob_start(); + + // Section heading title + printf( '

    %s - %s %s

    ', + esc_html__( 'Bulk Edit Costs', 'cost-of-goods-for-woocommerce' ), + $this->get_current_section( 'label' ), + $this->get_current_section( 'save_btn_top' ) + ); + + // Section navigations + $this->display_section_navs_html(); + + // Section description + if ( ! empty( $section_desc = $this->get_current_section( 'desc' ) ) ) { + printf( '

    %s

    ', $section_desc ); + } + + $section_method = 'display_section_' . $this->get_current_section( 'id' ); + + if ( method_exists( $this, $section_method ) && is_callable( array( $this, $section_method ) ) ) { + call_user_func( array( $this, $section_method ) ); + } + + // Bottom save button + if ( ! empty( $save_btn_bottom = $this->get_current_section( 'save_btn_bottom' ) ) ) { + printf( '
    %s%s
    ', + wp_nonce_field( "_nonce_{$this->get_current_section( 'id' )}_action", "_nonce_{$this->get_current_section( 'id' )}_val" ), + $save_btn_bottom + ); + } + + // Wrap up section content + printf( '

    %s
    ', + $this->get_current_section( 'form_class' ), + $this->get_current_section( 'id' ), + ob_get_clean() + ); + } + + /** + * Return current section or any argument value of current section. + * + * @version 2.5.1 + * @since 2.5.1 + * + * @param string $arg + * @return int|mixed|string|null + */ + function get_current_section( $arg = '' ) { + + $nav_sections = $this->get_section_nav_items(); + $section = isset( $_GET['section'] ) ? sanitize_text_field( $_GET['section'] ) : key( $nav_sections ); + + if ( $arg === 'id' ) { + return $section; + } + + if ( ! empty( $arg ) ) { + return isset( $nav_sections[ $section ][ $arg ] ) ? $nav_sections[ $section ][ $arg ] : ''; } - // Prices + + return $nav_sections[ $section ]; + } + + /** + * Return navigation items. + * + * @version 2.5.1 + * @since 2.5.1 + * + * @return mixed|void + */ + function get_section_nav_items() { + + $bulk_edit_sections = array( + 'manually' => array( + 'label' => esc_html__( 'Manually', 'cost-of-goods-for-woocommerce' ), + 'save_btn_top' => sprintf( '', + esc_html__( 'Save', 'cost-of-goods-for-woocommerce' ) + ), + 'save_btn_bottom' => sprintf( '', + esc_html__( 'Save', 'cost-of-goods-for-woocommerce' ) + ), + 'desc' => sprintf( __( 'Bulk edit products costs/prices/stock. Tools options can be set in "Cost of Goods for WooCommerce" plugin settings', 'cost-of-goods-for-woocommerce' ), + admin_url( 'admin.php?page=wc-settings&tab=alg_wc_cost_of_goods§ion=tools' ) + ), + ), + 'price' => array( + 'label' => esc_html__( 'By Price', 'cost-of-goods-for-woocommerce' ), + 'desc' => esc_html__( 'Here you can set the product costs from the product prices.', 'cost-of-goods-for-woocommerce' ) . '
    ' . + esc_html__( 'Variations costs will also be updated accordingly.', 'cost-of-goods-for-woocommerce' ), + 'save_btn_bottom' => sprintf( '', esc_html__( 'Update Costs', 'cost-of-goods-for-woocommerce' ) ), + 'form_class' => 'ajax-submission', + ), + 'profit' => array( + 'label' => esc_html__( 'By Profit', 'cost-of-goods-for-woocommerce' ), + 'desc' => esc_html__( 'Here you can set the product costs according to the profit you want to achieve.', 'cost-of-goods-for-woocommerce' ) . '
    ' . + esc_html__( 'Variations costs will also be updated accordingly.', 'cost-of-goods-for-woocommerce' ), + 'save_btn_bottom' => sprintf( '', esc_html__( 'Update Costs', 'cost-of-goods-for-woocommerce' ) ), + 'form_class' => 'ajax-submission', + ), + ); + + return apply_filters( 'alg_wc_cog_filters_bulk_edit_sections_nav', $bulk_edit_sections ); + } + + /** + * set_screen_option. + * + * @version 2.3.1 + * @since 2.3.1 + * + * @param $status + * @param $option + * @param $value + * + * @return mixed + * + */ + function set_screen_option( $status, $option, $value ) { + if ( 'alg_wc_cog_bulk_edit_per_page' === $option ) { + return $value; + } + + return $status; + } + + /** + * screen_option. + * + * @version 2.3.1 + * @since 2.3.1 + */ + function screen_option() { + $option = 'per_page'; + $args = [ + 'label' => __( 'Items per page', 'cost-of-goods-for-woocommerce' ), + 'default' => 20, + 'option' => 'alg_wc_cog_bulk_edit_per_page' + ]; + add_screen_option( $option, $args ); + require_once( 'class-alg-wc-cog-wplist-bulk-edit-tool.php' ); + $this->wp_list_bulk_edit_tool = new Alg_WC_Cost_of_Goods_WP_List_Bulk_Edit_Tool(); + } + + /** + * create_wp_list_tool. + * + * @version 2.3.4 + * @since 2.3.1 + */ + function create_wp_list_tool() { + if ( ! apply_filters( 'alg_wc_cog_create_edit_costs_tool_validation', true ) ) { + return; + } + $hook = add_submenu_page( + 'tools.php', + __( 'Bulk Edit Costs', 'cost-of-goods-for-woocommerce' ), + __( 'Bulk Edit Costs', 'cost-of-goods-for-woocommerce' ), + 'manage_woocommerce', + $this->page_slug, + array( $this, 'display_bulk_edit_tools' ) + ); + add_action( "load-{$hook}", array( $this, 'screen_option' ) ); + } + + /** + * enqueue_scripts_and_styles. + * + * @version 2.5.0 + * @since 1.3.3 + */ + function enqueue_scripts_and_styles( $hook ) { + if ( 'tools_page_bulk-edit-costs' != $hook ) { + return; + } + $min_suffix = ( defined( 'WP_DEBUG' ) && true === WP_DEBUG ? '' : '.min' ); + wp_enqueue_style( 'alg-wc-cog-bulk-edit-tool-style', + alg_wc_cog()->plugin_url() . '/includes/css/alg-wc-cog-bulk-edit-tool' . $min_suffix . '.css', + array(), + alg_wc_cog()->version + ); + wp_enqueue_script( 'alg-wc-cog-bulk-edit-tool', alg_wc_cog()->plugin_url() . '/includes/js/alg-wc-cog-bulk-edit-tool' . $min_suffix . '.js', array( 'jquery' ), alg_wc_cog()->version, true ); + wp_localize_script( 'alg-wc-cog-bulk-edit-tool', 'algWcCog', + array( + 'ajaxURL' => admin_url( 'admin-ajax.php' ), + 'confirmText' => esc_html__( 'Are you really want to update?', 'cost-of-goods-for-woocommerce' ) + ) + ); + } + + /** + * add_tool_to_wc_screen_ids. + * + * for `wc_input_price` class. + * + * @version 2.3.1 + * @since 1.2.0 + */ + function add_tool_to_wc_screen_ids( $screen_ids ) { + $screen_ids[] = 'tools_page_bulk-edit-costs'; + + return $screen_ids; + } + + /** + * save_costs. + * + * @version 2.2.0 + * @since 1.2.0 + * @see https://wordpress.org/support/topic/you-should-add-posibility-to-edit-regular-price-and-sale-price/ + * @todo [next] prices: `$do_update_func` + * @todo [maybe] nonce etc. + * @todo [maybe] output some error on ` ! ( $product = wc_get_product( $product_id ) )`? + */ + function save_costs() { + $do_edit_prices = ( 'yes' === get_option( 'alg_wc_cog_bulk_edit_tool_edit_prices', 'no' ) ); if ( $do_edit_prices ) { - if ( isset( $_POST['alg_wc_cog_bulk_edit_tool_regular_price'] ) && is_array( $_POST['alg_wc_cog_bulk_edit_tool_regular_price'] ) ) { - $regular_prices = wc_clean( $_POST['alg_wc_cog_bulk_edit_tool_regular_price'] ); - foreach ( $regular_prices as $product_id => $regular_price_value ) { - if ( $product = wc_get_product( $product_id ) ) { - $product->set_regular_price( $regular_price_value ); - $product->save(); - } + $error_sale_price_ids = array(); + } + if ( isset( $_POST['alg_wc_cog_bulk_edit_tool_save_costs'] ) ) { + // Costs + if ( isset( $_POST['alg_wc_cog_bulk_edit_tool_costs'] ) && is_array( $_POST['alg_wc_cog_bulk_edit_tool_costs'] ) ) { + foreach ( $_POST['alg_wc_cog_bulk_edit_tool_costs'] as $product_id => $cost_value ) { + update_post_meta( sanitize_key( $product_id ), '_alg_wc_cog_cost', sanitize_text_field( $cost_value ) ); } } - if ( isset( $_POST['alg_wc_cog_bulk_edit_tool_sale_price'] )&& is_array( $_POST['alg_wc_cog_bulk_edit_tool_sale_price'] ) ) { - $sale_prices = wc_clean( $_POST['alg_wc_cog_bulk_edit_tool_sale_price'] ); - foreach ( $sale_prices as $product_id => $sale_price_value ) { - if ( $product = wc_get_product( $product_id ) ) { - if ( $sale_price_value <= $product->get_regular_price() ) { - $product->set_sale_price( $sale_price_value ); + // Prices + if ( $do_edit_prices ) { + if ( isset( $_POST['alg_wc_cog_bulk_edit_tool_regular_price'] ) && is_array( $_POST['alg_wc_cog_bulk_edit_tool_regular_price'] ) ) { + $regular_prices = wc_clean( $_POST['alg_wc_cog_bulk_edit_tool_regular_price'] ); + foreach ( $regular_prices as $product_id => $regular_price_value ) { + if ( $product = wc_get_product( $product_id ) ) { + $product->set_regular_price( $regular_price_value ); $product->save(); - } else { - array_push( $error_sale_price_ids, $product_id ); + } + } + } + if ( isset( $_POST['alg_wc_cog_bulk_edit_tool_sale_price'] ) && is_array( $_POST['alg_wc_cog_bulk_edit_tool_sale_price'] ) ) { + $sale_prices = wc_clean( $_POST['alg_wc_cog_bulk_edit_tool_sale_price'] ); + foreach ( $sale_prices as $product_id => $sale_price_value ) { + if ( $product = wc_get_product( $product_id ) ) { + if ( $sale_price_value <= $product->get_regular_price() ) { + $product->set_sale_price( $sale_price_value ); + $product->save(); + } else { + array_push( $error_sale_price_ids, $product_id ); + } } } } } - } - // Stock - if ( isset( $_POST['alg_wc_cog_bulk_edit_tool_stock'] )&& is_array( $_POST['alg_wc_cog_bulk_edit_tool_stock'] ) ) { - $do_update_func = ( 'func' === get_option( 'alg_wc_cog_bulk_edit_tool_manage_stock_method', 'meta' ) ); - foreach ( $_POST['alg_wc_cog_bulk_edit_tool_stock'] as $product_id => $stock_value ) { - if ( $do_update_func && ( $product = wc_get_product( $product_id ) ) ) { - $product->set_stock_quantity( sanitize_text_field( $stock_value ) ); - $product->save(); - } else { - update_post_meta( sanitize_key( $product_id ), '_stock', sanitize_text_field( $stock_value ) ); + // Stock + if ( isset( $_POST['alg_wc_cog_bulk_edit_tool_stock'] ) && is_array( $_POST['alg_wc_cog_bulk_edit_tool_stock'] ) ) { + $do_update_func = ( 'func' === get_option( 'alg_wc_cog_bulk_edit_tool_manage_stock_method', 'meta' ) ); + foreach ( $_POST['alg_wc_cog_bulk_edit_tool_stock'] as $product_id => $stock_value ) { + if ( $do_update_func && ( $product = wc_get_product( $product_id ) ) ) { + $product->set_stock_quantity( sanitize_text_field( $stock_value ) ); + $product->save(); + } else { + update_post_meta( sanitize_key( $product_id ), '_stock', sanitize_text_field( $stock_value ) ); + } } } - } - // Notices - add_action( 'admin_notices', array( $this, 'admin_notice_costs_saved' ) ); - if ( $do_edit_prices && count( $error_sale_price_ids ) ) { - $this->error_sale_price_ids = $error_sale_price_ids; - add_action( 'admin_notices', array( $this, 'admin_notice_sale_price_higher' ) ); + // Notices + add_action( 'admin_notices', array( $this, 'admin_notice_costs_saved' ) ); + if ( $do_edit_prices && count( $error_sale_price_ids ) ) { + $this->error_sale_price_ids = $error_sale_price_ids; + add_action( 'admin_notices', array( $this, 'admin_notice_sale_price_higher' ) ); + } } } - } - /** - * admin_notice_costs_saved. - * - * @version 1.2.0 - * @since 1.2.0 - */ - function admin_notice_costs_saved() { - echo '

    ' . __( 'Costs have been saved.', 'cost-of-goods-for-woocommerce' ) . '

    '; - } + /** + * admin_notice_costs_saved. + * + * @version 1.2.0 + * @since 1.2.0 + */ + function admin_notice_costs_saved() { + echo '

    ' . __( 'Costs have been saved.', 'cost-of-goods-for-woocommerce' ) . '

    '; + } - /** - * get_the_title. - * - * @version 1.4.0 - * @since 1.4.0 - */ - function get_the_title( $post_id ) { - return get_the_title( $post_id ) . ' (#' . $post_id . ')'; - } + /** + * get_the_title. + * + * @version 1.4.0 + * @since 1.4.0 + */ + function get_the_title( $post_id ) { + return get_the_title( $post_id ) . ' (#' . $post_id . ')'; + } - /** - * admin_notice_sale_price_higher. - * - * @version 1.4.0 - * @since 1.4.0 - */ - function admin_notice_sale_price_higher() { - echo '

    ' . sprintf( __( 'Sale price is higher than regular price: %s.', 'cost-of-goods-for-woocommerce' ), - implode( ', ', array_map( array( $this, 'get_the_title' ), $this->error_sale_price_ids ) ) ) . '

    '; + /** + * admin_notice_sale_price_higher. + * + * @version 1.4.0 + * @since 1.4.0 + */ + function admin_notice_sale_price_higher() { + echo '

    ' . sprintf( __( 'Sale price is higher than regular price: %s.', 'cost-of-goods-for-woocommerce' ), + implode( ', ', array_map( array( $this, 'get_the_title' ), $this->error_sale_price_ids ) ) ) . '

    '; + } } -} - endif; return new Alg_WC_Cost_of_Goods_Bulk_Edit_Tool(); + + diff --git a/includes/tools/class-alg-wc-cog-import-tool.php b/includes/tools/class-alg-wc-cog-import-tool.php index 3624bbc..9902d5a 100644 --- a/includes/tools/class-alg-wc-cog-import-tool.php +++ b/includes/tools/class-alg-wc-cog-import-tool.php @@ -7,187 +7,195 @@ * @author WPFactory */ -if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly +if ( ! defined( 'ABSPATH' ) ) { + exit; +} // Exit if accessed directly if ( ! class_exists( 'Alg_WC_Cost_of_Goods_Import_Tool' ) ) : -class Alg_WC_Cost_of_Goods_Import_Tool { - - /** - * @var Alg_WC_Cost_of_Goods_Import_Tool_Bkg_Process - */ - public $import_tool_bkg_process; - - /** - * Constructor. - * - * @version 2.3.0 - * @since 1.1.0 - */ - function __construct() { - add_action( 'admin_menu', array( $this, 'create_import_tool' ) ); - // Bkg Process - add_action( 'plugins_loaded', array( $this, 'init_bkg_process' ) ); - } + class Alg_WC_Cost_of_Goods_Import_Tool { + + /** + * @var Alg_WC_Cost_of_Goods_Import_Tool_Bkg_Process + */ + public $import_tool_bkg_process; - /** - * init_bkg_process. - * - * @version 2.3.0 - * @since 2.3.0 - */ - function init_bkg_process() { - require_once( alg_wc_cog()->plugin_path() . '/includes/background-process/class-alg-wc-cog-import-tool-bkg-process.php' ); - $this->import_tool_bkg_process = new Alg_WC_Cost_of_Goods_Import_Tool_Bkg_Process(); - } - /** - * create_import_tool. - * - * @version 2.3.4 - * @since 1.0.0 - */ - function create_import_tool() { - if ( ! apply_filters( 'alg_wc_cog_create_import_tool_validation', true ) ) { - return; + /** + * Constructor. + * + * @version 2.3.0 + * @since 1.1.0 + */ + function __construct() { + add_action( 'admin_menu', array( $this, 'create_import_tool' ) ); + // Bkg Process + add_action( 'plugins_loaded', array( $this, 'init_bkg_process' ) ); } - add_submenu_page( - 'tools.php', - __( 'Import Costs', 'cost-of-goods-for-woocommerce' ), - __( 'Import Costs', 'cost-of-goods-for-woocommerce' ), - 'manage_woocommerce', - 'import-costs', - array( $this, 'import_tool' ) - ); - } - /** - * copy_product_meta. - * - * @version 2.4.6 - * @since 2.3.0 - * - * @param null $args - */ - function copy_product_meta( $args = null ) { - $args = wp_parse_args( $args, array( - 'product_id' => '', - 'from_key' => get_option( 'alg_wc_cog_tool_key', '_wc_cog_cost' ), - 'to_key' => get_option( 'alg_wc_cog_tool_key_to', '_alg_wc_cog_cost' ) - ) ); - $product_id = $args['product_id']; - $from_key = $args['from_key']; - $to_key = $args['to_key']; - if ( - ( - 'yes' === get_option( 'alg_wc_cog_import_tool_check_key', 'yes' ) - && ! metadata_exists( 'post', $product_id, $from_key ) - ) - || - ( - 'yes' === get_option( 'alg_wc_cog_import_tool_check_value', 'yes' ) - && empty( get_post_meta( $product_id, $from_key, true ) ) - ) - ) { - return; + /** + * init_bkg_process. + * + * @version 2.5.1 + * @since 2.3.0 + */ + function init_bkg_process() { + require_once( alg_wc_cog()->plugin_path() . '/includes/background-process/class-alg-wc-cog-import-tool-bkg-process.php' ); + + $this->import_tool_bkg_process = new Alg_WC_Cost_of_Goods_Import_Tool_Bkg_Process(); } - $source_cost = get_post_meta( $product_id, $from_key, true ); - update_post_meta( $product_id, $to_key, $source_cost ); - } - /** - * import_tool. - * - * @version 2.4.6 - * @since 1.0.0 - * @todo [later] use `wc_get_products()` - * @todo [later] better description here and in settings - * @todo [later] notice after import - * @todo [later] add "import from file" option (CSV, XML etc.) (#12169) - * @todo [maybe] import order items meta - */ - function import_tool() { - $perform_import = ( isset( $_POST['alg_wc_cog_import'] ) ); - $key_from = get_option( 'alg_wc_cog_tool_key', '_wc_cog_cost' ); - $key_to = get_option( 'alg_wc_cog_tool_key_to', '_alg_wc_cog_cost' ); - $bkg_process_min_amount = get_option( 'alg_wc_cog_bkg_process_min_amount', 100 ); - $table_data = array(); - $alg_wc_cog_get_table_html = ''; - $display_table = 'yes' === get_option( 'alg_wc_cog_import_tool_display_table', 'no' ); - $table_data[] = array( - __( 'Product ID', 'cost-of-goods-for-woocommerce' ), - __( 'Product Title', 'cost-of-goods-for-woocommerce' ), - sprintf( __( 'Source %s', 'cost-of-goods-for-woocommerce' ), '' . $key_from . '' ), - sprintf( __( 'Destination %s', 'cost-of-goods-for-woocommerce' ), '' . $key_to . '' ), - ); - $args = array( - 'post_type' => array( 'product', 'product_variation' ), - 'post_status' => 'any', - 'posts_per_page' => - 1, - 'orderby' => 'ID', - 'order' => 'ASC', - 'fields' => 'ids', - 'no_found_rows' => false, - 'update_post_term_cache' => false, - 'update_post_meta_cache' => false, - 'cache_results' => false - ); - $loop = new WP_Query( $args ); - $perform_bkg_process = $perform_import && $loop->post_count >= $bkg_process_min_amount; - - // Update values. - if ( $perform_bkg_process ) { - $this->import_tool_bkg_process->cancel_process(); - if ( $loop->have_posts() ) { - foreach ( $loop->posts as $product_id ) { - $this->import_tool_bkg_process->push_to_queue( array( 'id' => $product_id, 'from_key' => $key_from, 'to_key' => $key_to ) ); - } + + /** + * create_import_tool. + * + * @version 2.3.4 + * @since 1.0.0 + */ + function create_import_tool() { + if ( ! apply_filters( 'alg_wc_cog_create_import_tool_validation', true ) ) { + return; } - $this->import_tool_bkg_process->save()->dispatch(); - } else { - if ( $perform_import && $loop->have_posts() ) { - foreach ( $loop->posts as $product_id ) { - $this->copy_product_meta( array( - 'product_id' => $product_id, - 'from_key' => $key_from, - 'to_key' => $key_to - ) ); - } + add_submenu_page( + 'tools.php', + __( 'Import Costs', 'cost-of-goods-for-woocommerce' ), + __( 'Import Costs', 'cost-of-goods-for-woocommerce' ), + 'manage_woocommerce', + 'import-costs', + array( $this, 'import_tool' ) + ); + } + + + /** + * copy_product_meta. + * + * @param null $args + * + * @since 2.3.0 + * + * @version 2.4.6 + */ + function copy_product_meta( $args = null ) { + $args = wp_parse_args( $args, array( + 'product_id' => '', + 'from_key' => get_option( 'alg_wc_cog_tool_key', '_wc_cog_cost' ), + 'to_key' => get_option( 'alg_wc_cog_tool_key_to', '_alg_wc_cog_cost' ) + ) ); + $product_id = $args['product_id']; + $from_key = $args['from_key']; + $to_key = $args['to_key']; + if ( + ( + 'yes' === get_option( 'alg_wc_cog_import_tool_check_key', 'yes' ) + && ! metadata_exists( 'post', $product_id, $from_key ) + ) + || + ( + 'yes' === get_option( 'alg_wc_cog_import_tool_check_value', 'yes' ) + && empty( get_post_meta( $product_id, $from_key, true ) ) + ) + ) { + return; } + $source_cost = get_post_meta( $product_id, $from_key, true ); + update_post_meta( $product_id, $to_key, $source_cost ); } - // Output. - if ( $display_table ) { - if ( $loop->have_posts() ) { - foreach ( $loop->posts as $product_id ) { - $source_cost = get_post_meta( $product_id, $key_from, true ); - if ( '_alg_wc_cog_cost' === $key_to ) { - $meta_value_to = alg_wc_cog()->core->products->get_product_cost( $product_id ); - } else { - $meta_value_to = get_post_meta( $product_id, $key_to, true ); + + /** + * import_tool. + * + * @version 2.4.6 + * @since 1.0.0 + * @todo [later] use `wc_get_products()` + * @todo [later] better description here and in settings + * @todo [later] notice after import + * @todo [later] add "import from file" option (CSV, XML etc.) (#12169) + * @todo [maybe] import order items meta + */ + function import_tool() { + $perform_import = ( isset( $_POST['alg_wc_cog_import'] ) ); + $key_from = get_option( 'alg_wc_cog_tool_key', '_wc_cog_cost' ); + $key_to = get_option( 'alg_wc_cog_tool_key_to', '_alg_wc_cog_cost' ); + $bkg_process_min_amount = get_option( 'alg_wc_cog_bkg_process_min_amount', 100 ); + $table_data = array(); + $alg_wc_cog_get_table_html = ''; + $display_table = 'yes' === get_option( 'alg_wc_cog_import_tool_display_table', 'no' ); + $table_data[] = array( + __( 'Product ID', 'cost-of-goods-for-woocommerce' ), + __( 'Product Title', 'cost-of-goods-for-woocommerce' ), + sprintf( __( 'Source %s', 'cost-of-goods-for-woocommerce' ), '' . $key_from . '' ), + sprintf( __( 'Destination %s', 'cost-of-goods-for-woocommerce' ), '' . $key_to . '' ), + ); + $args = array( + 'post_type' => array( 'product', 'product_variation' ), + 'post_status' => 'any', + 'posts_per_page' => - 1, + 'orderby' => 'ID', + 'order' => 'ASC', + 'fields' => 'ids', + 'no_found_rows' => false, + 'update_post_term_cache' => false, + 'update_post_meta_cache' => false, + 'cache_results' => false + ); + $loop = new WP_Query( $args ); + $perform_bkg_process = $perform_import && $loop->post_count >= $bkg_process_min_amount; + + // Update values. + if ( $perform_bkg_process ) { + $this->import_tool_bkg_process->cancel_process(); + if ( $loop->have_posts() ) { + foreach ( $loop->posts as $product_id ) { + $this->import_tool_bkg_process->push_to_queue( array( 'id' => $product_id, 'from_key' => $key_from, 'to_key' => $key_to ) ); + } + } + $this->import_tool_bkg_process->save()->dispatch(); + } else { + if ( $perform_import && $loop->have_posts() ) { + foreach ( $loop->posts as $product_id ) { + $this->copy_product_meta( array( + 'product_id' => $product_id, + 'from_key' => $key_from, + 'to_key' => $key_to + ) ); } - $table_data[] = array( $product_id, get_the_title( $product_id ), $source_cost, $meta_value_to ); } } - $alg_wc_cog_get_table_html = alg_wc_cog_get_table_html( $table_data, array( 'table_heading_type' => 'horizontal', 'table_class' => 'widefat striped' ) ); + + // Output. + if ( $display_table ) { + if ( $loop->have_posts() ) { + foreach ( $loop->posts as $product_id ) { + $source_cost = get_post_meta( $product_id, $key_from, true ); + if ( '_alg_wc_cog_cost' === $key_to ) { + $meta_value_to = alg_wc_cog()->core->products->get_product_cost( $product_id ); + } else { + $meta_value_to = get_post_meta( $product_id, $key_to, true ); + } + $table_data[] = array( $product_id, get_the_title( $product_id ), $source_cost, $meta_value_to ); + } + } + $alg_wc_cog_get_table_html = alg_wc_cog_get_table_html( $table_data, array( 'table_heading_type' => 'horizontal', 'table_class' => 'widefat striped' ) ); + } + $button_form = '
    ' . + '' . + '
    '; + $html = '
    ' . + '

    ' . __( 'Costs Import', 'cost-of-goods-for-woocommerce' ) . '

    ' . + '

    ' . __( 'Import products costs to "Cost of Goods for WooCommerce" plugin.', 'cost-of-goods-for-woocommerce' ) . ' ' . + sprintf( __( 'Tool\'s options can be set in %s.', 'cost-of-goods-for-woocommerce' ), + '' . __( 'plugin settings', 'cost-of-goods-for-woocommerce' ) . '' + ) . '

    ' . + '

    ' . $button_form . '

    ' . + '

    ' . $alg_wc_cog_get_table_html . '

    ' . + '
    '; + echo $html; } - $button_form = '
    ' . - '' . - '
    '; - $html = '
    ' . - '

    ' . __( 'Costs Import', 'cost-of-goods-for-woocommerce' ) . '

    ' . - '

    ' . __( 'Import products costs to "Cost of Goods for WooCommerce" plugin.', 'cost-of-goods-for-woocommerce' ) . ' ' . - sprintf( __( 'Tool\'s options can be set in %s.', 'cost-of-goods-for-woocommerce' ), - '' . __( 'plugin settings', 'cost-of-goods-for-woocommerce' ) . '' - ) . '

    ' . - '

    ' . $button_form . '

    ' . - '

    ' . $alg_wc_cog_get_table_html . '

    ' . - '
    '; - echo $html; - } -} + } endif; diff --git a/langs/cost-of-goods-for-woocommerce.pot b/langs/cost-of-goods-for-woocommerce.pot index 688ca3d..083581e 100644 --- a/langs/cost-of-goods-for-woocommerce.pot +++ b/langs/cost-of-goods-for-woocommerce.pot @@ -2,20 +2,19 @@ # This file is distributed under the GNU General Public License v3.0. msgid "" msgstr "" -"Project-Id-Version: Cost of Goods for WooCommerce 2.5.0\n" +"Project-Id-Version: Cost of Goods for WooCommerce 2.5.1\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/cost-of-goods-for-woocommerce\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2022-01-20T02:04:52+01:00\n" +"POT-Creation-Date: 2022-02-10T23:46:09+01:00\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "X-Generator: WP-CLI 2.4.0\n" "X-Domain: cost-of-goods-for-woocommerce\n" #. Plugin Name of the plugin -#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:107 msgid "Cost of Goods for WooCommerce" msgstr "" @@ -35,28 +34,41 @@ msgstr "" msgid "https://wpfactory.com" msgstr "" -#: cost-of-goods-for-woocommerce.php:191 +#: cost-of-goods-for-woocommerce.php:192 msgid "Go Pro" msgstr "" +#: includes/alg-wc-cog-functions.php:213 +msgid "Disabled options can be unlocked using %s" +msgstr "" + +#: includes/alg-wc-cog-functions.php:213 +#: includes/settings/class-alg-wc-settings-cog.php:59 +msgid "Cost of Goods for WooCommerce Pro" +msgstr "" + #: includes/analytics/class-alg-wc-cog-analytics-orders.php:291 #: includes/analytics/class-alg-wc-cog-analytics-revenue.php:47 #: includes/analytics/class-alg-wc-cog-analytics-stock.php:77 #: includes/class-alg-wc-cog-orders-meta-boxes.php:73 #: includes/class-alg-wc-cog-orders.php:240 #: includes/class-alg-wc-cog-orders.php:320 -#: includes/class-alg-wc-cog-products.php:184 -#: includes/class-alg-wc-cog-products.php:211 -#: includes/class-alg-wc-cog-products.php:228 -#: includes/class-alg-wc-cog-products.php:427 -#: includes/class-alg-wc-cog-products.php:438 -#: includes/class-alg-wc-cog-products.php:449 -#: includes/class-alg-wc-cog-products.php:504 +#: includes/class-alg-wc-cog-products.php:216 +#: includes/class-alg-wc-cog-products.php:243 +#: includes/class-alg-wc-cog-products.php:260 +#: includes/class-alg-wc-cog-products.php:459 +#: includes/class-alg-wc-cog-products.php:470 +#: includes/class-alg-wc-cog-products.php:481 +#: includes/class-alg-wc-cog-products.php:536 #: includes/tools/class-alg-wc-cog-wplist-bulk-edit-tool.php:184 -#: includes/analytics/build/index.js:1 +#: includes/analytics/build/index.js:281 +#: includes/analytics/build/index.js:370 +#: includes/analytics/build/index.js:460 +#: includes/analytics/build/index.js:579 #: includes/analytics/src/modules/orders.js:33 -#: includes/analytics/src/modules/revenue.js:33 -#: includes/analytics/src/modules/stock.js:58 +#: includes/analytics/src/modules/products.js:31 +#: includes/analytics/src/modules/revenue.js:31 +#: includes/analytics/src/modules/stock.js:56 msgid "Cost" msgstr "" @@ -66,32 +78,40 @@ msgstr "" #: includes/class-alg-wc-cog-orders-meta-boxes.php:74 #: includes/class-alg-wc-cog-orders.php:241 #: includes/class-alg-wc-cog-orders.php:330 -#: includes/class-alg-wc-cog-products.php:507 -#: includes/analytics/build/index.js:1 +#: includes/class-alg-wc-cog-products.php:539 +#: includes/analytics/build/index.js:286 +#: includes/analytics/build/index.js:375 +#: includes/analytics/build/index.js:465 +#: includes/analytics/build/index.js:585 #: includes/analytics/src/modules/orders.js:39 -#: includes/analytics/src/modules/revenue.js:39 -#: includes/analytics/src/modules/stock.js:64 +#: includes/analytics/src/modules/products.js:37 +#: includes/analytics/src/modules/revenue.js:37 +#: includes/analytics/src/modules/stock.js:62 msgid "Profit" msgstr "" #: includes/analytics/class-alg-wc-cog-analytics-stock.php:82 -#: includes/analytics/build/index.js:1 -#: includes/analytics/src/modules/stock.js:73 +#: includes/analytics/build/index.js:595 +#: includes/analytics/src/modules/stock.js:71 msgid "Category" msgstr "" -#: includes/background-process/class-alg-wc-cog-import-tool-bkg-process.php:30 +#: includes/background-process/class-alg-wc-cog-import-tool-bkg-process.php:32 msgid "Cost of Goods for WooCommerce - Import Tool" msgstr "" -#: includes/background-process/class-alg-wc-cog-recalculate-orders-bkg-process.php:30 +#: includes/background-process/class-alg-wc-cog-recalculate-orders-bkg-process.php:32 msgid "Cost of Goods for WooCommerce - Recalculate orders" msgstr "" +#: includes/background-process/class-alg-wc-cog-update-cost-bkg-process.php:32 +msgid "Cost of Goods for WooCommerce - Bulk update costs" +msgstr "" + #: includes/class-alg-wc-cog-orders-meta-boxes.php:42 #: includes/class-alg-wc-cog-orders-meta-boxes.php:119 -#: includes/class-alg-wc-cog-products.php:150 -#: includes/class-alg-wc-cog-products.php:176 +#: includes/class-alg-wc-cog-products.php:182 +#: includes/class-alg-wc-cog-products.php:208 #: includes/settings/class-alg-wc-cog-settings-orders.php:390 #: includes/settings/class-alg-wc-cog-settings-products.php:185 #: includes/settings/class-alg-wc-settings-cog.php:24 @@ -201,45 +221,45 @@ msgstr "" msgid "Cost (excl. tax) (%s)" msgstr "" -#: includes/class-alg-wc-cog-products.php:147 +#: includes/class-alg-wc-cog-products.php:179 msgid "Enter values and \"Update\" the product." msgstr "" -#: includes/class-alg-wc-cog-products.php:148 +#: includes/class-alg-wc-cog-products.php:180 #: includes/settings/class-alg-wc-cog-settings-products.php:178 msgid "\"Stock\" will be added to your inventory, and \"Cost\" will be used to calculate new average cost of goods for the product." msgstr "" -#: includes/class-alg-wc-cog-products.php:150 -#: includes/class-alg-wc-cog-products.php:176 +#: includes/class-alg-wc-cog-products.php:182 +#: includes/class-alg-wc-cog-products.php:208 #: includes/settings/class-alg-wc-cog-settings-products.php:176 #: includes/settings/class-alg-wc-cog-settings-products.php:183 #: includes/settings/class-alg-wc-cog-settings-products.php:185 msgid "Add stock" msgstr "" -#: includes/class-alg-wc-cog-products.php:178 -#: includes/class-alg-wc-cog-products.php:207 -#: includes/class-alg-wc-cog-products.php:227 +#: includes/class-alg-wc-cog-products.php:210 +#: includes/class-alg-wc-cog-products.php:239 +#: includes/class-alg-wc-cog-products.php:259 #: includes/tools/class-alg-wc-cog-wplist-bulk-edit-tool.php:185 msgid "Stock" msgstr "" -#: includes/class-alg-wc-cog-products.php:223 +#: includes/class-alg-wc-cog-products.php:255 msgid "History" msgstr "" -#: includes/class-alg-wc-cog-products.php:226 +#: includes/class-alg-wc-cog-products.php:258 msgid "Date" msgstr "" -#: includes/class-alg-wc-cog-products.php:713 -#: includes/class-alg-wc-cog-products.php:759 +#: includes/class-alg-wc-cog-products.php:745 +#: includes/class-alg-wc-cog-products.php:791 msgid "Profit: %s" msgstr "" -#: includes/class-alg-wc-cog-products.php:714 -#: includes/class-alg-wc-cog-products.php:760 +#: includes/class-alg-wc-cog-products.php:746 +#: includes/class-alg-wc-cog-products.php:792 msgid "N/A" msgstr "" @@ -1613,42 +1633,44 @@ msgstr "" #: includes/settings/class-alg-wc-cog-settings-tools.php:276 #: includes/settings/class-alg-wc-cog-settings-tools.php:292 +#: includes/settings/class-alg-wc-cog-settings-tools.php:309 msgid "Add \"Cost\" and \"Profit\" columns" msgstr "" #: includes/settings/class-alg-wc-cog-settings-tools.php:283 -#: includes/settings/class-alg-wc-cog-settings-tools.php:326 +#: includes/settings/class-alg-wc-cog-settings-tools.php:300 +#: includes/settings/class-alg-wc-cog-settings-tools.php:343 msgid "Add \"Cost\" and \"Profit\" totals to the report charts" msgstr "" #: includes/settings/class-alg-wc-cog-settings-tools.php:291 +msgid "Products tab" +msgstr "" + +#: includes/settings/class-alg-wc-cog-settings-tools.php:308 msgid "Stock tab" msgstr "" -#: includes/settings/class-alg-wc-cog-settings-tools.php:300 +#: includes/settings/class-alg-wc-cog-settings-tools.php:317 msgid "Add \"Category\" column" msgstr "" -#: includes/settings/class-alg-wc-cog-settings-tools.php:308 +#: includes/settings/class-alg-wc-cog-settings-tools.php:325 msgid "Add filter allowing to restrict the query" msgstr "" -#: includes/settings/class-alg-wc-cog-settings-tools.php:309 -msgid "For now, allows to get only products with costs." +#: includes/settings/class-alg-wc-cog-settings-tools.php:326 +msgid "For now, it allows to get only products with costs." msgstr "" -#: includes/settings/class-alg-wc-cog-settings-tools.php:317 +#: includes/settings/class-alg-wc-cog-settings-tools.php:334 msgid "Revenue tab" msgstr "" -#: includes/settings/class-alg-wc-cog-settings-tools.php:318 +#: includes/settings/class-alg-wc-cog-settings-tools.php:335 msgid "Add \"Cost\" and \"Profit\" totals columns" msgstr "" -#: includes/settings/class-alg-wc-settings-cog.php:59 -msgid "Cost of Goods for WooCommerce Pro" -msgstr "" - #: includes/settings/class-alg-wc-settings-cog.php:60 msgid "Disabled options can be unlocked using %pro_version_title%" msgstr "" @@ -1678,88 +1700,172 @@ msgstr "" msgid "Your settings have been reset." msgstr "" -#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:58 -msgid "Items per page" +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:71 +msgid "Something went wrong! Please try again." msgstr "" #: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:79 -#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:80 +msgid "Invalid percentage or category." +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:102 +msgid "Costs are being updated via background processing." +msgstr "" + #: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:103 +msgid "An email is going to be sent to %s when the task is completed." +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:116 +msgid "Successfully changed product costs." +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:141 +msgid "Profit percentage (%)" +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:145 +msgid "Products costs will be set according to the profit percentage you'd like to achieve." +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:150 +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:189 +msgid "Filter by category" +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:152 +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:191 +msgid "Search for a category…" +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:158 +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:197 +msgid "Select only the categories you want to edit. Leave it empty to update all products." +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:179 +msgid "Price percentage (%)" +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:183 +msgid "Product costs will be defined from a percentage of product prices." +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:184 +msgid "Most probably you should use a number between 0 and 100." +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:214 +msgid "Search" +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:254 +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:407 +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:408 msgid "Bulk Edit Costs" msgstr "" -#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:97 -#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:99 +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:326 +msgid "Manually" +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:328 +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:331 msgid "Save" msgstr "" -#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:105 -msgid "Bulk edit products costs/prices/stock." +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:333 +msgid "Bulk edit products costs/prices/stock. Tools options can be set in \"Cost of Goods for WooCommerce\" plugin settings" msgstr "" -#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:106 -msgid "Tool's options can be set in \"%s\" %s." +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:338 +msgid "By Price" msgstr "" -#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:109 -#: includes/tools/class-alg-wc-cog-import-tool.php:182 -msgid "plugin settings" +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:339 +msgid "Here you can set the product costs from the product prices." msgstr "" -#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:111 -msgid "Search" +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:340 +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:347 +msgid "Variations costs will also be updated accordingly." +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:341 +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:348 +msgid "Update Costs" +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:345 +msgid "By Profit" +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:346 +msgid "Here you can set the product costs according to the profit you want to achieve." msgstr "" -#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:231 +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:386 +msgid "Items per page" +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:436 +msgid "Are you really want to update?" +msgstr "" + +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:530 msgid "Costs have been saved." msgstr "" -#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:251 +#: includes/tools/class-alg-wc-cog-bulk-edit-tool.php:550 msgid "Sale price is higher than regular price: %s." msgstr "" -#: includes/tools/class-alg-wc-cog-import-tool.php:56 -#: includes/tools/class-alg-wc-cog-import-tool.php:57 +#: includes/tools/class-alg-wc-cog-import-tool.php:61 +#: includes/tools/class-alg-wc-cog-import-tool.php:62 msgid "Import Costs" msgstr "" -#: includes/tools/class-alg-wc-cog-import-tool.php:118 +#: includes/tools/class-alg-wc-cog-import-tool.php:126 #: includes/tools/class-alg-wc-cog-wplist-bulk-edit-tool.php:181 msgid "Product ID" msgstr "" -#: includes/tools/class-alg-wc-cog-import-tool.php:119 +#: includes/tools/class-alg-wc-cog-import-tool.php:127 msgid "Product Title" msgstr "" -#: includes/tools/class-alg-wc-cog-import-tool.php:120 +#: includes/tools/class-alg-wc-cog-import-tool.php:128 msgid "Source %s" msgstr "" -#: includes/tools/class-alg-wc-cog-import-tool.php:121 +#: includes/tools/class-alg-wc-cog-import-tool.php:129 msgid "Destination %s" msgstr "" -#: includes/tools/class-alg-wc-cog-import-tool.php:175 +#: includes/tools/class-alg-wc-cog-import-tool.php:183 msgid "Import" msgstr "" -#: includes/tools/class-alg-wc-cog-import-tool.php:176 +#: includes/tools/class-alg-wc-cog-import-tool.php:184 msgid "Are you sure?" msgstr "" -#: includes/tools/class-alg-wc-cog-import-tool.php:179 +#: includes/tools/class-alg-wc-cog-import-tool.php:187 msgid "Costs Import" msgstr "" -#: includes/tools/class-alg-wc-cog-import-tool.php:180 +#: includes/tools/class-alg-wc-cog-import-tool.php:188 msgid "Import products costs to \"Cost of Goods for WooCommerce\" plugin." msgstr "" -#: includes/tools/class-alg-wc-cog-import-tool.php:181 +#: includes/tools/class-alg-wc-cog-import-tool.php:189 msgid "Tool's options can be set in %s." msgstr "" +#: includes/tools/class-alg-wc-cog-import-tool.php:190 +msgid "plugin settings" +msgstr "" + #: includes/tools/class-alg-wc-cog-wplist-bulk-edit-tool.php:160 msgid "Stock status: %s" msgstr "" @@ -1784,29 +1890,35 @@ msgstr "" msgid "Price" msgstr "" -#: includes/analytics/build/index.js:1 +#: includes/analytics/build/index.js:317 +#: includes/analytics/build/index.js:407 +#: includes/analytics/build/index.js:496 #: includes/analytics/src/modules/orders.js:79 -#: includes/analytics/src/modules/revenue.js:79 +#: includes/analytics/src/modules/products.js:79 +#: includes/analytics/src/modules/revenue.js:77 msgid "Costs total" msgstr "" -#: includes/analytics/build/index.js:1 +#: includes/analytics/build/index.js:321 +#: includes/analytics/build/index.js:411 +#: includes/analytics/build/index.js:500 #: includes/analytics/src/modules/orders.js:84 -#: includes/analytics/src/modules/revenue.js:84 +#: includes/analytics/src/modules/products.js:84 +#: includes/analytics/src/modules/revenue.js:82 msgid "Profit total" msgstr "" -#: includes/analytics/build/index.js:1 -#: includes/analytics/src/modules/stock.js:26 +#: includes/analytics/build/index.js:549 +#: includes/analytics/src/modules/stock.js:24 msgid "Cost of Goods filter" msgstr "" -#: includes/analytics/build/index.js:1 -#: includes/analytics/src/modules/stock.js:31 +#: includes/analytics/build/index.js:556 +#: includes/analytics/src/modules/stock.js:29 msgid "Disabled" msgstr "" -#: includes/analytics/build/index.js:1 -#: includes/analytics/src/modules/stock.js:32 +#: includes/analytics/build/index.js:559 +#: includes/analytics/src/modules/stock.js:30 msgid "Products with cost" msgstr "" diff --git a/readme.txt b/readme.txt index 9e801c1..25a6c47 100644 --- a/readme.txt +++ b/readme.txt @@ -1,9 +1,9 @@ === Cost of Goods for WooCommerce === -Contributors: wpcodefactory, kerbhavik, karzin +Contributors: wpcodefactory, karzin, kerbhavik, jaedm97 Tags: woocommerce, cost, cost of goods, cog, cost of goods sold, cogs, woo commerce Requires at least: 4.4 -Tested up to: 5.8 -Stable tag: 2.5.0 +Tested up to: 5.9 +Stable tag: 2.5.1 License: GNU General Public License v3.0 License URI: http://www.gnu.org/licenses/gpl-3.0.html @@ -98,6 +98,15 @@ And then you can follow these steps: == Changelog == += 2.5.1 - 10/02/2022 = +* Fix - Reports - Stock - Cost of goods - Products having costs and prices with decimal places after zero don't get displayed on the report. +* Dev - Tools - Bulk edit costs - Add "by price" and "by profit" sections. +* Dev - Tools - Bulk edit costs - By price - Add option to define the costs from a percentage of product prices. +* Dev - Tools - Bulk edit costs - By profit - Add option to define the costs according to a profit percentage. +* Dev - Tools - Analytics - Add option to add "Cost" and "Profit" columns to products tab. +* Dev - Tools - Analytics - Add option to add "Cost" and "Profit" totals to products tab. +* Tested up to: 5.9 + = 2.5.0 - 19/01/2022 = * WC tested up to: 6.1.