mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-09-23 03:05:00 -04:00
Merge branch 'master' into plugin-system-fresh
This commit is contained in:
90 files changed
+4225
-2824
No files matched your search
@@ -63,7 +63,7 @@ class Config extends Secure_Controller
|
||||
$this->db = Database::connect();
|
||||
|
||||
helper('security');
|
||||
if (check_encryption()) {
|
||||
if (checkEncryption()) {
|
||||
$this->encrypter = Services::encrypter();
|
||||
} else {
|
||||
log_message('alert', 'Error preparing encryption key');
|
||||
@@ -505,7 +505,7 @@ class Config extends Secure_Controller
|
||||
{
|
||||
$password = '';
|
||||
|
||||
if (check_encryption() && !empty($this->request->getPost('smtp_pass'))) {
|
||||
if (checkEncryption() && !empty($this->request->getPost('smtp_pass'))) {
|
||||
$password = $this->encrypter->encrypt($this->request->getPost('smtp_pass'));
|
||||
}
|
||||
|
||||
@@ -551,7 +551,7 @@ class Config extends Secure_Controller
|
||||
{
|
||||
$password = '';
|
||||
|
||||
if (check_encryption() && !empty($this->request->getPost('msg_pwd'))) {
|
||||
if (checkEncryption() && !empty($this->request->getPost('msg_pwd'))) {
|
||||
$password = $this->encrypter->encrypt($this->request->getPost('msg_pwd'));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Models\Module;
|
||||
use CodeIgniter\HTTP\Exceptions\RedirectException;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use Config\Services;
|
||||
|
||||
@@ -79,8 +80,7 @@ class Employees extends Persons
|
||||
$current_user = $this->employee->get_logged_in_employee_info();
|
||||
|
||||
if ($employee_id != NEW_ENTRY && !$this->employee->canModifyEmployee($person_info->person_id, $current_user->person_id)) {
|
||||
header('Location: ' . base_url('no_access/employees/employees'));
|
||||
exit();
|
||||
throw new RedirectException('no_access/employees/employees');
|
||||
}
|
||||
|
||||
foreach (get_object_vars($person_info) as $property => $value) {
|
||||
@@ -114,13 +114,13 @@ class Employees extends Persons
|
||||
* Inserts/updates an employee
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function postSave(int $employee_id = NEW_ENTRY): ResponseInterface
|
||||
public function postSave(int $employeeId = NEW_ENTRY): ResponseInterface
|
||||
{
|
||||
$current_user = $this->employee->get_logged_in_employee_info();
|
||||
$currentUser = $this->employee->get_logged_in_employee_info();
|
||||
|
||||
if ($employee_id != NEW_ENTRY) {
|
||||
$target_employee = $this->employee->getInfo($employee_id);
|
||||
if (!$this->employee->canModifyEmployee($target_employee->person_id, $current_user->person_id)) {
|
||||
if ($employeeId != NEW_ENTRY) {
|
||||
$targetEmployee = $this->employee->get_info($employeeId);
|
||||
if (!$this->employee->canModifyEmployee($targetEmployee->person_id, $currentUser->person_id)) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'message' => lang('Employees.error_updating_admin'),
|
||||
@@ -129,17 +129,17 @@ class Employees extends Persons
|
||||
}
|
||||
}
|
||||
|
||||
$first_name = $this->request->getPost('first_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS); // TODO: duplicated code
|
||||
$last_name = $this->request->getPost('last_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$firstName = $this->request->getPost('first_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS); // TODO: duplicated code
|
||||
$lastName = $this->request->getPost('last_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$email = strtolower($this->request->getPost('email', FILTER_SANITIZE_EMAIL));
|
||||
|
||||
// format first and last name properly
|
||||
$first_name = $this->nameize($first_name);
|
||||
$last_name = $this->nameize($last_name);
|
||||
$firstName = $this->nameize($firstName);
|
||||
$lastName = $this->nameize($lastName);
|
||||
|
||||
$person_data = [
|
||||
'first_name' => $first_name,
|
||||
'last_name' => $last_name,
|
||||
$personData = [
|
||||
'first_name' => $firstName,
|
||||
'last_name' => $lastName,
|
||||
'gender' => $this->request->getPost('gender', FILTER_SANITIZE_NUMBER_INT),
|
||||
'email' => $email,
|
||||
'phone_number' => $this->request->getPost('phone_number', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
|
||||
@@ -152,27 +152,55 @@ class Employees extends Persons
|
||||
'comments' => $this->request->getPost('comments', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
|
||||
];
|
||||
|
||||
$grants_array = [];
|
||||
$isAdmin = $this->employee->isAdmin($current_user->person_id);
|
||||
$grantsArray = [];
|
||||
$isAdmin = $this->employee->isAdmin($currentUser->person_id);
|
||||
|
||||
foreach ($this->module->get_all_permissions()->getResult() as $permission) {
|
||||
$grants = [];
|
||||
$grant = $this->request->getPost('grant_' . $permission->permission_id) != null ? $this->request->getPost('grant_' . $permission->permission_id, FILTER_SANITIZE_FULL_SPECIAL_CHARS) : '';
|
||||
|
||||
if ($grant == $permission->permission_id) {
|
||||
if (!$isAdmin && !$this->employee->has_grant($permission->permission_id, $current_user->person_id)) {
|
||||
if (!$isAdmin && !$this->employee->has_grant($permission->permission_id, $currentUser->person_id)) {
|
||||
continue;
|
||||
}
|
||||
$grants['permission_id'] = $permission->permission_id;
|
||||
$grants['menu_group'] = $this->request->getPost('menu_group_' . $permission->permission_id) != null ? $this->request->getPost('menu_group_' . $permission->permission_id, FILTER_SANITIZE_FULL_SPECIAL_CHARS) : '--';
|
||||
$grants_array[] = $grants;
|
||||
$grantsArray[] = $grants;
|
||||
}
|
||||
}
|
||||
|
||||
$minimumGrants = ['employees', 'home', 'office'];
|
||||
$missingMinimumGrant = array_diff($minimumGrants, array_column($grantsArray, 'permission_id'));
|
||||
|
||||
if ($isAdmin && $employeeId == $currentUser->person_id && !empty($missingMinimumGrant)) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'message' => lang('Employees.error_cannot_remove_own_minimum_grant'),
|
||||
'id' => $employeeId
|
||||
]);
|
||||
}
|
||||
|
||||
if (filter_var(getenv('DISALLOW_GRANT_CHANGE'), FILTER_VALIDATE_BOOLEAN)
|
||||
&& $this->hasGrantsChanged($employeeId, $isAdmin, $currentUser, $grantsArray)) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'message' => lang('Employees.error_grant_change_disallowed'),
|
||||
'id' => $employeeId
|
||||
]);
|
||||
}
|
||||
|
||||
if (!empty($this->request->getPost('password')) && ENVIRONMENT != 'testing' && filter_var(getenv('DISALLOW_PASSWORD_CHANGE'), FILTER_VALIDATE_BOOLEAN)) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'message' => lang('Employees.error_password_change_disallowed'),
|
||||
'id' => $employeeId
|
||||
]);
|
||||
}
|
||||
|
||||
// Password has been changed OR first time password set
|
||||
if (!empty($this->request->getPost('password')) && ENVIRONMENT != 'testing') {
|
||||
$exploded = explode(":", $this->request->getPost('language', FILTER_SANITIZE_FULL_SPECIAL_CHARS));
|
||||
$employee_data = [
|
||||
$employeeData = [
|
||||
'username' => $this->request->getPost('username', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
|
||||
'password' => password_hash($this->request->getPost('password'), PASSWORD_DEFAULT),
|
||||
'hash_version' => 2,
|
||||
@@ -181,42 +209,69 @@ class Employees extends Persons
|
||||
];
|
||||
} else { // Password not changed
|
||||
$exploded = explode(":", $this->request->getPost('language', FILTER_SANITIZE_FULL_SPECIAL_CHARS));
|
||||
$employee_data = [
|
||||
$employeeData = [
|
||||
'username' => $this->request->getPost('username', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
|
||||
'language_code' => $exploded[0],
|
||||
'language' => $exploded[1]
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->employee->save_employee($person_data, $employee_data, $grants_array, $employee_id)) {
|
||||
if ($this->employee->save_employee($personData, $employeeData, $grantsArray, $employeeId)) {
|
||||
// New employee
|
||||
if ($employee_id == NEW_ENTRY) {
|
||||
if ($employeeId == NEW_ENTRY) {
|
||||
return $this->response->setJSON([
|
||||
'success' => true,
|
||||
'message' => lang('Employees.successful_adding') . ' ' . $first_name . ' ' . $last_name,
|
||||
'id' => $employee_data['person_id']
|
||||
'message' => lang('Employees.successful_adding') . ' ' . $firstName . ' ' . $lastName,
|
||||
'id' => $employeeData['person_id']
|
||||
]);
|
||||
} else { // Existing employee
|
||||
$logged_in_employee_id = session()->get('person_id');
|
||||
if ($employee_id == $logged_in_employee_id) {
|
||||
session()->set('language_code', $employee_data['language_code']);
|
||||
session()->set('language', $employee_data['language']);
|
||||
$loggedInEmployeeId = session()->get('person_id');
|
||||
if ($employeeId == $loggedInEmployeeId) {
|
||||
session()->set('language_code', $employeeData['language_code']);
|
||||
session()->set('language', $employeeData['language']);
|
||||
}
|
||||
return $this->response->setJSON([
|
||||
'success' => true,
|
||||
'message' => lang('Employees.successful_updating') . ' ' . $first_name . ' ' . $last_name,
|
||||
'id' => $employee_id
|
||||
'message' => lang('Employees.successful_updating') . ' ' . $firstName . ' ' . $lastName,
|
||||
'id' => $employeeId
|
||||
]);
|
||||
}
|
||||
} else { // Failure
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'message' => lang('Employees.error_adding_updating') . ' ' . $first_name . ' ' . $last_name,
|
||||
'message' => lang('Employees.error_adding_updating') . ' ' . $firstName . ' ' . $lastName,
|
||||
'id' => NEW_ENTRY
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the submitted grants differ from the employee's current grants,
|
||||
* limited to the permissions the current user has authority over when not an admin.
|
||||
*/
|
||||
private function hasGrantsChanged(int $employeeId, bool $isAdmin, object $currentUser, array $grantsArray): bool
|
||||
{
|
||||
$currentGrantIds = [];
|
||||
|
||||
if ($employeeId != NEW_ENTRY) {
|
||||
$currentGrantIds = array_column($this->employee->get_employee_grants($employeeId), 'permission_id');
|
||||
|
||||
if (!$isAdmin) {
|
||||
$currentGrantIds = array_values(array_filter(
|
||||
$currentGrantIds,
|
||||
fn ($permissionId) => $this->employee->has_grant($permissionId, $currentUser->person_id)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$submittedGrantIds = array_column($grantsArray, 'permission_id');
|
||||
|
||||
sort($currentGrantIds);
|
||||
sort($submittedGrantIds);
|
||||
|
||||
return $currentGrantIds !== $submittedGrantIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* This deletes employees from the employees table
|
||||
* @return ResponseInterface
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Libraries\MY_Migration;
|
||||
use App\Models\Employee;
|
||||
use CodeIgniter\HTTP\RedirectResponse;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
|
||||
@@ -10,6 +11,13 @@ class Home extends Secure_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$methodName = urldecode(service('request')->getUri()->getSegment(2));
|
||||
|
||||
if ($methodName === 'logout') {
|
||||
$this->employee = model(Employee::class);
|
||||
return;
|
||||
}
|
||||
|
||||
parent::__construct('home', null, 'home');
|
||||
}
|
||||
|
||||
|
||||
@@ -255,39 +255,39 @@ class Item_kits extends Secure_Controller
|
||||
/**
|
||||
* AJAX called function that generates barcodes for selected item_kits.
|
||||
*
|
||||
* @param string $item_kit_ids Colon separated list of item_kit_id values to generate barcodes for.
|
||||
* @param string $itemKitIds Colon separated list of item_kit_id values to generate barcodes for.
|
||||
* @return string
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
public function getGenerateBarcodes(string $item_kit_ids): string
|
||||
public function getGenerateBarcodes(string $itemKitIds): string
|
||||
{
|
||||
$barcode_lib = new Barcode_lib();
|
||||
$barcodeLib = new Barcode_lib();
|
||||
$result = [];
|
||||
|
||||
$item_kit_ids = explode(':', $item_kit_ids);
|
||||
foreach ($item_kit_ids as $item_kid_id) {
|
||||
$itemKitIds = explode(':', $itemKitIds);
|
||||
foreach ($itemKitIds as $itemKitId) {
|
||||
// Calculate the total cost and retail price of the Kit, so it can be added to the barcode text at the bottom
|
||||
$item_kit = $this->_add_totals_to_item_kit($this->item_kit->get_info($item_kid_id));
|
||||
$itemKit = $this->_add_totals_to_item_kit($this->item_kit->get_info($itemKitId));
|
||||
|
||||
$item_kid_id = 'KIT ' . urldecode($item_kid_id);
|
||||
$itemKitId = 'KIT ' . $itemKitId;
|
||||
|
||||
$result[] = [
|
||||
'name' => $item_kit->name,
|
||||
'item_id' => $item_kid_id,
|
||||
'item_number' => $item_kid_id,
|
||||
'cost_price' => $item_kit->total_cost_price,
|
||||
'unit_price' => $item_kit->total_unit_price
|
||||
'name' => $itemKit->name,
|
||||
'item_id' => $itemKitId,
|
||||
'item_number' => $itemKitId,
|
||||
'cost_price' => $itemKit->total_cost_price,
|
||||
'unit_price' => $itemKit->total_unit_price
|
||||
];
|
||||
}
|
||||
|
||||
$data['items'] = $result;
|
||||
$barcode_config = $barcode_lib->get_barcode_config();
|
||||
$barcodeConfig = $barcodeLib->get_barcode_config();
|
||||
// In case the selected barcode type is not Code39 or Code128 we set by default Code128
|
||||
// The rationale for this is that EAN codes cannot have strings as seed, so 'KIT ' is not allowed
|
||||
if ($barcode_config['barcode_type'] != 'C39' && $barcode_config['barcode_type'] != 'C128') {
|
||||
$barcode_config['barcode_type'] = 'C128';
|
||||
if ($barcodeConfig['barcode_type'] != 'C39' && $barcodeConfig['barcode_type'] != 'C128') {
|
||||
$barcodeConfig['barcode_type'] = 'C128';
|
||||
}
|
||||
$data['barcode_config'] = $barcode_config;
|
||||
$data['barcode_config'] = $barcodeConfig;
|
||||
|
||||
// Display barcodes
|
||||
return view("barcodes/barcode_sheet", $data);
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Models\Employee;
|
||||
use App\Models\Module;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use Config\OSPOS;
|
||||
|
||||
/**
|
||||
* Part of the grants mechanism to restrict access to modules that the user doesn't have permission for.
|
||||
@@ -13,10 +15,12 @@ use CodeIgniter\HTTP\ResponseInterface;
|
||||
*/
|
||||
class No_access extends BaseController
|
||||
{
|
||||
private Employee $employee;
|
||||
private Module $module;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->employee = model(Employee::class);
|
||||
$this->module = model(Module::class);
|
||||
}
|
||||
|
||||
@@ -30,6 +34,20 @@ class No_access extends BaseController
|
||||
$data['module_name'] = $this->module->get_module_name($module_id);
|
||||
$data['permission_id'] = $permission_id;
|
||||
|
||||
return view('no_access', $data);
|
||||
$userInfo = $this->employee->get_logged_in_employee_info();
|
||||
if ($userInfo === false || $this->request->isAJAX()) {
|
||||
return view('no_access', $data);
|
||||
}
|
||||
|
||||
$menuGroup = session()->get('menu_group');
|
||||
$allowedModules = $menuGroup == 'home'
|
||||
? $this->module->get_allowed_home_modules($userInfo->person_id)
|
||||
: $this->module->get_allowed_office_modules($userInfo->person_id);
|
||||
|
||||
$data['user_info'] = $userInfo;
|
||||
$data['allowed_modules'] = $allowedModules->getResult();
|
||||
$data['config'] = config(OSPOS::class)->settings;
|
||||
|
||||
return view('partial/header', $data) . view('no_access', $data) . view('partial/footer');
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ use App\Models\Reports\Summary_sales;
|
||||
use App\Models\Reports\Summary_sales_taxes;
|
||||
use App\Models\Reports\Summary_suppliers;
|
||||
use App\Models\Reports\Summary_taxes;
|
||||
use CodeIgniter\HTTP\Exceptions\RedirectException;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use Config\OSPOS;
|
||||
use Config\Services;
|
||||
@@ -55,8 +56,8 @@ class Reports extends Secure_Controller
|
||||
{
|
||||
parent::__construct('reports');
|
||||
$request = Services::request();
|
||||
$method_name = $request->getUri()->getSegment(2);
|
||||
$exploder = explode('_', $method_name);
|
||||
$methodName = urldecode($request->getUri()->getSegment(2));
|
||||
$exploder = explode('_', $methodName);
|
||||
|
||||
$this->attribute = config(Attribute::class);
|
||||
$this->config = config(OSPOS::class)->settings;
|
||||
@@ -79,15 +80,16 @@ class Reports extends Secure_Controller
|
||||
$this->inventory_summary = model(Inventory_summary::class);
|
||||
|
||||
if (sizeof($exploder) > 1) {
|
||||
preg_match('/(?:inventory)|([^_.]*)(?:_graph|_row)?$/', $method_name, $matches);
|
||||
preg_match('/(?:inventory)|([^_.]*)(?:_graph|_row)?$/', $methodName, $matches);
|
||||
preg_match('/^(.*?)([sy])?$/', array_pop($matches), $matches);
|
||||
$submodule_id = $matches[1] . ((count($matches) > 2) ? $matches[2] : 's');
|
||||
$submoduleId = $matches[1] . ((count($matches) > 2) ? $matches[2] : 's');
|
||||
} else {
|
||||
$submoduleId = null;
|
||||
}
|
||||
|
||||
// Check access to report submodule
|
||||
if (!$this->employee->has_grant('reports_' . $submodule_id, $this->employee->get_logged_in_employee_info()->person_id)) {
|
||||
header('Location: ' . base_url('no_access/reports/reports_' . $submodule_id));
|
||||
exit();
|
||||
}
|
||||
// Check access to report submodule
|
||||
if ($submoduleId !== null && !$this->employee->has_grant('reports_' . $submoduleId, $this->employee->get_logged_in_employee_info()->person_id)) {
|
||||
throw new RedirectException('no_access/reports/reports_' . $submoduleId);
|
||||
}
|
||||
|
||||
helper('report');
|
||||
|
||||
+175
-126
@@ -126,26 +126,38 @@ class Sales extends Secure_Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $row_id
|
||||
* @param int $rowId
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function getRow(int $row_id): ResponseInterface
|
||||
public function getRow(int $rowId): ResponseInterface
|
||||
{
|
||||
$sale_info = $this->sale->getInfo($row_id)->getRow();
|
||||
$data_row = get_sale_data_row($sale_info);
|
||||
$personId = $this->session->get('person_id');
|
||||
|
||||
return $this->response->setJSON($data_row);
|
||||
if (!$this->employee->has_grant('reports_sales', $personId)) {
|
||||
return $this->response->setStatusCode(403)->setJSON(['success' => false, 'message' => lang('Sales.not_authorized')]);
|
||||
}
|
||||
|
||||
$saleInfo = $this->sale->get_info($rowId)->getRow();
|
||||
$dataRow = getSaleDataRow($saleInfo);
|
||||
|
||||
return $this->response->setJSON($dataRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function getSearch(): ResponseInterface
|
||||
{
|
||||
$personId = $this->session->get('person_id');
|
||||
|
||||
if (!$this->employee->has_grant('reports_sales', $personId)) {
|
||||
return $this->response->setStatusCode(403)->setJSON(['success' => false, 'message' => lang('Sales.not_authorized')]);
|
||||
}
|
||||
|
||||
$search = $this->request->getGet('search', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
|
||||
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
|
||||
$sort = $this->sanitizeSortColumn(sales_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'sale_id');
|
||||
$sort = $this->sanitizeSortColumn(salesHeaders(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'sale_id');
|
||||
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
|
||||
$filters = [
|
||||
@@ -166,24 +178,24 @@ class Sales extends Secure_Controller
|
||||
];
|
||||
|
||||
// Check if any filter is set in the multiselect dropdown
|
||||
$request_filters = array_fill_keys($this->request->getGet('filters', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?? [], true);
|
||||
$filters = array_merge($filters, $request_filters);
|
||||
$requestFilters = array_fill_keys($this->request->getGet('filters', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?? [], true);
|
||||
$filters = array_merge($filters, $requestFilters);
|
||||
|
||||
$sales = $this->sale->search($search, $filters, $limit, $offset, $sort, $order);
|
||||
$total_rows = $this->sale->get_found_rows($search, $filters);
|
||||
$payments = $this->sale->get_payments_summary($search, $filters);
|
||||
$payment_summary = get_sales_manage_payments_summary($payments);
|
||||
$totalRows = $this->sale->get_found_rows($search, $filters);
|
||||
$payments = $this->sale->getPaymentsSummary($search, $filters);
|
||||
$paymentSummary = getSalesManagePaymentsSummary($payments);
|
||||
|
||||
$data_rows = [];
|
||||
$dataRows = [];
|
||||
foreach ($sales->getResult() as $sale) {
|
||||
$data_rows[] = get_sale_data_row($sale);
|
||||
$dataRows[] = getSaleDataRow($sale);
|
||||
}
|
||||
|
||||
if ($total_rows > 0) {
|
||||
$data_rows[] = get_sale_data_last_row($sales);
|
||||
if ($totalRows > 0) {
|
||||
$dataRows[] = getSaleDataLastRow($sales);
|
||||
}
|
||||
|
||||
return $this->response->setJSON(['total' => $total_rows, 'rows' => $data_rows, 'payment_summary' => $payment_summary]);
|
||||
return $this->response->setJSON(['total' => $totalRows, 'rows' => $dataRows, 'payment_summary' => $paymentSummary]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -633,6 +645,7 @@ class Sales extends Secure_Controller
|
||||
$description = $this->request->getPost('description', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$serialnumber = $this->request->getPost('serialnumber', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$price = parse_decimals($this->request->getPost('price'));
|
||||
$price = $price !== false ? number_format((float) $price, totals_decimals(), '.', '') : $price;
|
||||
$quantity = parse_decimals($this->request->getPost('quantity'));
|
||||
$discount_type = $this->request->getPost('discount_type', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$discount = $discount_type
|
||||
@@ -1007,38 +1020,44 @@ class Sales extends Secure_Controller
|
||||
/**
|
||||
* Email PDF invoice to customer. Used in app/Views/sales/form.php, invoice.php, quote.php, tax_invoice.php and work_order.php
|
||||
*
|
||||
* @param int $sale_id
|
||||
* @param int $saleId
|
||||
* @param string $type
|
||||
* @return ResponseInterface
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
public function getSendPdf(int $sale_id, string $type = 'invoice'): ResponseInterface
|
||||
public function getSendPdf(int $saleId, string $type = 'invoice'): ResponseInterface
|
||||
{
|
||||
$sale_data = $this->_load_sale_data($sale_id);
|
||||
$personId = $this->session->get('person_id');
|
||||
|
||||
if (!$this->employee->has_grant('reports_sales', $personId)) {
|
||||
return $this->response->setStatusCode(403)->setJSON(['success' => false, 'message' => lang('Sales.not_authorized')]);
|
||||
}
|
||||
|
||||
$saleData = $this->_load_sale_data($saleId);
|
||||
|
||||
$result = false;
|
||||
$message = lang('Sales.invoice_no_email');
|
||||
|
||||
if (!empty($sale_data['customer_email'])) {
|
||||
$to = $sale_data['customer_email'];
|
||||
$number = array_key_exists($type . "_number", $sale_data) ? $sale_data[$type . "_number"] : "";
|
||||
if (!empty($saleData['customer_email'])) {
|
||||
$to = $saleData['customer_email'];
|
||||
$number = array_key_exists($type . "_number", $saleData) ? $saleData[$type . "_number"] : "";
|
||||
$subject = lang('Sales.' . $type) . ' ' . $number;
|
||||
|
||||
$text = $this->config['invoice_email_message'];
|
||||
$tokens = [
|
||||
new Token_invoice_sequence($number),
|
||||
new Token_invoice_count('POS ' . $sale_data['sale_id']),
|
||||
new Token_customer((array)$sale_data)
|
||||
new Token_invoice_count('POS ' . $saleData['sale_id']),
|
||||
new Token_customer((array)$saleData)
|
||||
];
|
||||
$text = $this->token_lib->render($text, $tokens);
|
||||
$sale_data['mimetype'] = $this->email_lib->getLogoMimeType();
|
||||
$saleData['mimetype'] = $this->email_lib->getLogoMimeType();
|
||||
|
||||
// Build img_tag for email views that need it (receipt_email.php)
|
||||
$sale_data['img_tag'] = $this->email_lib->buildLogoImgTag();
|
||||
$saleData['img_tag'] = $this->email_lib->buildLogoImgTag();
|
||||
|
||||
// Generate email attachment: invoice in PDF format
|
||||
$view = Services::renderer();
|
||||
$html = $view->setData($sale_data)->render("sales/$type" . '_email', $sale_data);
|
||||
$html = $view->setData($saleData)->render("sales/$type" . '_email', $saleData);
|
||||
|
||||
// Load PDF helper
|
||||
helper(['dompdf', 'file']);
|
||||
@@ -1052,32 +1071,38 @@ class Sales extends Secure_Controller
|
||||
|
||||
$this->sale_lib->clear_all();
|
||||
|
||||
return $this->response->setJSON(['success' => $result, 'message' => $message, 'id' => $sale_id]);
|
||||
return $this->response->setJSON(['success' => $result, 'message' => $message, 'id' => $saleId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emails sales receipt to customer. Used in app/Views/sales/receipt.php
|
||||
*
|
||||
* @param int $sale_id
|
||||
* @param int $saleId
|
||||
* @return ResponseInterface
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
public function getSendReceipt(int $sale_id): ResponseInterface
|
||||
public function getSendReceipt(int $saleId): ResponseInterface
|
||||
{
|
||||
$sale_data = $this->_load_sale_data($sale_id);
|
||||
$personId = $this->session->get('person_id');
|
||||
|
||||
if (!$this->employee->has_grant('reports_sales', $personId)) {
|
||||
return $this->response->setStatusCode(403)->setJSON(['success' => false, 'message' => lang('Sales.not_authorized')]);
|
||||
}
|
||||
|
||||
$saleData = $this->_load_sale_data($saleId);
|
||||
|
||||
$result = false;
|
||||
$message = lang('Sales.receipt_no_email');
|
||||
|
||||
if (!empty($sale_data['customer_email'])) {
|
||||
$sale_data['barcode'] = $this->barcode_lib->generate_receipt_barcode($sale_data['sale_id']);
|
||||
$sale_data['img_tag'] = $this->email_lib->buildLogoImgTag();
|
||||
if (!empty($saleData['customer_email'])) {
|
||||
$saleData['barcode'] = $this->barcode_lib->generate_receipt_barcode($saleData['sale_id']);
|
||||
$saleData['img_tag'] = $this->email_lib->buildLogoImgTag();
|
||||
|
||||
$to = $sale_data['customer_email'];
|
||||
$to = $saleData['customer_email'];
|
||||
$subject = lang('Sales.receipt');
|
||||
|
||||
$view = Services::renderer();
|
||||
$text = $view->setData($sale_data)->render('sales/receipt_email');
|
||||
$text = $view->setData($saleData)->render('sales/receipt_email');
|
||||
|
||||
$result = $this->email_lib->sendEmail($to, $subject, $text);
|
||||
|
||||
@@ -1086,7 +1111,7 @@ class Sales extends Secure_Controller
|
||||
|
||||
$this->sale_lib->clear_all();
|
||||
|
||||
return $this->response->setJSON(['success' => $result, 'message' => $message, 'id' => $sale_id]);
|
||||
return $this->response->setJSON(['success' => $result, 'message' => $message, 'id' => $saleId]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1382,13 +1407,19 @@ class Sales extends Secure_Controller
|
||||
/**
|
||||
* Load the sales receipt for a sale. Used in app/Views/sales/form.php
|
||||
*
|
||||
* @param int $sale_id
|
||||
* @param int $saleId
|
||||
* @return string
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
public function getReceipt(int $sale_id): string
|
||||
public function getReceipt(int $saleId): string|ResponseInterface
|
||||
{
|
||||
$data = $this->_load_sale_data($sale_id);
|
||||
$personId = $this->session->get('person_id');
|
||||
|
||||
if (!$this->employee->has_grant('reports_sales', $personId)) {
|
||||
return redirect()->to('no_access/sales/reports_sales');
|
||||
}
|
||||
|
||||
$data = $this->_load_sale_data($saleId);
|
||||
$this->sale_lib->clear_all();
|
||||
|
||||
return view('sales/receipt', $data);
|
||||
@@ -1397,13 +1428,19 @@ class Sales extends Secure_Controller
|
||||
/**
|
||||
* Loads the sales invoice for a sale. Used in app/Views/sales/form.php
|
||||
*
|
||||
* @param int $sale_id
|
||||
* @param int $saleId
|
||||
* @return string
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
public function getInvoice(int $sale_id): string
|
||||
public function getInvoice(int $saleId): string|ResponseInterface
|
||||
{
|
||||
$data = $this->_load_sale_data($sale_id);
|
||||
$personId = $this->session->get('person_id');
|
||||
|
||||
if (!$this->employee->has_grant('reports_sales', $personId)) {
|
||||
return redirect()->to('no_access/sales/reports_sales');
|
||||
}
|
||||
|
||||
$data = $this->_load_sale_data($saleId);
|
||||
$this->sale_lib->clear_all();
|
||||
|
||||
return view('sales/' . $data['invoice_view'], $data);
|
||||
@@ -1412,25 +1449,31 @@ class Sales extends Secure_Controller
|
||||
/**
|
||||
* Edits an existing sale or work order. Used in app/Views/sales/form.php
|
||||
*
|
||||
* @param int $sale_id
|
||||
* @param int $saleId
|
||||
* @return string
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function getEdit(int $sale_id): string
|
||||
public function getEdit(int $saleId): string|ResponseInterface
|
||||
{
|
||||
$personId = $this->session->get('person_id');
|
||||
|
||||
if (!$this->employee->has_grant('reports_sales', $personId)) {
|
||||
return redirect()->to('no_access/sales/reports_sales');
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
$sale_info = $this->sale->getInfo($sale_id)->getRowArray();
|
||||
$data['selected_customer_id'] = $sale_info['customer_id'];
|
||||
$data['selected_customer_name'] = $sale_info['customer_name'];
|
||||
$employee_info = $this->employee->getInfo($sale_info['employee_id']);
|
||||
$data['selected_employee_id'] = $sale_info['employee_id'];
|
||||
$data['selected_employee_name'] = $employee_info->first_name . ' ' . $employee_info->last_name;
|
||||
$data['sale_info'] = $sale_info;
|
||||
$balance_due = round($sale_info['amount_due'] - $sale_info['amount_tendered'] + $sale_info['cash_refund'], totals_decimals(), PHP_ROUND_HALF_UP);
|
||||
$saleInfo = $this->sale->get_info($saleId)->getRowArray();
|
||||
$data['selected_customer_id'] = $saleInfo['customer_id'];
|
||||
$data['selected_customer_name'] = $saleInfo['customer_name'];
|
||||
$employeeInfo = $this->employee->get_info($saleInfo['employee_id']);
|
||||
$data['selected_employee_id'] = $saleInfo['employee_id'];
|
||||
$data['selected_employee_name'] = $employeeInfo->first_name . ' ' . $employeeInfo->last_name;
|
||||
$data['sale_info'] = $saleInfo;
|
||||
$balanceDue = round($saleInfo['amount_due'] - $saleInfo['amount_tendered'] + $saleInfo['cash_refund'], totals_decimals(), PHP_ROUND_HALF_UP);
|
||||
|
||||
if (!$this->sale_lib->reset_cash_rounding() && $balance_due < 0) {
|
||||
$balance_due = 0;
|
||||
if (!$this->sale_lib->reset_cash_rounding() && $balanceDue < 0) {
|
||||
$balanceDue = 0;
|
||||
}
|
||||
|
||||
$data['payments'] = [];
|
||||
@@ -1443,24 +1486,24 @@ class Sales extends Secure_Controller
|
||||
}
|
||||
|
||||
$data['payment_type_new'] = PAYMENT_TYPE_UNASSIGNED;
|
||||
$data['payment_amount_new'] = $balance_due;
|
||||
$data['payment_amount_new'] = $balanceDue;
|
||||
|
||||
$data['balance_due'] = $balance_due != 0;
|
||||
$data['balance_due'] = $balanceDue != 0;
|
||||
|
||||
// Don't allow gift card to be a payment option in a sale transaction edit because it's a complex change
|
||||
$payment_options = $this->sale->get_payment_options(false);
|
||||
$paymentOptions = $this->sale->get_payment_options(false);
|
||||
|
||||
if ($this->sale_lib->reset_cash_rounding()) {
|
||||
$payment_options[lang('Sales.cash_adjustment')] = lang('Sales.cash_adjustment');
|
||||
$paymentOptions[lang('Sales.cash_adjustment')] = lang('Sales.cash_adjustment');
|
||||
}
|
||||
|
||||
$data['payment_options'] = $payment_options;
|
||||
$data['payment_options'] = $paymentOptions;
|
||||
$data['reference_code_payment_types'] = get_reference_code_payment_types();
|
||||
|
||||
// Set up a slightly modified list of payment types for new payment entry
|
||||
$payment_options["--"] = lang('Common.none_selected_text');
|
||||
$paymentOptions["--"] = lang('Common.none_selected_text');
|
||||
|
||||
$data['new_payment_options'] = $payment_options;
|
||||
$data['new_payment_options'] = $paymentOptions;
|
||||
|
||||
return view('sales/form', $data);
|
||||
}
|
||||
@@ -1476,7 +1519,7 @@ class Sales extends Secure_Controller
|
||||
$has_grant = $this->employee->has_grant('sales_delete', $employee_id);
|
||||
|
||||
if (!$has_grant) {
|
||||
return $this->response->setJSON(['success' => false, 'message' => lang('Sales.not_authorized')]);
|
||||
return $this->response->setStatusCode(403)->setJSON(['success' => false, 'message' => lang('Sales.not_authorized')]);
|
||||
} else {
|
||||
$sale_ids = $sale_id == NEW_ENTRY ? $this->request->getPost('ids', FILTER_SANITIZE_NUMBER_INT) : [$sale_id];
|
||||
|
||||
@@ -1503,7 +1546,7 @@ class Sales extends Secure_Controller
|
||||
$has_grant = $this->employee->has_grant('sales_delete', $employee_id);
|
||||
|
||||
if (!$has_grant) {
|
||||
return $this->response->setJSON(['success' => false, 'message' => lang('Sales.not_authorized')]);
|
||||
return $this->response->setStatusCode(403)->setJSON(['success' => false, 'message' => lang('Sales.not_authorized')]);
|
||||
} else {
|
||||
$sale_ids = $sale_id == NEW_ENTRY ? $this->request->getPost('ids', FILTER_SANITIZE_NUMBER_INT) : [$sale_id];
|
||||
|
||||
@@ -1522,20 +1565,26 @@ class Sales extends Secure_Controller
|
||||
/**
|
||||
* This saves the sale from the update sale view (sales/form).
|
||||
* It only updates the sales table and payments.
|
||||
* @param int $sale_id
|
||||
* @param int $saleId
|
||||
* @return ResponseInterface
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function postSave(int $sale_id = NEW_ENTRY): ResponseInterface
|
||||
public function postSave(int $saleId = NEW_ENTRY): ResponseInterface
|
||||
{
|
||||
$newdate = $this->request->getPost('date', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$employee_id = $this->employee->get_logged_in_employee_info()->person_id;
|
||||
$inventory = model(Inventory::class);
|
||||
$date_formatter = date_create_from_format($this->config['dateformat'] . ' ' . $this->config['timeformat'], $newdate);
|
||||
$sale_time = $date_formatter->format('Y-m-d H:i:s');
|
||||
$personId = $this->session->get('person_id');
|
||||
|
||||
$sale_data = [
|
||||
'sale_time' => $sale_time,
|
||||
if (!$this->employee->has_grant('reports_sales', $personId)) {
|
||||
return $this->response->setStatusCode(403)->setJSON(['success' => false, 'message' => lang('Sales.not_authorized')]);
|
||||
}
|
||||
|
||||
$newdate = $this->request->getPost('date', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$employeeId = $this->employee->get_logged_in_employee_info()->person_id;
|
||||
$inventory = model(Inventory::class);
|
||||
$dateFormatter = date_create_from_format($this->config['dateformat'] . ' ' . $this->config['timeformat'], $newdate);
|
||||
$saleTime = $dateFormatter->format('Y-m-d H:i:s');
|
||||
|
||||
$saleData = [
|
||||
'sale_time' => $saleTime,
|
||||
'customer_id' => $this->request->getPost('customer_id') != '' ? $this->request->getPost('customer_id', FILTER_SANITIZE_NUMBER_INT) : null,
|
||||
'employee_id' => $this->request->getPost('employee_id') != '' ? $this->request->getPost('employee_id', FILTER_SANITIZE_NUMBER_INT) : null,
|
||||
'comment' => $this->request->getPost('comment', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
|
||||
@@ -1543,10 +1592,10 @@ class Sales extends Secure_Controller
|
||||
];
|
||||
|
||||
// Validate reference_code for the new payment if applicable
|
||||
$payment_type_new_check = $this->request->getPost('payment_type_new', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$payment_amount_new_check = $this->request->getPost('payment_amount_new');
|
||||
if ($payment_type_new_check != PAYMENT_TYPE_UNASSIGNED && !empty($payment_amount_new_check)
|
||||
&& in_array($payment_type_new_check, get_reference_code_payment_types())) {
|
||||
$paymentTypeNewCheck = $this->request->getPost('payment_type_new', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$paymentAmountNewCheck = $this->request->getPost('payment_amount_new');
|
||||
if ($paymentTypeNewCheck != PAYMENT_TYPE_UNASSIGNED && !empty($paymentAmountNewCheck)
|
||||
&& in_array($paymentTypeNewCheck, get_reference_code_payment_types())) {
|
||||
$min = (int)($this->config['payment_reference_code_min'] ?? 3);
|
||||
$max = (int)($this->config['payment_reference_code_max'] ?? 40);
|
||||
$rules = [
|
||||
@@ -1562,82 +1611,82 @@ class Sales extends Secure_Controller
|
||||
];
|
||||
if (!$this->validate($rules, $messages)) {
|
||||
$errors = $this->validator->getErrors();
|
||||
return $this->response->setJSON(['success' => false, 'message' => reset($errors), 'id' => $sale_id]);
|
||||
return $this->response->setJSON(['success' => false, 'message' => reset($errors), 'id' => $saleId]);
|
||||
}
|
||||
}
|
||||
|
||||
// In order to maintain tradition the only element that can change on prior payments is the payment type
|
||||
$amount_tendered = 0;
|
||||
$number_of_payments = $this->request->getPost('number_of_payments', FILTER_SANITIZE_NUMBER_INT);
|
||||
for ($i = 0; $i < $number_of_payments; ++$i) {
|
||||
$payment_id = $this->request->getPost("payment_id_$i", FILTER_SANITIZE_NUMBER_INT);
|
||||
$payment_type = $this->request->getPost("payment_type_$i", FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$payment_amount = parse_decimals($this->request->getPost("payment_amount_$i"));
|
||||
$refund_type = $this->request->getPost("refund_type_$i", FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$cash_refund = parse_decimals($this->request->getPost("refund_amount_$i"));
|
||||
$reference_code = $this->request->getPost("reference_code_$i", FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?: null;
|
||||
$amountTendered = 0;
|
||||
$numberOfPayments = $this->request->getPost('number_of_payments', FILTER_SANITIZE_NUMBER_INT);
|
||||
for ($i = 0; $i < $numberOfPayments; ++$i) {
|
||||
$paymentId = $this->request->getPost("payment_id_$i", FILTER_SANITIZE_NUMBER_INT);
|
||||
$paymentType = $this->request->getPost("payment_type_$i", FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$paymentAmount = parse_decimals($this->request->getPost("payment_amount_$i"));
|
||||
$refundType = $this->request->getPost("refund_type_$i", FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$cashRefund = parse_decimals($this->request->getPost("refund_amount_$i"));
|
||||
$referenceCode = $this->request->getPost("reference_code_$i", FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?: null;
|
||||
|
||||
$cash_adjustment = $payment_type == lang('Sales.cash_adjustment') ? CASH_ADJUSTMENT_TRUE : CASH_ADJUSTMENT_FALSE;
|
||||
$cashAdjustment = $paymentType == lang('Sales.cash_adjustment') ? CASH_ADJUSTMENT_TRUE : CASH_ADJUSTMENT_FALSE;
|
||||
|
||||
if (!$cash_adjustment) {
|
||||
$amount_tendered += $payment_amount - $cash_refund;
|
||||
if (!$cashAdjustment) {
|
||||
$amountTendered += $paymentAmount - $cashRefund;
|
||||
}
|
||||
|
||||
// Non-cash positive refund amounts
|
||||
if (empty(strstr($refund_type, lang('Sales.cash'))) && $cash_refund > 0) { // TODO: This if and the one below can be combined.
|
||||
if (empty(strstr($refundType, lang('Sales.cash'))) && $cashRefund > 0) { // TODO: This if and the one below can be combined.
|
||||
// Change it to be a new negative payment (a "non-cash refund")
|
||||
$payment_type = $refund_type;
|
||||
$payment_amount = $payment_amount - $cash_refund;
|
||||
$cash_refund = 0.00;
|
||||
$paymentType = $refundType;
|
||||
$paymentAmount = $paymentAmount - $cashRefund;
|
||||
$cashRefund = 0.00;
|
||||
}
|
||||
|
||||
$sale_data['payments'][] = [
|
||||
'payment_id' => $payment_id,
|
||||
'payment_type' => $payment_type,
|
||||
'payment_amount' => $payment_amount,
|
||||
'cash_refund' => $cash_refund,
|
||||
'cash_adjustment' => $cash_adjustment,
|
||||
'employee_id' => $employee_id,
|
||||
'reference_code' => $reference_code,
|
||||
$saleData['payments'][] = [
|
||||
'payment_id' => $paymentId,
|
||||
'payment_type' => $paymentType,
|
||||
'payment_amount' => $paymentAmount,
|
||||
'cash_refund' => $cashRefund,
|
||||
'cash_adjustment' => $cashAdjustment,
|
||||
'employee_id' => $employeeId,
|
||||
'reference_code' => $referenceCode,
|
||||
];
|
||||
}
|
||||
|
||||
$payment_id = NEW_ENTRY;
|
||||
$payment_amount_new = $this->request->getPost('payment_amount_new');
|
||||
$payment_type = $this->request->getPost('payment_type_new', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$reference_code_new = $this->request->getPost('reference_code_new', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?: null;
|
||||
$paymentId = NEW_ENTRY;
|
||||
$paymentAmountNew = $this->request->getPost('payment_amount_new');
|
||||
$paymentType = $this->request->getPost('payment_type_new', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
|
||||
$referenceCodeNew = $this->request->getPost('reference_code_new', FILTER_SANITIZE_FULL_SPECIAL_CHARS) ?: null;
|
||||
|
||||
if ($payment_type != PAYMENT_TYPE_UNASSIGNED && !empty($payment_amount_new)) {
|
||||
$payment_amount = parse_decimals($payment_amount_new);
|
||||
$cash_refund = 0;
|
||||
if ($payment_type == lang('Sales.cash_adjustment')) {
|
||||
$cash_adjustment = CASH_ADJUSTMENT_TRUE;
|
||||
if ($paymentType != PAYMENT_TYPE_UNASSIGNED && !empty($paymentAmountNew)) {
|
||||
$paymentAmount = parse_decimals($paymentAmountNew);
|
||||
$cashRefund = 0;
|
||||
if ($paymentType == lang('Sales.cash_adjustment')) {
|
||||
$cashAdjustment = CASH_ADJUSTMENT_TRUE;
|
||||
} else {
|
||||
$cash_adjustment = CASH_ADJUSTMENT_FALSE;
|
||||
$amount_tendered += $payment_amount;
|
||||
$sale_info = $this->sale->getInfo($sale_id)->getRowArray();
|
||||
|
||||
if ($amount_tendered > $sale_info['amount_due']) {
|
||||
$cash_refund = $amount_tendered - $sale_info['amount_due'];
|
||||
if ($amountTendered > $saleInfo['amount_due']) {
|
||||
$cashRefund = $amountTendered - $saleInfo['amount_due'];
|
||||
}
|
||||
}
|
||||
|
||||
$sale_data['payments'][] = [
|
||||
'payment_id' => $payment_id,
|
||||
'payment_type' => $payment_type,
|
||||
'payment_amount' => $payment_amount,
|
||||
'cash_refund' => $cash_refund,
|
||||
'cash_adjustment' => $cash_adjustment,
|
||||
'employee_id' => $employee_id,
|
||||
'reference_code' => $reference_code_new,
|
||||
$saleData['payments'][] = [
|
||||
'payment_id' => $paymentId,
|
||||
'payment_type' => $paymentType,
|
||||
'payment_amount' => $paymentAmount,
|
||||
'cash_refund' => $cashRefund,
|
||||
'cash_adjustment' => $cashAdjustment,
|
||||
'employee_id' => $employeeId,
|
||||
'reference_code' => $referenceCodeNew,
|
||||
];
|
||||
}
|
||||
|
||||
$inventory->update('POS ' . $sale_id, ['trans_date' => $sale_time]); // TODO: Reflection Exception
|
||||
if ($this->sale->update($sale_id, $sale_data)) {
|
||||
return $this->response->setJSON(['success' => true, 'message' => lang('Sales.successfully_updated'), 'id' => $sale_id]);
|
||||
$inventory->update('POS ' . $saleId, ['trans_date' => $saleTime]); // TODO: Reflection Exception
|
||||
if ($this->sale->update($saleId, $saleData)) {
|
||||
return $this->response->setJSON(['success' => true, 'message' => lang('Sales.successfully_updated'), 'id' => $saleId]);
|
||||
} else {
|
||||
return $this->response->setJSON(['success' => false, 'message' => lang('Sales.unsuccessfully_updated'), 'id' => $sale_id]);
|
||||
return $this->response->setJSON(['success' => false, 'message' => lang('Sales.unsuccessfully_updated'), 'id' => $saleId]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Controllers;
|
||||
|
||||
use App\Models\Employee;
|
||||
use App\Models\Module;
|
||||
use CodeIgniter\HTTP\Exceptions\RedirectException;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use CodeIgniter\Model;
|
||||
use CodeIgniter\Session\Session;
|
||||
@@ -39,18 +40,12 @@ class Secure_Controller extends BaseController
|
||||
$config = config(OSPOS::class)->settings;
|
||||
$validation = Services::validation();
|
||||
|
||||
if (!$this->employee->is_logged_in()) {
|
||||
header("Location:" . base_url('login'));
|
||||
exit();
|
||||
}
|
||||
|
||||
$logged_in_employee_info = $this->employee->get_logged_in_employee_info();
|
||||
if (
|
||||
!$this->employee->has_module_grant($module_id, $logged_in_employee_info->person_id)
|
||||
|| (isset($submodule_id) && !$this->employee->has_module_grant($submodule_id, $logged_in_employee_info->person_id))
|
||||
) {
|
||||
header("Location:" . base_url("no_access/$module_id/$submodule_id"));
|
||||
exit();
|
||||
throw new RedirectException("no_access/$module_id/$submodule_id");
|
||||
}
|
||||
|
||||
// Load up global global_view_data visible to all the loaded views
|
||||
@@ -144,9 +139,9 @@ class Secure_Controller extends BaseController
|
||||
|
||||
/**
|
||||
* @param int $data_item_id
|
||||
* @return false
|
||||
* @return ResponseInterface|false
|
||||
*/
|
||||
public function postSave(int $data_item_id = -1)
|
||||
public function postSave(int $data_item_id = -1): ResponseInterface|false
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user