Plugin Directory

Changeset 3457039


Ignore:
Timestamp:
02/09/2026 12:22:10 PM (4 weeks ago)
Author:
wedevs
Message:

Tagging version 1.16.11

Location:
erp
Files:
58 added
26 edited
1 copied

Legend:

Unmodified
Added
Removed
  • erp/tags/1.16.11/includes/API/AnnouncementsController.php

    r2847329 r3457039  
    346346                    'type'        => 'string',
    347347                    'context'     => [ 'edit' ],
     348                    'recipient_type' => [ 'all_employee', 'selected_employee' ],
    348349                    'arg_options' => [
    349350                        'sanitize_callback' => 'sanitize_text_field',
     
    351352                    'required'    => true,
    352353                ],
     354                'employees'      => [
     355                    'description' => __( 'Employees for the resource.', 'erp' ),
     356                    'type'        => 'string',
     357                    'context'     => [ 'edit' ],
     358                    'arg_options' => [
     359                        'sanitize_callback' => 'sanitize_text_field',
     360                    ],
     361                    'required'    => false,
     362                ],
    353363            ],
    354364        ];
  • erp/tags/1.16.11/includes/functions-people.php

    r3430665 r3457039  
    6161    if ( false === $items ) {
    6262        extract( $args );
     63
     64        // Whitelist allowed orderby columns to prevent SQL injection
     65        $allowed_orderby = [
     66            'id',
     67            'user_id',
     68            'first_name',
     69            'last_name',
     70            'company',
     71            'email',
     72            'phone',
     73            'mobile',
     74            'other',
     75            'website',
     76            'fax',
     77            'notes',
     78            'street_1',
     79            'street_2',
     80            'city',
     81            'state',
     82            'postal_code',
     83            'country',
     84            'currency',
     85            'life_stage',
     86            'contact_owner',
     87            'hash',
     88            'created_by',
     89            'created',
     90        ];
     91
     92        if ( ! in_array( $orderby, $allowed_orderby, true ) ) {
     93            $orderby = 'id';
     94        }
     95
     96        // Whitelist allowed order directions to prevent SQL injection
     97        $order = strtoupper( $order );
     98        if ( ! in_array( $order, [ 'ASC', 'DESC' ], true ) ) {
     99            $order = 'DESC';
     100        }
    63101
    64102        $sql         = [];
  • erp/tags/1.16.11/modules/crm/includes/CLI/Commands.php

    r3071807 r3457039  
    2929
    3030WP_CLI::add_command( 'crm', 'WeDevs\ERP\CRM\CLI\Commands' );
     31
     32// Load seed commands.
     33$seed_dir = __DIR__ . '/Seed';
     34
     35if ( is_dir( $seed_dir ) ) {
     36    // Load base classes first.
     37    $base_files = [ 'AbstractCrmSeeder.php', 'CrmDataProvider.php' ];
     38
     39    foreach ( $base_files as $file ) {
     40        $file_path = $seed_dir . '/' . $file;
     41        if ( file_exists( $file_path ) ) {
     42            require_once $file_path;
     43        }
     44    }
     45
     46    // Load all Seed*.php files, except SeedCommand.php which is loaded separately.
     47    foreach ( glob( $seed_dir . '/Seed*.php' ) as $seed_file ) {
     48        if ( basename( $seed_file ) === 'SeedCommand.php' ) {
     49            continue;
     50        }
     51        require_once $seed_file;
     52    }
     53}
  • erp/tags/1.16.11/modules/hrm/includes/API/AnnouncementsController.php

    r2847329 r3457039  
    143143     */
    144144    public function create_announcement( $request ) {
     145
     146
     147        // Validate recipient_type
     148        $valid_recipient_types = ['all_employee', 'selected_employee'];
     149        if (! in_array($request['recipient_type'], $valid_recipient_types)) {
     150            return new WP_Error(
     151                'rest_invalid_recipient_type',
     152                __('Invalid recipient type. Must be either "all_employee" or "selected_employee".', 'erp'),
     153                ['status' => 400]
     154            );
     155        }
     156
     157        // Validate employees field when recipient_type is selected_employee
     158        if ($request['recipient_type'] === 'selected_employee') {
     159            if (empty($request['employees'])) {
     160                return new WP_Error(
     161                    'rest_missing_employees',
     162                    __('Employees field is required when recipient type is "selected_employee".', 'erp'),
     163                    ['status' => 400]
     164                );
     165            }
     166
     167            // Validate employee IDs
     168            $employees = explode(',', str_replace(' ', '', $request['employees']));
     169            $employees = array_filter(array_map('absint', $employees));
     170
     171            if (empty($employees)) {
     172                return new WP_Error(
     173                    'rest_invalid_employees',
     174                    __('Invalid employee IDs provided.', 'erp'),
     175                    ['status' => 400]
     176                );
     177            }
     178        }
     179
    145180        $item = $this->prepare_item_for_database( $request );
    146181
    147         $id   = wp_insert_post( $item );
     182        $id = wp_insert_post($item);
     183
     184        if (is_wp_error($id)) {
     185            return $id;
     186        }
     187
     188        if (! $id) {
     189            return new WP_Error(
     190                'rest_announcement_create_failed',
     191                __('Failed to create announcement.', 'erp'),
     192                ['status' => 500]
     193            );
     194        }
    148195
    149196        $type = ( $request['recipient_type'] == 'all_employee' ) ? 'all_employee' : 'selected_employee';
     
    185232        }
    186233
     234        // Validate recipient_type
     235        if (isset($request['recipient_type'])) {
     236            $valid_recipient_types = ['all_employee', 'selected_employee'];
     237            if (! in_array($request['recipient_type'], $valid_recipient_types)) {
     238                return new WP_Error(
     239                    'rest_invalid_recipient_type',
     240                    __('Invalid recipient type. Must be either "all_employee" or "selected_employee".', 'erp'),
     241                    ['status' => 400]
     242                );
     243            }
     244
     245            // Validate employees field when recipient_type is selected_employee
     246            if ($request['recipient_type'] === 'selected_employee') {
     247                if (empty($request['employees'])) {
     248                    return new WP_Error(
     249                        'rest_missing_employees',
     250                        __('Employees field is required when recipient type is "selected_employee".', 'erp'),
     251                        ['status' => 400]
     252                    );
     253                }
     254
     255                // Validate employee IDs
     256                $employees = explode(',', str_replace(' ', '', $request['employees']));
     257                $employees = array_filter(array_map('absint', $employees));
     258
     259                if (empty($employees)) {
     260                    return new WP_Error(
     261                        'rest_invalid_employees',
     262                        __('Invalid employee IDs provided.', 'erp'),
     263                        ['status' => 400]
     264                    );
     265                }
     266            }
     267        }
     268
    187269        $item = $this->prepare_item_for_database( $request );
    188270
    189         $id           = wp_insert_post( $item );
     271        $id = wp_insert_post($item);
     272
     273        if (is_wp_error($id)) {
     274            return $id;
     275        }
     276
     277        if (! $id) {
     278            return new WP_Error(
     279                'rest_announcement_update_failed',
     280                __('Failed to update announcement.', 'erp'),
     281                ['status' => 500]
     282            );
     283        }
     284
    190285        $announcement = get_post( $id );
    191286
     
    323418                    'context'     => [ 'edit' ],
    324419                    'arg_options' => [
    325                         'sanitize_callback' => 'sanitize_text_field',
     420                        'sanitize_callback' => 'wp_kses_post',
    326421                    ],
    327422                    'required'    => true,
     
    331426                    'type'        => 'string',
    332427                    'context'     => [ 'edit' ],
     428                    'enum'        => [ 'draft', 'publish', 'pending'],
    333429                    'arg_options' => [
    334430                        'sanitize_callback' => 'sanitize_text_field',
     
    339435                    'type'        => 'string',
    340436                    'context'     => [ 'edit' ],
     437                    'enum'        => ['all_employee', 'selected_employee'],
    341438                    'arg_options' => [
    342439                        'sanitize_callback' => 'sanitize_text_field',
     
    344441                    'required'    => true,
    345442                ],
     443                'employees'       => [
     444                    'description' => __('Comma-separated employee IDs (required when recipient_type is selected_employee).', 'erp'),
     445                    'type'        => 'string',
     446                    'context'     => ['edit'],
     447                    'arg_options' => [
     448                        'sanitize_callback' => 'sanitize_text_field',
     449                    ],
     450                ],
    346451            ],
    347452        ];
  • erp/tags/1.16.11/modules/hrm/includes/API/EmployeesController.php

    r3364496 r3457039  
    88use WeDevs\ERP\HRM\Models\Department;
    99use WeDevs\ERP\HRM\Models\Designation;
     10use WeDevs\ERP\Admin\Models\CompanyLocations;
    1011use WP_Error;
    1112use WP_REST_Request;
     
    466467        foreach ( $items as $item ) {
    467468            $additional_fields = [];
    468             $data              = $this->prepare_item_for_response( $item, $request, $additional_fields );
     469
     470
     471            $data = $this->prepare_item_for_response($item, $request, $additional_fields);
     472
    469473            $formatted_items[] = $this->prepare_response_for_collection( $data );
    470474        }
     475
    471476        $response = rest_ensure_response( $formatted_items );
     477
    472478        $response = $this->format_collection_response( $response, $request, (int) $total_items );
    473479
     
    12301236        );
    12311237
    1232         if ( ! is_wp_error( $request_id ) ) {
    1233             // notification email
    1234             $emailer = wperp()->emailer->get_email( 'NewLeaveRequest' );
    1235 
    1236             if ( is_a( $emailer, '\WeDevs\ERP\Email' ) ) {
    1237                 $emailer->trigger( $request_id );
    1238             }
     1238        if (is_wp_error($request_id)) {
     1239            return $request_id;
     1240        }
     1241
     1242        $emailer = wperp()->emailer->get_email('NewLeaveRequest');
     1243
     1244        if (is_a($emailer, '\WeDevs\ERP\Email')) {
     1245            $emailer->trigger($request_id);
    12391246        }
    12401247
    12411248        $response = rest_ensure_response( $request_id );
     1249
    12421250        $response->set_status( 201 );
    12431251        $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $request_id ) ) );
     
    14631471
    14641472    /**
     1473     * Format options array to consistent structure
     1474     *
     1475     * @param array $options Raw options array
     1476     *
     1477     * @return array
     1478     */
     1479    protected function format_enum_options($options) {
     1480        $formatted = [];
     1481
     1482        foreach ($options as $key => $label) {
     1483            $formatted[] = [
     1484                'value' => $key,
     1485                'label' => $label,
     1486            ];
     1487        }
     1488
     1489        return $formatted;
     1490    }
     1491
     1492    /**
     1493     * Add human-readable labels for enum fields
     1494     *
     1495     * @param array    $data Employee data
     1496     * @param Employee $item Employee object
     1497     *
     1498     * @return array
     1499     */
     1500    protected function add_enum_labels($data, Employee $item) {
     1501        $enum_fields = [
     1502            'pay_type'       => [
     1503                'getter' => 'erp_hr_get_pay_type',
     1504                'method' => null,
     1505            ],
     1506            'hiring_source'  => [
     1507                'getter' => 'erp_hr_get_hiring_sources',
     1508                'method' => 'get_hiring_source',
     1509            ],
     1510            'type'           => [
     1511                'getter' => 'erp_hr_get_employee_types',
     1512                'method' => 'get_type',
     1513            ],
     1514            'status'         => [
     1515                'getter' => 'erp_hr_get_employee_statuses',
     1516                'method' => 'get_status',
     1517            ],
     1518            'gender'         => [
     1519                'getter' => 'erp_hr_get_genders',
     1520                'method' => 'get_gender',
     1521            ],
     1522            'marital_status' => [
     1523                'getter' => 'erp_hr_get_marital_statuses',
     1524                'method' => 'get_marital_status',
     1525            ],
     1526            'blood_group'    => [
     1527                'getter' => 'erp_hr_get_blood_groups',
     1528                'method' => 'get_bloog_group',
     1529            ],
     1530        ];
     1531
     1532        foreach ($enum_fields as $field_key => $config) {
     1533            // Skip if field is empty or has default value
     1534            if (empty($data[$field_key]) || $data[$field_key] === '-1') {
     1535                continue;
     1536            }
     1537
     1538            // Get label for the current value
     1539            $label = '';
     1540            if (! empty($config['method']) && method_exists($item, $config['method'])) {
     1541                $label = $item->{$config['method']}('view');
     1542            } else {
     1543                // Fallback to getting from options array
     1544                $options = function_exists($config['getter']) ? call_user_func($config['getter']) : [];
     1545                if (isset($options[$data[$field_key]])) {
     1546                    $label = $options[$data[$field_key]];
     1547                }
     1548            }
     1549
     1550            // Always add label in the same consistent format
     1551            $data[$field_key . '_label'] = $label;
     1552        }
     1553
     1554        return $data;
     1555    }
     1556
     1557    /**
     1558     * Add enum field options when explicitly requested
     1559     *
     1560     * @param array $data Employee data
     1561     *
     1562     * @return array
     1563     */
     1564    protected function add_enum_options($data) {
     1565        $enum_getters = [
     1566            'pay_type'       => 'erp_hr_get_pay_type',
     1567            'hiring_source'  => 'erp_hr_get_hiring_sources',
     1568            'type'           => 'erp_hr_get_employee_types',
     1569            'status'         => 'erp_hr_get_employee_statuses',
     1570            'gender'         => 'erp_hr_get_genders',
     1571            'marital_status' => 'erp_hr_get_marital_statuses',
     1572            'blood_group'    => 'erp_hr_get_blood_groups',
     1573        ];
     1574
     1575        foreach ($enum_getters as $field_key => $getter) {
     1576            if (function_exists($getter)) {
     1577                $options = call_user_func($getter);
     1578                $data[$field_key . '_options'] = $this->format_enum_options($options);
     1579            }
     1580        }
     1581
     1582        return $data;
     1583    }
     1584
     1585    /**
    14651586     * Prepare a single user output for response
    14661587     *
    1467      * @param array $additional_fields
     1588     * @param Employee        $item              Employee object
     1589     * @param WP_REST_Request $request           Request object
     1590     * @param array           $additional_fields Additional fields
    14681591     *
    14691592     * @return mixed|object|WP_REST_Response
     
    15061629        ];
    15071630
    1508         $data = wp_parse_args( $item->get_data( [], true ), $default );
     1631        $data = $item->get_data([], true);
     1632
     1633        // Clean up any numeric keys that may have been added
     1634        $data = array_filter($data, function ($key) {
     1635            return !is_numeric($key) || $key === 'user_id' || $key === 'employee_id';
     1636        }, ARRAY_FILTER_USE_KEY);
     1637
     1638        // Merge with defaults
     1639        $data = wp_parse_args($data, $default);
     1640
     1641        // Clean up complex objects that shouldn't be serialized
     1642        foreach ($data as $key => $value) {
     1643            // Convert Eloquent Collections to arrays
     1644            if ($value instanceof \Illuminate\Database\Eloquent\Collection) {
     1645                $data[$key] = $value->first() ? $value->first()->id : 0;
     1646            }
     1647
     1648            // Convert WP_REST_Response objects to their data
     1649            if ($value instanceof \WP_REST_Response) {
     1650                $data[$key] = $value->get_data()['user_id'] ?? 0;
     1651            }
     1652
     1653            // Remove empty string values from numeric keys
     1654            if (is_numeric($key) && empty($value)) {
     1655                unset($data[$key]);
     1656            }
     1657        }
     1658
     1659        // Merge additional fields
     1660        $data = array_merge($data, $additional_fields);
     1661
     1662        // Final cleanup of numeric keys
     1663        $data = array_filter($data, function ($key) {
     1664            return !is_numeric($key);
     1665        }, ARRAY_FILTER_USE_KEY);
     1666
     1667        // Always add human-readable labels for enum fields
     1668        // $data = $this->add_enum_labels($data, $item);
    15091669
    15101670        if ( isset( $request['include'] ) ) {
     
    15341694                $data['roles'] = $item->get_roles();
    15351695            }
    1536         }
    1537 
    1538         $data = array_merge( $data, $additional_fields );
     1696
     1697             if ( in_array( 'location', $include_params ) && ! empty( $item->get_location() ) ) {
     1698                $data['location'] = CompanyLocations::all([
     1699                    'name', 'address_1', 'address_2', 'city', 'state', 'zip', 'country'
     1700                ]);
     1701            }
     1702
     1703            if (in_array('enum_options', $include_params)) {
     1704                $data = $this->add_enum_options($data);
     1705            }
     1706        }
     1707
     1708        $data = array_merge($data, $additional_fields);
    15391709
    15401710        // Wrap the data in a response object
  • erp/tags/1.16.11/modules/hrm/includes/CLI/Commands.php

    r3071807 r3457039  
    88/**
    99 * HRM CLI class
     10 */
     11
     12/**
     13 * HRM CLI Commands
     14 * # Master command - seeds everything
     15 *    wp hr clean
     16 *    wp hr seed
     17
     18 *   # With options
     19 *   wp hr seed --employees=100 --clean-first
     20 *   wp hr seed --skip=shifts,attendance,training,assets,payroll
     21 *   wp hr seed --only=financial-years,departments,designations,employees
     22 *
     23 *  # Individual seeders
     24 *   wp hr seed:financial-years
     25 *   wp hr seed:departments
     26 *   wp hr seed:designations
     27 *   wp hr seed:employees
     28 *   wp hr seed:leave-types
     29 *   wp hr seed:leave-policies
     30 *   wp hr seed:leave-entitlements
     31 *   wp hr seed:leave-requests
     32 *   wp hr seed:leave-approvals
     33 *   wp hr seed:holidays
     34 *   wp hr seed:shifts
     35 *   wp hr seed:attendance
     36 *   wp hr seed:training
     37 *   wp hr seed:assets
     38 *   wp hr seed:payroll
     39 *   wp hr seed:announcements
     40
     41 *  # Clean data
     42 *  wp hr clean
    1043 */
    1144class Commands extends WP_CLI_Command {
     
    2255
    2356        $tables = [
     57            'erp_hr_financial_years',
    2458            'erp_hr_depts',
    2559            'erp_hr_designations',
     
    4882
    4983WP_CLI::add_command( 'hr', 'WeDevs\ERP\HRM\CLI\Commands' );
     84
     85// Auto-load seed files
     86$seed_dir = __DIR__ . '/Seed';
     87if (is_dir($seed_dir)) {
     88    require_once $seed_dir . '/DataProvider.php';
     89    require_once $seed_dir . '/AbstractSeeder.php';
     90
     91    // Load master seed command first
     92    if (file_exists($seed_dir . '/SeedCommand.php')) {
     93        require_once $seed_dir . '/SeedCommand.php';
     94    }
     95
     96    // Load all other seed files
     97    foreach (glob($seed_dir . '/Seed*.php') as $file) {
     98        if (basename($file) !== 'SeedCommand.php') {
     99            require_once $file;
     100        }
     101    }
     102}
  • erp/tags/1.16.11/modules/hrm/includes/Employee.php

    r3364496 r3457039  
    209209                }
    210210                $this->data['personal']['full_name'] = $this->get_full_name();
     211                $this->data['personal']['photo_id'] = $this->get_photo_id();
    211212            }
    212213        }
  • erp/tags/1.16.11/readme.txt

    r3439385 r3457039  
    44Tags:  HR, CRM, Accounting, WooCommerce CRM, Recruitment, Job Listings, Inventory, ERP, Employee management, Leave management, Attendance, Reimbursement, WooCommerce Accounting, Document manager, Custom field builder, CRM integration
    55Requires at least: 5.6
    6 Tested up to: 6.9
     6Tested up to: 6.9.1
    77Requires PHP: 7.4
    8 Stable tag: 1.16.10
     8Stable tag: 1.16.11
    99License: GPLv2
    1010License: GPLv2 or later
     
    327327
    328328== Changelog ==
     329
     330= v1.16.11 → February 9, 2026
     331--------------------------
     332* [Fixed] Announcement API formating [#1542](https://github.com/wp-erp/wp-erp/pull/1542).
     333* [Fixed] Announcement API validation [#1544](https://github.com/wp-erp/wp-erp/pull/1544).
     334* [Fixed] Employee API photo id not showing [#1546](https://github.com/wp-erp/wp-erp/pull/1545).
     335* [Enhancement] Employee API meta data status [#1546](https://github.com/wp-erp/wp-erp/pull/1546).
     336* [Added] CRM CLI seeders for contacts, companies, activities, deals [#1548](https://github.com/wp-erp/wp-erp/pull/1548).
     337* [Added] HRM CLI seeders for demo data generation [#1549](https://github.com/wp-erp/wp-erp/pull/1549).
     338* [Fixed] Fix SQL injection in CRM contacts orderby parameter (#1550)(https://github.com/wp-erp/wp-erp/pull/1550).
    329339
    330340= v1.16.10 → January 14, 2026
  • erp/tags/1.16.11/vendor/autoload.php

    r3439387 r3457039  
    55require_once __DIR__ . '/composer/autoload_real.php';
    66
    7 return ComposerAutoloaderInit5f0587bf3efb7d54ac8e72b21db5ce48::getLoader();
     7return ComposerAutoloaderInit682261ccab0954ac517aab25221b14f9::getLoader();
  • erp/tags/1.16.11/vendor/composer/autoload_classmap.php

    r3221972 r3457039  
    12931293    'WeDevs\\ERP\\CRM\\AjaxHandler' => $baseDir . '/modules/crm/includes/AjaxHandler.php',
    12941294    'WeDevs\\ERP\\CRM\\CLI\\Commands' => $baseDir . '/modules/crm/includes/CLI/Commands.php',
     1295    'WeDevs\\ERP\\CRM\\CLI\\Seed\\AbstractCrmSeeder' => $baseDir . '/modules/crm/includes/CLI/Seed/AbstractCrmSeeder.php',
     1296    'WeDevs\\ERP\\CRM\\CLI\\Seed\\CrmDataProvider' => $baseDir . '/modules/crm/includes/CLI/Seed/CrmDataProvider.php',
     1297    'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedActivities' => $baseDir . '/modules/crm/includes/CLI/Seed/SeedActivities.php',
     1298    'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedCommand' => $baseDir . '/modules/crm/includes/CLI/Seed/SeedCommand.php',
     1299    'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedCompanies' => $baseDir . '/modules/crm/includes/CLI/Seed/SeedCompanies.php',
     1300    'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedContactGroups' => $baseDir . '/modules/crm/includes/CLI/Seed/SeedContactGroups.php',
     1301    'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedContacts' => $baseDir . '/modules/crm/includes/CLI/Seed/SeedContacts.php',
     1302    'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedDeals' => $baseDir . '/modules/crm/includes/CLI/Seed/SeedDeals.php',
    12951303    'WeDevs\\ERP\\CRM\\CampaignListTable' => $baseDir . '/modules/crm/includes/CampaignListTable.php',
    12961304    'WeDevs\\ERP\\CRM\\Contact' => $baseDir . '/modules/crm/includes/Contact.php',
     
    13571365    'WeDevs\\ERP\\HRM\\AnnouncementListTable' => $baseDir . '/modules/hrm/includes/AnnouncementListTable.php',
    13581366    'WeDevs\\ERP\\HRM\\CLI\\Commands' => $baseDir . '/modules/hrm/includes/CLI/Commands.php',
     1367    'WeDevs\\ERP\\HRM\\CLI\\Seed\\AbstractSeeder' => $baseDir . '/modules/hrm/includes/CLI/Seed/AbstractSeeder.php',
     1368    'WeDevs\\ERP\\HRM\\CLI\\Seed\\DataProvider' => $baseDir . '/modules/hrm/includes/CLI/Seed/DataProvider.php',
     1369    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedAnnouncements' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedAnnouncements.php',
     1370    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedAssets' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedAssets.php',
     1371    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedAttendance' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedAttendance.php',
     1372    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedCommand' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedCommand.php',
     1373    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedDepartments' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedDepartments.php',
     1374    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedDesignations' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedDesignations.php',
     1375    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedEmployees' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedEmployees.php',
     1376    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedFinancialYears' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedFinancialYears.php',
     1377    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedHolidays' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedHolidays.php',
     1378    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveApprovals' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedLeaveApprovals.php',
     1379    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveEntitlements' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedLeaveEntitlements.php',
     1380    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeavePolicies' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedLeavePolicies.php',
     1381    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveRequests' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedLeaveRequests.php',
     1382    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveTypes' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedLeaveTypes.php',
     1383    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedPayroll' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedPayroll.php',
     1384    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedShifts' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedShifts.php',
     1385    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedTraining' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedTraining.php',
    13591386    'WeDevs\\ERP\\HRM\\Department' => $baseDir . '/modules/hrm/includes/Department.php',
    13601387    'WeDevs\\ERP\\HRM\\DepartmentListTable' => $baseDir . '/modules/hrm/includes/DepartmentListTable.php',
  • erp/tags/1.16.11/vendor/composer/autoload_real.php

    r3439387 r3457039  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit5f0587bf3efb7d54ac8e72b21db5ce48
     5class ComposerAutoloaderInit682261ccab0954ac517aab25221b14f9
    66{
    77    private static $loader;
     
    2525        require __DIR__ . '/platform_check.php';
    2626
    27         spl_autoload_register(array('ComposerAutoloaderInit5f0587bf3efb7d54ac8e72b21db5ce48', 'loadClassLoader'), true, true);
     27        spl_autoload_register(array('ComposerAutoloaderInit682261ccab0954ac517aab25221b14f9', 'loadClassLoader'), true, true);
    2828        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
    29         spl_autoload_unregister(array('ComposerAutoloaderInit5f0587bf3efb7d54ac8e72b21db5ce48', 'loadClassLoader'));
     29        spl_autoload_unregister(array('ComposerAutoloaderInit682261ccab0954ac517aab25221b14f9', 'loadClassLoader'));
    3030
    3131        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
     
    3333            require __DIR__ . '/autoload_static.php';
    3434
    35             call_user_func(\Composer\Autoload\ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48::getInitializer($loader));
     35            call_user_func(\Composer\Autoload\ComposerStaticInit682261ccab0954ac517aab25221b14f9::getInitializer($loader));
    3636        } else {
    3737            $map = require __DIR__ . '/autoload_namespaces.php';
     
    5454
    5555        if ($useStaticLoader) {
    56             $includeFiles = Composer\Autoload\ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48::$files;
     56            $includeFiles = Composer\Autoload\ComposerStaticInit682261ccab0954ac517aab25221b14f9::$files;
    5757        } else {
    5858            $includeFiles = require __DIR__ . '/autoload_files.php';
    5959        }
    6060        foreach ($includeFiles as $fileIdentifier => $file) {
    61             composerRequire5f0587bf3efb7d54ac8e72b21db5ce48($fileIdentifier, $file);
     61            composerRequire682261ccab0954ac517aab25221b14f9($fileIdentifier, $file);
    6262        }
    6363
     
    7171 * @return void
    7272 */
    73 function composerRequire5f0587bf3efb7d54ac8e72b21db5ce48($fileIdentifier, $file)
     73function composerRequire682261ccab0954ac517aab25221b14f9($fileIdentifier, $file)
    7474{
    7575    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
  • erp/tags/1.16.11/vendor/composer/autoload_static.php

    r3439387 r3457039  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48
     7class ComposerStaticInit682261ccab0954ac517aab25221b14f9
    88{
    99    public static $files = array (
     
    16891689        'WeDevs\\ERP\\CRM\\AjaxHandler' => __DIR__ . '/../..' . '/modules/crm/includes/AjaxHandler.php',
    16901690        'WeDevs\\ERP\\CRM\\CLI\\Commands' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Commands.php',
     1691        'WeDevs\\ERP\\CRM\\CLI\\Seed\\AbstractCrmSeeder' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/AbstractCrmSeeder.php',
     1692        'WeDevs\\ERP\\CRM\\CLI\\Seed\\CrmDataProvider' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/CrmDataProvider.php',
     1693        'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedActivities' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/SeedActivities.php',
     1694        'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedCommand' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/SeedCommand.php',
     1695        'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedCompanies' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/SeedCompanies.php',
     1696        'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedContactGroups' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/SeedContactGroups.php',
     1697        'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedContacts' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/SeedContacts.php',
     1698        'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedDeals' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/SeedDeals.php',
    16911699        'WeDevs\\ERP\\CRM\\CampaignListTable' => __DIR__ . '/../..' . '/modules/crm/includes/CampaignListTable.php',
    16921700        'WeDevs\\ERP\\CRM\\Contact' => __DIR__ . '/../..' . '/modules/crm/includes/Contact.php',
     
    17531761        'WeDevs\\ERP\\HRM\\AnnouncementListTable' => __DIR__ . '/../..' . '/modules/hrm/includes/AnnouncementListTable.php',
    17541762        'WeDevs\\ERP\\HRM\\CLI\\Commands' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Commands.php',
     1763        'WeDevs\\ERP\\HRM\\CLI\\Seed\\AbstractSeeder' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/AbstractSeeder.php',
     1764        'WeDevs\\ERP\\HRM\\CLI\\Seed\\DataProvider' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/DataProvider.php',
     1765        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedAnnouncements' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedAnnouncements.php',
     1766        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedAssets' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedAssets.php',
     1767        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedAttendance' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedAttendance.php',
     1768        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedCommand' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedCommand.php',
     1769        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedDepartments' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedDepartments.php',
     1770        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedDesignations' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedDesignations.php',
     1771        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedEmployees' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedEmployees.php',
     1772        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedFinancialYears' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedFinancialYears.php',
     1773        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedHolidays' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedHolidays.php',
     1774        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveApprovals' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedLeaveApprovals.php',
     1775        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveEntitlements' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedLeaveEntitlements.php',
     1776        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeavePolicies' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedLeavePolicies.php',
     1777        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveRequests' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedLeaveRequests.php',
     1778        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveTypes' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedLeaveTypes.php',
     1779        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedPayroll' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedPayroll.php',
     1780        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedShifts' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedShifts.php',
     1781        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedTraining' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedTraining.php',
    17551782        'WeDevs\\ERP\\HRM\\Department' => __DIR__ . '/../..' . '/modules/hrm/includes/Department.php',
    17561783        'WeDevs\\ERP\\HRM\\DepartmentListTable' => __DIR__ . '/../..' . '/modules/hrm/includes/DepartmentListTable.php',
     
    21682195    {
    21692196        return \Closure::bind(function () use ($loader) {
    2170             $loader->prefixLengthsPsr4 = ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48::$prefixLengthsPsr4;
    2171             $loader->prefixDirsPsr4 = ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48::$prefixDirsPsr4;
    2172             $loader->prefixesPsr0 = ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48::$prefixesPsr0;
    2173             $loader->classMap = ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48::$classMap;
     2197            $loader->prefixLengthsPsr4 = ComposerStaticInit682261ccab0954ac517aab25221b14f9::$prefixLengthsPsr4;
     2198            $loader->prefixDirsPsr4 = ComposerStaticInit682261ccab0954ac517aab25221b14f9::$prefixDirsPsr4;
     2199            $loader->prefixesPsr0 = ComposerStaticInit682261ccab0954ac517aab25221b14f9::$prefixesPsr0;
     2200            $loader->classMap = ComposerStaticInit682261ccab0954ac517aab25221b14f9::$classMap;
    21742201
    21752202        }, null, ClassLoader::class);
  • erp/tags/1.16.11/wp-erp.php

    r3439387 r3457039  
    66 * Author: weDevs
    77 * Author URI: https://wedevs.com
    8  * Version: 1.16.10
     8 * Version: 1.16.11
    99 * License: GPL2
    1010 * Text Domain: erp
     
    6161
    6262require_once __DIR__ . '/vendor/autoload.php';
    63 define( 'WPERP_VERSION', '1.16.10' );
     63define( 'WPERP_VERSION', '1.16.11' );
    6464define( 'WPERP_FILE', __FILE__ );
    6565define( 'WPERP_PATH', dirname( WPERP_FILE ) );
  • erp/trunk/includes/API/AnnouncementsController.php

    r2847329 r3457039  
    346346                    'type'        => 'string',
    347347                    'context'     => [ 'edit' ],
     348                    'recipient_type' => [ 'all_employee', 'selected_employee' ],
    348349                    'arg_options' => [
    349350                        'sanitize_callback' => 'sanitize_text_field',
     
    351352                    'required'    => true,
    352353                ],
     354                'employees'      => [
     355                    'description' => __( 'Employees for the resource.', 'erp' ),
     356                    'type'        => 'string',
     357                    'context'     => [ 'edit' ],
     358                    'arg_options' => [
     359                        'sanitize_callback' => 'sanitize_text_field',
     360                    ],
     361                    'required'    => false,
     362                ],
    353363            ],
    354364        ];
  • erp/trunk/includes/functions-people.php

    r3430665 r3457039  
    6161    if ( false === $items ) {
    6262        extract( $args );
     63
     64        // Whitelist allowed orderby columns to prevent SQL injection
     65        $allowed_orderby = [
     66            'id',
     67            'user_id',
     68            'first_name',
     69            'last_name',
     70            'company',
     71            'email',
     72            'phone',
     73            'mobile',
     74            'other',
     75            'website',
     76            'fax',
     77            'notes',
     78            'street_1',
     79            'street_2',
     80            'city',
     81            'state',
     82            'postal_code',
     83            'country',
     84            'currency',
     85            'life_stage',
     86            'contact_owner',
     87            'hash',
     88            'created_by',
     89            'created',
     90        ];
     91
     92        if ( ! in_array( $orderby, $allowed_orderby, true ) ) {
     93            $orderby = 'id';
     94        }
     95
     96        // Whitelist allowed order directions to prevent SQL injection
     97        $order = strtoupper( $order );
     98        if ( ! in_array( $order, [ 'ASC', 'DESC' ], true ) ) {
     99            $order = 'DESC';
     100        }
    63101
    64102        $sql         = [];
  • erp/trunk/modules/crm/includes/CLI/Commands.php

    r3071807 r3457039  
    2929
    3030WP_CLI::add_command( 'crm', 'WeDevs\ERP\CRM\CLI\Commands' );
     31
     32// Load seed commands.
     33$seed_dir = __DIR__ . '/Seed';
     34
     35if ( is_dir( $seed_dir ) ) {
     36    // Load base classes first.
     37    $base_files = [ 'AbstractCrmSeeder.php', 'CrmDataProvider.php' ];
     38
     39    foreach ( $base_files as $file ) {
     40        $file_path = $seed_dir . '/' . $file;
     41        if ( file_exists( $file_path ) ) {
     42            require_once $file_path;
     43        }
     44    }
     45
     46    // Load all Seed*.php files, except SeedCommand.php which is loaded separately.
     47    foreach ( glob( $seed_dir . '/Seed*.php' ) as $seed_file ) {
     48        if ( basename( $seed_file ) === 'SeedCommand.php' ) {
     49            continue;
     50        }
     51        require_once $seed_file;
     52    }
     53}
  • erp/trunk/modules/hrm/includes/API/AnnouncementsController.php

    r2847329 r3457039  
    143143     */
    144144    public function create_announcement( $request ) {
     145
     146
     147        // Validate recipient_type
     148        $valid_recipient_types = ['all_employee', 'selected_employee'];
     149        if (! in_array($request['recipient_type'], $valid_recipient_types)) {
     150            return new WP_Error(
     151                'rest_invalid_recipient_type',
     152                __('Invalid recipient type. Must be either "all_employee" or "selected_employee".', 'erp'),
     153                ['status' => 400]
     154            );
     155        }
     156
     157        // Validate employees field when recipient_type is selected_employee
     158        if ($request['recipient_type'] === 'selected_employee') {
     159            if (empty($request['employees'])) {
     160                return new WP_Error(
     161                    'rest_missing_employees',
     162                    __('Employees field is required when recipient type is "selected_employee".', 'erp'),
     163                    ['status' => 400]
     164                );
     165            }
     166
     167            // Validate employee IDs
     168            $employees = explode(',', str_replace(' ', '', $request['employees']));
     169            $employees = array_filter(array_map('absint', $employees));
     170
     171            if (empty($employees)) {
     172                return new WP_Error(
     173                    'rest_invalid_employees',
     174                    __('Invalid employee IDs provided.', 'erp'),
     175                    ['status' => 400]
     176                );
     177            }
     178        }
     179
    145180        $item = $this->prepare_item_for_database( $request );
    146181
    147         $id   = wp_insert_post( $item );
     182        $id = wp_insert_post($item);
     183
     184        if (is_wp_error($id)) {
     185            return $id;
     186        }
     187
     188        if (! $id) {
     189            return new WP_Error(
     190                'rest_announcement_create_failed',
     191                __('Failed to create announcement.', 'erp'),
     192                ['status' => 500]
     193            );
     194        }
    148195
    149196        $type = ( $request['recipient_type'] == 'all_employee' ) ? 'all_employee' : 'selected_employee';
     
    185232        }
    186233
     234        // Validate recipient_type
     235        if (isset($request['recipient_type'])) {
     236            $valid_recipient_types = ['all_employee', 'selected_employee'];
     237            if (! in_array($request['recipient_type'], $valid_recipient_types)) {
     238                return new WP_Error(
     239                    'rest_invalid_recipient_type',
     240                    __('Invalid recipient type. Must be either "all_employee" or "selected_employee".', 'erp'),
     241                    ['status' => 400]
     242                );
     243            }
     244
     245            // Validate employees field when recipient_type is selected_employee
     246            if ($request['recipient_type'] === 'selected_employee') {
     247                if (empty($request['employees'])) {
     248                    return new WP_Error(
     249                        'rest_missing_employees',
     250                        __('Employees field is required when recipient type is "selected_employee".', 'erp'),
     251                        ['status' => 400]
     252                    );
     253                }
     254
     255                // Validate employee IDs
     256                $employees = explode(',', str_replace(' ', '', $request['employees']));
     257                $employees = array_filter(array_map('absint', $employees));
     258
     259                if (empty($employees)) {
     260                    return new WP_Error(
     261                        'rest_invalid_employees',
     262                        __('Invalid employee IDs provided.', 'erp'),
     263                        ['status' => 400]
     264                    );
     265                }
     266            }
     267        }
     268
    187269        $item = $this->prepare_item_for_database( $request );
    188270
    189         $id           = wp_insert_post( $item );
     271        $id = wp_insert_post($item);
     272
     273        if (is_wp_error($id)) {
     274            return $id;
     275        }
     276
     277        if (! $id) {
     278            return new WP_Error(
     279                'rest_announcement_update_failed',
     280                __('Failed to update announcement.', 'erp'),
     281                ['status' => 500]
     282            );
     283        }
     284
    190285        $announcement = get_post( $id );
    191286
     
    323418                    'context'     => [ 'edit' ],
    324419                    'arg_options' => [
    325                         'sanitize_callback' => 'sanitize_text_field',
     420                        'sanitize_callback' => 'wp_kses_post',
    326421                    ],
    327422                    'required'    => true,
     
    331426                    'type'        => 'string',
    332427                    'context'     => [ 'edit' ],
     428                    'enum'        => [ 'draft', 'publish', 'pending'],
    333429                    'arg_options' => [
    334430                        'sanitize_callback' => 'sanitize_text_field',
     
    339435                    'type'        => 'string',
    340436                    'context'     => [ 'edit' ],
     437                    'enum'        => ['all_employee', 'selected_employee'],
    341438                    'arg_options' => [
    342439                        'sanitize_callback' => 'sanitize_text_field',
     
    344441                    'required'    => true,
    345442                ],
     443                'employees'       => [
     444                    'description' => __('Comma-separated employee IDs (required when recipient_type is selected_employee).', 'erp'),
     445                    'type'        => 'string',
     446                    'context'     => ['edit'],
     447                    'arg_options' => [
     448                        'sanitize_callback' => 'sanitize_text_field',
     449                    ],
     450                ],
    346451            ],
    347452        ];
  • erp/trunk/modules/hrm/includes/API/EmployeesController.php

    r3364496 r3457039  
    88use WeDevs\ERP\HRM\Models\Department;
    99use WeDevs\ERP\HRM\Models\Designation;
     10use WeDevs\ERP\Admin\Models\CompanyLocations;
    1011use WP_Error;
    1112use WP_REST_Request;
     
    466467        foreach ( $items as $item ) {
    467468            $additional_fields = [];
    468             $data              = $this->prepare_item_for_response( $item, $request, $additional_fields );
     469
     470
     471            $data = $this->prepare_item_for_response($item, $request, $additional_fields);
     472
    469473            $formatted_items[] = $this->prepare_response_for_collection( $data );
    470474        }
     475
    471476        $response = rest_ensure_response( $formatted_items );
     477
    472478        $response = $this->format_collection_response( $response, $request, (int) $total_items );
    473479
     
    12301236        );
    12311237
    1232         if ( ! is_wp_error( $request_id ) ) {
    1233             // notification email
    1234             $emailer = wperp()->emailer->get_email( 'NewLeaveRequest' );
    1235 
    1236             if ( is_a( $emailer, '\WeDevs\ERP\Email' ) ) {
    1237                 $emailer->trigger( $request_id );
    1238             }
     1238        if (is_wp_error($request_id)) {
     1239            return $request_id;
     1240        }
     1241
     1242        $emailer = wperp()->emailer->get_email('NewLeaveRequest');
     1243
     1244        if (is_a($emailer, '\WeDevs\ERP\Email')) {
     1245            $emailer->trigger($request_id);
    12391246        }
    12401247
    12411248        $response = rest_ensure_response( $request_id );
     1249
    12421250        $response->set_status( 201 );
    12431251        $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $request_id ) ) );
     
    14631471
    14641472    /**
     1473     * Format options array to consistent structure
     1474     *
     1475     * @param array $options Raw options array
     1476     *
     1477     * @return array
     1478     */
     1479    protected function format_enum_options($options) {
     1480        $formatted = [];
     1481
     1482        foreach ($options as $key => $label) {
     1483            $formatted[] = [
     1484                'value' => $key,
     1485                'label' => $label,
     1486            ];
     1487        }
     1488
     1489        return $formatted;
     1490    }
     1491
     1492    /**
     1493     * Add human-readable labels for enum fields
     1494     *
     1495     * @param array    $data Employee data
     1496     * @param Employee $item Employee object
     1497     *
     1498     * @return array
     1499     */
     1500    protected function add_enum_labels($data, Employee $item) {
     1501        $enum_fields = [
     1502            'pay_type'       => [
     1503                'getter' => 'erp_hr_get_pay_type',
     1504                'method' => null,
     1505            ],
     1506            'hiring_source'  => [
     1507                'getter' => 'erp_hr_get_hiring_sources',
     1508                'method' => 'get_hiring_source',
     1509            ],
     1510            'type'           => [
     1511                'getter' => 'erp_hr_get_employee_types',
     1512                'method' => 'get_type',
     1513            ],
     1514            'status'         => [
     1515                'getter' => 'erp_hr_get_employee_statuses',
     1516                'method' => 'get_status',
     1517            ],
     1518            'gender'         => [
     1519                'getter' => 'erp_hr_get_genders',
     1520                'method' => 'get_gender',
     1521            ],
     1522            'marital_status' => [
     1523                'getter' => 'erp_hr_get_marital_statuses',
     1524                'method' => 'get_marital_status',
     1525            ],
     1526            'blood_group'    => [
     1527                'getter' => 'erp_hr_get_blood_groups',
     1528                'method' => 'get_bloog_group',
     1529            ],
     1530        ];
     1531
     1532        foreach ($enum_fields as $field_key => $config) {
     1533            // Skip if field is empty or has default value
     1534            if (empty($data[$field_key]) || $data[$field_key] === '-1') {
     1535                continue;
     1536            }
     1537
     1538            // Get label for the current value
     1539            $label = '';
     1540            if (! empty($config['method']) && method_exists($item, $config['method'])) {
     1541                $label = $item->{$config['method']}('view');
     1542            } else {
     1543                // Fallback to getting from options array
     1544                $options = function_exists($config['getter']) ? call_user_func($config['getter']) : [];
     1545                if (isset($options[$data[$field_key]])) {
     1546                    $label = $options[$data[$field_key]];
     1547                }
     1548            }
     1549
     1550            // Always add label in the same consistent format
     1551            $data[$field_key . '_label'] = $label;
     1552        }
     1553
     1554        return $data;
     1555    }
     1556
     1557    /**
     1558     * Add enum field options when explicitly requested
     1559     *
     1560     * @param array $data Employee data
     1561     *
     1562     * @return array
     1563     */
     1564    protected function add_enum_options($data) {
     1565        $enum_getters = [
     1566            'pay_type'       => 'erp_hr_get_pay_type',
     1567            'hiring_source'  => 'erp_hr_get_hiring_sources',
     1568            'type'           => 'erp_hr_get_employee_types',
     1569            'status'         => 'erp_hr_get_employee_statuses',
     1570            'gender'         => 'erp_hr_get_genders',
     1571            'marital_status' => 'erp_hr_get_marital_statuses',
     1572            'blood_group'    => 'erp_hr_get_blood_groups',
     1573        ];
     1574
     1575        foreach ($enum_getters as $field_key => $getter) {
     1576            if (function_exists($getter)) {
     1577                $options = call_user_func($getter);
     1578                $data[$field_key . '_options'] = $this->format_enum_options($options);
     1579            }
     1580        }
     1581
     1582        return $data;
     1583    }
     1584
     1585    /**
    14651586     * Prepare a single user output for response
    14661587     *
    1467      * @param array $additional_fields
     1588     * @param Employee        $item              Employee object
     1589     * @param WP_REST_Request $request           Request object
     1590     * @param array           $additional_fields Additional fields
    14681591     *
    14691592     * @return mixed|object|WP_REST_Response
     
    15061629        ];
    15071630
    1508         $data = wp_parse_args( $item->get_data( [], true ), $default );
     1631        $data = $item->get_data([], true);
     1632
     1633        // Clean up any numeric keys that may have been added
     1634        $data = array_filter($data, function ($key) {
     1635            return !is_numeric($key) || $key === 'user_id' || $key === 'employee_id';
     1636        }, ARRAY_FILTER_USE_KEY);
     1637
     1638        // Merge with defaults
     1639        $data = wp_parse_args($data, $default);
     1640
     1641        // Clean up complex objects that shouldn't be serialized
     1642        foreach ($data as $key => $value) {
     1643            // Convert Eloquent Collections to arrays
     1644            if ($value instanceof \Illuminate\Database\Eloquent\Collection) {
     1645                $data[$key] = $value->first() ? $value->first()->id : 0;
     1646            }
     1647
     1648            // Convert WP_REST_Response objects to their data
     1649            if ($value instanceof \WP_REST_Response) {
     1650                $data[$key] = $value->get_data()['user_id'] ?? 0;
     1651            }
     1652
     1653            // Remove empty string values from numeric keys
     1654            if (is_numeric($key) && empty($value)) {
     1655                unset($data[$key]);
     1656            }
     1657        }
     1658
     1659        // Merge additional fields
     1660        $data = array_merge($data, $additional_fields);
     1661
     1662        // Final cleanup of numeric keys
     1663        $data = array_filter($data, function ($key) {
     1664            return !is_numeric($key);
     1665        }, ARRAY_FILTER_USE_KEY);
     1666
     1667        // Always add human-readable labels for enum fields
     1668        // $data = $this->add_enum_labels($data, $item);
    15091669
    15101670        if ( isset( $request['include'] ) ) {
     
    15341694                $data['roles'] = $item->get_roles();
    15351695            }
    1536         }
    1537 
    1538         $data = array_merge( $data, $additional_fields );
     1696
     1697             if ( in_array( 'location', $include_params ) && ! empty( $item->get_location() ) ) {
     1698                $data['location'] = CompanyLocations::all([
     1699                    'name', 'address_1', 'address_2', 'city', 'state', 'zip', 'country'
     1700                ]);
     1701            }
     1702
     1703            if (in_array('enum_options', $include_params)) {
     1704                $data = $this->add_enum_options($data);
     1705            }
     1706        }
     1707
     1708        $data = array_merge($data, $additional_fields);
    15391709
    15401710        // Wrap the data in a response object
  • erp/trunk/modules/hrm/includes/CLI/Commands.php

    r3071807 r3457039  
    88/**
    99 * HRM CLI class
     10 */
     11
     12/**
     13 * HRM CLI Commands
     14 * # Master command - seeds everything
     15 *    wp hr clean
     16 *    wp hr seed
     17
     18 *   # With options
     19 *   wp hr seed --employees=100 --clean-first
     20 *   wp hr seed --skip=shifts,attendance,training,assets,payroll
     21 *   wp hr seed --only=financial-years,departments,designations,employees
     22 *
     23 *  # Individual seeders
     24 *   wp hr seed:financial-years
     25 *   wp hr seed:departments
     26 *   wp hr seed:designations
     27 *   wp hr seed:employees
     28 *   wp hr seed:leave-types
     29 *   wp hr seed:leave-policies
     30 *   wp hr seed:leave-entitlements
     31 *   wp hr seed:leave-requests
     32 *   wp hr seed:leave-approvals
     33 *   wp hr seed:holidays
     34 *   wp hr seed:shifts
     35 *   wp hr seed:attendance
     36 *   wp hr seed:training
     37 *   wp hr seed:assets
     38 *   wp hr seed:payroll
     39 *   wp hr seed:announcements
     40
     41 *  # Clean data
     42 *  wp hr clean
    1043 */
    1144class Commands extends WP_CLI_Command {
     
    2255
    2356        $tables = [
     57            'erp_hr_financial_years',
    2458            'erp_hr_depts',
    2559            'erp_hr_designations',
     
    4882
    4983WP_CLI::add_command( 'hr', 'WeDevs\ERP\HRM\CLI\Commands' );
     84
     85// Auto-load seed files
     86$seed_dir = __DIR__ . '/Seed';
     87if (is_dir($seed_dir)) {
     88    require_once $seed_dir . '/DataProvider.php';
     89    require_once $seed_dir . '/AbstractSeeder.php';
     90
     91    // Load master seed command first
     92    if (file_exists($seed_dir . '/SeedCommand.php')) {
     93        require_once $seed_dir . '/SeedCommand.php';
     94    }
     95
     96    // Load all other seed files
     97    foreach (glob($seed_dir . '/Seed*.php') as $file) {
     98        if (basename($file) !== 'SeedCommand.php') {
     99            require_once $file;
     100        }
     101    }
     102}
  • erp/trunk/modules/hrm/includes/Employee.php

    r3364496 r3457039  
    209209                }
    210210                $this->data['personal']['full_name'] = $this->get_full_name();
     211                $this->data['personal']['photo_id'] = $this->get_photo_id();
    211212            }
    212213        }
  • erp/trunk/readme.txt

    r3439385 r3457039  
    44Tags:  HR, CRM, Accounting, WooCommerce CRM, Recruitment, Job Listings, Inventory, ERP, Employee management, Leave management, Attendance, Reimbursement, WooCommerce Accounting, Document manager, Custom field builder, CRM integration
    55Requires at least: 5.6
    6 Tested up to: 6.9
     6Tested up to: 6.9.1
    77Requires PHP: 7.4
    8 Stable tag: 1.16.10
     8Stable tag: 1.16.11
    99License: GPLv2
    1010License: GPLv2 or later
     
    327327
    328328== Changelog ==
     329
     330= v1.16.11 → February 9, 2026
     331--------------------------
     332* [Fixed] Announcement API formating [#1542](https://github.com/wp-erp/wp-erp/pull/1542).
     333* [Fixed] Announcement API validation [#1544](https://github.com/wp-erp/wp-erp/pull/1544).
     334* [Fixed] Employee API photo id not showing [#1546](https://github.com/wp-erp/wp-erp/pull/1545).
     335* [Enhancement] Employee API meta data status [#1546](https://github.com/wp-erp/wp-erp/pull/1546).
     336* [Added] CRM CLI seeders for contacts, companies, activities, deals [#1548](https://github.com/wp-erp/wp-erp/pull/1548).
     337* [Added] HRM CLI seeders for demo data generation [#1549](https://github.com/wp-erp/wp-erp/pull/1549).
     338* [Fixed] Fix SQL injection in CRM contacts orderby parameter (#1550)(https://github.com/wp-erp/wp-erp/pull/1550).
    329339
    330340= v1.16.10 → January 14, 2026
  • erp/trunk/vendor/autoload.php

    r3439387 r3457039  
    55require_once __DIR__ . '/composer/autoload_real.php';
    66
    7 return ComposerAutoloaderInit5f0587bf3efb7d54ac8e72b21db5ce48::getLoader();
     7return ComposerAutoloaderInit682261ccab0954ac517aab25221b14f9::getLoader();
  • erp/trunk/vendor/composer/autoload_classmap.php

    r3221972 r3457039  
    12931293    'WeDevs\\ERP\\CRM\\AjaxHandler' => $baseDir . '/modules/crm/includes/AjaxHandler.php',
    12941294    'WeDevs\\ERP\\CRM\\CLI\\Commands' => $baseDir . '/modules/crm/includes/CLI/Commands.php',
     1295    'WeDevs\\ERP\\CRM\\CLI\\Seed\\AbstractCrmSeeder' => $baseDir . '/modules/crm/includes/CLI/Seed/AbstractCrmSeeder.php',
     1296    'WeDevs\\ERP\\CRM\\CLI\\Seed\\CrmDataProvider' => $baseDir . '/modules/crm/includes/CLI/Seed/CrmDataProvider.php',
     1297    'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedActivities' => $baseDir . '/modules/crm/includes/CLI/Seed/SeedActivities.php',
     1298    'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedCommand' => $baseDir . '/modules/crm/includes/CLI/Seed/SeedCommand.php',
     1299    'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedCompanies' => $baseDir . '/modules/crm/includes/CLI/Seed/SeedCompanies.php',
     1300    'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedContactGroups' => $baseDir . '/modules/crm/includes/CLI/Seed/SeedContactGroups.php',
     1301    'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedContacts' => $baseDir . '/modules/crm/includes/CLI/Seed/SeedContacts.php',
     1302    'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedDeals' => $baseDir . '/modules/crm/includes/CLI/Seed/SeedDeals.php',
    12951303    'WeDevs\\ERP\\CRM\\CampaignListTable' => $baseDir . '/modules/crm/includes/CampaignListTable.php',
    12961304    'WeDevs\\ERP\\CRM\\Contact' => $baseDir . '/modules/crm/includes/Contact.php',
     
    13571365    'WeDevs\\ERP\\HRM\\AnnouncementListTable' => $baseDir . '/modules/hrm/includes/AnnouncementListTable.php',
    13581366    'WeDevs\\ERP\\HRM\\CLI\\Commands' => $baseDir . '/modules/hrm/includes/CLI/Commands.php',
     1367    'WeDevs\\ERP\\HRM\\CLI\\Seed\\AbstractSeeder' => $baseDir . '/modules/hrm/includes/CLI/Seed/AbstractSeeder.php',
     1368    'WeDevs\\ERP\\HRM\\CLI\\Seed\\DataProvider' => $baseDir . '/modules/hrm/includes/CLI/Seed/DataProvider.php',
     1369    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedAnnouncements' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedAnnouncements.php',
     1370    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedAssets' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedAssets.php',
     1371    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedAttendance' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedAttendance.php',
     1372    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedCommand' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedCommand.php',
     1373    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedDepartments' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedDepartments.php',
     1374    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedDesignations' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedDesignations.php',
     1375    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedEmployees' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedEmployees.php',
     1376    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedFinancialYears' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedFinancialYears.php',
     1377    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedHolidays' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedHolidays.php',
     1378    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveApprovals' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedLeaveApprovals.php',
     1379    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveEntitlements' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedLeaveEntitlements.php',
     1380    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeavePolicies' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedLeavePolicies.php',
     1381    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveRequests' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedLeaveRequests.php',
     1382    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveTypes' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedLeaveTypes.php',
     1383    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedPayroll' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedPayroll.php',
     1384    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedShifts' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedShifts.php',
     1385    'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedTraining' => $baseDir . '/modules/hrm/includes/CLI/Seed/SeedTraining.php',
    13591386    'WeDevs\\ERP\\HRM\\Department' => $baseDir . '/modules/hrm/includes/Department.php',
    13601387    'WeDevs\\ERP\\HRM\\DepartmentListTable' => $baseDir . '/modules/hrm/includes/DepartmentListTable.php',
  • erp/trunk/vendor/composer/autoload_real.php

    r3439387 r3457039  
    33// autoload_real.php @generated by Composer
    44
    5 class ComposerAutoloaderInit5f0587bf3efb7d54ac8e72b21db5ce48
     5class ComposerAutoloaderInit682261ccab0954ac517aab25221b14f9
    66{
    77    private static $loader;
     
    2525        require __DIR__ . '/platform_check.php';
    2626
    27         spl_autoload_register(array('ComposerAutoloaderInit5f0587bf3efb7d54ac8e72b21db5ce48', 'loadClassLoader'), true, true);
     27        spl_autoload_register(array('ComposerAutoloaderInit682261ccab0954ac517aab25221b14f9', 'loadClassLoader'), true, true);
    2828        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
    29         spl_autoload_unregister(array('ComposerAutoloaderInit5f0587bf3efb7d54ac8e72b21db5ce48', 'loadClassLoader'));
     29        spl_autoload_unregister(array('ComposerAutoloaderInit682261ccab0954ac517aab25221b14f9', 'loadClassLoader'));
    3030
    3131        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
     
    3333            require __DIR__ . '/autoload_static.php';
    3434
    35             call_user_func(\Composer\Autoload\ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48::getInitializer($loader));
     35            call_user_func(\Composer\Autoload\ComposerStaticInit682261ccab0954ac517aab25221b14f9::getInitializer($loader));
    3636        } else {
    3737            $map = require __DIR__ . '/autoload_namespaces.php';
     
    5454
    5555        if ($useStaticLoader) {
    56             $includeFiles = Composer\Autoload\ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48::$files;
     56            $includeFiles = Composer\Autoload\ComposerStaticInit682261ccab0954ac517aab25221b14f9::$files;
    5757        } else {
    5858            $includeFiles = require __DIR__ . '/autoload_files.php';
    5959        }
    6060        foreach ($includeFiles as $fileIdentifier => $file) {
    61             composerRequire5f0587bf3efb7d54ac8e72b21db5ce48($fileIdentifier, $file);
     61            composerRequire682261ccab0954ac517aab25221b14f9($fileIdentifier, $file);
    6262        }
    6363
     
    7171 * @return void
    7272 */
    73 function composerRequire5f0587bf3efb7d54ac8e72b21db5ce48($fileIdentifier, $file)
     73function composerRequire682261ccab0954ac517aab25221b14f9($fileIdentifier, $file)
    7474{
    7575    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
  • erp/trunk/vendor/composer/autoload_static.php

    r3439387 r3457039  
    55namespace Composer\Autoload;
    66
    7 class ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48
     7class ComposerStaticInit682261ccab0954ac517aab25221b14f9
    88{
    99    public static $files = array (
     
    16891689        'WeDevs\\ERP\\CRM\\AjaxHandler' => __DIR__ . '/../..' . '/modules/crm/includes/AjaxHandler.php',
    16901690        'WeDevs\\ERP\\CRM\\CLI\\Commands' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Commands.php',
     1691        'WeDevs\\ERP\\CRM\\CLI\\Seed\\AbstractCrmSeeder' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/AbstractCrmSeeder.php',
     1692        'WeDevs\\ERP\\CRM\\CLI\\Seed\\CrmDataProvider' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/CrmDataProvider.php',
     1693        'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedActivities' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/SeedActivities.php',
     1694        'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedCommand' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/SeedCommand.php',
     1695        'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedCompanies' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/SeedCompanies.php',
     1696        'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedContactGroups' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/SeedContactGroups.php',
     1697        'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedContacts' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/SeedContacts.php',
     1698        'WeDevs\\ERP\\CRM\\CLI\\Seed\\SeedDeals' => __DIR__ . '/../..' . '/modules/crm/includes/CLI/Seed/SeedDeals.php',
    16911699        'WeDevs\\ERP\\CRM\\CampaignListTable' => __DIR__ . '/../..' . '/modules/crm/includes/CampaignListTable.php',
    16921700        'WeDevs\\ERP\\CRM\\Contact' => __DIR__ . '/../..' . '/modules/crm/includes/Contact.php',
     
    17531761        'WeDevs\\ERP\\HRM\\AnnouncementListTable' => __DIR__ . '/../..' . '/modules/hrm/includes/AnnouncementListTable.php',
    17541762        'WeDevs\\ERP\\HRM\\CLI\\Commands' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Commands.php',
     1763        'WeDevs\\ERP\\HRM\\CLI\\Seed\\AbstractSeeder' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/AbstractSeeder.php',
     1764        'WeDevs\\ERP\\HRM\\CLI\\Seed\\DataProvider' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/DataProvider.php',
     1765        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedAnnouncements' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedAnnouncements.php',
     1766        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedAssets' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedAssets.php',
     1767        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedAttendance' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedAttendance.php',
     1768        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedCommand' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedCommand.php',
     1769        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedDepartments' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedDepartments.php',
     1770        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedDesignations' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedDesignations.php',
     1771        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedEmployees' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedEmployees.php',
     1772        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedFinancialYears' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedFinancialYears.php',
     1773        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedHolidays' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedHolidays.php',
     1774        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveApprovals' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedLeaveApprovals.php',
     1775        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveEntitlements' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedLeaveEntitlements.php',
     1776        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeavePolicies' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedLeavePolicies.php',
     1777        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveRequests' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedLeaveRequests.php',
     1778        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedLeaveTypes' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedLeaveTypes.php',
     1779        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedPayroll' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedPayroll.php',
     1780        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedShifts' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedShifts.php',
     1781        'WeDevs\\ERP\\HRM\\CLI\\Seed\\SeedTraining' => __DIR__ . '/../..' . '/modules/hrm/includes/CLI/Seed/SeedTraining.php',
    17551782        'WeDevs\\ERP\\HRM\\Department' => __DIR__ . '/../..' . '/modules/hrm/includes/Department.php',
    17561783        'WeDevs\\ERP\\HRM\\DepartmentListTable' => __DIR__ . '/../..' . '/modules/hrm/includes/DepartmentListTable.php',
     
    21682195    {
    21692196        return \Closure::bind(function () use ($loader) {
    2170             $loader->prefixLengthsPsr4 = ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48::$prefixLengthsPsr4;
    2171             $loader->prefixDirsPsr4 = ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48::$prefixDirsPsr4;
    2172             $loader->prefixesPsr0 = ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48::$prefixesPsr0;
    2173             $loader->classMap = ComposerStaticInit5f0587bf3efb7d54ac8e72b21db5ce48::$classMap;
     2197            $loader->prefixLengthsPsr4 = ComposerStaticInit682261ccab0954ac517aab25221b14f9::$prefixLengthsPsr4;
     2198            $loader->prefixDirsPsr4 = ComposerStaticInit682261ccab0954ac517aab25221b14f9::$prefixDirsPsr4;
     2199            $loader->prefixesPsr0 = ComposerStaticInit682261ccab0954ac517aab25221b14f9::$prefixesPsr0;
     2200            $loader->classMap = ComposerStaticInit682261ccab0954ac517aab25221b14f9::$classMap;
    21742201
    21752202        }, null, ClassLoader::class);
  • erp/trunk/wp-erp.php

    r3439387 r3457039  
    66 * Author: weDevs
    77 * Author URI: https://wedevs.com
    8  * Version: 1.16.10
     8 * Version: 1.16.11
    99 * License: GPL2
    1010 * Text Domain: erp
     
    6161
    6262require_once __DIR__ . '/vendor/autoload.php';
    63 define( 'WPERP_VERSION', '1.16.10' );
     63define( 'WPERP_VERSION', '1.16.11' );
    6464define( 'WPERP_FILE', __FILE__ );
    6565define( 'WPERP_PATH', dirname( WPERP_FILE ) );
Note: See TracChangeset for help on using the changeset viewer.