Replace tabs with spaces (#4196)

Signed-off-by: objecttothis <objecttothis@gmail.com>
This commit is contained in:
objecttothis
2025-03-28 21:24:21 +04:00
committed by GitHub
parent 69bcd84699
commit e90b5b87da
1271 changed files with 106798 additions and 106801 deletions

22
.env
View File

@@ -47,7 +47,7 @@ database.tests.port = 3306
email.SMTPHost = ''
email.SMTPUser = ''
email.SMTPPass = ''
email.SMTPPort =
email.SMTPPort =
email.SMTPTimeout = 5
email.SMTPCrypto = 'tls'
@@ -69,16 +69,16 @@ honeypot.container = '<div style="display:none">{template}</div>'
#--------------------------------------------------------------------
# LOGGER
# - 0 = Disables logging, Error logging TURNED OFF
# - 1 = Emergency Messages - System is unusable
# - 2 = Alert Messages - Action Must Be Taken Immediately
# - 3 = Critical Messages - Application component unavailable, unexpected exception.
# - 4 = Runtime Errors - Don't need immediate action, but should be monitored.
# - 5 = Warnings - Exceptional occurrences that are not errors.
# - 6 = Notices - Normal but significant events.
# - 7 = Info - Interesting events, like user logging in, etc.
# - 8 = Debug - Detailed debug information.
# - 9 = All Messages
# - 0 = Disables logging, Error logging TURNED OFF
# - 1 = Emergency Messages - System is unusable
# - 2 = Alert Messages - Action Must Be Taken Immediately
# - 3 = Critical Messages - Application component unavailable, unexpected exception.
# - 4 = Runtime Errors - Don't need immediate action, but should be monitored.
# - 5 = Warnings - Exceptional occurrences that are not errors.
# - 6 = Notices - Normal but significant events.
# - 7 = Info - Interesting events, like user logging in, etc.
# - 8 = Debug - Detailed debug information.
# - 9 = All Messages
#--------------------------------------------------------------------
logger.threshold = 0

View File

@@ -37,16 +37,16 @@ encryption.key = ''
#--------------------------------------------------------------------
# LOGGER
# - 0 = Disables logging, Error logging TURNED OFF
# - 1 = Emergency Messages - System is unusable
# - 2 = Alert Messages - Action Must Be Taken Immediately
# - 3 = Critical Messages - Application component unavailable, unexpected exception.
# - 4 = Runtime Errors - Don't need immediate action, but should be monitored.
# - 5 = Warnings - Exceptional occurrences that are not errors.
# - 6 = Notices - Normal but significant events.
# - 7 = Info - Interesting events, like user logging in, etc.
# - 8 = Debug - Detailed debug information.
# - 9 = All Messages
# - 0 = Disables logging, Error logging TURNED OFF
# - 1 = Emergency Messages - System is unusable
# - 2 = Alert Messages - Action Must Be Taken Immediately
# - 3 = Critical Messages - Application component unavailable, unexpected exception.
# - 4 = Runtime Errors - Don't need immediate action, but should be monitored.
# - 5 = Warnings - Exceptional occurrences that are not errors.
# - 6 = Notices - Normal but significant events.
# - 7 = Info - Interesting events, like user logging in, etc.
# - 8 = Debug - Detailed debug information.
# - 9 = All Messages
#--------------------------------------------------------------------
logger.threshold = 0

View File

@@ -23,9 +23,9 @@ The build process uses the build tools "npm" and "gulp" to piece everything toge
2. Unzip it and copy the contents into the working folder.
3. Start a terminal session from the root of your working folder. For example, I normally open up the working folder in PHPStorm and run the commands from the Terminal provided by the IDE.
4. Enter the following three commands in sequence:
- `composer install`
- `npm install`
- `npm run build`
- `composer install`
- `npm install`
- `npm run build`
That's all there is to it.

View File

@@ -1,6 +1,6 @@
<IfModule authz_core_module>
Require all denied
Require all denied
</IfModule>
<IfModule !authz_core_module>
Deny from all
Deny from all
</IfModule>

View File

@@ -7,52 +7,52 @@ use CodeIgniter\Session\Handlers\DatabaseHandler;
class App extends BaseConfig
{
/**
* This is the code version of the Open Source Point of Sale you're running.
*
* @var string
*/
public string $application_version = '3.4.0';
/**
* This is the code version of the Open Source Point of Sale you're running.
*
* @var string
*/
public string $application_version = '3.4.0';
/**
* This is the commit hash for the version you are currently using.
*
* @var string
*/
public string $commit_sha1 = 'dev';
/**
* This is the commit hash for the version you are currently using.
*
* @var string
*/
public string $commit_sha1 = 'dev';
/**
* Logs are stored in writable/logs
*
* @var bool
*/
public bool $db_log_enabled = false;
/**
* Logs are stored in writable/logs
*
* @var bool
*/
public bool $db_log_enabled = false;
/**
* DB Query Log only long-running queries
*
* @var bool
*/
public bool $db_log_only_long = false;
/**
* DB Query Log only long-running queries
*
* @var bool
*/
public bool $db_log_only_long = false;
/**
* Defines whether to require/reroute to HTTPS
*
* @var bool
*/
public bool $https_on; //Set in the constructor
/**
* Defines whether to require/reroute to HTTPS
*
* @var bool
*/
public bool $https_on; //Set in the constructor
/**
* --------------------------------------------------------------------------
* Base Site URL
* --------------------------------------------------------------------------
*
* URL to your CodeIgniter root. Typically, this will be your base URL,
* WITH a trailing slash:
*
* E.g., http://example.com/
*/
public string $baseURL; //Defined in the constructor
/**
* --------------------------------------------------------------------------
* Base Site URL
* --------------------------------------------------------------------------
*
* URL to your CodeIgniter root. Typically, this will be your base URL,
* WITH a trailing slash:
*
* E.g., http://example.com/
*/
public string $baseURL; //Defined in the constructor
/**
* Allowed Hostnames in the Site URL other than the hostname in the baseURL.
@@ -143,63 +143,63 @@ class App extends BaseConfig
*/
public bool $negotiateLocale = true;
/**
* --------------------------------------------------------------------------
* Supported Locales
* --------------------------------------------------------------------------
*
* If $negotiateLocale is true, this array lists the locales supported
* by the application in descending order of priority. If no match is
* found, the first locale will be used.
*
* IncomingRequest::setLocale() also uses this list.
*
* @var list<string>
*/
public array $supportedLocales = [
'ar-EG',
'ar-LB',
'az',
'bg',
'bs',
'cs',
'da',
'de-CH',
'de-DE',
'el',
/**
* --------------------------------------------------------------------------
* Supported Locales
* --------------------------------------------------------------------------
*
* If $negotiateLocale is true, this array lists the locales supported
* by the application in descending order of priority. If no match is
* found, the first locale will be used.
*
* IncomingRequest::setLocale() also uses this list.
*
* @var list<string>
*/
public array $supportedLocales = [
'ar-EG',
'ar-LB',
'az',
'bg',
'bs',
'cs',
'da',
'de-CH',
'de-DE',
'el',
'en',
'en-GB',
'es-ES',
'es-MX',
'fa',
'fr',
'he',
'hr-HR',
'hu',
'hy',
'id',
'it',
'km',
'lo',
'ml',
'nb',
'nl-BE',
'en-GB',
'es-ES',
'es-MX',
'fa',
'fr',
'he',
'hr-HR',
'hu',
'hy',
'id',
'it',
'km',
'lo',
'ml',
'nb',
'nl-BE',
'nl-NL',
'pl',
'pt-BR',
'ro',
'ru',
'sv',
'ta',
'th',
'tl',
'tr',
'uk',
'ur',
'vi',
'zh-Hans',
'zh-Hant',
];
'pl',
'pt-BR',
'ro',
'ru',
'sv',
'ta',
'th',
'tl',
'tr',
'uk',
'ur',
'vi',
'zh-Hans',
'zh-Hant',
];
/**
* --------------------------------------------------------------------------
@@ -261,30 +261,30 @@ class App extends BaseConfig
*/
public array $proxyIPs = [];
/**
* --------------------------------------------------------------------------
* Content Security Policy
* --------------------------------------------------------------------------
*
* Enables the Response's Content Secure Policy to restrict the sources that
* can be used for images, scripts, CSS files, audio, video, etc. If enabled,
* the Response object will populate default values for the policy from the
* `ContentSecurityPolicy.php` file. Controllers can always add to those
* restrictions at run time.
*
* For a better understanding of CSP, see these documents:
*
* @see http://www.html5rocks.com/en/tutorials/security/content-security-policy/
* @see http://www.w3.org/TR/CSP/
*/
public bool $CSPEnabled = false; //TODO: Currently CSP3 tags are not supported so enabling this causes problems with script-src-elem, style-src-attr and style-src-elem
/**
* --------------------------------------------------------------------------
* Content Security Policy
* --------------------------------------------------------------------------
*
* Enables the Response's Content Secure Policy to restrict the sources that
* can be used for images, scripts, CSS files, audio, video, etc. If enabled,
* the Response object will populate default values for the policy from the
* `ContentSecurityPolicy.php` file. Controllers can always add to those
* restrictions at run time.
*
* For a better understanding of CSP, see these documents:
*
* @see http://www.html5rocks.com/en/tutorials/security/content-security-policy/
* @see http://www.w3.org/TR/CSP/
*/
public bool $CSPEnabled = false; //TODO: Currently CSP3 tags are not supported so enabling this causes problems with script-src-elem, style-src-attr and style-src-elem
public function __construct()
{
parent::__construct();
$this->https_on = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_ENV['FORCE_HTTPS']) && $_ENV['FORCE_HTTPS'] == 'true');
$this->baseURL = $this->https_on ? 'https' : 'http';
$this->baseURL .= '://' . ((isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : 'localhost') . '/';
$this->baseURL .= str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
}
public function __construct()
{
parent::__construct();
$this->https_on = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_ENV['FORCE_HTTPS']) && $_ENV['FORCE_HTTPS'] == 'true');
$this->baseURL = $this->https_on ? 'https' : 'http';
$this->baseURL .= '://' . ((isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : 'localhost') . '/';
$this->baseURL .= str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
}
}

View File

@@ -42,7 +42,7 @@ class Autoload extends AutoloadConfig
public $psr4 = [
APP_NAMESPACE => APPPATH,
'Config' => APPPATH . 'Config',
'dompdf' => APPPATH . 'ThirdParty/dompdf/src'
'dompdf' => APPPATH . 'ThirdParty/dompdf/src'
];
/**
@@ -62,115 +62,115 @@ class Autoload extends AutoloadConfig
*
* @var array<string, string>
*/
public $classmap = [
//Controllers
'Attributes' => '/App/Controllers/Attributes.php',
'Cashups' => '/App/Controllers/Cashups.php',
'Config' => '/App/Controllers/Config.php',
'Customers' => '/App/Controllers/Customers.php',
'Employees' => '/App/Controllers/Employees.php',
'Expenses' => '/App/Controllers/Expenses.php',
'Expenses_categories' => '/App/Controllers/Expenses_categories.php',
'Giftcards' => '/App/Controllers/Giftcards.php',
'Home' => '/App/Controllers/Home.php',
'Item_kits' => '/App/Controllers/Item_kits.php',
'Items' => '/App/Controllers/Items.php',
'Login' => '/App/Controllers/Login.php',
'Messages' => '/App/Controllers/Messages.php',
'No_access' => '/App/Controllers/No_access.php',
'Office' => '/App/Controllers/Office.php',
'Persons' => '/App/Controllers/Persons.php',
'Receivings' => '/App/Controllers/Receivings.php',
'Reports' => '/App/Controllers/Reports.php',
'Sales' => '/App/Controllers/Sales.php',
'Secure_Controller' => '/App/Controllers/Secure_Controller.php',
'Suppliers' => '/App/Controllers/Suppliers.php',
'Tax_categories' => '/App/Controllers/Tax_categories.php',
'Tax_codes' => '/App/Controllers/Tax_codes.php',
'Tax_jurisdictions' => '/App/Controllers/Tax_jurisdictions.php',
'Taxes' => '/App/Controllers/Taxes.php',
public $classmap = [
//Controllers
'Attributes' => '/App/Controllers/Attributes.php',
'Cashups' => '/App/Controllers/Cashups.php',
'Config' => '/App/Controllers/Config.php',
'Customers' => '/App/Controllers/Customers.php',
'Employees' => '/App/Controllers/Employees.php',
'Expenses' => '/App/Controllers/Expenses.php',
'Expenses_categories' => '/App/Controllers/Expenses_categories.php',
'Giftcards' => '/App/Controllers/Giftcards.php',
'Home' => '/App/Controllers/Home.php',
'Item_kits' => '/App/Controllers/Item_kits.php',
'Items' => '/App/Controllers/Items.php',
'Login' => '/App/Controllers/Login.php',
'Messages' => '/App/Controllers/Messages.php',
'No_access' => '/App/Controllers/No_access.php',
'Office' => '/App/Controllers/Office.php',
'Persons' => '/App/Controllers/Persons.php',
'Receivings' => '/App/Controllers/Receivings.php',
'Reports' => '/App/Controllers/Reports.php',
'Sales' => '/App/Controllers/Sales.php',
'Secure_Controller' => '/App/Controllers/Secure_Controller.php',
'Suppliers' => '/App/Controllers/Suppliers.php',
'Tax_categories' => '/App/Controllers/Tax_categories.php',
'Tax_codes' => '/App/Controllers/Tax_codes.php',
'Tax_jurisdictions' => '/App/Controllers/Tax_jurisdictions.php',
'Taxes' => '/App/Controllers/Taxes.php',
//Models
'Appconfig' => '/App/Models/Appconfig.php',
'Attribute' => '/App/Models/Attribute.php',
'Cashup' => '/App/Models/Cashup.php',
'Customer' => '/App/Models/Customer.php',
'Customer_rewards' => '/App/Models/Customer_rewards.php',
'Dinner_table' => '/App/Models/Dinner_table.php',
'Employee' => '/App/Models/Employee.php',
'Expense' => '/App/Models/Expense.php',
'Expense_category' => '/App/Models/Expense_category.php',
'Giftcard' => '/App/Models/Giftcard.php',
'Inventory' => '/App/Models/Inventory.php',
'Item_kit' => '/App/Models/Item_kit.php',
'Item_kit_items' => '/App/Models/Item_kit_items.php',
'Item_quantity' => '/App/Models/Item_quantity.php',
'Item_taxes' => '/App/Models/Item_taxes.php',
'Module' => '/App/Models/Module.php',
'Person' => '/App/Models/Person.php',
'Receiving' => '/App/Models/Receiving.php',
'Rewards' => '/App/Models/Rewards.php',
'Sale' => '/App/Models/Sale.php',
'Stock_location' => '/App/Models/Stock_location.php',
'Supplier' => '/App/Models/Supplier.php',
'Tax' => '/App/Models/Tax.php',
'Tax_category' => '/App/Models/Tax_category.php',
'Tax_code' => '/App/Models/Tax_code.php',
'Tax_jurisdiction' => '/App/Models/Tax_jurisdiction.php',
//Models
'Appconfig' => '/App/Models/Appconfig.php',
'Attribute' => '/App/Models/Attribute.php',
'Cashup' => '/App/Models/Cashup.php',
'Customer' => '/App/Models/Customer.php',
'Customer_rewards' => '/App/Models/Customer_rewards.php',
'Dinner_table' => '/App/Models/Dinner_table.php',
'Employee' => '/App/Models/Employee.php',
'Expense' => '/App/Models/Expense.php',
'Expense_category' => '/App/Models/Expense_category.php',
'Giftcard' => '/App/Models/Giftcard.php',
'Inventory' => '/App/Models/Inventory.php',
'Item_kit' => '/App/Models/Item_kit.php',
'Item_kit_items' => '/App/Models/Item_kit_items.php',
'Item_quantity' => '/App/Models/Item_quantity.php',
'Item_taxes' => '/App/Models/Item_taxes.php',
'Module' => '/App/Models/Module.php',
'Person' => '/App/Models/Person.php',
'Receiving' => '/App/Models/Receiving.php',
'Rewards' => '/App/Models/Rewards.php',
'Sale' => '/App/Models/Sale.php',
'Stock_location' => '/App/Models/Stock_location.php',
'Supplier' => '/App/Models/Supplier.php',
'Tax' => '/App/Models/Tax.php',
'Tax_category' => '/App/Models/Tax_category.php',
'Tax_code' => '/App/Models/Tax_code.php',
'Tax_jurisdiction' => '/App/Models/Tax_jurisdiction.php',
//Reports
'Report' => '/App/Models/Reports/Report.php',
'Detailed_receiving' => '/App/Models/Reports/Detailed_receiving.php',
'Detailed_sales' => '/App/Models/Reports/Detailed_sales.php',
'Inventory_low' => '/App/Models/Reports/Inventory_low.php',
'Inventory_summary' => '/App/Models/Reports/Inventory_summary.php',
'Specific_customer' => '/App/Models/Reports/Specific_customer.php',
'Specific_discount' => '/App/Models/Reports/Specific_discount.php',
'Specific_employee' => '/App/Models/Reports/Specific_employee.php',
'Specific_supplier' => '/App/Models/Reports/Specific_supplier.php',
'Summary_categories' => '/App/Models/Reports/Summary_categories.php',
'Summary_customers' => '/App/Models/Reports/Summary_customers.php',
'Summary_discounts' => '/App/Models/Reports/Summary_discounts.php',
'Summary_employees' => '/App/Models/Reports/Summary_employees.php',
'Summary_expenses_categories' => '/App/Models/Reports/Summary_expenses_categories.php',
'Summary_items' => '/App/Models/Reports/Summary_items.php',
'Summary_payments' => '/App/Models/Reports/Summary_payments.php',
'Summary_report' => '/App/Models/Reports/Summary_report.php',
'Summary_sales' => '/App/Models/Reports/Summary_sales.php',
'Summary_sales_taxes' => '/App/Models/Reports/Summary_sales_taxes.php',
'Summary_suppliers' => '/App/Models/Reports/Summary_suppliers.php',
'Summary_taxes' => '/App/Models/Reports/Summary_taxes.php',
//Reports
'Report' => '/App/Models/Reports/Report.php',
'Detailed_receiving' => '/App/Models/Reports/Detailed_receiving.php',
'Detailed_sales' => '/App/Models/Reports/Detailed_sales.php',
'Inventory_low' => '/App/Models/Reports/Inventory_low.php',
'Inventory_summary' => '/App/Models/Reports/Inventory_summary.php',
'Specific_customer' => '/App/Models/Reports/Specific_customer.php',
'Specific_discount' => '/App/Models/Reports/Specific_discount.php',
'Specific_employee' => '/App/Models/Reports/Specific_employee.php',
'Specific_supplier' => '/App/Models/Reports/Specific_supplier.php',
'Summary_categories' => '/App/Models/Reports/Summary_categories.php',
'Summary_customers' => '/App/Models/Reports/Summary_customers.php',
'Summary_discounts' => '/App/Models/Reports/Summary_discounts.php',
'Summary_employees' => '/App/Models/Reports/Summary_employees.php',
'Summary_expenses_categories' => '/App/Models/Reports/Summary_expenses_categories.php',
'Summary_items' => '/App/Models/Reports/Summary_items.php',
'Summary_payments' => '/App/Models/Reports/Summary_payments.php',
'Summary_report' => '/App/Models/Reports/Summary_report.php',
'Summary_sales' => '/App/Models/Reports/Summary_sales.php',
'Summary_sales_taxes' => '/App/Models/Reports/Summary_sales_taxes.php',
'Summary_suppliers' => '/App/Models/Reports/Summary_suppliers.php',
'Summary_taxes' => '/App/Models/Reports/Summary_taxes.php',
//Tokens
'Token' => '/App/Models/Tokens/Token.php',
'Token_barcode_ean' => '/App/Models/Tokens/Token_barcode_ean.php',
'Token_barcode_price' => '/App/Models/Tokens/Token_barcode_price.php',
'Token_barcode_weight' => '/App/Models/Tokens/Token_barcode_weight.php',
'Token_customer' => '/App/Models/Tokens/Token_customer.php',
'Token_invoice_count' => '/App/Models/Tokens/Token_invoice_count.php',
'Token_invoice_sequence' => '/App/Models/Tokens/Token_invoice_sequence.php',
'Token_quote_sequence' => '/App/Models/Tokens/Token_quote_sequence.php',
'Token_suspended_invoice_count' => '/App/Models/Tokens/Token_suspended_invoice_count.php',
'Token_work_order_sequence' => '/App/Models/Tokens/Token_work_order_sequence.php',
'Token_year_invoice_count' => '/App/Models/Tokens/Token_year_invoice_count.php',
'Token_year_quote_count' => '/App/Models/Tokens/Token_year_quote_count.php',
//Tokens
'Token' => '/App/Models/Tokens/Token.php',
'Token_barcode_ean' => '/App/Models/Tokens/Token_barcode_ean.php',
'Token_barcode_price' => '/App/Models/Tokens/Token_barcode_price.php',
'Token_barcode_weight' => '/App/Models/Tokens/Token_barcode_weight.php',
'Token_customer' => '/App/Models/Tokens/Token_customer.php',
'Token_invoice_count' => '/App/Models/Tokens/Token_invoice_count.php',
'Token_invoice_sequence' => '/App/Models/Tokens/Token_invoice_sequence.php',
'Token_quote_sequence' => '/App/Models/Tokens/Token_quote_sequence.php',
'Token_suspended_invoice_count' => '/App/Models/Tokens/Token_suspended_invoice_count.php',
'Token_work_order_sequence' => '/App/Models/Tokens/Token_work_order_sequence.php',
'Token_year_invoice_count' => '/App/Models/Tokens/Token_year_invoice_count.php',
'Token_year_quote_count' => '/App/Models/Tokens/Token_year_quote_count.php',
//Libraries
'Barcode_lib' => '/App/Libraries/Barcode_lib.php',
'Email_lib' => '/App/Libraries/Email_lib.php',
'Item_lib' => '/App/Libraries/Item_lib.php',
'Mailchimp_lib' => '/App/Libraries/Mailchimp_lib.php',
'MY_Email' => '/App/Libraries/MY_Email.php',
'MY_Migration' => '/App/Libraries/MY_Migration.php',
'Receving_lib' => '/App/Libraries/Receiving_lib.php',
'Sale_lib' => '/App/Libraries/Sale_lib.php',
'Sms_lib' => '/App/Libraries/Sms_lib.php',
'Tax_lib' => '/App/Libraries/Tax_lib.php',
'Token_lib' => '/App/Libraries/Token_lib.php',
//Libraries
'Barcode_lib' => '/App/Libraries/Barcode_lib.php',
'Email_lib' => '/App/Libraries/Email_lib.php',
'Item_lib' => '/App/Libraries/Item_lib.php',
'Mailchimp_lib' => '/App/Libraries/Mailchimp_lib.php',
'MY_Email' => '/App/Libraries/MY_Email.php',
'MY_Migration' => '/App/Libraries/MY_Migration.php',
'Receving_lib' => '/App/Libraries/Receiving_lib.php',
'Sale_lib' => '/App/Libraries/Sale_lib.php',
'Sms_lib' => '/App/Libraries/Sms_lib.php',
'Tax_lib' => '/App/Libraries/Tax_lib.php',
'Token_lib' => '/App/Libraries/Token_lib.php',
//Miscellaneous
'Rounding_mode' => '/App/Models/Enums/Rounding_mode.php'
];
//Miscellaneous
'Rounding_mode' => '/App/Models/Enums/Rounding_mode.php'
];
/**
* -------------------------------------------------------------------
@@ -201,10 +201,10 @@ class Autoload extends AutoloadConfig
* @var list<string>
*/
public $helpers = [
'form',
'cookie',
'tabular',
'locale',
'security'
];
'form',
'cookie',
'tabular',
'locale',
'security'
];
}

View File

@@ -48,9 +48,9 @@ class ContentSecurityPolicy extends BaseConfig
* @var list<string>|string|null
*/
public $defaultSrc = [
'self',
'www.google.com',
];
'self',
'www.google.com',
];
/**
* Lists allowed scripts' URLs.
@@ -58,23 +58,23 @@ class ContentSecurityPolicy extends BaseConfig
* @var list<string>|string
*/
public $scriptSrc = [
'self',
'unsafe-inline',
'unsafe-eval',
'www.google.com www.gstatic.com'
];
'self',
'unsafe-inline',
'unsafe-eval',
'www.google.com www.gstatic.com'
];
/**
* Lists allowed stylesheets' URLs.
*
* @var list<string>|string
*/
public $styleSrc = [
'self',
'unsafe-inline',
'nonce-{csp-style-nonce}',
'https://fonts.googleapis.com',
];
public $styleSrc = [
'self',
'unsafe-inline',
'nonce-{csp-style-nonce}',
'https://fonts.googleapis.com',
];
/**
* Defines the origins from which images can be loaded.
@@ -82,10 +82,10 @@ class ContentSecurityPolicy extends BaseConfig
* @var list<string>|string
*/
public $imageSrc = [
'self',
'data:',
'blob:',
];
'self',
'data:',
'blob:',
];
/**
* Restricts the URLs that can appear in a page's `<base>` element.
@@ -110,9 +110,9 @@ class ContentSecurityPolicy extends BaseConfig
* @var list<string>|string
*/
public $connectSrc = [
'self',
'nominatim.openstreetmap.org',
];
'self',
'nominatim.openstreetmap.org',
];
/**
* Specifies the origins that can serve web fonts.
@@ -120,10 +120,10 @@ class ContentSecurityPolicy extends BaseConfig
* @var list<string>|string
*/
public $fontSrc = [
'self',
'fonts.googleapis.com',
'fonts.gstatic.com',
];
'self',
'fonts.googleapis.com',
'fonts.gstatic.com',
];
/**
* Lists valid endpoints for submission from `<form>` tags.

View File

@@ -19,104 +19,104 @@ class Database extends Config
*/
public string $defaultGroup = 'default';
/**
* The default database connection.
*
* @var array<string, mixed>
*/
public array $default = [
'DSN' => '',
'hostname' => 'localhost',
'username' => 'admin',
'password' => 'pointofsale',
'database' => 'ospos',
'DBDriver' => 'MySQLi',
'DBPrefix' => 'ospos_',
'pConnect' => false,
'DBDebug' => (ENVIRONMENT !== 'production'),
'charset' => 'utf8mb4',
'DBCollat' => 'utf8mb4_general_ci',
'swapPre' => '',
'encrypt' => false,
'compress' => false,
'strictOn' => false,
'failover' => [],
'port' => 3306,
'numberNative' => false,
'dateFormat' => [
'date' => 'Y-m-d',
'datetime' => 'Y-m-d H:i:s',
'time' => 'H:i:s',
],
];
/**
* The default database connection.
*
* @var array<string, mixed>
*/
public array $default = [
'DSN' => '',
'hostname' => 'localhost',
'username' => 'admin',
'password' => 'pointofsale',
'database' => 'ospos',
'DBDriver' => 'MySQLi',
'DBPrefix' => 'ospos_',
'pConnect' => false,
'DBDebug' => (ENVIRONMENT !== 'production'),
'charset' => 'utf8mb4',
'DBCollat' => 'utf8mb4_general_ci',
'swapPre' => '',
'encrypt' => false,
'compress' => false,
'strictOn' => false,
'failover' => [],
'port' => 3306,
'numberNative' => false,
'dateFormat' => [
'date' => 'Y-m-d',
'datetime' => 'Y-m-d H:i:s',
'time' => 'H:i:s',
],
];
/**
* This database connection is used when
* running PHPUnit database tests.
*
* @var array<string, mixed>
*/
public array $tests = [
'DSN' => '',
'hostname' => 'localhost',
'username' => 'admin',
'password' => 'pointofsale',
'database' => 'ospos',
'DBDriver' => 'MySQLi',
'DBPrefix' => 'ospos_',
'pConnect' => false,
'DBDebug' => (ENVIRONMENT !== 'production'),
'charset' => 'utf8mb4',
'DBCollat' => 'utf8mb4_general_ci',
'swapPre' => '',
'encrypt' => false,
'compress' => false,
'strictOn' => false,
'failover' => [],
'port' => 3306,
'foreignKeys' => true,
'busyTimeout' => 1000,
'numberNative' => false,
'dateFormat' => [
'date' => 'Y-m-d',
'datetime' => 'Y-m-d H:i:s',
'time' => 'H:i:s',
],
];
/**
* This database connection is used when
* running PHPUnit database tests.
*
* @var array<string, mixed>
*/
public array $tests = [
'DSN' => '',
'hostname' => 'localhost',
'username' => 'admin',
'password' => 'pointofsale',
'database' => 'ospos',
'DBDriver' => 'MySQLi',
'DBPrefix' => 'ospos_',
'pConnect' => false,
'DBDebug' => (ENVIRONMENT !== 'production'),
'charset' => 'utf8mb4',
'DBCollat' => 'utf8mb4_general_ci',
'swapPre' => '',
'encrypt' => false,
'compress' => false,
'strictOn' => false,
'failover' => [],
'port' => 3306,
'foreignKeys' => true,
'busyTimeout' => 1000,
'numberNative' => false,
'dateFormat' => [
'date' => 'Y-m-d',
'datetime' => 'Y-m-d H:i:s',
'time' => 'H:i:s',
],
];
/**
* This database connection is used when
* developing against non-production data.
*
* @var array
*/
public $development = [
'DSN' => '',
'hostname' => 'localhost',
'username' => 'admin',
'password' => 'pointofsale',
'database' => 'ospos',
'DBDriver' => 'MySQLi',
'DBPrefix' => 'ospos_',
'pConnect' => false,
'DBDebug' => (ENVIRONMENT !== 'production'),
'charset' => 'utf8mb4',
'DBCollat' => 'utf8mb4_general_ci',
'swapPre' => '',
'encrypt' => false,
'compress' => false,
'strictOn' => false,
'failover' => [],
'port' => 3306,
'foreignKeys' => true,
'busyTimeout' => 1000,
'numberNative' => false,
'dateFormat' => [
'date' => 'Y-m-d',
'datetime' => 'Y-m-d H:i:s',
'time' => 'H:i:s',
],
];
/**
* This database connection is used when
* developing against non-production data.
*
* @var array
*/
public $development = [
'DSN' => '',
'hostname' => 'localhost',
'username' => 'admin',
'password' => 'pointofsale',
'database' => 'ospos',
'DBDriver' => 'MySQLi',
'DBPrefix' => 'ospos_',
'pConnect' => false,
'DBDebug' => (ENVIRONMENT !== 'production'),
'charset' => 'utf8mb4',
'DBCollat' => 'utf8mb4_general_ci',
'swapPre' => '',
'encrypt' => false,
'compress' => false,
'strictOn' => false,
'failover' => [],
'port' => 3306,
'foreignKeys' => true,
'busyTimeout' => 1000,
'numberNative' => false,
'dateFormat' => [
'date' => 'Y-m-d',
'datetime' => 'Y-m-d H:i:s',
'time' => 'H:i:s',
],
];
public function __construct()
{
@@ -125,22 +125,22 @@ class Database extends Config
// Ensure that we always set the database group to 'tests' if
// we are currently running an automated test suite, so that
// we don't overwrite live data on accident.
switch(ENVIRONMENT)
{
case 'testing':
$this->defaultGroup = 'tests';
break;
case 'development';
$this->defaultGroup = 'development';
break;
}
switch(ENVIRONMENT)
{
case 'testing':
$this->defaultGroup = 'tests';
break;
case 'development';
$this->defaultGroup = 'development';
break;
}
foreach ([&$this->development, &$this->tests, &$this->default] as &$config)
{
$config['hostname'] = !getenv('MYSQL_HOST_NAME') ? $config['hostname'] : getenv('MYSQL_HOST_NAME');
$config['username'] = !getenv('MYSQL_USERNAME') ? $config['username'] : getenv('MYSQL_USERNAME');
$config['password'] = !getenv('MYSQL_PASSWORD') ? $config['password'] : getenv('MYSQL_PASSWORD');
$config['database'] = !getenv('MYSQL_DB_NAME') ? $config['database'] : getenv('MYSQL_DB_NAME');
}
foreach ([&$this->development, &$this->tests, &$this->default] as &$config)
{
$config['hostname'] = !getenv('MYSQL_HOST_NAME') ? $config['hostname'] : getenv('MYSQL_HOST_NAME');
$config['username'] = !getenv('MYSQL_USERNAME') ? $config['username'] : getenv('MYSQL_USERNAME');
$config['password'] = !getenv('MYSQL_PASSWORD') ? $config['password'] : getenv('MYSQL_PASSWORD');
$config['database'] = !getenv('MYSQL_DB_NAME') ? $config['database'] : getenv('MYSQL_DB_NAME');
}
}
}

View File

@@ -70,7 +70,7 @@ class Filters extends BaseFilters
public array $globals = [
'before' => [
'honeypot',
//'csrf' => ['except' => 'login'], //TODO: Temporarily disable CSRF until we get everything sorted.
//'csrf' => ['except' => 'login'], //TODO: Temporarily disable CSRF until we get everything sorted.
'invalidchars',
],
'after' => [

View File

@@ -491,11 +491,11 @@ class Mimes
* @return string|null The mime type found, or none if unable to determine.
*/
public static function guessTypeFromExtension(string $extension): array|string|null
{
{
$extension = trim(strtolower($extension), '. ');
if (!array_key_exists($extension, static::$mimes))
{
{
return null;
}
@@ -510,7 +510,7 @@ class Mimes
* @return string|null The extension determined, or null if unable to match.
*/
public static function guessExtensionFromType(string $type, ?string $proposedExtension = null): ?string
{
{
$type = trim(strtolower($type), '. ');
$proposedExtension = trim(strtolower($proposedExtension ?? ''));

View File

@@ -13,45 +13,45 @@ use CodeIgniter\Config\BaseConfig;
*/
class OSPOS extends BaseConfig
{
public array $settings;
public string $commit_sha1 = 'dev'; //TODO: Travis scripts need to be updated to replace this with the commit hash on build
private CacheInterface $cache;
public array $settings;
public string $commit_sha1 = 'dev'; //TODO: Travis scripts need to be updated to replace this with the commit hash on build
private CacheInterface $cache;
public function __construct()
{
parent::__construct();
$this->cache = Services::cache();
$this->set_settings();
}
public function __construct()
{
parent::__construct();
$this->cache = Services::cache();
$this->set_settings();
}
/**
* @return void
*/
public function set_settings(): void
{
$cache = $this->cache->get('settings');
/**
* @return void
*/
public function set_settings(): void
{
$cache = $this->cache->get('settings');
if($cache)
{
$this->settings = decode_array($cache);
}
else
{
$appconfig = model(Appconfig::class);
foreach($appconfig->get_all()->getResult() as $app_config)
{
$this->settings[$app_config->key] = $app_config->value;
}
$this->cache->save('settings', encode_array($this->settings));
}
}
if($cache)
{
$this->settings = decode_array($cache);
}
else
{
$appconfig = model(Appconfig::class);
foreach($appconfig->get_all()->getResult() as $app_config)
{
$this->settings[$app_config->key] = $app_config->value;
}
$this->cache->save('settings', encode_array($this->settings));
}
}
/**
* @return void
*/
public function update_settings(): void
{
$this->cache->delete('settings');
$this->set_settings();
}
/**
* @return void
*/
public function update_settings(): void
{
$this->cache->delete('settings');
$this->set_settings();
}
}

View File

@@ -35,27 +35,27 @@ class Pager extends BaseConfig
*/
public int $perPage = 20;
/**
* --------------------------------------------------------------------------
* Bootstrap 3 pagination links styling
* --------------------------------------------------------------------------
*
* Source code from http://stackoverflow.com/questions/20088779/bootstrap-3-pagination-with-codeigniter
*/
public $config = [
'full_tag_open' => "<ul class='pagination pagination-sm'>",
'full_tag_close' => '</ul>',
'num_tag_open' => '<li>',
'num_tag_close' => '</li>',
'cur_tag_open' => "<li class='disabled'><li class='active'><a href='#'>",
'cur_tag_close' => "<span class='sr-only'></span></a></li>",
'next_tag_open' => "<li>",
'next_tagl_close' => "</li>",
'prev_tag_open' => "<li>",
'prev_tagl_close' => "</li>",
'first_tag_open' => "<li>",
'first_tagl_close' => "</li>",
'last_tag_open' => "<li>",
'last_tagl_close' => "</li>"
];
/**
* --------------------------------------------------------------------------
* Bootstrap 3 pagination links styling
* --------------------------------------------------------------------------
*
* Source code from http://stackoverflow.com/questions/20088779/bootstrap-3-pagination-with-codeigniter
*/
public $config = [
'full_tag_open' => "<ul class='pagination pagination-sm'>",
'full_tag_close' => '</ul>',
'num_tag_open' => '<li>',
'num_tag_close' => '</li>',
'cur_tag_open' => "<li class='disabled'><li class='active'><a href='#'>",
'cur_tag_close' => "<span class='sr-only'></span></a></li>",
'next_tag_open' => "<li>",
'next_tagl_close' => "</li>",
'prev_tag_open' => "<li>",
'prev_tagl_close' => "</li>",
'first_tag_open' => "<li>",
'first_tagl_close' => "</li>",
'last_tag_open' => "<li>",
'last_tagl_close' => "</li>"
];
}

View File

@@ -34,44 +34,44 @@ class Services extends BaseService
* }
*/
/**
* Responsible for loading the language string translations.
*
* @return MY_Language
*/
public static function language(?string $locale = null, bool $getShared = true)
{
if ($getShared) {
return static::getSharedInstance('language', $locale)->setLocale($locale);
}
/**
* Responsible for loading the language string translations.
*
* @return MY_Language
*/
public static function language(?string $locale = null, bool $getShared = true)
{
if ($getShared) {
return static::getSharedInstance('language', $locale)->setLocale($locale);
}
if (AppServices::get('request') instanceof IncomingRequest) {
$requestLocale = AppServices::get('request')->getLocale();
} else {
$requestLocale = Locale::getDefault();
}
if (AppServices::get('request') instanceof IncomingRequest) {
$requestLocale = AppServices::get('request')->getLocale();
} else {
$requestLocale = Locale::getDefault();
}
// Use '?:' for empty string check
$locale = $locale ?: $requestLocale;
// Use '?:' for empty string check
$locale = $locale ?: $requestLocale;
return new \App\Libraries\MY_Language($locale);
}
return new \App\Libraries\MY_Language($locale);
}
private static $htmlPurifier;
private static $htmlPurifier;
public static function htmlPurifier($getShared = true)
{
if ($getShared)
{
return static::getSharedInstance('htmlPurifier');
}
public static function htmlPurifier($getShared = true)
{
if ($getShared)
{
return static::getSharedInstance('htmlPurifier');
}
if (!isset(static::$htmlPurifier))
{
$config = HTMLPurifier_Config::createDefault();
static::$htmlPurifier = new HTMLPurifier($config);
}
if (!isset(static::$htmlPurifier))
{
$config = HTMLPurifier_Config::createDefault();
static::$htmlPurifier = new HTMLPurifier($config);
}
return static::$htmlPurifier;
}
return static::$htmlPurifier;
}
}

View File

@@ -26,8 +26,8 @@ class Validation extends BaseConfig
FormatRules::class,
FileRules::class,
CreditCardRules::class,
OSPOSRules::class
];
OSPOSRules::class
];
/**
* Specifies the views that are used to display the

View File

@@ -12,134 +12,134 @@ use Config\Services;
*/
class OSPOSRules
{
private IncomingRequest $request;
private array $config;
private IncomingRequest $request;
private array $config;
/**
* Validates the username and password sent to the login view. User is logged in on successful validation.
*
* @param string $username Username to check against.
* @param string $fields Comma separated string of the fields for validation.
* @param array $data Data sent to the view.
* @param string|null $error The error sent back to the validation handler on failure.
* @return bool True if validation passes or false if there are errors.
* @noinspection PhpUnused
*/
public function login_check(string $username, string $fields , array $data, ?string &$error = null): bool
{
$employee = model(Employee::class);
$this->request = Services::request();
$this->config = config(OSPOS::class)->settings;
/**
* Validates the username and password sent to the login view. User is logged in on successful validation.
*
* @param string $username Username to check against.
* @param string $fields Comma separated string of the fields for validation.
* @param array $data Data sent to the view.
* @param string|null $error The error sent back to the validation handler on failure.
* @return bool True if validation passes or false if there are errors.
* @noinspection PhpUnused
*/
public function login_check(string $username, string $fields , array $data, ?string &$error = null): bool
{
$employee = model(Employee::class);
$this->request = Services::request();
$this->config = config(OSPOS::class)->settings;
//Installation Check
if(!$this->installation_check())
{
$error = lang('Login.invalid_installation');
//Installation Check
if(!$this->installation_check())
{
$error = lang('Login.invalid_installation');
return false;
}
return false;
}
$password = $data['password'];
if(!$employee->login($username, $password))
{
$error = lang('Login.invalid_username_and_password');
$password = $data['password'];
if(!$employee->login($username, $password))
{
$error = lang('Login.invalid_username_and_password');
return false;
}
return false;
}
$gcaptcha_enabled = array_key_exists('gcaptcha_enable', $this->config) && $this->config['gcaptcha_enable'];
if($gcaptcha_enabled)
{
$g_recaptcha_response = $this->request->getPost('g-recaptcha-response');
$gcaptcha_enabled = array_key_exists('gcaptcha_enable', $this->config) && $this->config['gcaptcha_enable'];
if($gcaptcha_enabled)
{
$g_recaptcha_response = $this->request->getPost('g-recaptcha-response');
if(!$this->gcaptcha_check($g_recaptcha_response))
{
$error = lang('Login.invalid_gcaptcha');
if(!$this->gcaptcha_check($g_recaptcha_response))
{
$error = lang('Login.invalid_gcaptcha');
return false;
}
}
return false;
}
}
return true;
}
return true;
}
/**
* Checks to see if GCaptcha verification was successful.
*
* @param $response
* @return bool true on successful GCaptcha verification or false if GCaptcha failed.
*/
private function gcaptcha_check($response): bool
{
if(!empty($response))
{
$check = [
'secret' => $this->config['gcaptcha_secret_key'],
'response' => $response,
'remoteip' => $this->request->getIPAddress()
];
/**
* Checks to see if GCaptcha verification was successful.
*
* @param $response
* @return bool true on successful GCaptcha verification or false if GCaptcha failed.
*/
private function gcaptcha_check($response): bool
{
if(!empty($response))
{
$check = [
'secret' => $this->config['gcaptcha_secret_key'],
'response' => $response,
'remoteip' => $this->request->getIPAddress()
];
$ch = curl_init();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://www.google.com/recaptcha/api/siteverify");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($check));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, "https://www.google.com/recaptcha/api/siteverify");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($check));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$result = curl_exec($ch);
curl_close($ch);
curl_close($ch);
$status = json_decode($result, true);
$status = json_decode($result, true);
if(!empty($status['success']))
{
return true;
}
}
if(!empty($status['success']))
{
return true;
}
}
return false;
}
return false;
}
/**
* Checks to make sure dependency PHP extensions are installed
*
* @return bool
*/
private function installation_check(): bool
{
$installed_extensions = implode(', ', get_loaded_extensions());
$required_extensions = ['bcmath', 'intl', 'gd', 'openssl', 'mbstring', 'curl', 'xml', 'json'];
$pattern = '/';
/**
* Checks to make sure dependency PHP extensions are installed
*
* @return bool
*/
private function installation_check(): bool
{
$installed_extensions = implode(', ', get_loaded_extensions());
$required_extensions = ['bcmath', 'intl', 'gd', 'openssl', 'mbstring', 'curl', 'xml', 'json'];
$pattern = '/';
foreach($required_extensions as $extension)
{
$pattern .= '(?=.*\b' . preg_quote($extension, '/') . '\b)';
}
foreach($required_extensions as $extension)
{
$pattern .= '(?=.*\b' . preg_quote($extension, '/') . '\b)';
}
$pattern .= '/i';
$is_installed = preg_match($pattern, $installed_extensions);
$pattern .= '/i';
$is_installed = preg_match($pattern, $installed_extensions);
if(!$is_installed)
{
log_message('error', '[ERROR] Check your php.ini.');
log_message('error',"PHP installed extensions: $installed_extensions");
log_message('error','PHP required extensions: ' . implode(', ', $required_extensions));
}
if(!$is_installed)
{
log_message('error', '[ERROR] Check your php.ini.');
log_message('error',"PHP installed extensions: $installed_extensions");
log_message('error','PHP required extensions: ' . implode(', ', $required_extensions));
}
return $is_installed;
}
return $is_installed;
}
/**
* Validates the candidate as a decimal number. Takes the locale into account. Used in validation rule calls.
*
* @param string $candidate
* @param string|null $error
* @return bool
* @noinspection PhpUnused
*/
public function decimal_locale(string $candidate, ?string &$error = null): bool
{
return parse_decimals($candidate) !== false;
}
/**
* Validates the candidate as a decimal number. Takes the locale into account. Used in validation rule calls.
*
* @param string $candidate
* @param string|null $error
* @return bool
* @noinspection PhpUnused
*/
public function decimal_locale(string $candidate, ?string &$error = null): bool
{
return parse_decimals($candidate) !== false;
}
}

View File

@@ -12,252 +12,252 @@ require_once('Secure_Controller.php');
**/
class Attributes extends Secure_Controller
{
private Attribute $attribute;
private Attribute $attribute;
public function __construct()
{
parent::__construct('attributes');
public function __construct()
{
parent::__construct('attributes');
$this->attribute = model(Attribute::class);
}
$this->attribute = model(Attribute::class);
}
/**
* Gets and sends the main view for Attributes to the browser.
*
* @return void
**/
public function getIndex(): void
{
$data['table_headers'] = get_attribute_definition_manage_table_headers();
/**
* Gets and sends the main view for Attributes to the browser.
*
* @return void
**/
public function getIndex(): void
{
$data['table_headers'] = get_attribute_definition_manage_table_headers();
echo view('attributes/manage', $data);
}
echo view('attributes/manage', $data);
}
/**
* Returns attribute table data rows. This will be called with AJAX.
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(attribute_definition_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'definition_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* Returns attribute table data rows. This will be called with AJAX.
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(attribute_definition_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'definition_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$attributes = $this->attribute->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->attribute->get_found_rows($search);
$attributes = $this->attribute->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->attribute->get_found_rows($search);
$data_rows = [];
foreach($attributes->getResult() as $attribute_row)
{
$attribute_row->definition_flags = $this->get_attributes($attribute_row->definition_flags);
$data_rows[] = get_attribute_definition_data_row($attribute_row);
}
$data_rows = [];
foreach($attributes->getResult() as $attribute_row)
{
$attribute_row->definition_flags = $this->get_attributes($attribute_row->definition_flags);
$data_rows[] = get_attribute_definition_data_row($attribute_row);
}
echo json_encode(['total' => $total_rows, 'rows' => $data_rows]);
}
echo json_encode(['total' => $total_rows, 'rows' => $data_rows]);
}
/**
* AJAX called function which saves the attribute value sent via POST by using the model save function.
* @return void
* @noinspection PhpUnused
*/
public function postSaveAttributeValue(): void
{
$success = $this->attribute->saveAttributeValue(
html_entity_decode($this->request->getPost('attribute_value')),
$this->request->getPost('definition_id', FILTER_SANITIZE_NUMBER_INT),
$this->request->getPost('item_id', FILTER_SANITIZE_NUMBER_INT) ?? false,
$this->request->getPost('attribute_id', FILTER_SANITIZE_NUMBER_INT) ?? false
);
/**
* AJAX called function which saves the attribute value sent via POST by using the model save function.
* @return void
* @noinspection PhpUnused
*/
public function postSaveAttributeValue(): void
{
$success = $this->attribute->saveAttributeValue(
html_entity_decode($this->request->getPost('attribute_value')),
$this->request->getPost('definition_id', FILTER_SANITIZE_NUMBER_INT),
$this->request->getPost('item_id', FILTER_SANITIZE_NUMBER_INT) ?? false,
$this->request->getPost('attribute_id', FILTER_SANITIZE_NUMBER_INT) ?? false
);
echo json_encode(['success' => $success != 0]);
}
echo json_encode(['success' => $success != 0]);
}
/**
* AJAX called function deleting an attribute value using the model delete function.
* @return void
* @noinspection PhpUnused
*/
public function postDelete_attribute_value(): void
{
$success = $this->attribute->delete_value(
html_entity_decode($this->request->getPost('attribute_value')),
$this->request->getPost('definition_id', FILTER_SANITIZE_NUMBER_INT)
);
/**
* AJAX called function deleting an attribute value using the model delete function.
* @return void
* @noinspection PhpUnused
*/
public function postDelete_attribute_value(): void
{
$success = $this->attribute->delete_value(
html_entity_decode($this->request->getPost('attribute_value')),
$this->request->getPost('definition_id', FILTER_SANITIZE_NUMBER_INT)
);
echo json_encode(['success' => $success]);
}
echo json_encode(['success' => $success]);
}
/**
* AJAX called function which saves the attribute definition.
*
* @param int $definition_id
* @return void
* @noinspection PhpUnused
*/
public function postSaveDefinition(int $definition_id = NO_DEFINITION_ID): void
{
$definition_flags = 0;
/**
* AJAX called function which saves the attribute definition.
*
* @param int $definition_id
* @return void
* @noinspection PhpUnused
*/
public function postSaveDefinition(int $definition_id = NO_DEFINITION_ID): void
{
$definition_flags = 0;
$flags = (empty($this->request->getPost('definition_flags'))) ? [] : $this->request->getPost('definition_flags', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$flags = (empty($this->request->getPost('definition_flags'))) ? [] : $this->request->getPost('definition_flags', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
foreach($flags as $flag)
{
$definition_flags |= $flag;
}
foreach($flags as $flag)
{
$definition_flags |= $flag;
}
//Save definition data
$definition_data = [
'definition_name' => $this->request->getPost('definition_name'),
'definition_unit' => $this->request->getPost('definition_unit') != '' ? $this->request->getPost('definition_unit') : null,
'definition_flags' => $definition_flags,
'definition_fk' => $this->request->getPost('definition_group') != '' ? $this->request->getPost('definition_group') : null
];
//Save definition data
$definition_data = [
'definition_name' => $this->request->getPost('definition_name'),
'definition_unit' => $this->request->getPost('definition_unit') != '' ? $this->request->getPost('definition_unit') : null,
'definition_flags' => $definition_flags,
'definition_fk' => $this->request->getPost('definition_group') != '' ? $this->request->getPost('definition_group') : null
];
if ($this->request->getPost('definition_type') != null)
{
$definition_data['definition_type'] = DEFINITION_TYPES[$this->request->getPost('definition_type')];
}
if ($this->request->getPost('definition_type') != null)
{
$definition_data['definition_type'] = DEFINITION_TYPES[$this->request->getPost('definition_type')];
}
$definition_name = $definition_data['definition_name'];
$definition_name = $definition_data['definition_name'];
if($this->attribute->save_definition($definition_data, $definition_id))
{
//New definition
if($definition_id == NO_DEFINITION_ID)
{
$definition_values = json_decode(html_entity_decode($this->request->getPost('definition_values')));
if($this->attribute->save_definition($definition_data, $definition_id))
{
//New definition
if($definition_id == NO_DEFINITION_ID)
{
$definition_values = json_decode(html_entity_decode($this->request->getPost('definition_values')));
foreach($definition_values as $definition_value)
{
$this->attribute->saveAttributeValue($definition_value, $definition_data['definition_id']);
}
foreach($definition_values as $definition_value)
{
$this->attribute->saveAttributeValue($definition_value, $definition_data['definition_id']);
}
echo json_encode([
'success' => true,
'message' => lang('Attributes.definition_successful_adding') . ' ' . $definition_name,
'id' => $definition_data['definition_id']
]);
}
//Existing definition
else
{
echo json_encode([
'success' => true,
'message' => lang('Attributes.definition_successful_updating') . ' ' . $definition_name,
'id' => $definition_id
]);
}
}
//Failure
else
{
echo json_encode([
'success' => false,
'message' => lang('Attributes.definition_error_adding_updating', [$definition_name]),
'id' => NEW_ENTRY
]);
}
}
echo json_encode([
'success' => true,
'message' => lang('Attributes.definition_successful_adding') . ' ' . $definition_name,
'id' => $definition_data['definition_id']
]);
}
//Existing definition
else
{
echo json_encode([
'success' => true,
'message' => lang('Attributes.definition_successful_updating') . ' ' . $definition_name,
'id' => $definition_id
]);
}
}
//Failure
else
{
echo json_encode([
'success' => false,
'message' => lang('Attributes.definition_error_adding_updating', [$definition_name]),
'id' => NEW_ENTRY
]);
}
}
/**
*
* @param int $definition_id
* @return void
* @noinspection PhpUnused
*/
public function getSuggestAttribute(int $definition_id): void
{
$suggestions = $this->attribute->get_suggestions($definition_id, html_entity_decode($this->request->getGet('term')));
/**
*
* @param int $definition_id
* @return void
* @noinspection PhpUnused
*/
public function getSuggestAttribute(int $definition_id): void
{
$suggestions = $this->attribute->get_suggestions($definition_id, html_entity_decode($this->request->getGet('term')));
echo json_encode($suggestions);
}
echo json_encode($suggestions);
}
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$attribute_definition_info = $this->attribute->getAttributeInfo($row_id);
$attribute_definition_info->definition_flags = $this->get_attributes($attribute_definition_info->definition_flags);
$data_row = get_attribute_definition_data_row($attribute_definition_info);
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$attribute_definition_info = $this->attribute->getAttributeInfo($row_id);
$attribute_definition_info->definition_flags = $this->get_attributes($attribute_definition_info->definition_flags);
$data_row = get_attribute_definition_data_row($attribute_definition_info);
echo json_encode($data_row);
}
echo json_encode($data_row);
}
/**
* @param int $definition_flags
* @return array
*/
private function get_attributes(int $definition_flags = 0): array
{
$definition_flag_names = [];
foreach (Attribute::get_definition_flags() as $id => $term)
{
if ($id & $definition_flags)
{
$definition_flag_names[$id] = lang('Attributes.' . strtolower($term) . '_visibility');
}
}
return $definition_flag_names;
}
/**
* @param int $definition_flags
* @return array
*/
private function get_attributes(int $definition_flags = 0): array
{
$definition_flag_names = [];
foreach (Attribute::get_definition_flags() as $id => $term)
{
if ($id & $definition_flags)
{
$definition_flag_names[$id] = lang('Attributes.' . strtolower($term) . '_visibility');
}
}
return $definition_flag_names;
}
/**
* @param int $definition_id
* @return void
*/
public function getView(int $definition_id = NO_DEFINITION_ID): void
{
$info = $this->attribute->getAttributeInfo($definition_id);
foreach(get_object_vars($info) as $property => $value)
{
$info->$property = $value;
}
/**
* @param int $definition_id
* @return void
*/
public function getView(int $definition_id = NO_DEFINITION_ID): void
{
$info = $this->attribute->getAttributeInfo($definition_id);
foreach(get_object_vars($info) as $property => $value)
{
$info->$property = $value;
}
$data['definition_id'] = $definition_id;
$data['definition_values'] = $this->attribute->get_definition_values($definition_id);
$data['definition_group'] = $this->attribute->get_definitions_by_type(GROUP, $definition_id);
$data['definition_group'][''] = lang('Common.none_selected_text');
$data['definition_info'] = $info;
$data['definition_id'] = $definition_id;
$data['definition_values'] = $this->attribute->get_definition_values($definition_id);
$data['definition_group'] = $this->attribute->get_definitions_by_type(GROUP, $definition_id);
$data['definition_group'][''] = lang('Common.none_selected_text');
$data['definition_info'] = $info;
$show_all = Attribute::SHOW_IN_ITEMS | Attribute::SHOW_IN_RECEIVINGS | Attribute::SHOW_IN_SALES;
$data['definition_flags'] = $this->get_attributes($show_all);
$selected_flags = $info->definition_flags === '' ? $show_all : $info->definition_flags;
$data['selected_definition_flags'] = $this->get_attributes($selected_flags);
$show_all = Attribute::SHOW_IN_ITEMS | Attribute::SHOW_IN_RECEIVINGS | Attribute::SHOW_IN_SALES;
$data['definition_flags'] = $this->get_attributes($show_all);
$selected_flags = $info->definition_flags === '' ? $show_all : $info->definition_flags;
$data['selected_definition_flags'] = $this->get_attributes($selected_flags);
echo view('attributes/form', $data);
}
echo view('attributes/form', $data);
}
/**
* AJAX called function to delete an attribute value. This is called when a dropdown item is removed.
*
* @param string $attribute_value
* @return bool
* @noinspection PhpUnused
*/
public function delete_value(string $attribute_value): bool
{
return $this->attribute->delete_value($attribute_value, NO_DEFINITION_ID);
}
/**
* AJAX called function to delete an attribute value. This is called when a dropdown item is removed.
*
* @param string $attribute_value
* @return bool
* @noinspection PhpUnused
*/
public function delete_value(string $attribute_value): bool
{
return $this->attribute->delete_value($attribute_value, NO_DEFINITION_ID);
}
/**
* Deletes an attribute definition
* @return void
*/
public function postDelete(): void
{
$attributes_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* Deletes an attribute definition
* @return void
*/
public function postDelete(): void
{
$attributes_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if($this->attribute->delete_definition_list($attributes_to_delete))
{
$message = lang('Attributes.definition_successful_deleted') . ' ' . count($attributes_to_delete) . ' ' . lang('Attributes.definition_one_or_multiple');
echo json_encode(['success' => true, 'message' => $message]);
}
else
{
echo json_encode(['success' => false, 'message' => lang('Attributes.definition_cannot_be_deleted')]);
}
}
if($this->attribute->delete_definition_list($attributes_to_delete))
{
$message = lang('Attributes.definition_successful_deleted') . ' ' . count($attributes_to_delete) . ' ' . lang('Attributes.definition_one_or_multiple');
echo json_encode(['success' => true, 'message' => $message]);
}
else
{
echo json_encode(['success' => false, 'message' => lang('Attributes.definition_cannot_be_deleted')]);
}
}
}

View File

@@ -10,301 +10,301 @@ use Config\Services;
class Cashups extends Secure_Controller
{
private Cashup $cashup;
private Expense $expense;
private Summary_payments $summary_payments;
private array $config;
private Cashup $cashup;
private Expense $expense;
private Summary_payments $summary_payments;
private array $config;
public function __construct()
{
parent::__construct('cashups');
public function __construct()
{
parent::__construct('cashups');
$this->cashup = model(Cashup::class);
$this->expense = model(Expense::class);
$this->summary_payments = model(Summary_payments::class);
$this->config = config(OSPOS::class)->settings;
}
$this->cashup = model(Cashup::class);
$this->expense = model(Expense::class);
$this->summary_payments = model(Summary_payments::class);
$this->config = config(OSPOS::class)->settings;
}
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_cashups_manage_table_headers();
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_cashups_manage_table_headers();
// filters that will be loaded in the multiselect dropdown
$data['filters'] = ['is_deleted' => lang('Cashups.is_deleted')];
// filters that will be loaded in the multiselect dropdown
$data['filters'] = ['is_deleted' => lang('Cashups.is_deleted')];
echo view('cashups/manage', $data);
}
echo view('cashups/manage', $data);
}
/**
* @return void
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(cashup_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'cashup_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$filters = [
'start_date' => $this->request->getGet('start_date', FILTER_SANITIZE_FULL_SPECIAL_CHARS), //TODO: Is this the best way to filter dates
'end_date' => $this->request->getGet('end_date', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'is_deleted' => false
];
/**
* @return void
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(cashup_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'cashup_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$filters = [
'start_date' => $this->request->getGet('start_date', FILTER_SANITIZE_FULL_SPECIAL_CHARS), //TODO: Is this the best way to filter dates
'end_date' => $this->request->getGet('end_date', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'is_deleted' => false
];
// 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);
$cash_ups = $this->cashup->search($search, $filters, $limit, $offset, $sort, $order);
$total_rows = $this->cashup->get_found_rows($search, $filters);
$data_rows = [];
foreach($cash_ups->getResult() as $cash_up)
{
$data_rows[] = get_cash_up_data_row($cash_up);
}
// 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);
$cash_ups = $this->cashup->search($search, $filters, $limit, $offset, $sort, $order);
$total_rows = $this->cashup->get_found_rows($search, $filters);
$data_rows = [];
foreach($cash_ups->getResult() as $cash_up)
{
$data_rows[] = get_cash_up_data_row($cash_up);
}
echo json_encode(['total' => $total_rows, 'rows' => $data_rows]);
}
echo json_encode(['total' => $total_rows, 'rows' => $data_rows]);
}
/**
* @param int $cashup_id
* @return void
*/
public function getView(int $cashup_id = NEW_ENTRY): void
{
$data = [];
/**
* @param int $cashup_id
* @return void
*/
public function getView(int $cashup_id = NEW_ENTRY): void
{
$data = [];
$data['employees'] = [];
foreach($this->employee->get_all()->getResult() as $employee)
{
foreach(get_object_vars($employee) as $property => $value)
{
$employee->$property = $value;
}
$data['employees'] = [];
foreach($this->employee->get_all()->getResult() as $employee)
{
foreach(get_object_vars($employee) as $property => $value)
{
$employee->$property = $value;
}
$data['employees'][$employee->person_id] = $employee->first_name . ' ' . $employee->last_name;
}
$data['employees'][$employee->person_id] = $employee->first_name . ' ' . $employee->last_name;
}
$cash_ups_info = $this->cashup->get_info($cashup_id);
$cash_ups_info = $this->cashup->get_info($cashup_id);
foreach(get_object_vars($cash_ups_info) as $property => $value)
{
$cash_ups_info->$property = $value;
}
foreach(get_object_vars($cash_ups_info) as $property => $value)
{
$cash_ups_info->$property = $value;
}
// open cashup
if($cash_ups_info->cashup_id == NEW_ENTRY)
{
$cash_ups_info->open_date = date('Y-m-d H:i:s');
$cash_ups_info->close_date = $cash_ups_info->open_date;
$cash_ups_info->open_employee_id = $this->employee->get_logged_in_employee_info()->person_id;
$cash_ups_info->close_employee_id = $this->employee->get_logged_in_employee_info()->person_id;
}
// if all the amounts are null or 0 that means it's a close cashup
elseif(floatval($cash_ups_info->closed_amount_cash) == 0
&& floatval($cash_ups_info->closed_amount_due) == 0
&& floatval($cash_ups_info->closed_amount_card) == 0
&& floatval($cash_ups_info->closed_amount_check) == 0)
{
// set the close date and time to the actual as this is a close session
$cash_ups_info->close_date = date('Y-m-d H:i:s');
// open cashup
if($cash_ups_info->cashup_id == NEW_ENTRY)
{
$cash_ups_info->open_date = date('Y-m-d H:i:s');
$cash_ups_info->close_date = $cash_ups_info->open_date;
$cash_ups_info->open_employee_id = $this->employee->get_logged_in_employee_info()->person_id;
$cash_ups_info->close_employee_id = $this->employee->get_logged_in_employee_info()->person_id;
}
// if all the amounts are null or 0 that means it's a close cashup
elseif(floatval($cash_ups_info->closed_amount_cash) == 0
&& floatval($cash_ups_info->closed_amount_due) == 0
&& floatval($cash_ups_info->closed_amount_card) == 0
&& floatval($cash_ups_info->closed_amount_check) == 0)
{
// set the close date and time to the actual as this is a close session
$cash_ups_info->close_date = date('Y-m-d H:i:s');
// the closed amount starts with the open amount -/+ any trasferred amount
$cash_ups_info->closed_amount_cash = $cash_ups_info->open_amount_cash + $cash_ups_info->transfer_amount_cash;
// the closed amount starts with the open amount -/+ any trasferred amount
$cash_ups_info->closed_amount_cash = $cash_ups_info->open_amount_cash + $cash_ups_info->transfer_amount_cash;
// if it's date mode only and not date & time truncate the open and end date to date only
if(empty($this->config['date_or_time_format']))
{
if($cash_ups_info->open_date != null)
{
$start_date = substr($cash_ups_info->open_date, 0, 10);
}
else
{
$start_date = null;
}
if($cash_ups_info->close_date != null)
{
$end_date = substr($cash_ups_info->close_date, 0, 10);
}
else
{
$end_date = null;
}
// search for all the payments given the time range
$inputs = [
'start_date' => $start_date,
'end_date' => $end_date,
'sale_type' => 'complete',
'location_id' => 'all'
];
}
else
{
// search for all the payments given the time range
$inputs = [
'start_date' => $cash_ups_info->open_date,
'end_date' => $cash_ups_info->close_date,
'sale_type' => 'complete',
'location_id' => 'all'
];
}
// if it's date mode only and not date & time truncate the open and end date to date only
if(empty($this->config['date_or_time_format']))
{
if($cash_ups_info->open_date != null)
{
$start_date = substr($cash_ups_info->open_date, 0, 10);
}
else
{
$start_date = null;
}
if($cash_ups_info->close_date != null)
{
$end_date = substr($cash_ups_info->close_date, 0, 10);
}
else
{
$end_date = null;
}
// search for all the payments given the time range
$inputs = [
'start_date' => $start_date,
'end_date' => $end_date,
'sale_type' => 'complete',
'location_id' => 'all'
];
}
else
{
// search for all the payments given the time range
$inputs = [
'start_date' => $cash_ups_info->open_date,
'end_date' => $cash_ups_info->close_date,
'sale_type' => 'complete',
'location_id' => 'all'
];
}
// get all the transactions payment summaries
$reports_data = $this->summary_payments->getData($inputs);
// get all the transactions payment summaries
$reports_data = $this->summary_payments->getData($inputs);
foreach($reports_data as $row)
{
if($row['trans_group'] == lang('Reports.trans_payments'))
{
if($row['trans_type'] == lang('Sales.cash'))
{
$cash_ups_info->closed_amount_cash += $row['trans_amount'];
}
elseif($row['trans_type'] == lang('Sales.due'))
{
$cash_ups_info->closed_amount_due += $row['trans_amount'];
}
elseif($row['trans_type'] == lang('Sales.debit') ||
$row['trans_type'] == lang('Sales.credit'))
{
$cash_ups_info->closed_amount_card += $row['trans_amount'];
}
elseif($row['trans_type'] == lang('Sales.check'))
{
$cash_ups_info->closed_amount_check += $row['trans_amount'];
}
}
}
foreach($reports_data as $row)
{
if($row['trans_group'] == lang('Reports.trans_payments'))
{
if($row['trans_type'] == lang('Sales.cash'))
{
$cash_ups_info->closed_amount_cash += $row['trans_amount'];
}
elseif($row['trans_type'] == lang('Sales.due'))
{
$cash_ups_info->closed_amount_due += $row['trans_amount'];
}
elseif($row['trans_type'] == lang('Sales.debit') ||
$row['trans_type'] == lang('Sales.credit'))
{
$cash_ups_info->closed_amount_card += $row['trans_amount'];
}
elseif($row['trans_type'] == lang('Sales.check'))
{
$cash_ups_info->closed_amount_check += $row['trans_amount'];
}
}
}
// lookup expenses paid in cash
$filters = [
'only_cash' => true,
'only_due' => false,
'only_check' => false,
'only_credit' => false,
'only_debit' => false,
'is_deleted' => false
];
// lookup expenses paid in cash
$filters = [
'only_cash' => true,
'only_due' => false,
'only_check' => false,
'only_credit' => false,
'only_debit' => false,
'is_deleted' => false
];
$payments = $this->expense->get_payments_summary('', array_merge($inputs, $filters));
$payments = $this->expense->get_payments_summary('', array_merge($inputs, $filters));
foreach($payments as $row)
{
$cash_ups_info->closed_amount_cash -= $row['amount'];
}
foreach($payments as $row)
{
$cash_ups_info->closed_amount_cash -= $row['amount'];
}
$cash_ups_info->closed_amount_total = $this->_calculate_total($cash_ups_info->open_amount_cash, $cash_ups_info->transfer_amount_cash, $cash_ups_info->closed_amount_cash, $cash_ups_info->closed_amount_due, $cash_ups_info->closed_amount_card, $cash_ups_info->closed_amount_check);
}
$cash_ups_info->closed_amount_total = $this->_calculate_total($cash_ups_info->open_amount_cash, $cash_ups_info->transfer_amount_cash, $cash_ups_info->closed_amount_cash, $cash_ups_info->closed_amount_due, $cash_ups_info->closed_amount_card, $cash_ups_info->closed_amount_check);
}
$data['cash_ups_info'] = $cash_ups_info;
$data['cash_ups_info'] = $cash_ups_info;
echo view("cashups/form", $data);
}
echo view("cashups/form", $data);
}
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$cash_ups_info = $this->cashup->get_info($row_id);
$data_row = get_cash_up_data_row($cash_ups_info);
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$cash_ups_info = $this->cashup->get_info($row_id);
$data_row = get_cash_up_data_row($cash_ups_info);
echo json_encode($data_row);
}
echo json_encode($data_row);
}
/**
* @param int $cashup_id
* @return void
*/
public function postSave(int $cashup_id = NEW_ENTRY): void
{
$open_date = $this->request->getPost('open_date');
$open_date_formatter = date_create_from_format($this->config['dateformat'] . ' ' . $this->config['timeformat'], $open_date);
/**
* @param int $cashup_id
* @return void
*/
public function postSave(int $cashup_id = NEW_ENTRY): void
{
$open_date = $this->request->getPost('open_date');
$open_date_formatter = date_create_from_format($this->config['dateformat'] . ' ' . $this->config['timeformat'], $open_date);
$close_date = $this->request->getPost('close_date');
$close_date_formatter = date_create_from_format($this->config['dateformat'] . ' ' . $this->config['timeformat'], $close_date);
$close_date = $this->request->getPost('close_date');
$close_date_formatter = date_create_from_format($this->config['dateformat'] . ' ' . $this->config['timeformat'], $close_date);
$cash_up_data = [
'open_date' => $open_date_formatter->format('Y-m-d H:i:s'),
'close_date' => $close_date_formatter->format('Y-m-d H:i:s'),
'open_amount_cash' => parse_decimals($this->request->getPost('open_amount_cash')),
'transfer_amount_cash' => parse_decimals($this->request->getPost('transfer_amount_cash')),
'closed_amount_cash' => parse_decimals($this->request->getPost('closed_amount_cash')),
'closed_amount_due' => parse_decimals($this->request->getPost('closed_amount_due')),
'closed_amount_card' => parse_decimals($this->request->getPost('closed_amount_card')),
'closed_amount_check' => parse_decimals($this->request->getPost('closed_amount_check')),
'closed_amount_total' => parse_decimals($this->request->getPost('closed_amount_total')),
'note' => $this->request->getPost('note') != null,
'description' => $this->request->getPost('description', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'open_employee_id' => $this->request->getPost('open_employee_id', FILTER_SANITIZE_NUMBER_INT),
'close_employee_id' => $this->request->getPost('close_employee_id', FILTER_SANITIZE_NUMBER_INT),
'deleted' => $this->request->getPost('deleted') != null
];
$cash_up_data = [
'open_date' => $open_date_formatter->format('Y-m-d H:i:s'),
'close_date' => $close_date_formatter->format('Y-m-d H:i:s'),
'open_amount_cash' => parse_decimals($this->request->getPost('open_amount_cash')),
'transfer_amount_cash' => parse_decimals($this->request->getPost('transfer_amount_cash')),
'closed_amount_cash' => parse_decimals($this->request->getPost('closed_amount_cash')),
'closed_amount_due' => parse_decimals($this->request->getPost('closed_amount_due')),
'closed_amount_card' => parse_decimals($this->request->getPost('closed_amount_card')),
'closed_amount_check' => parse_decimals($this->request->getPost('closed_amount_check')),
'closed_amount_total' => parse_decimals($this->request->getPost('closed_amount_total')),
'note' => $this->request->getPost('note') != null,
'description' => $this->request->getPost('description', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'open_employee_id' => $this->request->getPost('open_employee_id', FILTER_SANITIZE_NUMBER_INT),
'close_employee_id' => $this->request->getPost('close_employee_id', FILTER_SANITIZE_NUMBER_INT),
'deleted' => $this->request->getPost('deleted') != null
];
if($this->cashup->save_value($cash_up_data, $cashup_id))
{
//New cashup_id
if($cashup_id == NEW_ENTRY)
{
echo json_encode(['success' => true, 'message' => lang('Cashups.successful_adding'), 'id' => $cash_up_data['cashup_id']]);
}
else // Existing Cashup
{
echo json_encode(['success' => true, 'message' => lang('Cashups.successful_updating'), 'id' => $cashup_id]);
}
}
else//failure
{
echo json_encode(['success' => false, 'message' => lang('Cashups.error_adding_updating'), 'id' => NEW_ENTRY]);
}
}
if($this->cashup->save_value($cash_up_data, $cashup_id))
{
//New cashup_id
if($cashup_id == NEW_ENTRY)
{
echo json_encode(['success' => true, 'message' => lang('Cashups.successful_adding'), 'id' => $cash_up_data['cashup_id']]);
}
else // Existing Cashup
{
echo json_encode(['success' => true, 'message' => lang('Cashups.successful_updating'), 'id' => $cashup_id]);
}
}
else//failure
{
echo json_encode(['success' => false, 'message' => lang('Cashups.error_adding_updating'), 'id' => NEW_ENTRY]);
}
}
/**
* @return void
*/
public function postDelete(): void
{
$cash_ups_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* @return void
*/
public function postDelete(): void
{
$cash_ups_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if($this->cashup->delete_list($cash_ups_to_delete))
{
echo json_encode(['success' => true, 'message' => lang('Cashups.successful_deleted') . ' ' . count($cash_ups_to_delete) . ' ' . lang('Cashups.one_or_multiple'), 'ids' => $cash_ups_to_delete]);
}
else
{
echo json_encode(['success' => false, 'message' => lang('Cashups.cannot_be_deleted'), 'ids' => $cash_ups_to_delete]);
}
}
if($this->cashup->delete_list($cash_ups_to_delete))
{
echo json_encode(['success' => true, 'message' => lang('Cashups.successful_deleted') . ' ' . count($cash_ups_to_delete) . ' ' . lang('Cashups.one_or_multiple'), 'ids' => $cash_ups_to_delete]);
}
else
{
echo json_encode(['success' => false, 'message' => lang('Cashups.cannot_be_deleted'), 'ids' => $cash_ups_to_delete]);
}
}
/**
* Calculate the total for cashups. Used in app\Views\cashups\form.php
*
* @return void
* @noinspection PhpUnused
*/
public function ajax_cashup_total(): void
{
$open_amount_cash = parse_decimals($this->request->getPost('open_amount_cash'));
$transfer_amount_cash = parse_decimals($this->request->getPost('transfer_amount_cash'));
$closed_amount_cash = parse_decimals($this->request->getPost('closed_amount_cash'));
$closed_amount_due = parse_decimals($this->request->getPost('closed_amount_due'));
$closed_amount_card = parse_decimals($this->request->getPost('closed_amount_card'));
$closed_amount_check = parse_decimals($this->request->getPost('closed_amount_check'));
/**
* Calculate the total for cashups. Used in app\Views\cashups\form.php
*
* @return void
* @noinspection PhpUnused
*/
public function ajax_cashup_total(): void
{
$open_amount_cash = parse_decimals($this->request->getPost('open_amount_cash'));
$transfer_amount_cash = parse_decimals($this->request->getPost('transfer_amount_cash'));
$closed_amount_cash = parse_decimals($this->request->getPost('closed_amount_cash'));
$closed_amount_due = parse_decimals($this->request->getPost('closed_amount_due'));
$closed_amount_card = parse_decimals($this->request->getPost('closed_amount_card'));
$closed_amount_check = parse_decimals($this->request->getPost('closed_amount_check'));
$total = $this->_calculate_total($open_amount_cash, $transfer_amount_cash, $closed_amount_due, $closed_amount_cash, $closed_amount_card, $closed_amount_check); //TODO: hungarian notation
$total = $this->_calculate_total($open_amount_cash, $transfer_amount_cash, $closed_amount_due, $closed_amount_cash, $closed_amount_card, $closed_amount_check); //TODO: hungarian notation
echo json_encode(['total' => to_currency_no_money($total)]);
}
echo json_encode(['total' => to_currency_no_money($total)]);
}
/**
* Calculate total
*/
private function _calculate_total(float $open_amount_cash, float $transfer_amount_cash, float $closed_amount_due, float $closed_amount_cash, float $closed_amount_card, $closed_amount_check): float //TODO: need to get rid of hungarian notation here. Also, the signature is pretty long. Perhaps they need to go into an object or array?
{
return ($closed_amount_cash - $open_amount_cash - $transfer_amount_cash + $closed_amount_due + $closed_amount_card + $closed_amount_check);
}
/**
* Calculate total
*/
private function _calculate_total(float $open_amount_cash, float $transfer_amount_cash, float $closed_amount_due, float $closed_amount_cash, float $closed_amount_card, $closed_amount_check): float //TODO: need to get rid of hungarian notation here. Also, the signature is pretty long. Perhaps they need to go into an object or array?
{
return ($closed_amount_cash - $open_amount_cash - $transfer_amount_cash + $closed_amount_due + $closed_amount_card + $closed_amount_check);
}
}

View File

@@ -87,9 +87,9 @@ class Config extends Secure_Controller
$license[$i]['text'] = 'LICENSE file must be in OSPOS license directory. You are not allowed to use OSPOS application until the distribution copy of LICENSE file is present.';
}
$dir = new DirectoryIterator('license'); // read all the files in the dir license
$dir = new DirectoryIterator('license'); // read all the files in the dir license
foreach ($dir as $fileinfo) { //TODO: $fileinfo doesn't match our variable naming convention
foreach ($dir as $fileinfo) { //TODO: $fileinfo doesn't match our variable naming convention
// license files must be in couples: .version (name & version) & .license (license text)
if ($fileinfo->isFile()) {
if ($fileinfo->getExtension() == 'version') {
@@ -129,7 +129,7 @@ class Config extends Secure_Controller
if (is_array($val) && $key == 'dependencies') {
foreach ($val as $key1 => $val1) {
if (is_array($val1)) {
$license[$i]['text'] .= "component: $key1\n"; //TODO: Duplicated Code
$license[$i]['text'] .= "component: $key1\n"; //TODO: Duplicated Code
foreach ($val1 as $key2 => $val2) {
if (is_array($val2)) {
@@ -165,7 +165,7 @@ class Config extends Secure_Controller
foreach ($array as $key => $val) {
if (is_array($val)) {
$license[$i]['text'] .= "component: $key\n"; //TODO: Duplicated Code.
$license[$i]['text'] .= "component: $key\n"; //TODO: Duplicated Code.
foreach ($val as $key1 => $val1) {
if (is_array($val1)) {
@@ -193,14 +193,14 @@ class Config extends Secure_Controller
* This function loads all the available themes in the dist/bootswatch directory
* @return array
*/
private function _themes(): array //TODO: Hungarian notation
private function _themes(): array //TODO: Hungarian notation
{
$themes = [];
// read all themes in the dist folder
$dir = new DirectoryIterator('resources/bootswatch');
foreach ($dir as $dirinfo) { //TODO: $dirinfo doesn't follow naming convention
foreach ($dir as $dirinfo) { //TODO: $dirinfo doesn't follow naming convention
if ($dirinfo->isDir() && !$dirinfo->isDot() && $dirinfo->getFileName() != 'fonts') {
$file = $dirinfo->getFileName();
$themes[$file] = ucfirst($file);
@@ -245,9 +245,9 @@ class Config extends Secure_Controller
$data['selected_image_allowed_types'] = explode(',', $this->config['image_allowed_types']);
//Integrations Related fields
$data['mailchimp'] = [];
$data['mailchimp'] = [];
if (check_encryption()) { //TODO: Hungarian notation
if (check_encryption()) { //TODO: Hungarian notation
if (!isset($this->encrypter)) {
helper('security');
$this->encrypter = Services::encrypter();
@@ -542,7 +542,7 @@ class Config extends Secure_Controller
/**
* This function fetches all the available lists from Mailchimp for the given API key
*/
private function _mailchimp(string $api_key = ''): array //TODO: Hungarian notation
private function _mailchimp(string $api_key = ''): array //TODO: Hungarian notation
{
$mailchimp_lib = new Mailchimp_lib(['api_key' => $api_key]);
@@ -638,7 +638,7 @@ class Config extends Secure_Controller
*
* @return void
*/
public function ajax_tax_categories(): void //TODO: Is this function called anywhere in the code?
public function ajax_tax_categories(): void //TODO: Is this function called anywhere in the code?
{
$tax_categories = $this->tax->get_all_tax_categories()->getResultArray();
@@ -661,7 +661,7 @@ class Config extends Secure_Controller
/**
* @return void
*/
private function _clear_session_state(): void //TODO: Hungarian notation
private function _clear_session_state(): void //TODO: Hungarian notation
{
$this->sale_lib->clear_sale_location();
$this->sale_lib->clear_table();
@@ -730,7 +730,7 @@ class Config extends Secure_Controller
if ($dinner_table_enable) {
$not_to_delete = [];
foreach ($this->request->getPost() as $key => $value) { //TODO: Not sure if this is the best way to filter the array
foreach ($this->request->getPost() as $key => $value) { //TODO: Not sure if this is the best way to filter the array
if (strstr($key, 'dinner_table') && $key != 'dinner_table_enable') {
$dinner_table_id = preg_replace("/.*?_(\d+)$/", "$1", $key);
$not_to_delete[] = $dinner_table_id;
@@ -738,7 +738,7 @@ class Config extends Secure_Controller
// save or update
$table_data = ['name' => $value];
if ($this->dinner_table->save_value($table_data, $dinner_table_id)) {
$this->_clear_session_state(); //TODO: Remove hungarian notation.
$this->_clear_session_state(); //TODO: Remove hungarian notation.
}
}
}
@@ -825,7 +825,7 @@ class Config extends Secure_Controller
foreach ($array_save as $key => $value) {
// save or update
$package_data = ['package_name' => $value['package_name'], 'points_percent' => $value['points_percent']];
$this->customer_rewards->save_value($package_data, $key); //TODO: reflection exception
$this->customer_rewards->save_value($package_data, $key); //TODO: reflection exception
}
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -13,222 +13,222 @@ use Config\Services;
*/
class Employees extends Persons
{
public function __construct()
{
parent::__construct('employees');
public function __construct()
{
parent::__construct('employees');
$this->module = model('Module');
}
$this->module = model('Module');
}
/**
* Returns employee table data rows. This will be called with AJAX.
*
* @return void
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(person_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'people.person_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* Returns employee table data rows. This will be called with AJAX.
*
* @return void
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(person_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'people.person_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$employees = $this->employee->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->employee->get_found_rows($search);
$employees = $this->employee->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->employee->get_found_rows($search);
$data_rows = [];
foreach($employees->getResult() as $person)
{
$data_rows[] = get_person_data_row($person);
}
$data_rows = [];
foreach($employees->getResult() as $person)
{
$data_rows[] = get_person_data_row($person);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
/**
* AJAX called function gives search suggestions based on what is being searched for.
*
* @return void
*/
public function getSuggest(): void
{
$search = $this->request->getGet('term');
$suggestions = $this->employee->get_search_suggestions($search, 25, true);
/**
* AJAX called function gives search suggestions based on what is being searched for.
*
* @return void
*/
public function getSuggest(): void
{
$search = $this->request->getGet('term');
$suggestions = $this->employee->get_search_suggestions($search, 25, true);
echo json_encode($suggestions);
}
echo json_encode($suggestions);
}
/**
* @return void
*/
public function suggest_search(): void
{
$search = $this->request->getPost('term');
$suggestions = $this->employee->get_search_suggestions($search);
/**
* @return void
*/
public function suggest_search(): void
{
$search = $this->request->getPost('term');
$suggestions = $this->employee->get_search_suggestions($search);
echo json_encode($suggestions);
}
echo json_encode($suggestions);
}
/**
* Loads the employee edit form
*/
public function getView(int $employee_id = NEW_ENTRY): void
{
$person_info = $this->employee->get_info($employee_id);
foreach(get_object_vars($person_info) as $property => $value)
{
$person_info->$property = $value;
}
$data['person_info'] = $person_info;
$data['employee_id'] = $employee_id;
/**
* Loads the employee edit form
*/
public function getView(int $employee_id = NEW_ENTRY): void
{
$person_info = $this->employee->get_info($employee_id);
foreach(get_object_vars($person_info) as $property => $value)
{
$person_info->$property = $value;
}
$data['person_info'] = $person_info;
$data['employee_id'] = $employee_id;
$modules = [];
foreach($this->module->get_all_modules()->getResult() as $module)
{
$module->grant = $this->employee->has_grant($module->module_id, $person_info->person_id);
$module->menu_group = $this->employee->get_menu_group($module->module_id, $person_info->person_id);
$modules = [];
foreach($this->module->get_all_modules()->getResult() as $module)
{
$module->grant = $this->employee->has_grant($module->module_id, $person_info->person_id);
$module->menu_group = $this->employee->get_menu_group($module->module_id, $person_info->person_id);
$modules[] = $module;
}
$data['all_modules'] = $modules;
$modules[] = $module;
}
$data['all_modules'] = $modules;
$permissions = [];
foreach($this->module->get_all_subpermissions()->getResult() as $permission) //TODO: subpermissions does not follow naming standards.
{
$permission->permission_id = str_replace(' ', '_', $permission->permission_id);
$permission->grant = $this->employee->has_grant($permission->permission_id, $person_info->person_id);
$permissions = [];
foreach($this->module->get_all_subpermissions()->getResult() as $permission) //TODO: subpermissions does not follow naming standards.
{
$permission->permission_id = str_replace(' ', '_', $permission->permission_id);
$permission->grant = $this->employee->has_grant($permission->permission_id, $person_info->person_id);
$permissions[] = $permission;
}
$data['all_subpermissions'] = $permissions;
$permissions[] = $permission;
}
$data['all_subpermissions'] = $permissions;
echo view('employees/form', $data);
}
echo view('employees/form', $data);
}
/**
* Inserts/updates an employee
*/
public function postSave(int $employee_id = NEW_ENTRY): void
{
$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);
$email = strtolower($this->request->getPost('email', FILTER_SANITIZE_EMAIL));
/**
* Inserts/updates an employee
*/
public function postSave(int $employee_id = NEW_ENTRY): void
{
$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);
$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);
// format first and last name properly
$first_name = $this->nameize($first_name);
$last_name = $this->nameize($last_name);
$person_data = [
'first_name' => $first_name,
'last_name' => $last_name,
'gender' => $this->request->getPost('gender', FILTER_SANITIZE_NUMBER_INT),
'email' => $email,
'phone_number' => $this->request->getPost('phone_number', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'address_1' => $this->request->getPost('address_1', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'address_2' => $this->request->getPost('address_2', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'city' => $this->request->getPost('city', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'state' => $this->request->getPost('state', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'zip' => $this->request->getPost('zip', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'country' => $this->request->getPost('country', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'comments' => $this->request->getPost('comments', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
];
$person_data = [
'first_name' => $first_name,
'last_name' => $last_name,
'gender' => $this->request->getPost('gender', FILTER_SANITIZE_NUMBER_INT),
'email' => $email,
'phone_number' => $this->request->getPost('phone_number', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'address_1' => $this->request->getPost('address_1', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'address_2' => $this->request->getPost('address_2', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'city' => $this->request->getPost('city', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'state' => $this->request->getPost('state', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'zip' => $this->request->getPost('zip', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'country' => $this->request->getPost('country', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'comments' => $this->request->getPost('comments', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
];
$grants_array = [];
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) : '';
$grants_array = [];
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)
{
$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;
}
}
if($grant == $permission->permission_id)
{
$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;
}
}
//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 = [
'username' => $this->request->getPost('username', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'password' => password_hash($this->request->getPost('password'), PASSWORD_DEFAULT),
'hash_version' => 2,
'language_code' => $exploded[0],
'language' => $exploded[1]
];
}
else //Password not changed
{
$exploded = explode(":", $this->request->getPost('language', FILTER_SANITIZE_FULL_SPECIAL_CHARS));
$employee_data = [
'username' => $this->request->getPost('username', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'language_code' => $exploded[0],
'language' => $exploded[1]
];
}
//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 = [
'username' => $this->request->getPost('username', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'password' => password_hash($this->request->getPost('password'), PASSWORD_DEFAULT),
'hash_version' => 2,
'language_code' => $exploded[0],
'language' => $exploded[1]
];
}
else //Password not changed
{
$exploded = explode(":", $this->request->getPost('language', FILTER_SANITIZE_FULL_SPECIAL_CHARS));
$employee_data = [
'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))
{
// New employee
if($employee_id == NEW_ENTRY)
{
echo json_encode ([
'success' => true,
'message' => lang('Employees.successful_adding') . ' ' . $first_name . ' ' . $last_name,
'id' => $employee_data['person_id']
]);
}
else // Existing employee
{
echo json_encode ([
'success' => true,
'message' => lang('Employees.successful_updating') . ' ' . $first_name . ' ' . $last_name,
'id' => $employee_id
]);
}
}
else // Failure
{
echo json_encode ([
'success' => false,
'message' => lang('Employees.error_adding_updating') . ' ' . $first_name . ' ' . $last_name,
'id' => NEW_ENTRY
]);
}
}
if($this->employee->save_employee($person_data, $employee_data, $grants_array, $employee_id))
{
// New employee
if($employee_id == NEW_ENTRY)
{
echo json_encode ([
'success' => true,
'message' => lang('Employees.successful_adding') . ' ' . $first_name . ' ' . $last_name,
'id' => $employee_data['person_id']
]);
}
else // Existing employee
{
echo json_encode ([
'success' => true,
'message' => lang('Employees.successful_updating') . ' ' . $first_name . ' ' . $last_name,
'id' => $employee_id
]);
}
}
else // Failure
{
echo json_encode ([
'success' => false,
'message' => lang('Employees.error_adding_updating') . ' ' . $first_name . ' ' . $last_name,
'id' => NEW_ENTRY
]);
}
}
/**
* This deletes employees from the employees table
*/
public function postDelete(): void
{
$employees_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* This deletes employees from the employees table
*/
public function postDelete(): void
{
$employees_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if($this->employee->delete_list($employees_to_delete)) //TODO: this is passing a string, but delete_list expects an array
{
echo json_encode ([
'success' => true,
'message' => lang('Employees.successful_deleted') . ' ' . count($employees_to_delete) . ' ' . lang('Employees.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Employees.cannot_be_deleted')]);
}
}
if($this->employee->delete_list($employees_to_delete)) //TODO: this is passing a string, but delete_list expects an array
{
echo json_encode ([
'success' => true,
'message' => lang('Employees.successful_deleted') . ' ' . count($employees_to_delete) . ' ' . lang('Employees.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Employees.cannot_be_deleted')]);
}
}
/**
* Checks an employee username against the database. Used in app\Views\employees\form.php
*
* @param $employee_id
* @return void
* @noinspection PhpUnused
*/
public function getCheckUsername($employee_id): void
{
$exists = $this->employee->username_exists($employee_id, $this->request->getGet('username'));
echo !$exists ? 'true' : 'false';
}
/**
* Checks an employee username against the database. Used in app\Views\employees\form.php
*
* @param $employee_id
* @return void
* @noinspection PhpUnused
*/
public function getCheckUsername($employee_id): void
{
$exists = $this->employee->username_exists($employee_id, $this->request->getGet('username'));
echo !$exists ? 'true' : 'false';
}
}

View File

@@ -9,201 +9,201 @@ use Config\Services;
class Expenses extends Secure_Controller
{
private Expense $expense;
private Expense_category $expense_category;
private Expense $expense;
private Expense_category $expense_category;
public function __construct()
{
parent::__construct('expenses');
public function __construct()
{
parent::__construct('expenses');
$this->expense = model(Expense::class);
$this->expense_category = model(Expense_category::class);
}
$this->expense = model(Expense::class);
$this->expense_category = model(Expense_category::class);
}
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_expenses_manage_table_headers();
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_expenses_manage_table_headers();
// filters that will be loaded in the multiselect dropdown
$data['filters'] = [
'only_cash' => lang('Expenses.cash_filter'),
'only_due' => lang('Expenses.due_filter'),
'only_check' => lang('Expenses.check_filter'),
'only_credit' => lang('Expenses.credit_filter'),
'only_debit' => lang('Expenses.debit_filter'),
'is_deleted' => lang('Expenses.is_deleted')
];
// filters that will be loaded in the multiselect dropdown
$data['filters'] = [
'only_cash' => lang('Expenses.cash_filter'),
'only_due' => lang('Expenses.due_filter'),
'only_check' => lang('Expenses.check_filter'),
'only_credit' => lang('Expenses.credit_filter'),
'only_debit' => lang('Expenses.debit_filter'),
'is_deleted' => lang('Expenses.is_deleted')
];
echo view('expenses/manage', $data);
}
echo view('expenses/manage', $data);
}
/**
* @return void
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(expense_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'expense_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$filters = [
'start_date' => $this->request->getGet('start_date', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'end_date' => $this->request->getGet('end_date', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'only_cash' => false,
'only_due' => false,
'only_check' => false,
'only_credit' => false,
'only_debit' => false,
'is_deleted' => false
];
/**
* @return void
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(expense_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'expense_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$filters = [
'start_date' => $this->request->getGet('start_date', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'end_date' => $this->request->getGet('end_date', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'only_cash' => false,
'only_due' => false,
'only_check' => false,
'only_credit' => false,
'only_debit' => false,
'is_deleted' => false
];
// 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);
$expenses = $this->expense->search($search, $filters, $limit, $offset, $sort, $order);
$total_rows = $this->expense->get_found_rows($search, $filters);
$payments = $this->expense->get_payments_summary($search, $filters);
$payment_summary = get_expenses_manage_payments_summary($payments, $expenses);
$data_rows = [];
// 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);
$expenses = $this->expense->search($search, $filters, $limit, $offset, $sort, $order);
$total_rows = $this->expense->get_found_rows($search, $filters);
$payments = $this->expense->get_payments_summary($search, $filters);
$payment_summary = get_expenses_manage_payments_summary($payments, $expenses);
$data_rows = [];
foreach($expenses->getResult() as $expense)
{
$data_rows[] = get_expenses_data_row($expense);
}
foreach($expenses->getResult() as $expense)
{
$data_rows[] = get_expenses_data_row($expense);
}
if($total_rows > 0)
{
$data_rows[] = get_expenses_data_last_row($expenses);
}
if($total_rows > 0)
{
$data_rows[] = get_expenses_data_last_row($expenses);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows, 'payment_summary' => $payment_summary]);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows, 'payment_summary' => $payment_summary]);
}
/**
* @param int $expense_id
* @return void
*/
public function getView(int $expense_id = NEW_ENTRY): void
{
$data = []; //TODO: Duplicated code
/**
* @param int $expense_id
* @return void
*/
public function getView(int $expense_id = NEW_ENTRY): void
{
$data = []; //TODO: Duplicated code
$data['employees'] = [];
foreach($this->employee->get_all()->getResult() as $employee)
{
foreach(get_object_vars($employee) as $property => $value)
{
$employee->$property = $value;
}
$data['employees'] = [];
foreach($this->employee->get_all()->getResult() as $employee)
{
foreach(get_object_vars($employee) as $property => $value)
{
$employee->$property = $value;
}
$data['employees'][$employee->person_id] = $employee->first_name . ' ' . $employee->last_name;
}
$data['employees'][$employee->person_id] = $employee->first_name . ' ' . $employee->last_name;
}
$data['expenses_info'] = $this->expense->get_info($expense_id);
$data['expenses_info'] = $this->expense->get_info($expense_id);
$expense_categories = [];
foreach($this->expense_category->get_all(0, 0, true)->getResultArray() as $row)
{
$expense_categories[$row['expense_category_id']] = $row['category_name'];
}
$data['expense_categories'] = $expense_categories;
$expense_categories = [];
foreach($this->expense_category->get_all(0, 0, true)->getResultArray() as $row)
{
$expense_categories[$row['expense_category_id']] = $row['category_name'];
}
$data['expense_categories'] = $expense_categories;
$expense_id = $data['expenses_info']->expense_id;
$expense_id = $data['expenses_info']->expense_id;
if($expense_id == NEW_ENTRY)
{
$data['expenses_info']->date = date('Y-m-d H:i:s');
$data['expenses_info']->employee_id = $this->employee->get_logged_in_employee_info()->person_id;
}
if($expense_id == NEW_ENTRY)
{
$data['expenses_info']->date = date('Y-m-d H:i:s');
$data['expenses_info']->employee_id = $this->employee->get_logged_in_employee_info()->person_id;
}
$data['payments'] = [];
foreach($this->expense->get_expense_payment($expense_id)->getResult() as $payment)
{
foreach(get_object_vars($payment) as $property => $value)
{
$payment->$property = $value;
}
$data['payments'] = [];
foreach($this->expense->get_expense_payment($expense_id)->getResult() as $payment)
{
foreach(get_object_vars($payment) as $property => $value)
{
$payment->$property = $value;
}
$data['payments'][] = $payment;
}
$data['payments'][] = $payment;
}
// don't allow gift card to be a payment option in a sale transaction edit because it's a complex change
$data['payment_options'] = $this->expense->get_payment_options();
// don't allow gift card to be a payment option in a sale transaction edit because it's a complex change
$data['payment_options'] = $this->expense->get_payment_options();
echo view("expenses/form", $data);
}
echo view("expenses/form", $data);
}
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$expense_info = $this->expense->get_info($row_id);
$data_row = get_expenses_data_row($expense_info);
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$expense_info = $this->expense->get_info($row_id);
$data_row = get_expenses_data_row($expense_info);
echo json_encode($data_row);
}
echo json_encode($data_row);
}
/**
* @param int $expense_id
* @return void
*/
public function postSave(int $expense_id = NEW_ENTRY): void
{
$config = config(OSPOS::class)->settings;
$newdate = $this->request->getPost('date', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* @param int $expense_id
* @return void
*/
public function postSave(int $expense_id = NEW_ENTRY): void
{
$config = config(OSPOS::class)->settings;
$newdate = $this->request->getPost('date', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$date_formatter = date_create_from_format($config['dateformat'] . ' ' . $config['timeformat'], $newdate);
$date_formatter = date_create_from_format($config['dateformat'] . ' ' . $config['timeformat'], $newdate);
$expense_data = [
'date' => $date_formatter->format('Y-m-d H:i:s'),
'supplier_id' => $this->request->getPost('supplier_id') == '' ? null : $this->request->getPost('supplier_id', FILTER_SANITIZE_NUMBER_INT),
'supplier_tax_code' => $this->request->getPost('supplier_tax_code', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'amount' => parse_decimals($this->request->getPost('amount')),
'tax_amount' => parse_decimals($this->request->getPost('tax_amount')),
'payment_type' => $this->request->getPost('payment_type', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'expense_category_id' => $this->request->getPost('expense_category_id', FILTER_SANITIZE_NUMBER_INT),
'description' => $this->request->getPost('description', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'employee_id' => $this->request->getPost('employee_id', FILTER_SANITIZE_NUMBER_INT),
'deleted' => $this->request->getPost('deleted') != null
];
$expense_data = [
'date' => $date_formatter->format('Y-m-d H:i:s'),
'supplier_id' => $this->request->getPost('supplier_id') == '' ? null : $this->request->getPost('supplier_id', FILTER_SANITIZE_NUMBER_INT),
'supplier_tax_code' => $this->request->getPost('supplier_tax_code', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'amount' => parse_decimals($this->request->getPost('amount')),
'tax_amount' => parse_decimals($this->request->getPost('tax_amount')),
'payment_type' => $this->request->getPost('payment_type', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'expense_category_id' => $this->request->getPost('expense_category_id', FILTER_SANITIZE_NUMBER_INT),
'description' => $this->request->getPost('description', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'employee_id' => $this->request->getPost('employee_id', FILTER_SANITIZE_NUMBER_INT),
'deleted' => $this->request->getPost('deleted') != null
];
if($this->expense->save_value($expense_data, $expense_id))
{
//New Expense
if($expense_id == NEW_ENTRY)
{
echo json_encode (['success' => true, 'message' => lang('Expenses.successful_adding'), 'id' => $expense_data['expense_id']]);
}
else // Existing Expense
{
echo json_encode (['success' => true, 'message' => lang('Expenses.successful_updating'), 'id' => $expense_id]);
}
}
else//failure
{
echo json_encode (['success' => false, 'message' => lang('Expenses.error_adding_updating'), 'id' => NEW_ENTRY]);
}
}
if($this->expense->save_value($expense_data, $expense_id))
{
//New Expense
if($expense_id == NEW_ENTRY)
{
echo json_encode (['success' => true, 'message' => lang('Expenses.successful_adding'), 'id' => $expense_data['expense_id']]);
}
else // Existing Expense
{
echo json_encode (['success' => true, 'message' => lang('Expenses.successful_updating'), 'id' => $expense_id]);
}
}
else//failure
{
echo json_encode (['success' => false, 'message' => lang('Expenses.error_adding_updating'), 'id' => NEW_ENTRY]);
}
}
/**
* @return void
*/
public function postDelete(): void
{
$expenses_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* @return void
*/
public function postDelete(): void
{
$expenses_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if($this->expense->delete_list($expenses_to_delete))
{
echo json_encode (['success' => true, 'message' => lang('Expenses.successful_deleted') . ' ' . count($expenses_to_delete) . ' ' . lang('Expenses.one_or_multiple'), 'ids' => $expenses_to_delete]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Expenses.cannot_be_deleted'), 'ids' => $expenses_to_delete]);
}
}
if($this->expense->delete_list($expenses_to_delete))
{
echo json_encode (['success' => true, 'message' => lang('Expenses.successful_deleted') . ' ' . count($expenses_to_delete) . ' ' . lang('Expenses.one_or_multiple'), 'ids' => $expenses_to_delete]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Expenses.cannot_be_deleted'), 'ids' => $expenses_to_delete]);
}
}
}

View File

@@ -5,130 +5,130 @@ namespace App\Controllers;
use App\Models\Expense_category;
use Config\Services;
class Expenses_categories extends Secure_Controller //TODO: Is this class ever used?
class Expenses_categories extends Secure_Controller //TODO: Is this class ever used?
{
private Expense_category $expense_category;
private Expense_category $expense_category;
public function __construct()
{
parent::__construct('expenses_categories');
public function __construct()
{
parent::__construct('expenses_categories');
$this->expense_category = model(Expense_category::class);
}
$this->expense_category = model(Expense_category::class);
}
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_expense_category_manage_table_headers();
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_expense_category_manage_table_headers();
echo view('expenses_categories/manage', $data);
}
echo view('expenses_categories/manage', $data);
}
/**
* Returns expense_category_manage table data rows. This will be called with AJAX.
**/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(expense_category_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'expense_category_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* Returns expense_category_manage table data rows. This will be called with AJAX.
**/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(expense_category_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'expense_category_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$expense_categories = $this->expense_category->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->expense_category->get_found_rows($search);
$expense_categories = $this->expense_category->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->expense_category->get_found_rows($search);
$data_rows = [];
foreach($expense_categories->getResult() as $expense_category)
{
$data_rows[] = get_expense_category_data_row($expense_category);
}
$data_rows = [];
foreach($expense_categories->getResult() as $expense_category)
{
$data_rows[] = get_expense_category_data_row($expense_category);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$data_row = get_expense_category_data_row($this->expense_category->get_info($row_id));
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$data_row = get_expense_category_data_row($this->expense_category->get_info($row_id));
echo json_encode($data_row);
}
echo json_encode($data_row);
}
/**
* @param int $expense_category_id
* @return void
*/
public function getView(int $expense_category_id = NEW_ENTRY): void
{
$data['category_info'] = $this->expense_category->get_info($expense_category_id);
/**
* @param int $expense_category_id
* @return void
*/
public function getView(int $expense_category_id = NEW_ENTRY): void
{
$data['category_info'] = $this->expense_category->get_info($expense_category_id);
echo view("expenses_categories/form", $data);
}
echo view("expenses_categories/form", $data);
}
/**
* @param int $expense_category_id
* @return void
*/
public function postSave(int $expense_category_id = NEW_ENTRY): void
{
$expense_category_data = [
'category_name' => $this->request->getPost('category_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'category_description' => $this->request->getPost('category_description', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
];
/**
* @param int $expense_category_id
* @return void
*/
public function postSave(int $expense_category_id = NEW_ENTRY): void
{
$expense_category_data = [
'category_name' => $this->request->getPost('category_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'category_description' => $this->request->getPost('category_description', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
];
if($this->expense_category->save_value($expense_category_data, $expense_category_id))
{
// New expense_category
if($expense_category_id == NEW_ENTRY)
{
echo json_encode ([
'success' => true,
'message' => lang('Expenses_categories.successful_adding'),
'id' => $expense_category_data['expense_category_id']
]);
}
else // Existing Expense Category
{
echo json_encode ([
'success' => true,
'message' => lang('Expenses_categories.successful_updating'),
'id' => $expense_category_id
]);
}
}
else//failure
{
echo json_encode ([
'success' => true,
'message' => lang('Expenses_categories.error_adding_updating') . ' ' . $expense_category_data['category_name'],
'id' => NEW_ENTRY
]);
}
}
if($this->expense_category->save_value($expense_category_data, $expense_category_id))
{
// New expense_category
if($expense_category_id == NEW_ENTRY)
{
echo json_encode ([
'success' => true,
'message' => lang('Expenses_categories.successful_adding'),
'id' => $expense_category_data['expense_category_id']
]);
}
else // Existing Expense Category
{
echo json_encode ([
'success' => true,
'message' => lang('Expenses_categories.successful_updating'),
'id' => $expense_category_id
]);
}
}
else//failure
{
echo json_encode ([
'success' => true,
'message' => lang('Expenses_categories.error_adding_updating') . ' ' . $expense_category_data['category_name'],
'id' => NEW_ENTRY
]);
}
}
/**
* @return void
*/
public function postDelete(): void
{
$expense_category_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* @return void
*/
public function postDelete(): void
{
$expense_category_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if($this->expense_category->delete_list($expense_category_to_delete)) //TODO: Convert to ternary notation.
{
echo json_encode([
'success' => true,
'message' => lang('Expenses_categories.successful_deleted') . ' ' . count($expense_category_to_delete) . ' ' . lang('Expenses_categories.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Expenses_categories.cannot_be_deleted')]);
}
}
if($this->expense_category->delete_list($expense_category_to_delete)) //TODO: Convert to ternary notation.
{
echo json_encode([
'success' => true,
'message' => lang('Expenses_categories.successful_deleted') . ' ' . count($expense_category_to_delete) . ' ' . lang('Expenses_categories.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Expenses_categories.cannot_be_deleted')]);
}
}
}

View File

@@ -8,191 +8,191 @@ use Config\Services;
class Giftcards extends Secure_Controller
{
private Giftcard $giftcard;
private Giftcard $giftcard;
public function __construct()
{
parent::__construct('giftcards');
public function __construct()
{
parent::__construct('giftcards');
$this->giftcard = model(Giftcard::class);
}
$this->giftcard = model(Giftcard::class);
}
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_giftcards_manage_table_headers();
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_giftcards_manage_table_headers();
echo view('giftcards/manage', $data);
}
echo view('giftcards/manage', $data);
}
/**
* Returns Giftcards table data rows. This will be called with AJAX.
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(giftcard_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'giftcard_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* Returns Giftcards table data rows. This will be called with AJAX.
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(giftcard_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'giftcard_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$giftcards = $this->giftcard->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->giftcard->get_found_rows($search);
$giftcards = $this->giftcard->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->giftcard->get_found_rows($search);
$data_rows = [];
foreach($giftcards->getResult() as $giftcard)
{
$data_rows[] = get_giftcard_data_row($giftcard);
}
$data_rows = [];
foreach($giftcards->getResult() as $giftcard)
{
$data_rows[] = get_giftcard_data_row($giftcard);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
/**
* Gets search suggestions for giftcards. Used in app\Views\sales\register.php
*
* @return void
* @noinspection PhpUnused
*/
public function getSuggest(): void
{
$search = $this->request->getGet('term');
$suggestions = $this->giftcard->get_search_suggestions($search, true);
/**
* Gets search suggestions for giftcards. Used in app\Views\sales\register.php
*
* @return void
* @noinspection PhpUnused
*/
public function getSuggest(): void
{
$search = $this->request->getGet('term');
$suggestions = $this->giftcard->get_search_suggestions($search, true);
echo json_encode($suggestions);
}
echo json_encode($suggestions);
}
/**
* @return void
*/
public function suggest_search(): void
{
$search = $this->request->getPost('term');
$suggestions = $this->giftcard->get_search_suggestions($search);
/**
* @return void
*/
public function suggest_search(): void
{
$search = $this->request->getPost('term');
$suggestions = $this->giftcard->get_search_suggestions($search);
echo json_encode($suggestions);
}
echo json_encode($suggestions);
}
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$data_row = get_giftcard_data_row($this->giftcard->get_info($row_id));
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$data_row = get_giftcard_data_row($this->giftcard->get_info($row_id));
echo json_encode($data_row);
}
echo json_encode($data_row);
}
/**
* @param int $giftcard_id
* @return void
*/
public function getView(int $giftcard_id = NEW_ENTRY): void
{
$config = config(OSPOS::class)->settings;
$giftcard_info = $this->giftcard->get_info($giftcard_id);
/**
* @param int $giftcard_id
* @return void
*/
public function getView(int $giftcard_id = NEW_ENTRY): void
{
$config = config(OSPOS::class)->settings;
$giftcard_info = $this->giftcard->get_info($giftcard_id);
$data['selected_person_name'] = ($giftcard_id > 0 && isset($giftcard_info->person_id)) ? $giftcard_info->first_name . ' ' . $giftcard_info->last_name : '';
$data['selected_person_id'] = $giftcard_info->person_id;
if($config['giftcard_number'] == 'random')
{
$data['giftcard_number'] = $giftcard_id > 0 ? $giftcard_info->giftcard_number : '';
}
else
{
$max_number_obj = $this->giftcard->get_max_number();
$max_giftnumber = isset($max_number_obj) ? $this->giftcard->get_max_number()->giftcard_number : 0; //TODO: variable does not follow naming standard.
$data['giftcard_number'] = $giftcard_id > 0 ? $giftcard_info->giftcard_number : $max_giftnumber + 1;
}
$data['giftcard_id'] = $giftcard_id;
$data['giftcard_value'] = $giftcard_info->value;
$data['selected_person_name'] = ($giftcard_id > 0 && isset($giftcard_info->person_id)) ? $giftcard_info->first_name . ' ' . $giftcard_info->last_name : '';
$data['selected_person_id'] = $giftcard_info->person_id;
if($config['giftcard_number'] == 'random')
{
$data['giftcard_number'] = $giftcard_id > 0 ? $giftcard_info->giftcard_number : '';
}
else
{
$max_number_obj = $this->giftcard->get_max_number();
$max_giftnumber = isset($max_number_obj) ? $this->giftcard->get_max_number()->giftcard_number : 0; //TODO: variable does not follow naming standard.
$data['giftcard_number'] = $giftcard_id > 0 ? $giftcard_info->giftcard_number : $max_giftnumber + 1;
}
$data['giftcard_id'] = $giftcard_id;
$data['giftcard_value'] = $giftcard_info->value;
echo view("giftcards/form", $data);
}
echo view("giftcards/form", $data);
}
/**
* @param int $giftcard_id
* @return void
*/
public function postSave(int $giftcard_id = NEW_ENTRY): void
{
$giftcard_number = $this->request->getPost('giftcard_number', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* @param int $giftcard_id
* @return void
*/
public function postSave(int $giftcard_id = NEW_ENTRY): void
{
$giftcard_number = $this->request->getPost('giftcard_number', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if($giftcard_id == NEW_ENTRY && trim($giftcard_number) == '')
{
$giftcard_number = $this->giftcard->generate_unique_giftcard_name($giftcard_number);
}
if($giftcard_id == NEW_ENTRY && trim($giftcard_number) == '')
{
$giftcard_number = $this->giftcard->generate_unique_giftcard_name($giftcard_number);
}
$giftcard_data = [
'record_time' => date('Y-m-d H:i:s'),
'giftcard_number' => $giftcard_number,
'value' => parse_decimals($this->request->getPost('giftcard_amount')),
'person_id' => $this->request->getPost('person_id') == '' ? null : $this->request->getPost('person_id', FILTER_SANITIZE_NUMBER_INT)
];
$giftcard_data = [
'record_time' => date('Y-m-d H:i:s'),
'giftcard_number' => $giftcard_number,
'value' => parse_decimals($this->request->getPost('giftcard_amount')),
'person_id' => $this->request->getPost('person_id') == '' ? null : $this->request->getPost('person_id', FILTER_SANITIZE_NUMBER_INT)
];
if($this->giftcard->save_value($giftcard_data, $giftcard_id))
{
//New giftcard
if($giftcard_id == NEW_ENTRY) //TODO: Constant needed
{
echo json_encode ([
'success' => true,
'message' => lang('Giftcards.successful_adding') . ' ' . $giftcard_data['giftcard_number'],
'id' => $giftcard_data['giftcard_id']
]);
}
else //Existing giftcard
{
echo json_encode ([
'success' => true,
'message' => lang('Giftcards.successful_updating') . ' ' . $giftcard_data['giftcard_number'],
'id' => $giftcard_id
]);
}
}
else //failure
{
echo json_encode ([
'success' => false,
'message' => lang('Giftcards.error_adding_updating') . ' ' . $giftcard_data['giftcard_number'],
'id' => NEW_ENTRY
]);
}
}
if($this->giftcard->save_value($giftcard_data, $giftcard_id))
{
//New giftcard
if($giftcard_id == NEW_ENTRY) //TODO: Constant needed
{
echo json_encode ([
'success' => true,
'message' => lang('Giftcards.successful_adding') . ' ' . $giftcard_data['giftcard_number'],
'id' => $giftcard_data['giftcard_id']
]);
}
else //Existing giftcard
{
echo json_encode ([
'success' => true,
'message' => lang('Giftcards.successful_updating') . ' ' . $giftcard_data['giftcard_number'],
'id' => $giftcard_id
]);
}
}
else //failure
{
echo json_encode ([
'success' => false,
'message' => lang('Giftcards.error_adding_updating') . ' ' . $giftcard_data['giftcard_number'],
'id' => NEW_ENTRY
]);
}
}
/**
* Checks the giftcard number validity. Used in app\Views\giftcards\form.php
*
* @return void
* @noinspection PhpUnused
*/
public function postCheckNumberGiftcard(): void
{
$giftcard_amount = parse_decimals($this->request->getPost('giftcard_amount'));
$parsed_value = filter_var($giftcard_amount, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
echo json_encode (['success' => $parsed_value !== false && $parsed_value > 0 && $giftcard_amount !== false, 'giftcard_amount' => to_currency_no_money($parsed_value)]);
}
/**
* Checks the giftcard number validity. Used in app\Views\giftcards\form.php
*
* @return void
* @noinspection PhpUnused
*/
public function postCheckNumberGiftcard(): void
{
$giftcard_amount = parse_decimals($this->request->getPost('giftcard_amount'));
$parsed_value = filter_var($giftcard_amount, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
echo json_encode (['success' => $parsed_value !== false && $parsed_value > 0 && $giftcard_amount !== false, 'giftcard_amount' => to_currency_no_money($parsed_value)]);
}
/**
* @return void
*/
public function postDelete(): void
{
$giftcards_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* @return void
*/
public function postDelete(): void
{
$giftcards_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if($this->giftcard->delete_list($giftcards_to_delete))
{
echo json_encode ([
'success' => true,
'message' => lang('Giftcards.successful_deleted') . ' ' . count($giftcards_to_delete).' '.lang('Giftcards.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Giftcards.cannot_be_deleted')]);
}
}
if($this->giftcard->delete_list($giftcards_to_delete))
{
echo json_encode ([
'success' => true,
'message' => lang('Giftcards.successful_deleted') . ' ' . count($giftcards_to_delete).' '.lang('Giftcards.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Giftcards.cannot_be_deleted')]);
}
}
}

View File

@@ -6,97 +6,97 @@ use CodeIgniter\HTTP\RedirectResponse;
class Home extends Secure_Controller
{
public function __construct()
{
parent::__construct('home', null, 'home');
}
public function __construct()
{
parent::__construct('home', null, 'home');
}
/**
* @return void
*/
public function getIndex(): void
{
$logged_in = $this->employee->is_logged_in();
echo view('home/home');
}
/**
* @return void
*/
public function getIndex(): void
{
$logged_in = $this->employee->is_logged_in();
echo view('home/home');
}
/**
* Logs the currently logged in employee out of the system. Used in app/Views/partial/header.php
*
* @return RedirectResponse
* @noinspection PhpUnused
*/
public function getLogout(): RedirectResponse
{
$this->employee->logout();
return redirect()->to('login');
}
/**
* Logs the currently logged in employee out of the system. Used in app/Views/partial/header.php
*
* @return RedirectResponse
* @noinspection PhpUnused
*/
public function getLogout(): RedirectResponse
{
$this->employee->logout();
return redirect()->to('login');
}
/**
* Load "change employee password" form
*
* @noinspection PhpUnused
*/
public function getChangePassword(int $employee_id = -1): void //TODO: Replace -1 with a constant
{
$person_info = $this->employee->get_info($employee_id);
foreach(get_object_vars($person_info) as $property => $value)
{
$person_info->$property = $value;
}
$data['person_info'] = $person_info;
/**
* Load "change employee password" form
*
* @noinspection PhpUnused
*/
public function getChangePassword(int $employee_id = -1): void //TODO: Replace -1 with a constant
{
$person_info = $this->employee->get_info($employee_id);
foreach(get_object_vars($person_info) as $property => $value)
{
$person_info->$property = $value;
}
$data['person_info'] = $person_info;
echo view('home/form_change_password', $data);
}
echo view('home/form_change_password', $data);
}
/**
* Change employee password
*/
public function save(int $employee_id = -1): void //TODO: Replace -1 with a constant
{
if(!empty($this->request->getPost('current_password')) && $employee_id != -1)
{
if($this->employee->check_password($this->request->getPost('username', FILTER_SANITIZE_FULL_SPECIAL_CHARS), $this->request->getPost('current_password')))
{
$employee_data = [
'username' => $this->request->getPost('username', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'password' => password_hash($this->request->getPost('password'), PASSWORD_DEFAULT),
'hash_version' => 2
];
/**
* Change employee password
*/
public function save(int $employee_id = -1): void //TODO: Replace -1 with a constant
{
if(!empty($this->request->getPost('current_password')) && $employee_id != -1)
{
if($this->employee->check_password($this->request->getPost('username', FILTER_SANITIZE_FULL_SPECIAL_CHARS), $this->request->getPost('current_password')))
{
$employee_data = [
'username' => $this->request->getPost('username', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'password' => password_hash($this->request->getPost('password'), PASSWORD_DEFAULT),
'hash_version' => 2
];
if($this->employee->change_password($employee_data, $employee_id))
{
echo json_encode ([
'success' => true,
'message' => lang('Employees.successful_change_password'),
'id' => $employee_id
]);
}
else//failure
{//TODO: Replace -1 with constant
echo json_encode ([
'success' => false,
'message' => lang('Employees.unsuccessful_change_password'),
'id' => -1
]);
}
}
else
{//TODO: Replace -1 with constant
echo json_encode ([
'success' => false,
'message' => lang('Employees.current_password_invalid'),
'id' => -1
]);
}
}
else
{//TODO: Replace -1 with constant
echo json_encode ([
'success' => false,
'message' => lang('Employees.current_password_invalid'),
'id' => -1
]);
}
}
if($this->employee->change_password($employee_data, $employee_id))
{
echo json_encode ([
'success' => true,
'message' => lang('Employees.successful_change_password'),
'id' => $employee_id
]);
}
else//failure
{//TODO: Replace -1 with constant
echo json_encode ([
'success' => false,
'message' => lang('Employees.unsuccessful_change_password'),
'id' => -1
]);
}
}
else
{//TODO: Replace -1 with constant
echo json_encode ([
'success' => false,
'message' => lang('Employees.current_password_invalid'),
'id' => -1
]);
}
}
else
{//TODO: Replace -1 with constant
echo json_encode ([
'success' => false,
'message' => lang('Employees.current_password_invalid'),
'id' => -1
]);
}
}
}

View File

@@ -11,309 +11,309 @@ use Config\Services;
class Item_kits extends Secure_Controller
{
private Item $item;
private Item_kit $item_kit;
private Item_kit_items $item_kit_items;
private Item $item;
private Item_kit $item_kit;
private Item_kit_items $item_kit_items;
public function __construct()
{
parent::__construct('item_kits');
public function __construct()
{
parent::__construct('item_kits');
$this->item = model(Item::class);
$this->item_kit = model(Item_kit::class);
$this->item_kit_items = model(Item_kit_items::class);
}
$this->item = model(Item::class);
$this->item_kit = model(Item_kit::class);
$this->item_kit_items = model(Item_kit_items::class);
}
/**
* Add the total cost and retail price to a passed item_kit retrieving the data from each singular item part of the kit
*/
private function _add_totals_to_item_kit(object $item_kit): object //TODO: Hungarian notation
{
$kit_item_info = $this->item->get_info($item_kit->kit_item_id ?? $item_kit->item_id);
/**
* Add the total cost and retail price to a passed item_kit retrieving the data from each singular item part of the kit
*/
private function _add_totals_to_item_kit(object $item_kit): object //TODO: Hungarian notation
{
$kit_item_info = $this->item->get_info($item_kit->kit_item_id ?? $item_kit->item_id);
$item_kit->total_cost_price = 0;
$item_kit->total_unit_price = $kit_item_info->unit_price;
$total_quantity = 0;
$item_kit->total_cost_price = 0;
$item_kit->total_unit_price = $kit_item_info->unit_price;
$total_quantity = 0;
foreach($this->item_kit_items->get_info($item_kit->item_kit_id) as $item_kit_item)
{
$item_info = $this->item->get_info($item_kit_item['item_id']);
foreach(get_object_vars($item_info) as $property => $value)
{
$item_info->$property = $value;
}
foreach($this->item_kit_items->get_info($item_kit->item_kit_id) as $item_kit_item)
{
$item_info = $this->item->get_info($item_kit_item['item_id']);
foreach(get_object_vars($item_info) as $property => $value)
{
$item_info->$property = $value;
}
$item_kit->total_cost_price += $item_info->cost_price * $item_kit_item['quantity'];
$item_kit->total_cost_price += $item_info->cost_price * $item_kit_item['quantity'];
if($item_kit->price_option == PRICE_OPTION_ALL || ($item_kit->price_option == PRICE_OPTION_KIT_STOCK && $item_info->stock_type == HAS_STOCK ))
{
$item_kit->total_unit_price += $item_info->unit_price * $item_kit_item['quantity'];
$total_quantity += $item_kit_item['quantity'];
}
}
if($item_kit->price_option == PRICE_OPTION_ALL || ($item_kit->price_option == PRICE_OPTION_KIT_STOCK && $item_info->stock_type == HAS_STOCK ))
{
$item_kit->total_unit_price += $item_info->unit_price * $item_kit_item['quantity'];
$total_quantity += $item_kit_item['quantity'];
}
}
$discount_fraction = bcdiv($item_kit->kit_discount, '100');
$discount_fraction = bcdiv($item_kit->kit_discount, '100');
$item_kit->total_unit_price = $item_kit->total_unit_price - round(($item_kit->kit_discount_type == PERCENT)
? bcmul($item_kit->total_unit_price, $discount_fraction)
: $item_kit->kit_discount, totals_decimals(), PHP_ROUND_HALF_UP);
$item_kit->total_unit_price = $item_kit->total_unit_price - round(($item_kit->kit_discount_type == PERCENT)
? bcmul($item_kit->total_unit_price, $discount_fraction)
: $item_kit->kit_discount, totals_decimals(), PHP_ROUND_HALF_UP);
return $item_kit;
}
return $item_kit;
}
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_item_kits_manage_table_headers();
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_item_kits_manage_table_headers();
echo view('item_kits/manage', $data);
}
echo view('item_kits/manage', $data);
}
/**
* Returns Item_kit table data rows. This will be called with AJAX.
*/
public function getSearch(): void
{
$search = $this->request->getGet('search') ?? '';
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(item_kit_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'item_kit_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* Returns Item_kit table data rows. This will be called with AJAX.
*/
public function getSearch(): void
{
$search = $this->request->getGet('search') ?? '';
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(item_kit_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'item_kit_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$item_kits = $this->item_kit->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->item_kit->get_found_rows($search);
$item_kits = $this->item_kit->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->item_kit->get_found_rows($search);
$data_rows = [];
foreach($item_kits->getResult() as $item_kit)
{
// calculate the total cost and retail price of the Kit, so it can be printed out in the manage table
$item_kit = $this->_add_totals_to_item_kit($item_kit);
$data_rows[] = get_item_kit_data_row($item_kit);
}
$data_rows = [];
foreach($item_kits->getResult() as $item_kit)
{
// calculate the total cost and retail price of the Kit, so it can be printed out in the manage table
$item_kit = $this->_add_totals_to_item_kit($item_kit);
$data_rows[] = get_item_kit_data_row($item_kit);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
/**
* @return void
*/
public function suggest_search(): void
{
$search = $this->request->getPost('term');
$suggestions = $this->item_kit->get_search_suggestions($search);
/**
* @return void
*/
public function suggest_search(): void
{
$search = $this->request->getPost('term');
$suggestions = $this->item_kit->get_search_suggestions($search);
echo json_encode($suggestions);
}
echo json_encode($suggestions);
}
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
// calculate the total cost and retail price of the Kit, so it can be added to the table refresh
$item_kit = $this->_add_totals_to_item_kit($this->item_kit->get_info($row_id));
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
// calculate the total cost and retail price of the Kit, so it can be added to the table refresh
$item_kit = $this->_add_totals_to_item_kit($this->item_kit->get_info($row_id));
echo json_encode(get_item_kit_data_row($item_kit));
}
echo json_encode(get_item_kit_data_row($item_kit));
}
/**
* @param int $item_kit_id
* @return void
*/
public function getView(int $item_kit_id = NEW_ENTRY): void
{
$info = $this->item_kit->get_info($item_kit_id);
/**
* @param int $item_kit_id
* @return void
*/
public function getView(int $item_kit_id = NEW_ENTRY): void
{
$info = $this->item_kit->get_info($item_kit_id);
if($item_kit_id == NEW_ENTRY)
{
$info->price_option = '0';
$info->print_option = PRINT_ALL;
$info->kit_item_id = 0;
$info->item_number = '';
$info->kit_discount = 0;
}
if($item_kit_id == NEW_ENTRY)
{
$info->price_option = '0';
$info->print_option = PRINT_ALL;
$info->kit_item_id = 0;
$info->item_number = '';
$info->kit_discount = 0;
}
foreach(get_object_vars($info) as $property => $value)
{
$info->$property = $value;
}
foreach(get_object_vars($info) as $property => $value)
{
$info->$property = $value;
}
$data['item_kit_info'] = $info;
$data['item_kit_info'] = $info;
$items = [];
$items = [];
foreach($this->item_kit_items->get_info($item_kit_id) as $item_kit_item)
{
$item['kit_sequence'] = $item_kit_item['kit_sequence'];
$item['name'] = $this->item->get_info($item_kit_item['item_id'])->name;
$item['item_id'] = $item_kit_item['item_id'];
$item['quantity'] = $item_kit_item['quantity'];
foreach($this->item_kit_items->get_info($item_kit_id) as $item_kit_item)
{
$item['kit_sequence'] = $item_kit_item['kit_sequence'];
$item['name'] = $this->item->get_info($item_kit_item['item_id'])->name;
$item['item_id'] = $item_kit_item['item_id'];
$item['quantity'] = $item_kit_item['quantity'];
$items[] = $item;
}
$items[] = $item;
}
$data['item_kit_items'] = $items;
$data['item_kit_items'] = $items;
$data['selected_kit_item_id'] = $info->kit_item_id;
$data['selected_kit_item'] = ($item_kit_id > 0 && isset($info->kit_item_id)) ? $info->item_name : '';
$data['selected_kit_item_id'] = $info->kit_item_id;
$data['selected_kit_item'] = ($item_kit_id > 0 && isset($info->kit_item_id)) ? $info->item_name : '';
echo view("item_kits/form", $data);
}
echo view("item_kits/form", $data);
}
/**
* @param int $item_kit_id
* @return void
*/
public function postSave(int $item_kit_id = NEW_ENTRY): void
{
$item_kit_data = [
'name' => $this->request->getPost('name'),
'item_kit_number' => $this->request->getPost('item_kit_number'),
'item_id' => $this->request->getPost('kit_item_id') ? null : intval($this->request->getPost('kit_item_id')),
'kit_discount' => parse_decimals($this->request->getPost('kit_discount')),
'kit_discount_type' => $this->request->getPost('kit_discount_type') === null ? PERCENT : intval($this->request->getPost('kit_discount_type')),
'price_option' => $this->request->getPost('price_option') === null ? PRICE_ALL : intval($this->request->getPost('price_option')),
'print_option' => $this->request->getPost('print_option') === null ? PRINT_ALL : intval($this->request->getPost('print_option')),
'description' => $this->request->getPost('description')
];
/**
* @param int $item_kit_id
* @return void
*/
public function postSave(int $item_kit_id = NEW_ENTRY): void
{
$item_kit_data = [
'name' => $this->request->getPost('name'),
'item_kit_number' => $this->request->getPost('item_kit_number'),
'item_id' => $this->request->getPost('kit_item_id') ? null : intval($this->request->getPost('kit_item_id')),
'kit_discount' => parse_decimals($this->request->getPost('kit_discount')),
'kit_discount_type' => $this->request->getPost('kit_discount_type') === null ? PERCENT : intval($this->request->getPost('kit_discount_type')),
'price_option' => $this->request->getPost('price_option') === null ? PRICE_ALL : intval($this->request->getPost('price_option')),
'print_option' => $this->request->getPost('print_option') === null ? PRINT_ALL : intval($this->request->getPost('print_option')),
'description' => $this->request->getPost('description')
];
if($this->item_kit->save_value($item_kit_data, $item_kit_id))
{
$new_item = false;
//New item kit
if($item_kit_id == NEW_ENTRY)
{
$item_kit_id = $item_kit_data['item_kit_id'];
$new_item = true;
}
if($this->item_kit->save_value($item_kit_data, $item_kit_id))
{
$new_item = false;
//New item kit
if($item_kit_id == NEW_ENTRY)
{
$item_kit_id = $item_kit_data['item_kit_id'];
$new_item = true;
}
$item_kit_items_array = $this->request->getPost('item_kit_qty') === null ? null : $this->request->getPost('item_kit_qty');
$item_kit_items_array = $this->request->getPost('item_kit_qty') === null ? null : $this->request->getPost('item_kit_qty');
if($item_kit_items_array != null)
{
$item_kit_items = [];
foreach($item_kit_items_array as $item_id => $item_kit_qty)
{
$item_kit_items[] = [
'item_id' => $item_id,
'quantity' => $item_kit_qty === null ? 0 : parse_quantity($item_kit_qty),
'kit_sequence' => $this->request->getPost("item_kit_seq[$item_id]") === null ? 0 : intval($this->request->getPost("item_kit_seq[$item_id]"))
];
}
}
if($item_kit_items_array != null)
{
$item_kit_items = [];
foreach($item_kit_items_array as $item_id => $item_kit_qty)
{
$item_kit_items[] = [
'item_id' => $item_id,
'quantity' => $item_kit_qty === null ? 0 : parse_quantity($item_kit_qty),
'kit_sequence' => $this->request->getPost("item_kit_seq[$item_id]") === null ? 0 : intval($this->request->getPost("item_kit_seq[$item_id]"))
];
}
}
if (!empty($item_kit_items))
{
$success = $this->item_kit_items->save_value($item_kit_items, $item_kit_id);
}
else
{
$success = true;
}
if (!empty($item_kit_items))
{
$success = $this->item_kit_items->save_value($item_kit_items, $item_kit_id);
}
else
{
$success = true;
}
if($new_item)
{
echo json_encode ([
'success' => $success,
'message' => lang('Item_kits.successful_adding').' '.$item_kit_data['name'],
'id' => $item_kit_id
]);
if($new_item)
{
echo json_encode ([
'success' => $success,
'message' => lang('Item_kits.successful_adding').' '.$item_kit_data['name'],
'id' => $item_kit_id
]);
}
else
{
echo json_encode ([
'success' => $success,
'message' => lang('Item_kits.successful_updating').' '.$item_kit_data['name'],
'id' => $item_kit_id
]);
}
}
else//failure
{
echo json_encode ([
'success' => false,
'message' => lang('Item_kits.error_adding_updating') . ' ' . $item_kit_data['name'],
'id' => NEW_ENTRY
]);
}
}
}
else
{
echo json_encode ([
'success' => $success,
'message' => lang('Item_kits.successful_updating').' '.$item_kit_data['name'],
'id' => $item_kit_id
]);
}
}
else//failure
{
echo json_encode ([
'success' => false,
'message' => lang('Item_kits.error_adding_updating') . ' ' . $item_kit_data['name'],
'id' => NEW_ENTRY
]);
}
}
/**
* @return void
*/
public function postDelete(): void
{
$item_kits_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* @return void
*/
public function postDelete(): void
{
$item_kits_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if($this->item_kit->delete_list($item_kits_to_delete))
{
echo json_encode ([
'success' => true,
'message' => lang('Item_kits.successful_deleted') . ' ' . count($item_kits_to_delete) . ' ' . lang('Item_kits.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Item_kits.cannot_be_deleted')]);
}
}
if($this->item_kit->delete_list($item_kits_to_delete))
{
echo json_encode ([
'success' => true,
'message' => lang('Item_kits.successful_deleted') . ' ' . count($item_kits_to_delete) . ' ' . lang('Item_kits.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Item_kits.cannot_be_deleted')]);
}
}
/**
* Checks the validity of the item kit number. Used in app/Views/item_kits/form.php
*
* @return void
* @noinspection PhpUnused
*/
public function postCheckItemNumber(): void
{
$exists = $this->item_kit->item_number_exists($this->request->getPost('item_kit_number', FILTER_SANITIZE_FULL_SPECIAL_CHARS), $this->request->getPost('item_kit_id', FILTER_SANITIZE_NUMBER_INT));
echo !$exists ? 'true' : 'false';
}
/**
* Checks the validity of the item kit number. Used in app/Views/item_kits/form.php
*
* @return void
* @noinspection PhpUnused
*/
public function postCheckItemNumber(): void
{
$exists = $this->item_kit->item_number_exists($this->request->getPost('item_kit_number', FILTER_SANITIZE_FULL_SPECIAL_CHARS), $this->request->getPost('item_kit_id', FILTER_SANITIZE_NUMBER_INT));
echo !$exists ? 'true' : 'false';
}
/**
* 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.
* @return void
* @noinspection PhpUnused
*/
public function getGenerateBarcodes(string $item_kit_ids): void
{
$barcode_lib = new Barcode_lib();
$result = [];
/**
* 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.
* @return void
* @noinspection PhpUnused
*/
public function getGenerateBarcodes(string $item_kit_ids): void
{
$barcode_lib = new Barcode_lib();
$result = [];
$item_kit_ids = explode(':', $item_kit_ids);
foreach($item_kit_ids as $item_kid_id)
{
// 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));
$item_kit_ids = explode(':', $item_kit_ids);
foreach($item_kit_ids as $item_kid_id)
{
// 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));
$item_kid_id = 'KIT '. urldecode($item_kid_id);
$item_kid_id = 'KIT '. urldecode($item_kid_id);
$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
];
}
$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
];
}
$data['items'] = $result;
$barcode_config = $barcode_lib->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';
}
$data['barcode_config'] = $barcode_config;
$data['items'] = $result;
$barcode_config = $barcode_lib->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';
}
$data['barcode_config'] = $barcode_config;
// display barcodes
echo view("barcodes/barcode_sheet", $data);
}
// display barcodes
echo view("barcodes/barcode_sheet", $data);
}
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -14,65 +14,65 @@ use Config\Services;
*/
class Login extends BaseController
{
public Model $employee;
public Model $employee;
/**
* @return RedirectResponse|string
*/
public function index(): string|RedirectResponse
{
$this->employee = model(Employee::class);
if(!$this->employee->is_logged_in())
{
$migration = new MY_Migration(config('Migrations'));
$config = config(OSPOS::class)->settings;
/**
* @return RedirectResponse|string
*/
public function index(): string|RedirectResponse
{
$this->employee = model(Employee::class);
if(!$this->employee->is_logged_in())
{
$migration = new MY_Migration(config('Migrations'));
$config = config(OSPOS::class)->settings;
$gcaptcha_enabled = array_key_exists('gcaptcha_enable', $config)
? $config['gcaptcha_enable']
: false;
$gcaptcha_enabled = array_key_exists('gcaptcha_enable', $config)
? $config['gcaptcha_enable']
: false;
$migration->migrate_to_ci4();
$migration->migrate_to_ci4();
$validation = Services::validation();
$validation = Services::validation();
$data = [
'has_errors' => false,
'is_latest' => $migration->is_latest(),
'latest_version' => $migration->get_latest_migration(),
'gcaptcha_enabled' => $gcaptcha_enabled,
'config' => $config,
'validation' => $validation
];
$data = [
'has_errors' => false,
'is_latest' => $migration->is_latest(),
'latest_version' => $migration->get_latest_migration(),
'gcaptcha_enabled' => $gcaptcha_enabled,
'config' => $config,
'validation' => $validation
];
if($this->request->getMethod() !== 'POST')
{
return view('login', $data);
}
if($this->request->getMethod() !== 'POST')
{
return view('login', $data);
}
$rules = ['username' => 'required|login_check[data]'];
$messages = [
'username' => [
'required' => lang('Login.required_username'),
'login_check' => lang('Login.invalid_username_and_password'),
]
];
$rules = ['username' => 'required|login_check[data]'];
$messages = [
'username' => [
'required' => lang('Login.required_username'),
'login_check' => lang('Login.invalid_username_and_password'),
]
];
if(!$this->validate($rules, $messages))
{
$data['has_errors'] = !empty($validation->getErrors());
if(!$this->validate($rules, $messages))
{
$data['has_errors'] = !empty($validation->getErrors());
return view('login', $data);
}
return view('login', $data);
}
if(!$data['is_latest'])
{
set_time_limit(3600);
if(!$data['is_latest'])
{
set_time_limit(3600);
$migration->setNamespace('App')->latest();
return redirect()->to('login');
}
}
$migration->setNamespace('App')->latest();
return redirect()->to('login');
}
}
return redirect()->to('home');
}
return redirect()->to('home');
}
}

View File

@@ -8,90 +8,90 @@ use App\Models\Person;
class Messages extends Secure_Controller
{
private Sms_lib $sms_lib;
private Sms_lib $sms_lib;
public function __construct()
{
parent::__construct('messages');
public function __construct()
{
parent::__construct('messages');
$this->sms_lib = new Sms_lib();
}
$this->sms_lib = new Sms_lib();
}
/**
* @return void
*/
public function getIndex(): void
{
echo view('messages/sms');
}
/**
* @return void
*/
public function getIndex(): void
{
echo view('messages/sms');
}
/**
* @param int $person_id
* @return void
*/
public function getView(int $person_id = NEW_ENTRY): void
{
$person = model(Person::class);
$info = $person->get_info($person_id);
/**
* @param int $person_id
* @return void
*/
public function getView(int $person_id = NEW_ENTRY): void
{
$person = model(Person::class);
$info = $person->get_info($person_id);
foreach(get_object_vars($info) as $property => $value)
{
$info->$property = $value;
}
$data['person_info'] = $info;
foreach(get_object_vars($info) as $property => $value)
{
$info->$property = $value;
}
$data['person_info'] = $info;
echo view('messages/form_sms', $data);
}
echo view('messages/form_sms', $data);
}
/**
* @return void
*/
public function send(): void
{
$phone = $this->request->getPost('phone', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$message = $this->request->getPost('message', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* @return void
*/
public function send(): void
{
$phone = $this->request->getPost('phone', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$message = $this->request->getPost('message', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$response = $this->sms_lib->sendSMS($phone, $message);
$response = $this->sms_lib->sendSMS($phone, $message);
if($response)
{
echo json_encode (['success' => true, 'message' => lang('Messages.successfully_sent') . ' ' . esc($phone)]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Messages.unsuccessfully_sent') . ' ' . esc($phone)]);
}
}
if($response)
{
echo json_encode (['success' => true, 'message' => lang('Messages.successfully_sent') . ' ' . esc($phone)]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Messages.unsuccessfully_sent') . ' ' . esc($phone)]);
}
}
/**
* Sends an SMS message to a user. Used in app/Views/messages/form_sms.php.
*
* @param int $person_id
* @return void
* @noinspection PhpUnused
*/
public function send_form(int $person_id = NEW_ENTRY): void
{
$phone = $this->request->getPost('phone', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$message = $this->request->getPost('message', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* Sends an SMS message to a user. Used in app/Views/messages/form_sms.php.
*
* @param int $person_id
* @return void
* @noinspection PhpUnused
*/
public function send_form(int $person_id = NEW_ENTRY): void
{
$phone = $this->request->getPost('phone', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$message = $this->request->getPost('message', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$response = $this->sms_lib->sendSMS($phone, $message);
$response = $this->sms_lib->sendSMS($phone, $message);
if($response)
{
echo json_encode ([
'success' => true,
'message' => lang('Messages.successfully_sent') . ' ' . esc($phone),
'person_id' => $person_id
]);
}
else
{
echo json_encode ([
'success' => false,
'message' => lang('Messages.unsuccessfully_sent') . ' ' . esc($phone),
'person_id' => NEW_ENTRY
]);
}
}
if($response)
{
echo json_encode ([
'success' => true,
'message' => lang('Messages.successfully_sent') . ' ' . esc($phone),
'person_id' => $person_id
]);
}
else
{
echo json_encode ([
'success' => false,
'message' => lang('Messages.unsuccessfully_sent') . ' ' . esc($phone),
'person_id' => NEW_ENTRY
]);
}
}
}

View File

@@ -12,23 +12,23 @@ use App\Models\Module;
*/
class No_access extends BaseController
{
private Module $module;
private Module $module;
public function __construct()
{
$this->module = model(Module::class);
}
public function __construct()
{
$this->module = model(Module::class);
}
/**
* @param string $module_id
* @param string $permission_id
* @return void
*/
public function getIndex(string $module_id = '', string $permission_id = ''): void
{
$data['module_name'] = $this->module->get_module_name($module_id);
$data['permission_id'] = $permission_id;
/**
* @param string $module_id
* @param string $permission_id
* @return void
*/
public function getIndex(string $module_id = '', string $permission_id = ''): void
{
$data['module_name'] = $this->module->get_module_name($module_id);
$data['permission_id'] = $permission_id;
echo view('no_access', $data);
}
echo view('no_access', $data);
}
}

View File

@@ -9,28 +9,28 @@ use App\Models\Employee;
*/
class Office extends Secure_Controller
{
protected Employee $employee;
protected Employee $employee;
public function __construct()
{
parent::__construct('office', null, 'office');
}
public function __construct()
{
parent::__construct('office', null, 'office');
}
/**
* @return void
*/
public function getIndex(): void
{
echo view('home/office');
}
/**
* @return void
*/
public function getIndex(): void
{
echo view('home/office');
}
/**
* @return void
*/
public function logout(): void
{
$this->employee = model(Employee::class);
/**
* @return void
*/
public function logout(): void
{
$this->employee = model(Employee::class);
$this->employee->logout();
}
$this->employee->logout();
}
}

View File

@@ -8,64 +8,64 @@ use function Tamtamchik\NameCase\str_name_case;
abstract class Persons extends Secure_Controller
{
protected Person $person;
protected Person $person;
/**
* @param string|null $module_id
*/
public function __construct(string $module_id = null)
{
parent::__construct($module_id);
/**
* @param string|null $module_id
*/
public function __construct(string $module_id = null)
{
parent::__construct($module_id);
$this->person = model(Person::class);
}
$this->person = model(Person::class);
}
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_people_manage_table_headers();
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_people_manage_table_headers();
echo view('people/manage', $data);
}
echo view('people/manage', $data);
}
/**
* Gives search suggestions based on what is being searched for
*/
public function getSuggest(): void
{
$search = $this->request->getGet('term');
$suggestions = $this->person->get_search_suggestions($search);
/**
* Gives search suggestions based on what is being searched for
*/
public function getSuggest(): void
{
$search = $this->request->getGet('term');
$suggestions = $this->person->get_search_suggestions($search);
echo json_encode($suggestions);
}
echo json_encode($suggestions);
}
/**
* Gets one row for a person manage table. This is called using AJAX to update one row.
*/
public function getRow(int $row_id): void
{
$data_row = get_person_data_row($this->person->get_info($row_id));
/**
* Gets one row for a person manage table. This is called using AJAX to update one row.
*/
public function getRow(int $row_id): void
{
$data_row = get_person_data_row($this->person->get_info($row_id));
echo json_encode($data_row);
}
echo json_encode($data_row);
}
/**
* Capitalize segments of a name, and put the rest into lower case.
* You can pass the characters you want to use as delimiters as exceptions.
* The function supports UTF-8 strings
*
* Example:
* i.e. <?php echo nameize("john o'grady-smith"); ?>
*
* returns John O'Grady-Smith
*/
protected function nameize(string $input): string
{
$adjusted_name = str_name_case($input);
/**
* Capitalize segments of a name, and put the rest into lower case.
* You can pass the characters you want to use as delimiters as exceptions.
* The function supports UTF-8 strings
*
* Example:
* i.e. <?php echo nameize("john o'grady-smith"); ?>
*
* returns John O'Grady-Smith
*/
protected function nameize(string $input): string
{
$adjusted_name = str_name_case($input);
//TODO:Use preg_replace to match HTML entities and convert them to lowercase. This is a workaround for https://github.com/tamtamchik/namecase/issues/20
return preg_replace_callback('/&[a-zA-Z0-9#]+;/', function($matches) { return strtolower($matches[0]); }, $adjusted_name);
}
//TODO:Use preg_replace to match HTML entities and convert them to lowercase. This is a workaround for https://github.com/tamtamchik/namecase/issues/20
return preg_replace_callback('/&[a-zA-Z0-9#]+;/', function($matches) { return strtolower($matches[0]); }, $adjusted_name);
}
}

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

@@ -22,130 +22,130 @@ use Config\Services;
*/
class Secure_Controller extends BaseController
{
public array $global_view_data;
protected Employee $employee;
protected Module $module;
protected Session $session;
public array $global_view_data;
protected Employee $employee;
protected Module $module;
protected Session $session;
/**
* @param string $module_id
* @param string|null $submodule_id
* @param string|null $menu_group
*/
public function __construct(string $module_id = '', string $submodule_id = null, string $menu_group = null)
{
$this->employee = model(Employee::class);
$this->module = model(Module::class);
$config = config(OSPOS::class)->settings;
$validation = Services::validation();
/**
* @param string $module_id
* @param string|null $submodule_id
* @param string|null $menu_group
*/
public function __construct(string $module_id = '', string $submodule_id = null, string $menu_group = null)
{
$this->employee = model(Employee::class);
$this->module = model(Module::class);
$config = config(OSPOS::class)->settings;
$validation = Services::validation();
if(!$this->employee->is_logged_in())
{
header("Location:".base_url('login'));
exit();
}
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();
}
$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();
}
// load up global global_view_data visible to all the loaded views
$this->session = session();
if($menu_group == null)
{
$menu_group = $this->session->get('menu_group');
}
else
{
$this->session->set('menu_group', $menu_group);
}
// load up global global_view_data visible to all the loaded views
$this->session = session();
if($menu_group == null)
{
$menu_group = $this->session->get('menu_group');
}
else
{
$this->session->set('menu_group', $menu_group);
}
$allowed_modules = $menu_group == 'home'
? $this->module->get_allowed_home_modules($logged_in_employee_info->person_id)
: $this->module->get_allowed_office_modules($logged_in_employee_info->person_id);
$allowed_modules = $menu_group == 'home'
? $this->module->get_allowed_home_modules($logged_in_employee_info->person_id)
: $this->module->get_allowed_office_modules($logged_in_employee_info->person_id);
$this->global_view_data = [];
foreach($allowed_modules->getResult() as $module)
{
$this->global_view_data['allowed_modules'][] = $module;
}
$this->global_view_data = [];
foreach($allowed_modules->getResult() as $module)
{
$this->global_view_data['allowed_modules'][] = $module;
}
$this->global_view_data += [
'user_info' => $logged_in_employee_info,
'controller_name' => $module_id,
'config' => $config
];
view('viewData', $this->global_view_data);
}
$this->global_view_data += [
'user_info' => $logged_in_employee_info,
'controller_name' => $module_id,
'config' => $config
];
view('viewData', $this->global_view_data);
}
public function sanitizeSortColumn($headers, $field, $default): string
{
return $field != null && in_array($field, array_keys(array_merge(...$headers))) ? $field : $default;
}
public function sanitizeSortColumn($headers, $field, $default): string
{
return $field != null && in_array($field, array_keys(array_merge(...$headers))) ? $field : $default;
}
/**
* AJAX function used to confirm whether values sent in the request are numeric
* @return void
* @noinspection PhpUnused
*/
public function getCheckNumeric(): void
{
foreach($this->request->getGet() as $value)
{
if (parse_decimals($value) === false)
{
echo 'false';
return;
}
}
echo 'true';
}
/**
* AJAX function used to confirm whether values sent in the request are numeric
* @return void
* @noinspection PhpUnused
*/
public function getCheckNumeric(): void
{
foreach($this->request->getGet() as $value)
{
if (parse_decimals($value) === false)
{
echo 'false';
return;
}
}
echo 'true';
}
/**
* @param $key
* @return mixed|void
*/
public function getConfig($key)
{
if (isset($config[$key]))
{
return $config[$key];
}
}
/**
* @param $key
* @return mixed|void
*/
public function getConfig($key)
{
if (isset($config[$key]))
{
return $config[$key];
}
}
/**
* @return false
*/
public function getIndex() { return false; }
/**
* @return false
*/
public function getIndex() { return false; }
/**
* @return false
*/
public function getSearch() { return false; }
/**
* @return false
*/
public function getSearch() { return false; }
/**
* @return false
*/
public function suggest_search() { return false; }
/**
* @return false
*/
public function suggest_search() { return false; }
/**
* @param int $data_item_id
* @return false
*/
public function getView(int $data_item_id = -1) { return false; }
/**
* @param int $data_item_id
* @return false
*/
public function getView(int $data_item_id = -1) { return false; }
/**
* @param int $data_item_id
* @return false
*/
public function postSave(int $data_item_id = -1) { return false; }
/**
* @param int $data_item_id
* @return false
*/
public function postSave(int $data_item_id = -1) { return false; }
/**
* @return false
*/
public function postDelete() { return false; }
/**
* @return false
*/
public function postDelete() { return false; }
}

View File

@@ -7,193 +7,193 @@ use Config\Services;
class Suppliers extends Persons
{
private Supplier $supplier;
private Supplier $supplier;
public function __construct()
{
parent::__construct('suppliers');
public function __construct()
{
parent::__construct('suppliers');
$this->supplier = model(Supplier::class);
}
$this->supplier = model(Supplier::class);
}
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_suppliers_manage_table_headers();
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_suppliers_manage_table_headers();
echo view('people/manage', $data);
}
echo view('people/manage', $data);
}
/**
* Gets one row for a supplier manage table. This is called using AJAX to update one row.
* @param $row_id
* @return void
*/
public function getRow($row_id): void
{
$data_row = get_supplier_data_row($this->supplier->get_info($row_id));
$data_row['category'] = $this->supplier->get_category_name($data_row['category']);
/**
* Gets one row for a supplier manage table. This is called using AJAX to update one row.
* @param $row_id
* @return void
*/
public function getRow($row_id): void
{
$data_row = get_supplier_data_row($this->supplier->get_info($row_id));
$data_row['category'] = $this->supplier->get_category_name($data_row['category']);
echo json_encode($data_row);
}
echo json_encode($data_row);
}
/**
* Returns Supplier table data rows. This will be called with AJAX.
* @return void
**/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(supplier_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'people.person_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* Returns Supplier table data rows. This will be called with AJAX.
* @return void
**/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->sanitizeSortColumn(supplier_headers(), $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS), 'people.person_id');
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$suppliers = $this->supplier->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->supplier->get_found_rows($search);
$suppliers = $this->supplier->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->supplier->get_found_rows($search);
$data_rows = [];
$data_rows = [];
foreach($suppliers->getResult() as $supplier)
{
$row = get_supplier_data_row($supplier);
$row['category'] = $this->supplier->get_category_name($row['category']);
$data_rows[] = $row;
}
foreach($suppliers->getResult() as $supplier)
{
$row = get_supplier_data_row($supplier);
$row['category'] = $this->supplier->get_category_name($row['category']);
$data_rows[] = $row;
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
/**
* Gives search suggestions based on what is being searched for
**/
public function getSuggest(): void
{
$search = $this->request->getGet('term');
$suggestions = $this->supplier->get_search_suggestions($search, true);
/**
* Gives search suggestions based on what is being searched for
**/
public function getSuggest(): void
{
$search = $this->request->getGet('term');
$suggestions = $this->supplier->get_search_suggestions($search, true);
echo json_encode($suggestions);
}
echo json_encode($suggestions);
}
/**
* @return void
*/
public function suggest_search(): void
{
$search = $this->request->getPost('term');
$suggestions = $this->supplier->get_search_suggestions($search, false);
/**
* @return void
*/
public function suggest_search(): void
{
$search = $this->request->getPost('term');
$suggestions = $this->supplier->get_search_suggestions($search, false);
echo json_encode($suggestions);
}
echo json_encode($suggestions);
}
/**
* Loads the supplier edit form
*
* @param int $supplier_id
* @return void
*/
public function getView(int $supplier_id = NEW_ENTRY): void
{
$info = $this->supplier->get_info($supplier_id);
foreach(get_object_vars($info) as $property => $value)
{
$info->$property = $value;
}
$data['person_info'] = $info;
$data['categories'] = $this->supplier->get_categories();
/**
* Loads the supplier edit form
*
* @param int $supplier_id
* @return void
*/
public function getView(int $supplier_id = NEW_ENTRY): void
{
$info = $this->supplier->get_info($supplier_id);
foreach(get_object_vars($info) as $property => $value)
{
$info->$property = $value;
}
$data['person_info'] = $info;
$data['categories'] = $this->supplier->get_categories();
echo view("suppliers/form", $data);
}
echo view("suppliers/form", $data);
}
/**
* Inserts/updates a supplier
*
* @param int $supplier_id
* @return void
*/
public function postSave(int $supplier_id = NEW_ENTRY): void
{
$first_name = $this->request->getPost('first_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS); //TODO: Duplicate code
$last_name = $this->request->getPost('last_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$email = strtolower($this->request->getPost('email', FILTER_SANITIZE_EMAIL));
/**
* Inserts/updates a supplier
*
* @param int $supplier_id
* @return void
*/
public function postSave(int $supplier_id = NEW_ENTRY): void
{
$first_name = $this->request->getPost('first_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS); //TODO: Duplicate code
$last_name = $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);
// format first and last name properly
$first_name = $this->nameize($first_name);
$last_name = $this->nameize($last_name);
$person_data = [
'first_name' => $first_name,
'last_name' => $last_name,
'gender' => $this->request->getPost('gender'),
'email' => $email,
'phone_number' => $this->request->getPost('phone_number', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'address_1' => $this->request->getPost('address_1', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'address_2' => $this->request->getPost('address_2', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'city' => $this->request->getPost('city', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'state' => $this->request->getPost('state', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'zip' => $this->request->getPost('zip', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'country' => $this->request->getPost('country', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'comments' => $this->request->getPost('comments', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
];
$person_data = [
'first_name' => $first_name,
'last_name' => $last_name,
'gender' => $this->request->getPost('gender'),
'email' => $email,
'phone_number' => $this->request->getPost('phone_number', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'address_1' => $this->request->getPost('address_1', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'address_2' => $this->request->getPost('address_2', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'city' => $this->request->getPost('city', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'state' => $this->request->getPost('state', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'zip' => $this->request->getPost('zip', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'country' => $this->request->getPost('country', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'comments' => $this->request->getPost('comments', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
];
$supplier_data = [
'company_name' => $this->request->getPost('company_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'agency_name' => $this->request->getPost('agency_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'category' => $this->request->getPost('category', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'account_number' => $this->request->getPost('account_number') == '' ? null : $this->request->getPost('account_number', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'tax_id' => $this->request->getPost('tax_id', FILTER_SANITIZE_NUMBER_INT)
];
$supplier_data = [
'company_name' => $this->request->getPost('company_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'agency_name' => $this->request->getPost('agency_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'category' => $this->request->getPost('category', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'account_number' => $this->request->getPost('account_number') == '' ? null : $this->request->getPost('account_number', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'tax_id' => $this->request->getPost('tax_id', FILTER_SANITIZE_NUMBER_INT)
];
if($this->supplier->save_supplier($person_data, $supplier_data, $supplier_id))
{
//New supplier
if($supplier_id == NEW_ENTRY)
{
echo json_encode ([
'success' => true,
'message' => lang('Suppliers.successful_adding') . ' ' . $supplier_data['company_name'],
'id' => $supplier_data['person_id']
]);
}
else //Existing supplier
{
echo json_encode ([
'success' => true,
'message' => lang('Suppliers.successful_updating') . ' ' . $supplier_data['company_name'],
'id' => $supplier_id]);
}
}
else//failure
{
echo json_encode ([
'success' => false,
'message' => lang('Suppliers.error_adding_updating') . ' ' . $supplier_data['company_name'],
'id' => NEW_ENTRY
]);
}
}
if($this->supplier->save_supplier($person_data, $supplier_data, $supplier_id))
{
//New supplier
if($supplier_id == NEW_ENTRY)
{
echo json_encode ([
'success' => true,
'message' => lang('Suppliers.successful_adding') . ' ' . $supplier_data['company_name'],
'id' => $supplier_data['person_id']
]);
}
else //Existing supplier
{
echo json_encode ([
'success' => true,
'message' => lang('Suppliers.successful_updating') . ' ' . $supplier_data['company_name'],
'id' => $supplier_id]);
}
}
else//failure
{
echo json_encode ([
'success' => false,
'message' => lang('Suppliers.error_adding_updating') . ' ' . $supplier_data['company_name'],
'id' => NEW_ENTRY
]);
}
}
/**
* This deletes suppliers from the suppliers table
*
* @return void
*/
public function postDelete(): void
{
$suppliers_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_NUMBER_INT);
/**
* This deletes suppliers from the suppliers table
*
* @return void
*/
public function postDelete(): void
{
$suppliers_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_NUMBER_INT);
if($this->supplier->delete_list($suppliers_to_delete))
{
echo json_encode ([
'success' => true,
'message' => lang('Suppliers.successful_deleted') . ' ' . count($suppliers_to_delete) . ' ' . lang('Suppliers.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Suppliers.cannot_be_deleted')]);
}
}
if($this->supplier->delete_list($suppliers_to_delete))
{
echo json_encode ([
'success' => true,
'message' => lang('Suppliers.successful_deleted') . ' ' . count($suppliers_to_delete) . ' ' . lang('Suppliers.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Suppliers.cannot_be_deleted')]);
}
}
}

View File

@@ -10,132 +10,132 @@ use Config\Services;
*/
class Tax_categories extends Secure_Controller
{
private Tax_category $tax_category;
private Tax_category $tax_category;
public function __construct()
{
parent::__construct('tax_categories');
public function __construct()
{
parent::__construct('tax_categories');
$this->tax_category = model(Tax_category::class);
}
$this->tax_category = model(Tax_category::class);
}
/**
* @return void
*/
public function getIndex(): void
{
$data['tax_categories_table_headers'] = get_tax_categories_table_headers();
/**
* @return void
*/
public function getIndex(): void
{
$data['tax_categories_table_headers'] = get_tax_categories_table_headers();
echo view('taxes/tax_categories', $data);
}
echo view('taxes/tax_categories', $data);
}
/**
* Returns tax_category table data rows. This will be called with AJAX.
*
* @return void
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* Returns tax_category table data rows. This will be called with AJAX.
*
* @return void
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$tax_categories = $this->tax_category->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->tax_category->get_found_rows($search);
$tax_categories = $this->tax_category->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->tax_category->get_found_rows($search);
$data_rows = [];
foreach($tax_categories->getResult() as $tax_category)
{
$data_rows[] = get_tax_categories_data_row($tax_category);
}
$data_rows = [];
foreach($tax_categories->getResult() as $tax_category)
{
$data_rows[] = get_tax_categories_data_row($tax_category);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
/**
* @param $row_id
* @return void
*/
public function getRow($row_id): void
{
$data_row = get_tax_categories_data_row($this->tax_category->get_info($row_id));
/**
* @param $row_id
* @return void
*/
public function getRow($row_id): void
{
$data_row = get_tax_categories_data_row($this->tax_category->get_info($row_id));
echo json_encode($data_row);
}
echo json_encode($data_row);
}
/**
* @param int $tax_category_id
* @return void
*/
public function getView(int $tax_category_id = NEW_ENTRY): void
{
$data['tax_category_info'] = $this->tax_category->get_info($tax_category_id);
/**
* @param int $tax_category_id
* @return void
*/
public function getView(int $tax_category_id = NEW_ENTRY): void
{
$data['tax_category_info'] = $this->tax_category->get_info($tax_category_id);
echo view("taxes/tax_category_form", $data);
}
echo view("taxes/tax_category_form", $data);
}
/**
* @param int $tax_category_id
* @return void
*/
public function postSave(int $tax_category_id = NEW_ENTRY): void
{
$tax_category_data = [
'tax_category' => $this->request->getPost('tax_category', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'tax_category_code' => $this->request->getPost('tax_category_code', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'tax_group_sequence' => $this->request->getPost('tax_group_sequence', FILTER_SANITIZE_NUMBER_INT)
];
/**
* @param int $tax_category_id
* @return void
*/
public function postSave(int $tax_category_id = NEW_ENTRY): void
{
$tax_category_data = [
'tax_category' => $this->request->getPost('tax_category', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'tax_category_code' => $this->request->getPost('tax_category_code', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'tax_group_sequence' => $this->request->getPost('tax_group_sequence', FILTER_SANITIZE_NUMBER_INT)
];
if($this->tax_category->save_value($tax_category_data, $tax_category_id))
{
// New tax_category_id
if($tax_category_id == NEW_ENTRY)
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_categories.successful_adding'),
'id' => $tax_category_data['tax_category_id']
]);
}
else
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_categories.successful_updating'),
'id' => $tax_category_id
]);
}
}
else
{
echo json_encode ([
'success' => false,
'message' => lang('Tax_categories.error_adding_updating') . ' ' . $tax_category_data['tax_category'],
'id' => NEW_ENTRY
]);
}
}
if($this->tax_category->save_value($tax_category_data, $tax_category_id))
{
// New tax_category_id
if($tax_category_id == NEW_ENTRY)
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_categories.successful_adding'),
'id' => $tax_category_data['tax_category_id']
]);
}
else
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_categories.successful_updating'),
'id' => $tax_category_id
]);
}
}
else
{
echo json_encode ([
'success' => false,
'message' => lang('Tax_categories.error_adding_updating') . ' ' . $tax_category_data['tax_category'],
'id' => NEW_ENTRY
]);
}
}
/**
* @return void
*/
public function postDelete(): void
{
$tax_categories_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_NUMBER_INT);
/**
* @return void
*/
public function postDelete(): void
{
$tax_categories_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_NUMBER_INT);
if($this->tax_category->delete_list($tax_categories_to_delete))
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_categories.successful_deleted') . ' ' . count($tax_categories_to_delete) . ' ' . lang('Tax_categories.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Tax_categories.cannot_be_deleted')]);
}
}
if($this->tax_category->delete_list($tax_categories_to_delete))
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_categories.successful_deleted') . ' ' . count($tax_categories_to_delete) . ' ' . lang('Tax_categories.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Tax_categories.cannot_be_deleted')]);
}
}
}

View File

@@ -10,143 +10,143 @@ use Config\Services;
*/
class Tax_codes extends Secure_Controller
{
private Tax_code $tax_code;
private Tax_code $tax_code;
public function __construct()
{
parent::__construct('tax_codes');
public function __construct()
{
parent::__construct('tax_codes');
$this->tax_code = model(Tax_code::class);
helper('tax_helper');
}
$this->tax_code = model(Tax_code::class);
helper('tax_helper');
}
/**
* @return void
*/
public function getIndex(): void
{
echo view('taxes/tax_codes', $this->get_data());
}
/**
* @return void
*/
public function getIndex(): void
{
echo view('taxes/tax_codes', $this->get_data());
}
/**
* @return array
*/
public function get_data(): array
{
/**
* @return array
*/
public function get_data(): array
{
$data['table_headers'] = get_tax_code_table_headers();
return $data;
}
$data['table_headers'] = get_tax_code_table_headers();
return $data;
}
/**
* Returns tax_category table data rows. This will be called with AJAX.
*
* @return void
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* Returns tax_category table data rows. This will be called with AJAX.
*
* @return void
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$tax_codes = $this->tax_code->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->tax_code->get_found_rows($search);
$tax_codes = $this->tax_code->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->tax_code->get_found_rows($search);
$data_rows = [];
$data_rows = [];
foreach($tax_codes->getResult() as $tax_code)
{
$data_rows[] = get_tax_code_data_row($tax_code);
}
foreach($tax_codes->getResult() as $tax_code)
{
$data_rows[] = get_tax_code_data_row($tax_code);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$data_row = get_tax_code_data_row($this->tax_code->get_info($row_id));
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$data_row = get_tax_code_data_row($this->tax_code->get_info($row_id));
echo json_encode($data_row);
}
echo json_encode($data_row);
}
/**
* @param int $tax_code_id
* @return void
*/
public function getView(int $tax_code_id = NEW_ENTRY): void
{
$data['tax_code_info'] = $this->tax_code->get_info($tax_code_id);
/**
* @param int $tax_code_id
* @return void
*/
public function getView(int $tax_code_id = NEW_ENTRY): void
{
$data['tax_code_info'] = $this->tax_code->get_info($tax_code_id);
echo view("taxes/tax_code_form", $data);
}
echo view("taxes/tax_code_form", $data);
}
/**
* @param int $tax_code_id
* @return void
*/
public function postSave(int $tax_code_id = NEW_ENTRY): void
{
$tax_code_data = [
'tax_code' => $this->request->getPost('tax_code', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'tax_code_name' => $this->request->getPost('tax_code_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'city' => $this->request->getPost('city', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'state' => $this->request->getPost('state', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
];
/**
* @param int $tax_code_id
* @return void
*/
public function postSave(int $tax_code_id = NEW_ENTRY): void
{
$tax_code_data = [
'tax_code' => $this->request->getPost('tax_code', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'tax_code_name' => $this->request->getPost('tax_code_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'city' => $this->request->getPost('city', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'state' => $this->request->getPost('state', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
];
if($this->tax_code->save($tax_code_data))
{
if($tax_code_id == NEW_ENTRY)
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_codes.successful_adding'),
'id' => $tax_code_data['tax_code_id']
]);
}
else
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_codes.successful_updating'),
'id' => $tax_code_id
]);
}
}
else
{
echo json_encode ([
'success' => false,
'message' => lang('Tax_codes.error_adding_updating') . ' ' . $tax_code_data['tax_code_id'],
'id' => NEW_ENTRY
]);
}
}
if($this->tax_code->save($tax_code_data))
{
if($tax_code_id == NEW_ENTRY)
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_codes.successful_adding'),
'id' => $tax_code_data['tax_code_id']
]);
}
else
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_codes.successful_updating'),
'id' => $tax_code_id
]);
}
}
else
{
echo json_encode ([
'success' => false,
'message' => lang('Tax_codes.error_adding_updating') . ' ' . $tax_code_data['tax_code_id'],
'id' => NEW_ENTRY
]);
}
}
/**
* @return void
*/
public function postDelete(): void
{
$tax_codes_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_NUMBER_INT);
/**
* @return void
*/
public function postDelete(): void
{
$tax_codes_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_NUMBER_INT);
if($this->tax_code->delete_list($tax_codes_to_delete))
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_codes.successful_deleted') . ' ' . count($tax_codes_to_delete) . ' ' . lang('Tax_codes.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Tax_codes.cannot_be_deleted')]);
}
}
if($this->tax_code->delete_list($tax_codes_to_delete))
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_codes.successful_deleted') . ' ' . count($tax_codes_to_delete) . ' ' . lang('Tax_codes.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Tax_codes.cannot_be_deleted')]);
}
}
}

View File

@@ -10,133 +10,133 @@ use Config\Services;
*/
class Tax_jurisdictions extends Secure_Controller
{
private Tax_jurisdiction $tax_jurisdiction;
private Tax_jurisdiction $tax_jurisdiction;
public function __construct()
{
parent::__construct('tax_jurisdictions');
public function __construct()
{
parent::__construct('tax_jurisdictions');
$this->tax_jurisdiction = model(Tax_jurisdiction::class);
$this->tax_jurisdiction = model(Tax_jurisdiction::class);
helper('tax_helper');
}
helper('tax_helper');
}
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_tax_jurisdictions_table_headers();
/**
* @return void
*/
public function getIndex(): void
{
$data['table_headers'] = get_tax_jurisdictions_table_headers();
echo view('taxes/tax_jurisdictions', $data);
}
echo view('taxes/tax_jurisdictions', $data);
}
/**
* Returns tax_category table data rows. This will be called with AJAX.
*
* @return void
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
/**
* Returns tax_category table data rows. This will be called with AJAX.
*
* @return void
*/
public function getSearch(): void
{
$search = $this->request->getGet('search');
$limit = $this->request->getGet('limit', FILTER_SANITIZE_NUMBER_INT);
$offset = $this->request->getGet('offset', FILTER_SANITIZE_NUMBER_INT);
$sort = $this->request->getGet('sort', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$order = $this->request->getGet('order', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$tax_jurisdictions = $this->tax_jurisdiction->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->tax_jurisdiction->get_found_rows($search);
$tax_jurisdictions = $this->tax_jurisdiction->search($search, $limit, $offset, $sort, $order);
$total_rows = $this->tax_jurisdiction->get_found_rows($search);
$data_rows = [];
foreach($tax_jurisdictions->getResult() as $tax_jurisdiction)
{
$data_rows[] = get_tax_jurisdictions_data_row($tax_jurisdiction);
}
$data_rows = [];
foreach($tax_jurisdictions->getResult() as $tax_jurisdiction)
{
$data_rows[] = get_tax_jurisdictions_data_row($tax_jurisdiction);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
echo json_encode (['total' => $total_rows, 'rows' => $data_rows]);
}
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$data_row = get_tax_jurisdictions_data_row($this->tax_jurisdiction->get_info($row_id));
/**
* @param int $row_id
* @return void
*/
public function getRow(int $row_id): void
{
$data_row = get_tax_jurisdictions_data_row($this->tax_jurisdiction->get_info($row_id));
echo json_encode($data_row);
}
echo json_encode($data_row);
}
/**
* @param int $tax_jurisdiction_id
* @return void
*/
public function getView(int $tax_jurisdiction_id = NEW_ENTRY): void
{
$data['tax_jurisdiction_info'] = $this->tax_jurisdiction->get_info($tax_jurisdiction_id);
/**
* @param int $tax_jurisdiction_id
* @return void
*/
public function getView(int $tax_jurisdiction_id = NEW_ENTRY): void
{
$data['tax_jurisdiction_info'] = $this->tax_jurisdiction->get_info($tax_jurisdiction_id);
echo view("taxes/tax_jurisdiction_form", $data);
}
echo view("taxes/tax_jurisdiction_form", $data);
}
/**
* @param int $jurisdiction_id
* @return void
*/
public function postSave(int $jurisdiction_id = NEW_ENTRY): void
{
$tax_jurisdiction_data = [
'jurisdiction_name' => $this->request->getPost('jurisdiction_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'reporting_authority' => $this->request->getPost('reporting_authority', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
];
/**
* @param int $jurisdiction_id
* @return void
*/
public function postSave(int $jurisdiction_id = NEW_ENTRY): void
{
$tax_jurisdiction_data = [
'jurisdiction_name' => $this->request->getPost('jurisdiction_name', FILTER_SANITIZE_FULL_SPECIAL_CHARS),
'reporting_authority' => $this->request->getPost('reporting_authority', FILTER_SANITIZE_FULL_SPECIAL_CHARS)
];
if($this->tax_jurisdiction->save_value($tax_jurisdiction_data))
{
if($jurisdiction_id == NEW_ENTRY)
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_jurisdictions.successful_adding'),
'id' => $tax_jurisdiction_data['jurisdiction_id']
]);
}
else
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_jurisdictions.successful_updating'),
'id' => $jurisdiction_id
]);
}
}
else
{
echo json_encode ([
'success' => false,
'message' => lang('Tax_jurisdictions.error_adding_updating') . ' ' . $tax_jurisdiction_data['jurisdiction_name'],
'id' => NEW_ENTRY
]);
}
}
if($this->tax_jurisdiction->save_value($tax_jurisdiction_data))
{
if($jurisdiction_id == NEW_ENTRY)
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_jurisdictions.successful_adding'),
'id' => $tax_jurisdiction_data['jurisdiction_id']
]);
}
else
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_jurisdictions.successful_updating'),
'id' => $jurisdiction_id
]);
}
}
else
{
echo json_encode ([
'success' => false,
'message' => lang('Tax_jurisdictions.error_adding_updating') . ' ' . $tax_jurisdiction_data['jurisdiction_name'],
'id' => NEW_ENTRY
]);
}
}
/**
* @return void
*/
public function postDelete(): void
{
$tax_jurisdictions_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_NUMBER_INT);
/**
* @return void
*/
public function postDelete(): void
{
$tax_jurisdictions_to_delete = $this->request->getPost('ids', FILTER_SANITIZE_NUMBER_INT);
if($this->tax_jurisdiction->delete_list($tax_jurisdictions_to_delete))
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_jurisdictions.successful_deleted') . ' ' . count($tax_jurisdictions_to_delete) . ' ' . lang('Tax_jurisdictions.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Tax_jurisdictions.cannot_be_deleted')]);
}
}
if($this->tax_jurisdiction->delete_list($tax_jurisdictions_to_delete))
{
echo json_encode ([
'success' => true,
'message' => lang('Tax_jurisdictions.successful_deleted') . ' ' . count($tax_jurisdictions_to_delete) . ' ' . lang('Tax_jurisdictions.one_or_multiple')
]);
}
else
{
echo json_encode (['success' => false, 'message' => lang('Tax_jurisdictions.cannot_be_deleted')]);
}
}
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>403 Forbidden</title>
<title>403 Forbidden</title>
</head>
<body>

View File

@@ -6,25 +6,25 @@ use CodeIgniter\Database\Migration;
class Migration_Upgrade_To_3_1_1 extends Migration
{
public function __construct()
{
parent::__construct();
}
public function __construct()
{
parent::__construct();
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.0.2_to_3.1.1.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.0.2_to_3.1.1.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -13,425 +13,425 @@ use CodeIgniter\Database\ResultInterface;
*/
class Migration_Sales_Tax_Data extends Migration
{
public const ROUND_UP = 5; //TODO: These need to be moved to constants.php
public const ROUND_DOWN = 6;
public const HALF_FIVE = 7;
public const YES = '1';
public const VAT_TAX = '0';
public const SALES_TAX = '1';
private Appconfig $appconfig;
public const ROUND_UP = 5; //TODO: These need to be moved to constants.php
public const ROUND_DOWN = 6;
public const HALF_FIVE = 7;
public const YES = '1';
public const VAT_TAX = '0';
public const SALES_TAX = '1';
private Appconfig $appconfig;
public function __construct()
{
parent::__construct();
$this->appconfig = model(Appconfig::class);
}
public function __construct()
{
parent::__construct();
$this->appconfig = model(Appconfig::class);
}
//TODO: we need to figure out why we get a server error when uncommented portions of this migration run
/**
* Perform a migration step.
*/
public function up(): void
{
$number_of_unmigrated = $this->get_count_of_unmigrated();
error_log("Migrating sales tax history. The number of sales that will be migrated is $number_of_unmigrated");
/**
* Perform a migration step.
*/
public function up(): void
{
$number_of_unmigrated = $this->get_count_of_unmigrated();
error_log("Migrating sales tax history. The number of sales that will be migrated is $number_of_unmigrated");
if($number_of_unmigrated > 0)
{
$unmigrated_invoices = $this->get_unmigrated($number_of_unmigrated)->getResultArray();
if($number_of_unmigrated > 0)
{
$unmigrated_invoices = $this->get_unmigrated($number_of_unmigrated)->getResultArray();
foreach($unmigrated_invoices as $key => $unmigrated_invoice)
{
$this->upgrade_tax_history_for_sale($unmigrated_invoice['sale_id']);
}
}
foreach($unmigrated_invoices as $key => $unmigrated_invoice)
{
$this->upgrade_tax_history_for_sale($unmigrated_invoice['sale_id']);
}
}
error_log('Migrating sales tax history. The number of sales that will be migrated is finished.');
}
error_log('Migrating sales tax history. The number of sales that will be migrated is finished.');
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
/**
* @param int $sale_id
* @return void
*/
private function upgrade_tax_history_for_sale(int $sale_id): void
{
$tax_decimals = $this->appconfig->get_value('tax_decimals', 2);
$tax_included = $this->appconfig->get_value('tax_included', Migration_Sales_Tax_Data::YES) == Migration_Sales_Tax_Data::YES;
$customer_sales_tax_support = false;
/**
* @param int $sale_id
* @return void
*/
private function upgrade_tax_history_for_sale(int $sale_id): void
{
$tax_decimals = $this->appconfig->get_value('tax_decimals', 2);
$tax_included = $this->appconfig->get_value('tax_included', Migration_Sales_Tax_Data::YES) == Migration_Sales_Tax_Data::YES;
$customer_sales_tax_support = false;
if($tax_included) //TODO: Convert to ternary notation.
{
$tax_type = Migration_Sales_Tax_Data::VAT_TAX;
}
else
{
$tax_type = Migration_Sales_Tax_Data::SALES_TAX;
}
if($tax_included) //TODO: Convert to ternary notation.
{
$tax_type = Migration_Sales_Tax_Data::VAT_TAX;
}
else
{
$tax_type = Migration_Sales_Tax_Data::SALES_TAX;
}
$sales_taxes = [];
$tax_group_sequence = 0;
$items = $this->get_sale_items_for_migration($sale_id)->getResultArray();
$sales_taxes = [];
$tax_group_sequence = 0;
$items = $this->get_sale_items_for_migration($sale_id)->getResultArray();
foreach($items as $item)
{
// This computes tax for each line item and adds it to the tax type total
$tax_group = (float)$item['percent'] . '% ' . $item['name'];
$tax_basis = $this->get_item_total($item['quantity_purchased'], $item['item_unit_price'], $item['discount_percent'], true);
foreach($items as $item)
{
// This computes tax for each line item and adds it to the tax type total
$tax_group = (float)$item['percent'] . '% ' . $item['name'];
$tax_basis = $this->get_item_total($item['quantity_purchased'], $item['item_unit_price'], $item['discount_percent'], true);
$item_tax_amount = $tax_included
? $this->get_item_tax($item['quantity_purchased'], $item['item_unit_price'], $item['discount_percent'], $item['percent'])
: $this->get_sales_tax_for_amount($tax_basis, $item['percent'], PHP_ROUND_HALF_UP, $tax_decimals);
$item_tax_amount = $tax_included
? $this->get_item_tax($item['quantity_purchased'], $item['item_unit_price'], $item['discount_percent'], $item['percent'])
: $this->get_sales_tax_for_amount($tax_basis, $item['percent'], PHP_ROUND_HALF_UP, $tax_decimals);
$this->update_sales_items_taxes_amount($sale_id, $item['line'], $item['name'], $item['percent'], $tax_type, $item_tax_amount);
$this->update_sales_taxes($sales_taxes, $tax_type, $tax_group, $item['percent'], $tax_basis, $item_tax_amount, $tax_group_sequence, PHP_ROUND_HALF_UP, $sale_id, $item['name']);
$tax_group_sequence++;
}
//Not sure when this would ever kick in, but this is technically the correct logic.
if($customer_sales_tax_support) //TODO: This will always evaluate to false
{
$this->apply_invoice_taxing($sales_taxes);
}
$this->update_sales_items_taxes_amount($sale_id, $item['line'], $item['name'], $item['percent'], $tax_type, $item_tax_amount);
$this->update_sales_taxes($sales_taxes, $tax_type, $tax_group, $item['percent'], $tax_basis, $item_tax_amount, $tax_group_sequence, PHP_ROUND_HALF_UP, $sale_id, $item['name']);
$tax_group_sequence++;
}
//Not sure when this would ever kick in, but this is technically the correct logic.
if($customer_sales_tax_support) //TODO: This will always evaluate to false
{
$this->apply_invoice_taxing($sales_taxes);
}
$this->round_sales_taxes($sales_taxes);
$this->save_sales_tax($sales_taxes);
}
$this->round_sales_taxes($sales_taxes);
$this->save_sales_tax($sales_taxes);
}
/**
* @param int $block_count
* @return ResultInterface
*/
private function get_unmigrated(int $block_count): ResultInterface
{
$builder = $this->db->table('sales_items_taxes as SIT');
$builder->select('SIT.sale_id');
$builder->select('ST.sale_id as sales_taxes_sale_id');
$builder->join('sales_taxes as ST','SIT.sale_id = ST.sale_id', 'left');
$builder->where('ST.sale_id', null);
$builder->groupBy('SIT.sale_id');
$builder->groupBy('ST.sale_id');
$builder->orderBy('SIT.sale_id');
$builder->limit($block_count);
/**
* @param int $block_count
* @return ResultInterface
*/
private function get_unmigrated(int $block_count): ResultInterface
{
$builder = $this->db->table('sales_items_taxes as SIT');
$builder->select('SIT.sale_id');
$builder->select('ST.sale_id as sales_taxes_sale_id');
$builder->join('sales_taxes as ST','SIT.sale_id = ST.sale_id', 'left');
$builder->where('ST.sale_id', null);
$builder->groupBy('SIT.sale_id');
$builder->groupBy('ST.sale_id');
$builder->orderBy('SIT.sale_id');
$builder->limit($block_count);
return $builder->get();
}
return $builder->get();
}
/**
* @param int $sale_id
* @return ResultInterface
*/
private function get_sale_items_for_migration(int $sale_id): ResultInterface
{
$builder = $this->db->table('sales_items as sales_items');
$builder->select('sales_items.sale_id as sale_id');
$builder->select('sales_items.line as line');
$builder->select('item_unit_price');
$builder->select('discount_percent');
$builder->select('quantity_purchased');
$builder->select('percent');
$builder->select('name');
$builder->join('sales_items_taxes as sales_items_taxes', 'sales_items.sale_id = sales_items_taxes.sale_id and sales_items.line = sales_items_taxes.line');
$builder->where('sales_items.sale_id', $sale_id);
/**
* @param int $sale_id
* @return ResultInterface
*/
private function get_sale_items_for_migration(int $sale_id): ResultInterface
{
$builder = $this->db->table('sales_items as sales_items');
$builder->select('sales_items.sale_id as sale_id');
$builder->select('sales_items.line as line');
$builder->select('item_unit_price');
$builder->select('discount_percent');
$builder->select('quantity_purchased');
$builder->select('percent');
$builder->select('name');
$builder->join('sales_items_taxes as sales_items_taxes', 'sales_items.sale_id = sales_items_taxes.sale_id and sales_items.line = sales_items_taxes.line');
$builder->where('sales_items.sale_id', $sale_id);
return $builder->get();
}
return $builder->get();
}
/**
* @return int
*/
private function get_count_of_unmigrated(): int
{
$result = $this->db->query('SELECT COUNT(*) FROM(SELECT SIT.sale_id, ST.sale_id as sales_taxes_sale_id FROM '
. $this->db->prefixTable('sales_items_taxes')
. ' as SIT LEFT JOIN '
. $this->db->prefixTable('sales_taxes')
. ' as ST ON SIT.sale_id = ST.sale_id WHERE ST.sale_id is null GROUP BY SIT.sale_id, ST.sale_id'
. ' ORDER BY SIT.sale_id) as US')->getResultArray();
/**
* @return int
*/
private function get_count_of_unmigrated(): int
{
$result = $this->db->query('SELECT COUNT(*) FROM(SELECT SIT.sale_id, ST.sale_id as sales_taxes_sale_id FROM '
. $this->db->prefixTable('sales_items_taxes')
. ' as SIT LEFT JOIN '
. $this->db->prefixTable('sales_taxes')
. ' as ST ON SIT.sale_id = ST.sale_id WHERE ST.sale_id is null GROUP BY SIT.sale_id, ST.sale_id'
. ' ORDER BY SIT.sale_id) as US')->getResultArray();
if(!$result)
{
error_log('Database error in 20170502221506_sales_tax_data.php related to sales_taxes or sales_items_taxes.');
return 0;
}
if(!$result)
{
error_log('Database error in 20170502221506_sales_tax_data.php related to sales_taxes or sales_items_taxes.');
return 0;
}
return $result[0]['COUNT(*)'] ?: 0;
}
return $result[0]['COUNT(*)'] ?: 0;
}
/**
* @param int $sale_id
* @param int $line
* @param string $name
* @param float $percent
* @param int $tax_type
* @param float $item_tax_amount
* @return void
*/
private function update_sales_items_taxes_amount(int $sale_id, int $line, string $name, float $percent, int $tax_type, float $item_tax_amount): void
{
$builder = $this->db->table('sales_items_taxes');
$builder->where('sale_id', $sale_id);
$builder->where('line', $line);
$builder->where('name', $name);
$builder->where('percent', $percent);
$builder->update(['tax_type' => $tax_type, 'item_tax_amount' => $item_tax_amount]);
}
/**
* @param int $sale_id
* @param int $line
* @param string $name
* @param float $percent
* @param int $tax_type
* @param float $item_tax_amount
* @return void
*/
private function update_sales_items_taxes_amount(int $sale_id, int $line, string $name, float $percent, int $tax_type, float $item_tax_amount): void
{
$builder = $this->db->table('sales_items_taxes');
$builder->where('sale_id', $sale_id);
$builder->where('line', $line);
$builder->where('name', $name);
$builder->where('percent', $percent);
$builder->update(['tax_type' => $tax_type, 'item_tax_amount' => $item_tax_amount]);
}
/**
* @param array $sales_taxes
* @return void
*/
private function save_sales_tax(array &$sales_taxes): void
{
$builder = $this->db->Table('sales_taxes');
/**
* @param array $sales_taxes
* @return void
*/
private function save_sales_tax(array &$sales_taxes): void
{
$builder = $this->db->Table('sales_taxes');
foreach($sales_taxes as $line => $sales_tax)
{
$builder->insert($sales_tax);
}
}
foreach($sales_taxes as $line => $sales_tax)
{
$builder->insert($sales_tax);
}
}
/**
* @param string $quantity
* @param string $price
* @param string $discount_percentage
* @param bool $include_discount
* @return string
*/
public function get_item_total(string $quantity, string $price, string $discount_percentage, bool $include_discount = false): string
{
$total = bcmul($quantity, $price);
/**
* @param string $quantity
* @param string $price
* @param string $discount_percentage
* @param bool $include_discount
* @return string
*/
public function get_item_total(string $quantity, string $price, string $discount_percentage, bool $include_discount = false): string
{
$total = bcmul($quantity, $price);
if($include_discount)
{
$discount_amount = $this->get_item_discount($quantity, $price, $discount_percentage);
return bcsub($total, $discount_amount);
}
if($include_discount)
{
$discount_amount = $this->get_item_discount($quantity, $price, $discount_percentage);
return bcsub($total, $discount_amount);
}
return $total;
}
return $total;
}
/**
* @param string $quantity
* @param string $price
* @param string $discount
* @return float
*/
public function get_item_discount(string $quantity, string $price, string $discount): float
{
$total = bcmul($quantity, $price);
$discount_fraction = bcdiv($discount, 100);
$discount = bcmul($total, $discount_fraction);
/**
* @param string $quantity
* @param string $price
* @param string $discount
* @return float
*/
public function get_item_discount(string $quantity, string $price, string $discount): float
{
$total = bcmul($quantity, $price);
$discount_fraction = bcdiv($discount, 100);
$discount = bcmul($total, $discount_fraction);
return round($discount, totals_decimals(), PHP_ROUND_HALF_UP); //TODO: I don't think this is currency safe. Round will cast it's first parameter to a float. It also returns a float.
}
return round($discount, totals_decimals(), PHP_ROUND_HALF_UP); //TODO: I don't think this is currency safe. Round will cast it's first parameter to a float. It also returns a float.
}
/**
* @param string $quantity
* @param string $price
* @param string $discount_percentage
* @param string $tax_percentage
* @return string
*/
public function get_item_tax(string $quantity, string $price, string $discount_percentage, string $tax_percentage): string
{
$tax_included = $this->appconfig->get_value('tax_included', Migration_Sales_Tax_Data::YES) == Migration_Sales_Tax_Data::YES;
/**
* @param string $quantity
* @param string $price
* @param string $discount_percentage
* @param string $tax_percentage
* @return string
*/
public function get_item_tax(string $quantity, string $price, string $discount_percentage, string $tax_percentage): string
{
$tax_included = $this->appconfig->get_value('tax_included', Migration_Sales_Tax_Data::YES) == Migration_Sales_Tax_Data::YES;
$price = $this->get_item_total($quantity, $price, $discount_percentage, true);
$price = $this->get_item_total($quantity, $price, $discount_percentage, true);
if($tax_included)
{
$tax_fraction = bcadd('100', $tax_percentage);
$tax_fraction = bcdiv($tax_fraction, '100');
$price_tax_excl = bcdiv($price, $tax_fraction);
if($tax_included)
{
$tax_fraction = bcadd('100', $tax_percentage);
$tax_fraction = bcdiv($tax_fraction, '100');
$price_tax_excl = bcdiv($price, $tax_fraction);
return bcsub($price, $price_tax_excl);
}
$tax_fraction = bcdiv($tax_percentage, '100');
return bcsub($price, $price_tax_excl);
}
$tax_fraction = bcdiv($tax_percentage, '100');
return bcmul($price, $tax_fraction);
}
return bcmul($price, $tax_fraction);
}
/**
* @param string $tax_basis
* @param string $tax_percentage
* @param int $rounding_mode
* @param int $decimals
* @return float
*/
public function get_sales_tax_for_amount(string $tax_basis, string $tax_percentage, int $rounding_mode, int $decimals): float
{
$tax_fraction = bcdiv($tax_percentage, '100');
$tax_amount = bcmul($tax_basis, $tax_fraction);
/**
* @param string $tax_basis
* @param string $tax_percentage
* @param int $rounding_mode
* @param int $decimals
* @return float
*/
public function get_sales_tax_for_amount(string $tax_basis, string $tax_percentage, int $rounding_mode, int $decimals): float
{
$tax_fraction = bcdiv($tax_percentage, '100');
$tax_amount = bcmul($tax_basis, $tax_fraction);
return $this->round_number($rounding_mode, $tax_amount, $decimals);
}
return $this->round_number($rounding_mode, $tax_amount, $decimals);
}
/**
* @param int $rounding_mode
* @param string $amount
* @param int $decimals
* @return float
*/
public function round_number(int $rounding_mode, string $amount, int $decimals): float
{
if($rounding_mode == Migration_Sales_Tax_Data::ROUND_UP)
{
$fig = pow(10,$decimals);
$rounded_total = (ceil($fig * $amount) + ceil($fig * $amount - ceil($fig * $amount)))/$fig;
}
elseif($rounding_mode == Migration_Sales_Tax_Data::ROUND_DOWN)
{
$fig = pow(10,$decimals);
$rounded_total = (floor($fig * $amount) + floor($fig * $amount - floor($fig * $amount)))/$fig;
}
elseif($rounding_mode == Migration_Sales_Tax_Data::HALF_FIVE)
{
$rounded_total = round($amount / 5) * 5;
}
else
{
$rounded_total = round($amount, $decimals, $rounding_mode);
}
/**
* @param int $rounding_mode
* @param string $amount
* @param int $decimals
* @return float
*/
public function round_number(int $rounding_mode, string $amount, int $decimals): float
{
if($rounding_mode == Migration_Sales_Tax_Data::ROUND_UP)
{
$fig = pow(10,$decimals);
$rounded_total = (ceil($fig * $amount) + ceil($fig * $amount - ceil($fig * $amount)))/$fig;
}
elseif($rounding_mode == Migration_Sales_Tax_Data::ROUND_DOWN)
{
$fig = pow(10,$decimals);
$rounded_total = (floor($fig * $amount) + floor($fig * $amount - floor($fig * $amount)))/$fig;
}
elseif($rounding_mode == Migration_Sales_Tax_Data::HALF_FIVE)
{
$rounded_total = round($amount / 5) * 5;
}
else
{
$rounded_total = round($amount, $decimals, $rounding_mode);
}
return $rounded_total; //TODO: I don't think this is currency safe. I think we need to be using bcmath() functions like we are in the rest of the code.
}
return $rounded_total; //TODO: I don't think this is currency safe. I think we need to be using bcmath() functions like we are in the rest of the code.
}
/**
* @param array $sales_taxes
* @param string $tax_type
* @param string $tax_group
* @param float $tax_rate
* @param string $tax_basis
* @param string $item_tax_amount
* @param int $tax_group_sequence
* @param int $rounding_code
* @param int $sale_id
* @param string $name
* @param string $tax_code
* @return void
*/
public function update_sales_taxes(array &$sales_taxes, string $tax_type, string $tax_group, float $tax_rate, string $tax_basis, string $item_tax_amount, int $tax_group_sequence, int $rounding_code, int $sale_id, string $name = '', string $tax_code = ''): void
{
$tax_group_index = $this->clean('X'.$tax_group);
if(!array_key_exists($tax_group_index, $sales_taxes))
{
$insertkey = $tax_group_index; //TODO: $insertkey does not follow naming conventions.
$sales_tax = [
$insertkey => [
'sale_id' => $sale_id,
'tax_type' => $tax_type,
'tax_group' => $tax_group,
'sale_tax_basis' => $tax_basis,
'sale_tax_amount' => $item_tax_amount,
'print_sequence' => $tax_group_sequence,
'name' => $name,
'tax_rate' => $tax_rate,
'sales_tax_code' => $tax_code,
'rounding_code' => $rounding_code
]
];
//add to existing array
$sales_taxes += $sales_tax;
}
else
{
// Important ... the sales amounts are accumulated for the group at the maximum configurable scale value of 4
// but the scale will in reality be the scale specified by the tax_decimal configuration value used for sales_items_taxes
$sales_taxes[$tax_group_index]['sale_tax_basis'] = bcadd($sales_taxes[$tax_group_index]['sale_tax_basis'], $tax_basis, 4);
$sales_taxes[$tax_group_index]['sale_tax_amount'] = bcadd($sales_taxes[$tax_group_index]['sale_tax_amount'], $item_tax_amount, 4);
}
}
/**
* @param array $sales_taxes
* @param string $tax_type
* @param string $tax_group
* @param float $tax_rate
* @param string $tax_basis
* @param string $item_tax_amount
* @param int $tax_group_sequence
* @param int $rounding_code
* @param int $sale_id
* @param string $name
* @param string $tax_code
* @return void
*/
public function update_sales_taxes(array &$sales_taxes, string $tax_type, string $tax_group, float $tax_rate, string $tax_basis, string $item_tax_amount, int $tax_group_sequence, int $rounding_code, int $sale_id, string $name = '', string $tax_code = ''): void
{
$tax_group_index = $this->clean('X'.$tax_group);
if(!array_key_exists($tax_group_index, $sales_taxes))
{
$insertkey = $tax_group_index; //TODO: $insertkey does not follow naming conventions.
$sales_tax = [
$insertkey => [
'sale_id' => $sale_id,
'tax_type' => $tax_type,
'tax_group' => $tax_group,
'sale_tax_basis' => $tax_basis,
'sale_tax_amount' => $item_tax_amount,
'print_sequence' => $tax_group_sequence,
'name' => $name,
'tax_rate' => $tax_rate,
'sales_tax_code' => $tax_code,
'rounding_code' => $rounding_code
]
];
//add to existing array
$sales_taxes += $sales_tax;
}
else
{
// Important ... the sales amounts are accumulated for the group at the maximum configurable scale value of 4
// but the scale will in reality be the scale specified by the tax_decimal configuration value used for sales_items_taxes
$sales_taxes[$tax_group_index]['sale_tax_basis'] = bcadd($sales_taxes[$tax_group_index]['sale_tax_basis'], $tax_basis, 4);
$sales_taxes[$tax_group_index]['sale_tax_amount'] = bcadd($sales_taxes[$tax_group_index]['sale_tax_amount'], $item_tax_amount, 4);
}
}
/**
* @param string $string
* @return string
*/
public function clean(string $string): string //TODO: $string is not a good name for this variable
{
$string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.
/**
* @param string $string
* @return string
*/
public function clean(string $string): string //TODO: $string is not a good name for this variable
{
$string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.
return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
}
return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
}
/**
* @param array $sales_taxes
* @return void
*/
public function apply_invoice_taxing(array &$sales_taxes): void
{
if(!empty($sales_taxes)) //TODO: Duplicated code
{
$sort = [];
/**
* @param array $sales_taxes
* @return void
*/
public function apply_invoice_taxing(array &$sales_taxes): void
{
if(!empty($sales_taxes)) //TODO: Duplicated code
{
$sort = [];
foreach($sales_taxes as $key => $value)
{
$sort['print_sequence'][$key] = $value['print_sequence'];
}
foreach($sales_taxes as $key => $value)
{
$sort['print_sequence'][$key] = $value['print_sequence'];
}
array_multisort($sort['print_sequence'], SORT_ASC, $sales_taxes);
}
array_multisort($sort['print_sequence'], SORT_ASC, $sales_taxes);
}
$decimals = totals_decimals();
$decimals = totals_decimals();
foreach($sales_taxes as $row_number => $sales_tax)
{
$sales_taxes[$row_number]['sale_tax_amount'] = $this->get_sales_tax_for_amount($sales_tax['sale_tax_basis'], $sales_tax['tax_rate'], $sales_tax['rounding_code'], $decimals);
}
}
foreach($sales_taxes as $row_number => $sales_tax)
{
$sales_taxes[$row_number]['sale_tax_amount'] = $this->get_sales_tax_for_amount($sales_tax['sale_tax_basis'], $sales_tax['tax_rate'], $sales_tax['rounding_code'], $decimals);
}
}
/**
* @param array $sales_taxes
* @return void
*/
public function round_sales_taxes(array &$sales_taxes): void
{
if(!empty($sales_taxes))
{
$sort = [];
foreach($sales_taxes as $k=>$v)
{
$sort['print_sequence'][$k] = $v['print_sequence'];
}
array_multisort($sort['print_sequence'], SORT_ASC, $sales_taxes);
}
/**
* @param array $sales_taxes
* @return void
*/
public function round_sales_taxes(array &$sales_taxes): void
{
if(!empty($sales_taxes))
{
$sort = [];
foreach($sales_taxes as $k=>$v)
{
$sort['print_sequence'][$k] = $v['print_sequence'];
}
array_multisort($sort['print_sequence'], SORT_ASC, $sales_taxes);
}
$decimals = totals_decimals();
$decimals = totals_decimals();
foreach($sales_taxes as $row_number => $sales_tax)
{
$sale_tax_amount = $sales_tax['sale_tax_amount'];
$rounding_code = $sales_tax['rounding_code'];
$rounded_sale_tax_amount = $sale_tax_amount;
foreach($sales_taxes as $row_number => $sales_tax)
{
$sale_tax_amount = $sales_tax['sale_tax_amount'];
$rounding_code = $sales_tax['rounding_code'];
$rounded_sale_tax_amount = $sale_tax_amount;
if ($rounding_code == PHP_ROUND_HALF_UP
|| $rounding_code == PHP_ROUND_HALF_DOWN
|| $rounding_code == PHP_ROUND_HALF_EVEN
|| $rounding_code == PHP_ROUND_HALF_ODD)
{
$rounded_sale_tax_amount = round($sale_tax_amount, $decimals, $rounding_code);
}
elseif($rounding_code == Migration_Sales_Tax_Data::ROUND_UP)
{
$fig = (int) str_pad('1', $decimals, '0');
$rounded_sale_tax_amount = (ceil($sale_tax_amount * $fig) / $fig);
}
elseif($rounding_code == Migration_Sales_Tax_Data::ROUND_DOWN)
{
$fig = (int) str_pad('1', $decimals, '0');
$rounded_sale_tax_amount = (floor($sale_tax_amount * $fig) / $fig);
}
elseif($rounding_code == Migration_Sales_Tax_Data::HALF_FIVE)
{
$rounded_sale_tax_amount = round($sale_tax_amount / 5) * 5;
}
if ($rounding_code == PHP_ROUND_HALF_UP
|| $rounding_code == PHP_ROUND_HALF_DOWN
|| $rounding_code == PHP_ROUND_HALF_EVEN
|| $rounding_code == PHP_ROUND_HALF_ODD)
{
$rounded_sale_tax_amount = round($sale_tax_amount, $decimals, $rounding_code);
}
elseif($rounding_code == Migration_Sales_Tax_Data::ROUND_UP)
{
$fig = (int) str_pad('1', $decimals, '0');
$rounded_sale_tax_amount = (ceil($sale_tax_amount * $fig) / $fig);
}
elseif($rounding_code == Migration_Sales_Tax_Data::ROUND_DOWN)
{
$fig = (int) str_pad('1', $decimals, '0');
$rounded_sale_tax_amount = (floor($sale_tax_amount * $fig) / $fig);
}
elseif($rounding_code == Migration_Sales_Tax_Data::HALF_FIVE)
{
$rounded_sale_tax_amount = round($sale_tax_amount / 5) * 5;
}
$sales_taxes[$row_number]['sale_tax_amount'] = $rounded_sale_tax_amount;
}
}
$sales_taxes[$row_number]['sale_tax_amount'] = $rounded_sale_tax_amount;
}
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_Upgrade_To_3_2_0 extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.1.1_to_3.2.0.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.1.1_to_3.2.0.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_Upgrade_To_3_2_1 extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.2.0_to_3.2.1.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.2.0_to_3.2.1.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_Attributes extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_attributes.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_attributes.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_Upgrade_To_3_3_0 extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.2.1_to_3.3.0.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.2.1_to_3.3.0.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -6,169 +6,169 @@ use CodeIgniter\Database\Migration;
class Migration_IndiaGST extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
if(!$this->db->fieldExists('sales_tax_code', 'customers'))
{
return;
}
/**
* Perform a migration step.
*/
public function up(): void
{
if(!$this->db->fieldExists('sales_tax_code', 'customers'))
{
return;
}
// If number of entries is greater than zero then the tax data needs to be migrated
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_indiagst.sql');
// If number of entries is greater than zero then the tax data needs to be migrated
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_indiagst.sql');
error_log('Migrating tax configuration');
error_log('Migrating tax configuration');
$count_of_tax_codes = $this->get_count_of_tax_code_entries();
$count_of_tax_codes = $this->get_count_of_tax_code_entries();
if($count_of_tax_codes > 0)
{
$this->migrate_tax_code_data();
}
if($count_of_tax_codes > 0)
{
$this->migrate_tax_code_data();
}
$this->migrate_customer_tax_codes();
$this->migrate_customer_tax_codes();
$count_of_rate_entries = $this->get_count_of_rate_entries();
$count_of_rate_entries = $this->get_count_of_rate_entries();
if($count_of_rate_entries > 0)
{
$this->migrate_tax_rates();
}
if($count_of_rate_entries > 0)
{
$this->migrate_tax_rates();
}
$count_of_sales_taxes_entries = $this->get_count_of_sales_taxes_entries();
$count_of_sales_taxes_entries = $this->get_count_of_sales_taxes_entries();
if($count_of_sales_taxes_entries > 0)
{
$this->migrate_sales_taxes_data();
}
if($count_of_sales_taxes_entries > 0)
{
$this->migrate_sales_taxes_data();
}
$this->drop_backups();
$this->drop_backups();
error_log('Migrating tax configuration completed');
}
error_log('Migrating tax configuration completed');
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
/**
* @return int
*/
private function get_count_of_tax_code_entries(): int
{
$builder = $this->db->table('tax_codes_backup');
$builder->select('COUNT(*) as count');
/**
* @return int
*/
private function get_count_of_tax_code_entries(): int
{
$builder = $this->db->table('tax_codes_backup');
$builder->select('COUNT(*) as count');
return $builder->get()->getRow()->count;
}
return $builder->get()->getRow()->count;
}
/**
* @return int
*/
private function get_count_of_sales_taxes_entries(): int
{
$builder = $this->db->table('sales_taxes_backup');
$builder->select('COUNT(*) as count');
/**
* @return int
*/
private function get_count_of_sales_taxes_entries(): int
{
$builder = $this->db->table('sales_taxes_backup');
$builder->select('COUNT(*) as count');
return $builder->get()->getRow()->count;
}
return $builder->get()->getRow()->count;
}
/**
* @return int
*/
private function get_count_of_rate_entries(): int
{
$builder = $this->db->table('tax_code_rates_backup');
$builder->select('COUNT(*) as count');
/**
* @return int
*/
private function get_count_of_rate_entries(): int
{
$builder = $this->db->table('tax_code_rates_backup');
$builder->select('COUNT(*) as count');
return $builder->get()->getRow()->count;
}
return $builder->get()->getRow()->count;
}
/**
* This copies the old tax code configuration into the new tax code configuration
* assigning a tax_code_id id to the entry This only needs to be done if there are
* tax codes in the table.
*
* @return void
*/
private function migrate_tax_code_data(): void
{
$this->db->query('INSERT INTO ' . $this->db->prefixTable('tax_codes') . ' (tax_code, tax_code_name, city, state)
SELECT tax_code, tax_code_name, city, state FROM ' . $this->db->prefixTable('tax_codes_backup'));
}
/**
* This copies the old tax code configuration into the new tax code configuration
* assigning a tax_code_id id to the entry This only needs to be done if there are
* tax codes in the table.
*
* @return void
*/
private function migrate_tax_code_data(): void
{
$this->db->query('INSERT INTO ' . $this->db->prefixTable('tax_codes') . ' (tax_code, tax_code_name, city, state)
SELECT tax_code, tax_code_name, city, state FROM ' . $this->db->prefixTable('tax_codes_backup'));
}
/**
* The previous upgrade script added the new column to the customers table.
* This will assign a tax code id using the tax code field that was left in place on the customer table.
* After it is complete then it will drop the old customer tax code.
* This MUST run so that the old tax code is dropped
*
* @return void
*/
private function migrate_customer_tax_codes(): void
{
$this->db->query('UPDATE ' . $this->db->prefixTable('customers') . ' AS fa SET fa.sales_tax_code_id = (
SELECT tax_code_id FROM ' . $this->db->prefixTable('tax_codes') . ' AS fb where fa.sales_tax_code = fb.tax_code)');
/**
* The previous upgrade script added the new column to the customers table.
* This will assign a tax code id using the tax code field that was left in place on the customer table.
* After it is complete then it will drop the old customer tax code.
* This MUST run so that the old tax code is dropped
*
* @return void
*/
private function migrate_customer_tax_codes(): void
{
$this->db->query('UPDATE ' . $this->db->prefixTable('customers') . ' AS fa SET fa.sales_tax_code_id = (
SELECT tax_code_id FROM ' . $this->db->prefixTable('tax_codes') . ' AS fb where fa.sales_tax_code = fb.tax_code)');
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' DROP COLUMN sales_tax_code');
}
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' DROP COLUMN sales_tax_code');
}
/**
* The sales taxes table is undergoing a significant primary key change
* The new table assumes that sales taxes are associated with a jurisdiction
* For base taxes and the older tax system the tax jurisdiction code table will be
* initialized with an entry that is used to represent a dummy or consolidated jurisdiction.
* If there is only one tax jurisdiction then it can be renamed and life moves on.
* If the user wants to start reporting taxes by jurisdiction then the new jurisdictions need
* to be created and defined manually AFTER the upgrade.
* CONVERTING OLD TAX DATA TO BE SPLIT OUT BY JURISDICTION IS BEYOND THE SCOPE OF THIS EFFORT
*/
private function migrate_sales_taxes_data(): void
{
$this->db->query('INSERT INTO ' . $this->db->prefixTable('sales_taxes')
. ' (sale_id, jurisdiction_id, tax_category_id, tax_type, tax_group, sale_tax_basis, sale_tax_amount, print_sequence, '
. '`name`, tax_rate, sales_tax_code_id, rounding_code) '
. 'select sale_id, rate_jurisdiction_id, rate_tax_category_id, tax_type, tax_group, sale_tax_basis, sale_tax_amount, '
. 'print_sequence, `name`, A.tax_rate, tax_code_id, rounding_code '
. 'from ' . $this->db->prefixTable('sales_taxes_backup') . ' AS A '
. 'left outer join ' . $this->db->prefixTable('tax_codes') . ' AS B on sales_tax_code = tax_code '
. 'left outer join ' . $this->db->prefixTable('tax_rates') . ' AS C on tax_code_id = rate_tax_code_id and A.tax_rate = C.tax_rate '
. 'order by sale_id');
}
/**
* The sales taxes table is undergoing a significant primary key change
* The new table assumes that sales taxes are associated with a jurisdiction
* For base taxes and the older tax system the tax jurisdiction code table will be
* initialized with an entry that is used to represent a dummy or consolidated jurisdiction.
* If there is only one tax jurisdiction then it can be renamed and life moves on.
* If the user wants to start reporting taxes by jurisdiction then the new jurisdictions need
* to be created and defined manually AFTER the upgrade.
* CONVERTING OLD TAX DATA TO BE SPLIT OUT BY JURISDICTION IS BEYOND THE SCOPE OF THIS EFFORT
*/
private function migrate_sales_taxes_data(): void
{
$this->db->query('INSERT INTO ' . $this->db->prefixTable('sales_taxes')
. ' (sale_id, jurisdiction_id, tax_category_id, tax_type, tax_group, sale_tax_basis, sale_tax_amount, print_sequence, '
. '`name`, tax_rate, sales_tax_code_id, rounding_code) '
. 'select sale_id, rate_jurisdiction_id, rate_tax_category_id, tax_type, tax_group, sale_tax_basis, sale_tax_amount, '
. 'print_sequence, `name`, A.tax_rate, tax_code_id, rounding_code '
. 'from ' . $this->db->prefixTable('sales_taxes_backup') . ' AS A '
. 'left outer join ' . $this->db->prefixTable('tax_codes') . ' AS B on sales_tax_code = tax_code '
. 'left outer join ' . $this->db->prefixTable('tax_rates') . ' AS C on tax_code_id = rate_tax_code_id and A.tax_rate = C.tax_rate '
. 'order by sale_id');
}
/**
* @return void
*/
private function migrate_tax_rates(): void
{
// create a dummy jurisdiction record and retrieve the jurisdiction rate id
/**
* @return void
*/
private function migrate_tax_rates(): void
{
// create a dummy jurisdiction record and retrieve the jurisdiction rate id
$this->db->query('INSERT INTO ' . $this->db->prefixTable('tax_jurisdictions') . ' (jurisdiction_name, tax_group, tax_type, reporting_authority, '
. "tax_group_sequence, cascade_sequence, deleted) VALUES ('Jurisdiction1', 'TaxGroup1', '1', 'Authority1', 1, 0, '0')");
$this->db->query('INSERT INTO ' . $this->db->prefixTable('tax_jurisdictions') . ' (jurisdiction_name, tax_group, tax_type, reporting_authority, '
. "tax_group_sequence, cascade_sequence, deleted) VALUES ('Jurisdiction1', 'TaxGroup1', '1', 'Authority1', 1, 0, '0')");
$jurisdiction_id = $this->db->query('SELECT jurisdiction_id FROM ' . $this->db->prefixTable('tax_jurisdictions') . " WHERE jurisdiction_name = 'Jurisdiction1'")->getRow()->jurisdiction_id;
$jurisdiction_id = $this->db->query('SELECT jurisdiction_id FROM ' . $this->db->prefixTable('tax_jurisdictions') . " WHERE jurisdiction_name = 'Jurisdiction1'")->getRow()->jurisdiction_id;
// Insert old tax_code rates data into the new tax rates table
$this->db->query('INSERT INTO ' . $this->db->prefixTable('tax_rates')
. ' (rate_tax_category_id, rate_jurisdiction_id, rate_tax_code_id, tax_rate, tax_rounding_code) '
. 'SELECT rate_tax_category_id, ' . $jurisdiction_id . ', tax_code_id, tax_rate, rounding_code FROM '
. $this->db->prefixTable('tax_code_rates_backup') . ' JOIN ' . $this->db->prefixTable('tax_codes')
. ' ON tax_code = rate_tax_code');
}
// Insert old tax_code rates data into the new tax rates table
$this->db->query('INSERT INTO ' . $this->db->prefixTable('tax_rates')
. ' (rate_tax_category_id, rate_jurisdiction_id, rate_tax_code_id, tax_rate, tax_rounding_code) '
. 'SELECT rate_tax_category_id, ' . $jurisdiction_id . ', tax_code_id, tax_rate, rounding_code FROM '
. $this->db->prefixTable('tax_code_rates_backup') . ' JOIN ' . $this->db->prefixTable('tax_codes')
. ' ON tax_code = rate_tax_code');
}
/**
* @return void
*/
private function drop_backups(): void
{
$this->db->query('DROP TABLE IF EXISTS ' . $this->db->prefixTable('tax_codes_backup'));
$this->db->query('DROP TABLE IF EXISTS ' . $this->db->prefixTable('sales_taxes_backup'));
$this->db->query('DROP TABLE IF EXISTS ' . $this->db->prefixTable('tax_code_rates_backup'));
}
/**
* @return void
*/
private function drop_backups(): void
{
$this->db->query('DROP TABLE IF EXISTS ' . $this->db->prefixTable('tax_codes_backup'));
$this->db->query('DROP TABLE IF EXISTS ' . $this->db->prefixTable('sales_taxes_backup'));
$this->db->query('DROP TABLE IF EXISTS ' . $this->db->prefixTable('tax_code_rates_backup'));
}
}

View File

@@ -6,24 +6,24 @@ use CodeIgniter\Database\Migration;
class Migration_IndiaGST1 extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_indiagst1.sql');
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_indiagst1.sql');
error_log('Fix definition of Supplier.Tax Id');
error_log('Fix definition of Supplier.Tax Id');
error_log('Definition of Supplier.Tax Id corrected');
}
error_log('Definition of Supplier.Tax Id corrected');
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_IndiaGST2 extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_indiagst2.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_indiagst2.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_decimal_attribute_type extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_decimal_attribute_type.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_decimal_attribute_type.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_add_iso_4217 extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_add_iso_4217.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_add_iso_4217.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_PaymentTracking extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_paymenttracking.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_paymenttracking.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -6,108 +6,108 @@ use CodeIgniter\Database\Migration;
class Migration_RefundTracking extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper(['migration', 'locale']);
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_refundtracking.sql');
/**
* Perform a migration step.
*/
public function up(): void
{
helper(['migration', 'locale']);
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_refundtracking.sql');
// Add missing cash_refund amounts to payments table
$decimals = totals_decimals();
// Add missing cash_refund amounts to payments table
$decimals = totals_decimals();
$trans_amount = 'ROUND(SUM(CASE WHEN sales_items.discount_type = ' . PERCENT
. ' THEN sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount / 100) '
. 'ELSE sales_items.item_unit_price * sales_items.quantity_purchased - sales_items.discount END), ' . $decimals . ') AS trans_amount';
$trans_amount = 'ROUND(SUM(CASE WHEN sales_items.discount_type = ' . PERCENT
. ' THEN sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount / 100) '
. 'ELSE sales_items.item_unit_price * sales_items.quantity_purchased - sales_items.discount END), ' . $decimals . ') AS trans_amount';
$cash_payment = lang('Sales.cash');
$cash_payment = lang('Sales.cash');
$this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->prefixTable('migrate_taxes') .
' (INDEX(sale_id)) ENGINE=MEMORY
(
SELECT sales.sale_id, SUM(sales_taxes.sale_tax_amount) AS total_taxes
FROM ' . $this->db->prefixTable('sales') . ' AS sales
LEFT OUTER JOIN ' . $this->db->prefixTable('sales_taxes') . ' AS sales_taxes
ON sales.sale_id = sales_taxes.sale_id
WHERE sales.sale_status = \'' . COMPLETED . '\' AND sales_taxes.tax_type = \'1\'
GROUP BY sale_id
)'
);
$this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->prefixTable('migrate_taxes') .
' (INDEX(sale_id)) ENGINE=MEMORY
(
SELECT sales.sale_id, SUM(sales_taxes.sale_tax_amount) AS total_taxes
FROM ' . $this->db->prefixTable('sales') . ' AS sales
LEFT OUTER JOIN ' . $this->db->prefixTable('sales_taxes') . ' AS sales_taxes
ON sales.sale_id = sales_taxes.sale_id
WHERE sales.sale_status = \'' . COMPLETED . '\' AND sales_taxes.tax_type = \'1\'
GROUP BY sale_id
)'
);
$this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->prefixTable('migrate_sales') .
' (INDEX(sale_id)) ENGINE=MEMORY
(
SELECT sales.sale_id, '. $trans_amount . ', sales.employee_id, sales.sale_time'
. ' FROM ' . $this->db->prefixTable('sales') . ' AS sales '
. 'LEFT OUTER JOIN ' . $this->db->prefixTable('sales_items') . ' AS sales_items '
. 'ON sales.sale_id = sales_items.sale_id '
. 'LEFT OUTER JOIN ' . $this->db->prefixTable('migrate_taxes') . ' AS sumpay_taxes '
. 'ON sales.sale_id = sumpay_taxes.sale_id '
. 'WHERE sales.sale_status = \'' . COMPLETED . '\' GROUP BY sale_id
)'
);
$this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->prefixTable('migrate_sales') .
' (INDEX(sale_id)) ENGINE=MEMORY
(
SELECT sales.sale_id, '. $trans_amount . ', sales.employee_id, sales.sale_time'
. ' FROM ' . $this->db->prefixTable('sales') . ' AS sales '
. 'LEFT OUTER JOIN ' . $this->db->prefixTable('sales_items') . ' AS sales_items '
. 'ON sales.sale_id = sales_items.sale_id '
. 'LEFT OUTER JOIN ' . $this->db->prefixTable('migrate_taxes') . ' AS sumpay_taxes '
. 'ON sales.sale_id = sumpay_taxes.sale_id '
. 'WHERE sales.sale_status = \'' . COMPLETED . '\' GROUP BY sale_id
)'
);
$this->db->query('UPDATE ' . $this->db->prefixTable('migrate_sales') . ' AS sumpay_items '
. 'SET trans_amount = trans_amount + IFNULL((SELECT total_taxes FROM ' . $this->db->prefixTable('migrate_taxes')
. ' AS sumpay_taxes WHERE sumpay_items.sale_id = sumpay_taxes.sale_id),0)');
$this->db->query('UPDATE ' . $this->db->prefixTable('migrate_sales') . ' AS sumpay_items '
. 'SET trans_amount = trans_amount + IFNULL((SELECT total_taxes FROM ' . $this->db->prefixTable('migrate_taxes')
. ' AS sumpay_taxes WHERE sumpay_items.sale_id = sumpay_taxes.sale_id),0)');
$this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->prefixTable('migrate_payments') .
' (INDEX(sale_id)) ENGINE=MEMORY
(
SELECT sales.sale_id, COUNT(sales.sale_id) AS number_payments,
SUM(sales_payments.payment_amount - sales_payments.cash_refund) AS total_payments
FROM ' . $this->db->prefixTable('sales') . ' AS sales
LEFT OUTER JOIN ' . $this->db->prefixTable('sales_payments') . ' AS sales_payments
ON sales.sale_id = sales_payments.sale_id
WHERE sales.sale_status = \'' . COMPLETED . '\' GROUP BY sale_id
)'
);
$this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->prefixTable('migrate_payments') .
' (INDEX(sale_id)) ENGINE=MEMORY
(
SELECT sales.sale_id, COUNT(sales.sale_id) AS number_payments,
SUM(sales_payments.payment_amount - sales_payments.cash_refund) AS total_payments
FROM ' . $this->db->prefixTable('sales') . ' AS sales
LEFT OUTER JOIN ' . $this->db->prefixTable('sales_payments') . ' AS sales_payments
ON sales.sale_id = sales_payments.sale_id
WHERE sales.sale_status = \'' . COMPLETED . '\' GROUP BY sale_id
)'
);
// You may be asking yourself why the following is not creating a temporary table.
// It should be, it originallly was, but there is a bug in MySQL where temporary tables where some SQL statements fail.
// The update statement that follows this CREATE TABLE is one of those statements.
$this->db->query('CREATE TABLE IF NOT EXISTS ' . $this->db->prefixTable('migrate_refund') .
' (INDEX(sale_id)) ENGINE=MEMORY
(
SELECT a.sale_id, total_payments - trans_amount AS refund_amount
FROM ' . $this->db->prefixTable('migrate_sales') . ' AS a
JOIN ' . $this->db->prefixTable('migrate_payments') . ' AS b ON a.sale_id = b.sale_id
WHERE total_payments > trans_amount AND number_payments = 1
)'
);
// You may be asking yourself why the following is not creating a temporary table.
// It should be, it originallly was, but there is a bug in MySQL where temporary tables where some SQL statements fail.
// The update statement that follows this CREATE TABLE is one of those statements.
$this->db->query('CREATE TABLE IF NOT EXISTS ' . $this->db->prefixTable('migrate_refund') .
' (INDEX(sale_id)) ENGINE=MEMORY
(
SELECT a.sale_id, total_payments - trans_amount AS refund_amount
FROM ' . $this->db->prefixTable('migrate_sales') . ' AS a
JOIN ' . $this->db->prefixTable('migrate_payments') . ' AS b ON a.sale_id = b.sale_id
WHERE total_payments > trans_amount AND number_payments = 1
)'
);
// Update existing cash transactions with refund amount
$this->db->query('UPDATE ' . $this->db->prefixTable('sales_payments') . ' AS a
SET a.cash_refund =
(SELECT b.refund_amount
FROM ' . $this->db->prefixTable('migrate_refund') . ' AS b
WHERE a.sale_id = b.sale_id AND a.payment_type = \'' . $cash_payment . '\')
WHERE EXISTS
(SELECT b.refund_amount
FROM ' . $this->db->prefixTable('migrate_refund') . ' AS b
WHERE a.sale_id = b.sale_id AND a.payment_type = \'' . $cash_payment . ' \')'
);
// Update existing cash transactions with refund amount
$this->db->query('UPDATE ' . $this->db->prefixTable('sales_payments') . ' AS a
SET a.cash_refund =
(SELECT b.refund_amount
FROM ' . $this->db->prefixTable('migrate_refund') . ' AS b
WHERE a.sale_id = b.sale_id AND a.payment_type = \'' . $cash_payment . '\')
WHERE EXISTS
(SELECT b.refund_amount
FROM ' . $this->db->prefixTable('migrate_refund') . ' AS b
WHERE a.sale_id = b.sale_id AND a.payment_type = \'' . $cash_payment . ' \')'
);
// Insert new cash refund transactions for non-cash payments
$this->db->query('INSERT INTO ' . $this->db->prefixTable('sales_payments') .
' (sale_id, payment_type, employee_id, payment_time, payment_amount, cash_refund)
SELECT r.sale_id, \'' . $cash_payment . '\', s.employee_id, sale_time, 0, r.refund_amount
FROM ' . $this->db->prefixTable('migrate_refund') . ' AS r
JOIN ' . $this->db->prefixTable('sales_payments') . ' AS p ON r.sale_id = p.sale_id
JOIN ' . $this->db->prefixTable('migrate_sales') . ' AS s ON r.sale_id = s.sale_id
WHERE p.payment_type != \'' . $cash_payment . '\''
);
// Insert new cash refund transactions for non-cash payments
$this->db->query('INSERT INTO ' . $this->db->prefixTable('sales_payments') .
' (sale_id, payment_type, employee_id, payment_time, payment_amount, cash_refund)
SELECT r.sale_id, \'' . $cash_payment . '\', s.employee_id, sale_time, 0, r.refund_amount
FROM ' . $this->db->prefixTable('migrate_refund') . ' AS r
JOIN ' . $this->db->prefixTable('sales_payments') . ' AS p ON r.sale_id = p.sale_id
JOIN ' . $this->db->prefixTable('migrate_sales') . ' AS s ON r.sale_id = s.sale_id
WHERE p.payment_type != \'' . $cash_payment . '\''
);
// Post migration cleanup
$this->db->query('DROP TABLE IF EXISTS ' . $this->db->prefixTable('migrate_refund'));
}
// Post migration cleanup
$this->db->query('DROP TABLE IF EXISTS ' . $this->db->prefixTable('migrate_refund'));
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_DBFix extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_dbfix.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_dbfix.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_fix_attribute_datetime extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_fix_attribute_datetime.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.0_fix_attribute_datetime.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -6,30 +6,30 @@ use CodeIgniter\Database\Migration;
class Migration_fix_empty_reports extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
$builder = $this->db->table('stock_locations');
$builder->select('location_name');
$builder->where('location_id', 1);
$builder->limit(1);
$location_name = $builder->get()->getResultArray()[0]['location_name'];
/**
* Perform a migration step.
*/
public function up(): void
{
$builder = $this->db->table('stock_locations');
$builder->select('location_name');
$builder->where('location_id', 1);
$builder->limit(1);
$location_name = $builder->get()->getResultArray()[0]['location_name'];
$location_name = str_replace(' ', '_', $location_name);
$builder = $this->db->table('permissions');
$builder->set('location_id', 1);
$builder->where('permission_id','receivings_' . $location_name);
$builder->orWhere('permission_id', 'sales_' . $location_name);
$builder->update();
}
$location_name = str_replace(' ', '_', $location_name);
$builder = $this->db->table('permissions');
$builder->set('location_id', 1);
$builder->where('permission_id','receivings_' . $location_name);
$builder->orWhere('permission_id', 'sales_' . $location_name);
$builder->update();
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_receipttaxindicator extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
$this->db->query('INSERT INTO ' . $this->db->prefixTable('app_config') . ' (`key`, `value`)
VALUES (\'receipt_show_tax_ind\', \'0\')');
}
/**
* Perform a migration step.
*/
public function up(): void
{
$this->db->query('INSERT INTO ' . $this->db->prefixTable('app_config') . ' (`key`, `value`)
VALUES (\'receipt_show_tax_ind\', \'0\')');
}
/**
* Revert a migration step.
*/
public function down(): void
{
$this->db->query('DELETE FROM ' . $this->db->prefixTable('app_config') . ' WHERE key = \'receipt_show_tax_ind\'');
}
/**
* Revert a migration step.
*/
public function down(): void
{
$this->db->query('DELETE FROM ' . $this->db->prefixTable('app_config') . ' WHERE key = \'receipt_show_tax_ind\'');
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_PaymentDateFix extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.2_paymentdatefix.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.2_paymentdatefix.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -6,20 +6,20 @@ use CodeIgniter\Database\Migration;
class Migration_SalesChangePrice extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.2_saleschangeprice.sql');
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.2_saleschangeprice.sql');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -15,399 +15,399 @@ use CodeIgniter\Database\ResultInterface;
*/
class Migration_TaxAmount extends Migration
{
public const ROUND_UP = 5;
public const ROUND_DOWN = 6;
public const HALF_FIVE = 7;
public const YES = '1';
public const VAT_TAX = '0';
public const SALES_TAX = '1'; //TODO: It appears that this constant is never used
private Appconfig $appconfig;
public const ROUND_UP = 5;
public const ROUND_DOWN = 6;
public const HALF_FIVE = 7;
public const YES = '1';
public const VAT_TAX = '0';
public const SALES_TAX = '1'; //TODO: It appears that this constant is never used
private Appconfig $appconfig;
public function __construct()
{
parent::__construct();
public function __construct()
{
parent::__construct();
$this->appconfig = model(Appconfig::class);
}
$this->appconfig = model(Appconfig::class);
}
/**
* Perform a migration step.
*/
public function up(): void
{
$tax_included = ($this->appconfig->get_value('tax_included', Migration_TaxAmount::YES) == Migration_TaxAmount::YES);
/**
* Perform a migration step.
*/
public function up(): void
{
$tax_included = ($this->appconfig->get_value('tax_included', Migration_TaxAmount::YES) == Migration_TaxAmount::YES);
if($tax_included)
{
$tax_decimals = $this->appconfig->get_value('tax_decimals', 2);
$number_of_unmigrated = $this->get_count_of_unmigrated();
if($tax_included)
{
$tax_decimals = $this->appconfig->get_value('tax_decimals', 2);
$number_of_unmigrated = $this->get_count_of_unmigrated();
error_log('Migrating sales tax fixing. The number of sales that will be migrated is ' . $number_of_unmigrated);
error_log('Migrating sales tax fixing. The number of sales that will be migrated is ' . $number_of_unmigrated);
if($number_of_unmigrated > 0)
{
$unmigrated_invoices = $this->get_unmigrated($number_of_unmigrated)->getResultArray();
$this->db->query('RENAME TABLE ' . $this->db->prefixTable('sales_taxes') . ' TO ' . $this->db->prefixTable('sales_taxes_backup'));
$this->db->query('CREATE TABLE ' . $this->db->prefixTable('sales_taxes') . ' LIKE ' . $this->db->prefixTable('sales_taxes_backup'));
if($number_of_unmigrated > 0)
{
$unmigrated_invoices = $this->get_unmigrated($number_of_unmigrated)->getResultArray();
$this->db->query('RENAME TABLE ' . $this->db->prefixTable('sales_taxes') . ' TO ' . $this->db->prefixTable('sales_taxes_backup'));
$this->db->query('CREATE TABLE ' . $this->db->prefixTable('sales_taxes') . ' LIKE ' . $this->db->prefixTable('sales_taxes_backup'));
foreach($unmigrated_invoices as $key => $unmigrated_invoice)
{
$this->upgrade_tax_history_for_sale($unmigrated_invoice['sale_id'], $tax_decimals, true);
}
$this->db->query('DROP TABLE ' . $this->db->prefixTable('sales_taxes_backup'));
}
foreach($unmigrated_invoices as $key => $unmigrated_invoice)
{
$this->upgrade_tax_history_for_sale($unmigrated_invoice['sale_id'], $tax_decimals, true);
}
$this->db->query('DROP TABLE ' . $this->db->prefixTable('sales_taxes_backup'));
}
error_log('Migrating sales tax fixing. The number of sales that will be migrated is finished.');
}
}
error_log('Migrating sales tax fixing. The number of sales that will be migrated is finished.');
}
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
/**
* @param int $sale_id
* @param string $tax_decimals
* @param bool $tax_included
* @return void
*/
private function upgrade_tax_history_for_sale(int $sale_id, string $tax_decimals, bool $tax_included): void //TODO: $tax_included is passed as a parameter but never used in the function body.
{
$customer_sales_tax_support = false;
$tax_type = Migration_TaxAmount::VAT_TAX;
$sales_taxes = [];
$tax_group_sequence = 0;
$items = $this->get_sale_items_for_migration($sale_id)->getResultArray();
/**
* @param int $sale_id
* @param string $tax_decimals
* @param bool $tax_included
* @return void
*/
private function upgrade_tax_history_for_sale(int $sale_id, string $tax_decimals, bool $tax_included): void //TODO: $tax_included is passed as a parameter but never used in the function body.
{
$customer_sales_tax_support = false;
$tax_type = Migration_TaxAmount::VAT_TAX;
$sales_taxes = [];
$tax_group_sequence = 0;
$items = $this->get_sale_items_for_migration($sale_id)->getResultArray();
foreach($items as $item)
{
// This computes tax for each line item and adds it to the tax type total
$tax_group = (float)$item['percent'] . '% ' . $item['name'];
$tax_basis = $this->get_item_total($item['quantity_purchased'], $item['item_unit_price'], $item['discount'], true);
$item_tax_amount = $this->get_item_tax($tax_basis, $item['percent'], PHP_ROUND_HALF_UP, $tax_decimals);
$this->update_sales_items_taxes_amount($sale_id, $item['line'], $item['name'], $item['percent'], $tax_type, $item_tax_amount);
$this->update_sales_taxes($sales_taxes, $tax_type, $tax_group, $item['percent'], $tax_basis, $item_tax_amount, $tax_group_sequence, PHP_ROUND_HALF_UP, $sale_id, $item['name']);
$tax_group_sequence += 1;
}
foreach($items as $item)
{
// This computes tax for each line item and adds it to the tax type total
$tax_group = (float)$item['percent'] . '% ' . $item['name'];
$tax_basis = $this->get_item_total($item['quantity_purchased'], $item['item_unit_price'], $item['discount'], true);
$item_tax_amount = $this->get_item_tax($tax_basis, $item['percent'], PHP_ROUND_HALF_UP, $tax_decimals);
$this->update_sales_items_taxes_amount($sale_id, $item['line'], $item['name'], $item['percent'], $tax_type, $item_tax_amount);
$this->update_sales_taxes($sales_taxes, $tax_type, $tax_group, $item['percent'], $tax_basis, $item_tax_amount, $tax_group_sequence, PHP_ROUND_HALF_UP, $sale_id, $item['name']);
$tax_group_sequence += 1;
}
if($customer_sales_tax_support) //TODO: This will always evaluate to false.
{
$this->apply_invoice_taxing($sales_taxes);
}
if($customer_sales_tax_support) //TODO: This will always evaluate to false.
{
$this->apply_invoice_taxing($sales_taxes);
}
$this->round_sales_taxes($sales_taxes);
$this->save_sales_tax($sales_taxes);
}
$this->round_sales_taxes($sales_taxes);
$this->save_sales_tax($sales_taxes);
}
/**
* @param int $block_count
* @return ResultInterface
*/
private function get_unmigrated(int $block_count): ResultInterface
{
$builder = $this->db->table('sales_items_taxes as SIT');
$builder->select('SIT.sale_id');
$builder->select('ST.sale_id as sales_taxes_sale_id');
$builder->join('sales_taxes as ST', 'SIT.sale_id = ST.sale_id', 'left');
$builder->groupBy('SIT.sale_id');
$builder->groupBy('ST.sale_id');
$builder->orderBy('SIT.sale_id');
$builder->limit($block_count);
/**
* @param int $block_count
* @return ResultInterface
*/
private function get_unmigrated(int $block_count): ResultInterface
{
$builder = $this->db->table('sales_items_taxes as SIT');
$builder->select('SIT.sale_id');
$builder->select('ST.sale_id as sales_taxes_sale_id');
$builder->join('sales_taxes as ST', 'SIT.sale_id = ST.sale_id', 'left');
$builder->groupBy('SIT.sale_id');
$builder->groupBy('ST.sale_id');
$builder->orderBy('SIT.sale_id');
$builder->limit($block_count);
return $builder->get();
}
return $builder->get();
}
/**
* @return int
*/
private function get_count_of_unmigrated(): int
{
$result = $this->db->query('SELECT COUNT(*) FROM(SELECT SIT.sale_id, ST.sale_id as sales_taxes_sale_id FROM '
. $this->db->prefixTable('sales_items_taxes')
. ' as SIT LEFT JOIN '
. $this->db->prefixTable('sales_taxes')
. ' as ST ON SIT.sale_id = ST.sale_id GROUP BY SIT.sale_id, ST.sale_id'
. ' ORDER BY SIT.sale_id) as US')->getResultArray();
/**
* @return int
*/
private function get_count_of_unmigrated(): int
{
$result = $this->db->query('SELECT COUNT(*) FROM(SELECT SIT.sale_id, ST.sale_id as sales_taxes_sale_id FROM '
. $this->db->prefixTable('sales_items_taxes')
. ' as SIT LEFT JOIN '
. $this->db->prefixTable('sales_taxes')
. ' as ST ON SIT.sale_id = ST.sale_id GROUP BY SIT.sale_id, ST.sale_id'
. ' ORDER BY SIT.sale_id) as US')->getResultArray();
if(!$result)
{
error_log('Database error in 20200202000000_taxamount.php related to sales_taxes or sales_items_taxes.');
return 0;
}
if(!$result)
{
error_log('Database error in 20200202000000_taxamount.php related to sales_taxes or sales_items_taxes.');
return 0;
}
return $result[0]['COUNT(*)'] ?: 0;
}
return $result[0]['COUNT(*)'] ?: 0;
}
/**
* @param int $sale_id
* @return ResultInterface
*/
private function get_sale_items_for_migration(int $sale_id): ResultInterface
{
$builder = $this->db->table('sales_items as sales_items');
$builder->select('sales_items.sale_id as sale_id');
$builder->select('sales_items.line as line');
$builder->select('item_unit_price');
$builder->select('discount');
$builder->select('quantity_purchased');
$builder->select('percent');
$builder->select('name');
$builder->join('sales_items_taxes as sales_items_taxes', 'sales_items.sale_id = sales_items_taxes.sale_id and sales_items.line = sales_items_taxes.line');
$builder->where('sales_items.sale_id', $sale_id);
/**
* @param int $sale_id
* @return ResultInterface
*/
private function get_sale_items_for_migration(int $sale_id): ResultInterface
{
$builder = $this->db->table('sales_items as sales_items');
$builder->select('sales_items.sale_id as sale_id');
$builder->select('sales_items.line as line');
$builder->select('item_unit_price');
$builder->select('discount');
$builder->select('quantity_purchased');
$builder->select('percent');
$builder->select('name');
$builder->join('sales_items_taxes as sales_items_taxes', 'sales_items.sale_id = sales_items_taxes.sale_id and sales_items.line = sales_items_taxes.line');
$builder->where('sales_items.sale_id', $sale_id);
return $builder->get();
}
return $builder->get();
}
/**
* @param int $sale_id
* @param int $line
* @param string $name
* @param float $percent
* @param int $tax_type
* @param float $item_tax_amount
* @return void
*/
private function update_sales_items_taxes_amount(int $sale_id, int $line, string $name, float $percent, int $tax_type, float $item_tax_amount): void
{
$builder = $this->db->table('sales_items_taxes');
$builder->where('sale_id', $sale_id);
$builder->where('line', $line);
$builder->where('name', $name);
$builder->where('percent', $percent);
$builder->update(['tax_type' => $tax_type, 'item_tax_amount' => $item_tax_amount]);
}
/**
* @param int $sale_id
* @param int $line
* @param string $name
* @param float $percent
* @param int $tax_type
* @param float $item_tax_amount
* @return void
*/
private function update_sales_items_taxes_amount(int $sale_id, int $line, string $name, float $percent, int $tax_type, float $item_tax_amount): void
{
$builder = $this->db->table('sales_items_taxes');
$builder->where('sale_id', $sale_id);
$builder->where('line', $line);
$builder->where('name', $name);
$builder->where('percent', $percent);
$builder->update(['tax_type' => $tax_type, 'item_tax_amount' => $item_tax_amount]);
}
/**
* @param array $sales_taxes
* @return void
*/
private function save_sales_tax(array &$sales_taxes): void
{
$builder = $this->db->table('sales_taxes');
/**
* @param array $sales_taxes
* @return void
*/
private function save_sales_tax(array &$sales_taxes): void
{
$builder = $this->db->table('sales_taxes');
foreach($sales_taxes as $line => $sales_tax)
{
$builder->insert($sales_tax);
}
}
foreach($sales_taxes as $line => $sales_tax)
{
$builder->insert($sales_tax);
}
}
/**
* @param string $quantity
* @param string $price
* @param string $discount
* @param bool $include_discount
* @return string
*/
public function get_item_total(string $quantity, string $price, string $discount, bool $include_discount = false): string
{
$total = bcmul($quantity, $price);
/**
* @param string $quantity
* @param string $price
* @param string $discount
* @param bool $include_discount
* @return string
*/
public function get_item_total(string $quantity, string $price, string $discount, bool $include_discount = false): string
{
$total = bcmul($quantity, $price);
if($include_discount)
{
$total = bcsub($total, bcmul(bcmul($quantity, $price), bcdiv($discount, 100)));
}
if($include_discount)
{
$total = bcsub($total, bcmul(bcmul($quantity, $price), bcdiv($discount, 100)));
}
return $total;
}
return $total;
}
/**
* @param string $tax_basis
* @param string $tax_percentage
* @param int $rounding_mode
* @param int $decimals
* @return float
*/
public function get_item_tax(string $tax_basis, string $tax_percentage, int $rounding_mode, int $decimals): float //TODO: is this currency safe?
{
$tax_fraction = bcdiv(bcadd('100', $tax_percentage), '100');
$price_tax_excl = bcdiv($tax_basis, $tax_fraction);
$tax_amount = bcsub($tax_basis, $price_tax_excl);
/**
* @param string $tax_basis
* @param string $tax_percentage
* @param int $rounding_mode
* @param int $decimals
* @return float
*/
public function get_item_tax(string $tax_basis, string $tax_percentage, int $rounding_mode, int $decimals): float //TODO: is this currency safe?
{
$tax_fraction = bcdiv(bcadd('100', $tax_percentage), '100');
$price_tax_excl = bcdiv($tax_basis, $tax_fraction);
$tax_amount = bcsub($tax_basis, $price_tax_excl);
return $this->round_number($rounding_mode, $tax_amount, $decimals);
}
return $this->round_number($rounding_mode, $tax_amount, $decimals);
}
/**
* @param string $tax_basis
* @param string $tax_percentage
* @param int $rounding_mode
* @param int $decimals
* @return float
*/
public function get_sales_tax_for_amount(string $tax_basis, string $tax_percentage, int $rounding_mode, int $decimals): float //TODO: is this currency safe?
{
$tax_fraction = bcdiv($tax_percentage, '100');
$tax_amount = bcmul($tax_basis, $tax_fraction);
/**
* @param string $tax_basis
* @param string $tax_percentage
* @param int $rounding_mode
* @param int $decimals
* @return float
*/
public function get_sales_tax_for_amount(string $tax_basis, string $tax_percentage, int $rounding_mode, int $decimals): float //TODO: is this currency safe?
{
$tax_fraction = bcdiv($tax_percentage, '100');
$tax_amount = bcmul($tax_basis, $tax_fraction);
return $this->round_number($rounding_mode, $tax_amount, $decimals);
}
return $this->round_number($rounding_mode, $tax_amount, $decimals);
}
/**
* @param int $rounding_mode
* @param string $amount
* @param int $decimals
* @return float
*/
public function round_number(int $rounding_mode, string $amount, int $decimals): float //TODO: is this currency safe?
{//TODO: This needs to be converted to a switch
if($rounding_mode == Migration_TaxAmount::ROUND_UP) //TODO: === ?
{
$fig = pow(10, $decimals);
$rounded_total = (ceil($fig * $amount) + ceil($fig*$amount - ceil($fig * $amount)))/$fig;
}
elseif($rounding_mode == Migration_TaxAmount::ROUND_DOWN) //TODO: === ?
{
$fig = pow(10, $decimals);
$rounded_total = (floor($fig * $amount) + floor($fig * $amount - floor($fig * $amount)))/$fig;
}
elseif($rounding_mode == Migration_TaxAmount::HALF_FIVE) //TODO: === ?
{
$rounded_total = round($amount / 5) * 5;
}
else
{
$rounded_total = round($amount, $decimals, $rounding_mode);
}
/**
* @param int $rounding_mode
* @param string $amount
* @param int $decimals
* @return float
*/
public function round_number(int $rounding_mode, string $amount, int $decimals): float //TODO: is this currency safe?
{//TODO: This needs to be converted to a switch
if($rounding_mode == Migration_TaxAmount::ROUND_UP) //TODO: === ?
{
$fig = pow(10, $decimals);
$rounded_total = (ceil($fig * $amount) + ceil($fig*$amount - ceil($fig * $amount)))/$fig;
}
elseif($rounding_mode == Migration_TaxAmount::ROUND_DOWN) //TODO: === ?
{
$fig = pow(10, $decimals);
$rounded_total = (floor($fig * $amount) + floor($fig * $amount - floor($fig * $amount)))/$fig;
}
elseif($rounding_mode == Migration_TaxAmount::HALF_FIVE) //TODO: === ?
{
$rounded_total = round($amount / 5) * 5;
}
else
{
$rounded_total = round($amount, $decimals, $rounding_mode);
}
return $rounded_total;
}
return $rounded_total;
}
/**
* @param array $sales_taxes
* @param int $tax_type
* @param string $tax_group
* @param float $tax_rate
* @param string $tax_basis
* @param string $item_tax_amount
* @param int $tax_group_sequence
* @param int $rounding_code
* @param int $sale_id
* @param string $name
* @param string $tax_code
* @return void
*/
public function update_sales_taxes(array &$sales_taxes, int $tax_type, string $tax_group, float $tax_rate, string $tax_basis, string $item_tax_amount, int $tax_group_sequence, int $rounding_code, int $sale_id, string $name = '', string $tax_code = ''): void
{
$tax_group_index = $this->clean('X' . $tax_group);
/**
* @param array $sales_taxes
* @param int $tax_type
* @param string $tax_group
* @param float $tax_rate
* @param string $tax_basis
* @param string $item_tax_amount
* @param int $tax_group_sequence
* @param int $rounding_code
* @param int $sale_id
* @param string $name
* @param string $tax_code
* @return void
*/
public function update_sales_taxes(array &$sales_taxes, int $tax_type, string $tax_group, float $tax_rate, string $tax_basis, string $item_tax_amount, int $tax_group_sequence, int $rounding_code, int $sale_id, string $name = '', string $tax_code = ''): void
{
$tax_group_index = $this->clean('X' . $tax_group);
if(!array_key_exists($tax_group_index, $sales_taxes))
{
$insertkey = $tax_group_index;
$sales_tax = [
$insertkey => [
'sale_id' => $sale_id,
'tax_type' => $tax_type,
'tax_group' => $tax_group,
'sale_tax_basis' => $tax_basis,
'sale_tax_amount' => $item_tax_amount,
'print_sequence' => $tax_group_sequence,
'name' => $name,
'tax_rate' => $tax_rate,
'sales_tax_code_id' => $tax_code,
'rounding_code' => $rounding_code
]
];
if(!array_key_exists($tax_group_index, $sales_taxes))
{
$insertkey = $tax_group_index;
$sales_tax = [
$insertkey => [
'sale_id' => $sale_id,
'tax_type' => $tax_type,
'tax_group' => $tax_group,
'sale_tax_basis' => $tax_basis,
'sale_tax_amount' => $item_tax_amount,
'print_sequence' => $tax_group_sequence,
'name' => $name,
'tax_rate' => $tax_rate,
'sales_tax_code_id' => $tax_code,
'rounding_code' => $rounding_code
]
];
//add to existing array
$sales_taxes += $sales_tax;
}
else
{
// Important ... the sales amounts are accumulated for the group at the maximum configurable scale value of 4
// but the scale will in reality be the scale specified by the tax_decimal configuration value used for sales_items_taxes
$sales_taxes[$tax_group_index]['sale_tax_basis'] = bcadd($sales_taxes[$tax_group_index]['sale_tax_basis'], $tax_basis, 4);
$sales_taxes[$tax_group_index]['sale_tax_amount'] = bcadd($sales_taxes[$tax_group_index]['sale_tax_amount'], $item_tax_amount, 4);
}
}
//add to existing array
$sales_taxes += $sales_tax;
}
else
{
// Important ... the sales amounts are accumulated for the group at the maximum configurable scale value of 4
// but the scale will in reality be the scale specified by the tax_decimal configuration value used for sales_items_taxes
$sales_taxes[$tax_group_index]['sale_tax_basis'] = bcadd($sales_taxes[$tax_group_index]['sale_tax_basis'], $tax_basis, 4);
$sales_taxes[$tax_group_index]['sale_tax_amount'] = bcadd($sales_taxes[$tax_group_index]['sale_tax_amount'], $item_tax_amount, 4);
}
}
/**
* @param string $string
* @return string
*/
public function clean(string $string): string //TODO: This can probably go into the migration helper as it's used it more than one migration. Also, $string needs to be refactored to a different name.
{
$string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.
/**
* @param string $string
* @return string
*/
public function clean(string $string): string //TODO: This can probably go into the migration helper as it's used it more than one migration. Also, $string needs to be refactored to a different name.
{
$string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.
return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
}
return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
}
/**
* @param array $sales_taxes
* @return void
*/
public function apply_invoice_taxing(array &$sales_taxes): void
{
if(!empty($sales_taxes)) //TODO: Duplicated code
{
$sort = [];
foreach($sales_taxes as $k => $v)
{
$sort['print_sequence'][$k] = $v['print_sequence'];
}
array_multisort($sort['print_sequence'], SORT_ASC, $sales_taxes);
}
/**
* @param array $sales_taxes
* @return void
*/
public function apply_invoice_taxing(array &$sales_taxes): void
{
if(!empty($sales_taxes)) //TODO: Duplicated code
{
$sort = [];
foreach($sales_taxes as $k => $v)
{
$sort['print_sequence'][$k] = $v['print_sequence'];
}
array_multisort($sort['print_sequence'], SORT_ASC, $sales_taxes);
}
$decimals = totals_decimals();
$decimals = totals_decimals();
foreach($sales_taxes as $row_number => $sales_tax)
{
$sales_taxes[$row_number]['sale_tax_amount'] = $this->get_sales_tax_for_amount($sales_tax['sale_tax_basis'], $sales_tax['tax_rate'], $sales_tax['rounding_code'], $decimals);
}
}
foreach($sales_taxes as $row_number => $sales_tax)
{
$sales_taxes[$row_number]['sale_tax_amount'] = $this->get_sales_tax_for_amount($sales_tax['sale_tax_basis'], $sales_tax['tax_rate'], $sales_tax['rounding_code'], $decimals);
}
}
/**
* @param array $sales_taxes
* @return void
*/
public function round_sales_taxes(array &$sales_taxes): void
{
if(!empty($sales_taxes))
{
$sort = [];
/**
* @param array $sales_taxes
* @return void
*/
public function round_sales_taxes(array &$sales_taxes): void
{
if(!empty($sales_taxes))
{
$sort = [];
foreach($sales_taxes as $k=>$v)
{
$sort['print_sequence'][$k] = $v['print_sequence'];
}
foreach($sales_taxes as $k=>$v)
{
$sort['print_sequence'][$k] = $v['print_sequence'];
}
array_multisort($sort['print_sequence'], SORT_ASC, $sales_taxes);
}
array_multisort($sort['print_sequence'], SORT_ASC, $sales_taxes);
}
$decimals = totals_decimals();
$decimals = totals_decimals();
foreach($sales_taxes as $row_number => $sales_tax)
{
$sale_tax_amount = $sales_tax['sale_tax_amount'];
$rounding_code = $sales_tax['rounding_code'];
$rounded_sale_tax_amount = $sale_tax_amount;
foreach($sales_taxes as $row_number => $sales_tax)
{
$sale_tax_amount = $sales_tax['sale_tax_amount'];
$rounding_code = $sales_tax['rounding_code'];
$rounded_sale_tax_amount = $sale_tax_amount;
if ($rounding_code == PHP_ROUND_HALF_UP //TODO: This block of if/elseif statements can be converted to a switch.
|| $rounding_code == PHP_ROUND_HALF_DOWN
|| $rounding_code == PHP_ROUND_HALF_EVEN
|| $rounding_code == PHP_ROUND_HALF_ODD)
{
$rounded_sale_tax_amount = round($sale_tax_amount, $decimals, $rounding_code);
}
elseif($rounding_code == Migration_TaxAmount::ROUND_UP)
{
$fig = (int) str_pad('1', $decimals, '0');
$rounded_sale_tax_amount = (ceil($sale_tax_amount * $fig) / $fig);
}
elseif($rounding_code == Migration_TaxAmount::ROUND_DOWN)
{
$fig = (int) str_pad('1', $decimals, '0');
$rounded_sale_tax_amount = (floor($sale_tax_amount * $fig) / $fig);
}
elseif($rounding_code == Migration_TaxAmount::HALF_FIVE)
{
$rounded_sale_tax_amount = round($sale_tax_amount / 5) * 5;
}
if ($rounding_code == PHP_ROUND_HALF_UP //TODO: This block of if/elseif statements can be converted to a switch.
|| $rounding_code == PHP_ROUND_HALF_DOWN
|| $rounding_code == PHP_ROUND_HALF_EVEN
|| $rounding_code == PHP_ROUND_HALF_ODD)
{
$rounded_sale_tax_amount = round($sale_tax_amount, $decimals, $rounding_code);
}
elseif($rounding_code == Migration_TaxAmount::ROUND_UP)
{
$fig = (int) str_pad('1', $decimals, '0');
$rounded_sale_tax_amount = (ceil($sale_tax_amount * $fig) / $fig);
}
elseif($rounding_code == Migration_TaxAmount::ROUND_DOWN)
{
$fig = (int) str_pad('1', $decimals, '0');
$rounded_sale_tax_amount = (floor($sale_tax_amount * $fig) / $fig);
}
elseif($rounding_code == Migration_TaxAmount::HALF_FIVE)
{
$rounded_sale_tax_amount = round($sale_tax_amount / 5) * 5;
}
$sales_taxes[$row_number]['sale_tax_amount'] = $rounded_sale_tax_amount;
}
}
$sales_taxes[$row_number]['sale_tax_amount'] = $rounded_sale_tax_amount;
}
}
}

View File

@@ -6,19 +6,19 @@ use CodeIgniter\Database\Migration;
class Migration_taxgroupconstraint extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('tax_jurisdictions') . ' ADD CONSTRAINT tax_jurisdictions_uq1 UNIQUE (tax_group)');
}
/**
* Perform a migration step.
*/
public function up(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('tax_jurisdictions') . ' ADD CONSTRAINT tax_jurisdictions_uq1 UNIQUE (tax_group)');
}
/**
* Revert a migration step.
*/
public function down(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('tax_jurisdictions') . ' DROP INDEX tax_jurisdictions_uq1');
}
/**
* Revert a migration step.
*/
public function down(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('tax_jurisdictions') . ' DROP INDEX tax_jurisdictions_uq1');
}
}

View File

@@ -6,29 +6,29 @@ use CodeIgniter\Database\Migration;
class Migration_image_upload_defaults extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
$image_values = [
['key' => 'image_allowed_types', 'value' => 'gif|jpg|png'],
['key' => 'image_max_height', 'value' => '480'],
['key' => 'image_max_size', 'value' => '128'],
['key' => 'image_max_width', 'value' => '640']
];
/**
* Perform a migration step.
*/
public function up(): void
{
$image_values = [
['key' => 'image_allowed_types', 'value' => 'gif|jpg|png'],
['key' => 'image_max_height', 'value' => '480'],
['key' => 'image_max_size', 'value' => '128'],
['key' => 'image_max_width', 'value' => '640']
];
$builder = $this->db->table('app_config');
$builder->insertBatch($image_values);
}
$builder = $this->db->table('app_config');
$builder->insertBatch($image_values);
}
/**
* Revert a migration step.
*/
public function down(): void
{
$builder = $this->db->table('app_config');
$builder->whereIn('key', ['image_allowed_types','image_max_height','image_max_size','image_max_width']);
$builder->delete();
}
/**
* Revert a migration step.
*/
public function down(): void
{
$builder = $this->db->table('app_config');
$builder->whereIn('key', ['image_allowed_types','image_max_height','image_max_size','image_max_width']);
$builder->delete();
}
}

View File

@@ -6,23 +6,23 @@ use CodeIgniter\Database\Migration;
class Migration_modify_attr_links_constraint extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating modify_attr_links_constraint');
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating modify_attr_links_constraint');
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.2_modify_attr_links_constraint.sql');
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.2_modify_attr_links_constraint.sql');
error_log('Migrating modify_attr_links_constraint');
}
error_log('Migrating modify_attr_links_constraint');
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
}

View File

@@ -6,19 +6,19 @@ use CodeIgniter\Database\Migration;
class Migration_cashrounding extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('sales_payments') . ' ADD COLUMN `cash_adjustment` tinyint NOT NULL DEFAULT 0 AFTER `cash_refund`');
}
/**
* Perform a migration step.
*/
public function up(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('sales_payments') . ' ADD COLUMN `cash_adjustment` tinyint NOT NULL DEFAULT 0 AFTER `cash_refund`');
}
/**
* Revert a migration step.
*/
public function down(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('sales_payments') . ' DROP COLUMN `cash_adjustment`');
}
/**
* Revert a migration step.
*/
public function down(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('sales_payments') . ' DROP COLUMN `cash_adjustment`');
}
}

View File

@@ -6,23 +6,23 @@ use CodeIgniter\Database\Migration;
class Migration_add_item_kit_number extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating add_item_kit_number');
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating add_item_kit_number');
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.3_add_kits_item_number.sql');
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.3_add_kits_item_number.sql');
error_log('Migrating add_item_kit_number');
}
error_log('Migrating add_item_kit_number');
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
}

View File

@@ -6,23 +6,23 @@ use CodeIgniter\Database\Migration;
class Migration_modify_session_datatype extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating modify_session_datatype');
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating modify_session_datatype');
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.4_modify_session_datatype.sql');
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.3.4_modify_session_datatype.sql');
error_log('Migrating modify_session_datatype');
}
error_log('Migrating modify_session_datatype');
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
}

View File

@@ -11,150 +11,150 @@ use DateTime;
class Migration_database_optimizations extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating database_optimizations');
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating database_optimizations');
$attribute = model(Attribute::class);
$attribute = model(Attribute::class);
$attribute->delete_orphaned_values();
$attribute->delete_orphaned_values();
$this->migrate_duplicate_attribute_values(DECIMAL);
$this->migrate_duplicate_attribute_values(DATE);
$this->migrate_duplicate_attribute_values(DECIMAL);
$this->migrate_duplicate_attribute_values(DATE);
//Select all attributes that have data in more than one column
$builder = $this->db->table('attribute_values');
$builder->select('attribute_id, attribute_value, attribute_decimal, attribute_date');
$builder->groupStart();
$builder->where('attribute_value IS NOT NULL');
$builder->where('attribute_date IS NOT NULL');
$builder->groupEnd();
$builder->orGroupStart();
$builder->where('attribute_value IS NOT NULL');
$builder->where('attribute_decimal IS NOT NULL');
$builder->groupEnd();
$attribute_values = $builder->get();
//Select all attributes that have data in more than one column
$builder = $this->db->table('attribute_values');
$builder->select('attribute_id, attribute_value, attribute_decimal, attribute_date');
$builder->groupStart();
$builder->where('attribute_value IS NOT NULL');
$builder->where('attribute_date IS NOT NULL');
$builder->groupEnd();
$builder->orGroupStart();
$builder->where('attribute_value IS NOT NULL');
$builder->where('attribute_decimal IS NOT NULL');
$builder->groupEnd();
$attribute_values = $builder->get();
$this->db->transStart();
$this->db->transStart();
//Clean up Attribute values table where there is an attribute value and an attribute_date/attribute_decimal
foreach($attribute_values->getResultArray() as $attribute_value)
{
$builder = $this->db->table('attribute_values');
$builder->delete(['attribute_id' => $attribute_value['attribute_id']]);
//Clean up Attribute values table where there is an attribute value and an attribute_date/attribute_decimal
foreach($attribute_values->getResultArray() as $attribute_value)
{
$builder = $this->db->table('attribute_values');
$builder->delete(['attribute_id' => $attribute_value['attribute_id']]);
$builder = $this->db->table('attribute_links');
$builder->select('links.definition_id, links.item_id, links.attribute_id, defs.definition_type');
$builder->join('attribute_definitions defs', 'defs.definition_id = links.definition_id');
$builder->where('attribute_id', $attribute_value['attribute_id']);
$attribute_links = $builder->get();
$builder = $this->db->table('attribute_links');
$builder->select('links.definition_id, links.item_id, links.attribute_id, defs.definition_type');
$builder->join('attribute_definitions defs', 'defs.definition_id = links.definition_id');
$builder->where('attribute_id', $attribute_value['attribute_id']);
$attribute_links = $builder->get();
if($attribute_links)
{
$builder = $this->db->table('attribute_links');
$attribute_links = $attribute_links->getResultArray() ?: [];
if($attribute_links)
{
$builder = $this->db->table('attribute_links');
$attribute_links = $attribute_links->getResultArray() ?: [];
foreach($attribute_links->getResultArray() as $attribute_link)
{
$builder->where('attribute_id', $attribute_link['attribute_id']);
$builder->where('item_id', $attribute_link['item_id']);
$builder->delete();
foreach($attribute_links->getResultArray() as $attribute_link)
{
$builder->where('attribute_id', $attribute_link['attribute_id']);
$builder->where('item_id', $attribute_link['item_id']);
$builder->delete();
switch($attribute_link['definition_type'])
{
case DECIMAL:
$value = $attribute_value['attribute_decimal'];
break;
case DATE:
$config = config(OSPOS::class)->settings;
$attribute_date = DateTime::createFromFormat('Y-m-d', $attribute_value['attribute_date']);
$value = $attribute_date->format($config['dateformat']);
break;
default:
$value = $attribute_value['attribute_value'];
break;
}
switch($attribute_link['definition_type'])
{
case DECIMAL:
$value = $attribute_value['attribute_decimal'];
break;
case DATE:
$config = config(OSPOS::class)->settings;
$attribute_date = DateTime::createFromFormat('Y-m-d', $attribute_value['attribute_date']);
$value = $attribute_date->format($config['dateformat']);
break;
default:
$value = $attribute_value['attribute_value'];
break;
}
$attribute->saveAttributeValue($value, $attribute_link['definition_id'], $attribute_link['item_id'], false, $attribute_link['definition_type']);
}
}
}
$this->db->transComplete();
$attribute->saveAttributeValue($value, $attribute_link['definition_id'], $attribute_link['item_id'], false, $attribute_link['definition_type']);
}
}
}
$this->db->transComplete();
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_database_optimizations.sql');
error_log('Migrating database_optimizations completed');
}
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_database_optimizations.sql');
error_log('Migrating database_optimizations completed');
}
/**
* Given the type of attribute, deletes any duplicates it finds in the attribute_values table and reassigns those
*/
private function migrate_duplicate_attribute_values($attribute_type): void
{
//Remove duplicate attribute values needed to make attribute_decimals and attribute_dates unique
$this->db->transStart();
/**
* Given the type of attribute, deletes any duplicates it finds in the attribute_values table and reassigns those
*/
private function migrate_duplicate_attribute_values($attribute_type): void
{
//Remove duplicate attribute values needed to make attribute_decimals and attribute_dates unique
$this->db->transStart();
$column = 'attribute_' . strtolower($attribute_type);
$column = 'attribute_' . strtolower($attribute_type);
$builder = $this->db->table('attribute_values');
$builder->select("$column");
$builder->groupBy($column);
$builder->having("COUNT($column) > 1");
$duplicated_values = $builder->get();
$builder = $this->db->table('attribute_values');
$builder->select("$column");
$builder->groupBy($column);
$builder->having("COUNT($column) > 1");
$duplicated_values = $builder->get();
foreach($duplicated_values->getResultArray() as $duplicated_value)
{
$subquery_builder = $this->db->table('attribute_values');
$subquery_builder->select('attribute_id');
$subquery_builder->where($column, $duplicated_value[$column]);
$subquery = $subquery_builder->getCompiledSelect();
foreach($duplicated_values->getResultArray() as $duplicated_value)
{
$subquery_builder = $this->db->table('attribute_values');
$subquery_builder->select('attribute_id');
$subquery_builder->where($column, $duplicated_value[$column]);
$subquery = $subquery_builder->getCompiledSelect();
$builder = $this->db->table('attribute_values');
$builder->select('attribute_id');
$builder->where($column, $duplicated_value[$column]);
$builder->where("attribute_id IN ($subquery)", null, false);
$attribute_ids_to_fix = $builder->get();
$builder = $this->db->table('attribute_values');
$builder->select('attribute_id');
$builder->where($column, $duplicated_value[$column]);
$builder->where("attribute_id IN ($subquery)", null, false);
$attribute_ids_to_fix = $builder->get();
$this->reassign_duplicate_attribute_values($attribute_ids_to_fix, $duplicated_value);
}
$this->reassign_duplicate_attribute_values($attribute_ids_to_fix, $duplicated_value);
}
$this->db->transComplete();
}
$this->db->transComplete();
}
/**
* Updates the attribute_id in all attribute_link rows with duplicated attribute_ids then deletes unneeded rows from attribute_values
*
* @param ResultInterface $attribute_ids_to_fix All attribute_ids that need to parsed
* @param array $attribute_value The attribute value in question.
*/
private function reassign_duplicate_attribute_values(ResultInterface $attribute_ids_to_fix, array $attribute_value): void
{
$attribute_ids = $attribute_ids_to_fix->getResultArray();
$retain_attribute_id = $attribute_ids[0]['attribute_id'];
/**
* Updates the attribute_id in all attribute_link rows with duplicated attribute_ids then deletes unneeded rows from attribute_values
*
* @param ResultInterface $attribute_ids_to_fix All attribute_ids that need to parsed
* @param array $attribute_value The attribute value in question.
*/
private function reassign_duplicate_attribute_values(ResultInterface $attribute_ids_to_fix, array $attribute_value): void
{
$attribute_ids = $attribute_ids_to_fix->getResultArray();
$retain_attribute_id = $attribute_ids[0]['attribute_id'];
foreach($attribute_ids as $attribute_id)
{
//Update attribute_link with the attribute_id we are keeping
$builder = $this->db->table('attribute_links');
$builder->where('attribute_id', $attribute_id['attribute_id']);
$builder->update(['attribute_id' => $retain_attribute_id]);
foreach($attribute_ids as $attribute_id)
{
//Update attribute_link with the attribute_id we are keeping
$builder = $this->db->table('attribute_links');
$builder->where('attribute_id', $attribute_id['attribute_id']);
$builder->update(['attribute_id' => $retain_attribute_id]);
//Delete the row from attribute_values if it isn't our keeper
if($attribute_id['attribute_id'] !== $retain_attribute_id)
{
$builder = $this->db->table('attribute_values');
$builder->delete(['attribute_id' => $attribute_id['attribute_id']]);
}
}
}
//Delete the row from attribute_values if it isn't our keeper
if($attribute_id['attribute_id'] !== $retain_attribute_id)
{
$builder = $this->db->table('attribute_values');
$builder->delete(['attribute_id' => $attribute_id['attribute_id']]);
}
}
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
}

View File

@@ -7,60 +7,60 @@ use App\Models\Attribute;
class Migration_remove_duplicate_links extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating remove_duplicate_links');
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating remove_duplicate_links');
$this->migrate_duplicate_attribute_links();
$this->migrate_duplicate_attribute_links();
error_log('Migrating remove_duplicate_links completed');
}
error_log('Migrating remove_duplicate_links completed');
}
/**
* Given the type of attribute, deletes any duplicates it finds in the attribute_values table and reassigns those
*
* @property attribute $attribute
*/
private function migrate_duplicate_attribute_links(): void
{
$attribute = model(Attribute::class);
/**
* Given the type of attribute, deletes any duplicates it finds in the attribute_values table and reassigns those
*
* @property attribute $attribute
*/
private function migrate_duplicate_attribute_links(): void
{
$attribute = model(Attribute::class);
//Remove duplicate attribute links
$this->db->transStart();
//Remove duplicate attribute links
$this->db->transStart();
$builder = $this->db->table('attribute_links');
$builder->select('item_id, definition_id, attribute_id, COUNT(*) as count');
$builder->where('sale_id', null);
$builder->where('receiving_id', null);
$builder->groupBy('item_id');
$builder->groupBy('definition_id');
$builder->groupBy('attribute_id');
$builder->having('count > 1');
$duplicated_links = $builder->get();
$builder = $this->db->table('attribute_links');
$builder->select('item_id, definition_id, attribute_id, COUNT(*) as count');
$builder->where('sale_id', null);
$builder->where('receiving_id', null);
$builder->groupBy('item_id');
$builder->groupBy('definition_id');
$builder->groupBy('attribute_id');
$builder->having('count > 1');
$duplicated_links = $builder->get();
$builder = $this->db->table('attribute_links');
$builder = $this->db->table('attribute_links');
foreach($duplicated_links->getResultArray() as $duplicated_link)
{
$builder->where('sale_id', null);
$builder->where('receiving_id', null);
$builder->where('item_id', $duplicated_link['item_id']);
$builder->where('definition_id', $duplicated_link['definition_id']);
$builder->delete();
foreach($duplicated_links->getResultArray() as $duplicated_link)
{
$builder->where('sale_id', null);
$builder->where('receiving_id', null);
$builder->where('item_id', $duplicated_link['item_id']);
$builder->where('definition_id', $duplicated_link['definition_id']);
$builder->delete();
$attribute->saveAttributeLink($duplicated_link['item_id'], $duplicated_link['definition_id'], $duplicated_link['attribute_id']);
}
$attribute->saveAttributeLink($duplicated_link['item_id'], $duplicated_link['definition_id'], $duplicated_link['attribute_id']);
}
$this->db->transComplete();
}
$this->db->transComplete();
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
/**
* Revert a migration step.
*/
public function down(): void
{
}
}

View File

@@ -6,23 +6,23 @@ use CodeIgniter\Database\Migration;
class Migration_move_expenses_categories extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating expense categories module');
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating expense categories module');
$this->db->simpleQuery("UPDATE ospos_grants SET menu_group = 'office' WHERE permission_id = 'expenses_categories'");
$this->db->simpleQuery("UPDATE ospos_grants SET menu_group = 'office' WHERE permission_id = 'expenses_categories'");
error_log('Migrating expense categories module completed');
}
error_log('Migrating expense categories module completed');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -13,153 +13,153 @@ use ReflectionException;
class Convert_to_ci4 extends Migration
{
/**
* Constructor.
*/
public function __construct(?Forge $forge = null)
{
parent::__construct($forge);
helper('security');
}
/**
* Constructor.
*/
public function __construct(?Forge $forge = null)
{
parent::__construct($forge);
helper('security');
}
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating database to CodeIgniter4 formats');
/**
* Perform a migration step.
*/
public function up(): void
{
error_log('Migrating database to CodeIgniter4 formats');
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_ci4_conversion.sql');
helper('migration');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_ci4_conversion.sql');
if(!empty(config('Encryption')->key))
{
$this->convert_ci3_encrypted_data();
}
else
{
check_encryption();
}
if(!empty(config('Encryption')->key))
{
$this->convert_ci3_encrypted_data();
}
else
{
check_encryption();
}
remove_backup();
remove_backup();
error_log('Migrating to CodeIgniter4 formats completed');
}
error_log('Migrating to CodeIgniter4 formats completed');
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
/**
* @return RedirectResponse|void
* @throws ReflectionException
*/
private function convert_ci3_encrypted_data()
{
$appconfig = model(Appconfig::class);
/**
* @return RedirectResponse|void
* @throws ReflectionException
*/
private function convert_ci3_encrypted_data()
{
$appconfig = model(Appconfig::class);
$ci3_encrypted_data = [
'clcdesq_api_key' => '',
'clcdesq_api_url' => '',
'mailchimp_api_key' => '',
'mailchimp_list_id' => '',
'smtp_pass' => ''
];
$ci3_encrypted_data = [
'clcdesq_api_key' => '',
'clcdesq_api_url' => '',
'mailchimp_api_key' => '',
'mailchimp_list_id' => '',
'smtp_pass' => ''
];
foreach($ci3_encrypted_data as $key => $value)
{
$ci3_encrypted_data[$key] = $appconfig->get_value($key);
}
foreach($ci3_encrypted_data as $key => $value)
{
$ci3_encrypted_data[$key] = $appconfig->get_value($key);
}
$decrypted_data = $this->decrypt_ci3_data($ci3_encrypted_data);
$decrypted_data = $this->decrypt_ci3_data($ci3_encrypted_data);
check_encryption();
check_encryption();
try
{
$ci4_encrypted_data = $this->encrypt_data($decrypted_data);
try
{
$ci4_encrypted_data = $this->encrypt_data($decrypted_data);
$success = empty(array_diff_assoc($decrypted_data, $this->decrypt_data($ci4_encrypted_data)));
if(!$success)
{
abort_encryption_conversion();
remove_backup();
throw new RedirectException('login');
}
$success = empty(array_diff_assoc($decrypted_data, $this->decrypt_data($ci4_encrypted_data)));
if(!$success)
{
abort_encryption_conversion();
remove_backup();
throw new RedirectException('login');
}
$appconfig->batch_save($ci4_encrypted_data);
} catch(RedirectException $e)
{
return redirect()->to('login'); //TODO: Need to figure out how to pass the error to the Login controller so that it gets displayed.
}
}
$appconfig->batch_save($ci4_encrypted_data);
} catch(RedirectException $e)
{
return redirect()->to('login'); //TODO: Need to figure out how to pass the error to the Login controller so that it gets displayed.
}
}
/**
* Decrypts CI3 encrypted data and returns the plaintext values.
*
* @param array $encrypted_data Data encrypted using CI3 methodology.
* @return array Plaintext, unencrypted data.
*/
private function decrypt_ci3_data(array $encrypted_data): array
{
$config = new Encryption();
$config->driver = 'OpenSSL';
$config->key = config('Encryption')->key;
$config->cipher = 'AES-128-CBC';
$config->rawData = false;
$config->encryptKeyInfo = 'encryption';
$config->authKeyInfo = 'authentication';
/**
* Decrypts CI3 encrypted data and returns the plaintext values.
*
* @param array $encrypted_data Data encrypted using CI3 methodology.
* @return array Plaintext, unencrypted data.
*/
private function decrypt_ci3_data(array $encrypted_data): array
{
$config = new Encryption();
$config->driver = 'OpenSSL';
$config->key = config('Encryption')->key;
$config->cipher = 'AES-128-CBC';
$config->rawData = false;
$config->encryptKeyInfo = 'encryption';
$config->authKeyInfo = 'authentication';
$encrypter = Services::encrypter($config);
$encrypter = Services::encrypter($config);
$decrypted_data = [];
foreach($encrypted_data as $key => $value)
{
$decrypted_data[$key] = !empty($value) ? $encrypter->decrypt($value): '';
}
$decrypted_data = [];
foreach($encrypted_data as $key => $value)
{
$decrypted_data[$key] = !empty($value) ? $encrypter->decrypt($value): '';
}
return $decrypted_data;
}
return $decrypted_data;
}
/**
* Encrypts data using CI4 algorithms.
*
* @param array $plain_data Data to be encrypted.
* @return array Encrypted data.
*/
private function encrypt_data(array $plain_data): array
{
$encrypter = Services::encrypter();
/**
* Encrypts data using CI4 algorithms.
*
* @param array $plain_data Data to be encrypted.
* @return array Encrypted data.
*/
private function encrypt_data(array $plain_data): array
{
$encrypter = Services::encrypter();
$encrypted_data = [];
foreach($plain_data as $key => $value)
{
$encrypted_data[$key] = !empty($value) ? $encrypter->encrypt($value) : '';
}
$encrypted_data = [];
foreach($plain_data as $key => $value)
{
$encrypted_data[$key] = !empty($value) ? $encrypter->encrypt($value) : '';
}
return $encrypted_data;
}
return $encrypted_data;
}
/**
* Decrypts data using CI4 algorithms.
*
* @param array $encrypted_data Data to be decrypted.
* @return array Decrypted data.
*/
private function decrypt_data(array $encrypted_data): array
{
$encrypter = Services::encrypter();
/**
* Decrypts data using CI4 algorithms.
*
* @param array $encrypted_data Data to be decrypted.
* @return array Decrypted data.
*/
private function decrypt_data(array $encrypted_data): array
{
$encrypter = Services::encrypter();
$decrypted_data = [];
foreach($encrypted_data as $key => $value)
{
$decrypted_data[$key] = !empty($value) ? $encrypter->decrypt($value) : '';
}
$decrypted_data = [];
foreach($encrypted_data as $key => $value)
{
$decrypted_data[$key] = !empty($value) ? $encrypter->decrypt($value) : '';
}
return $decrypted_data;
}
return $decrypted_data;
}
}

View File

@@ -6,22 +6,22 @@ use CodeIgniter\Database\Migration;
class IntToTinyint extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' MODIFY `consent` tinyint NOT NULL DEFAULT 0');
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('cash_up') . ' MODIFY `note` tinyint NOT NULL DEFAULT 0');
}
/**
* Perform a migration step.
*/
public function up(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' MODIFY `consent` tinyint NOT NULL DEFAULT 0');
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('cash_up') . ' MODIFY `note` tinyint NOT NULL DEFAULT 0');
}
/**
* Revert a migration step.
*/
public function down(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' MODIFY `consent` int NOT NULL DEFAULT 0');
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('cash_up') . ' MODIFY `note` int NOT NULL DEFAULT 0');
/**
* Revert a migration step.
*/
public function down(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' MODIFY `consent` int NOT NULL DEFAULT 0');
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('cash_up') . ' MODIFY `note` int NOT NULL DEFAULT 0');
}
}
}

View File

@@ -6,30 +6,30 @@ use CodeIgniter\Database\Migration;
class Migration_add_missing_config extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
$image_values = [
['key' => 'account_number', 'value' => ''], // This has no current maintenance, but it's used in Sales
['key' => 'category_dropdown', 'value' => ''],
['key' => 'smtp_host', 'value' => ''],
['key' => 'smtp_user', 'value' => ''],
['key' => 'smtp_pass', 'value' => ''],
['key' => 'login_form', 'value' => ''],
['key' => 'receiving_calculate_average_price', 'value' => ''],
['key' => 'payment_message', 'value' => '']
];
/**
* Perform a migration step.
*/
public function up(): void
{
$image_values = [
['key' => 'account_number', 'value' => ''], // This has no current maintenance, but it's used in Sales
['key' => 'category_dropdown', 'value' => ''],
['key' => 'smtp_host', 'value' => ''],
['key' => 'smtp_user', 'value' => ''],
['key' => 'smtp_pass', 'value' => ''],
['key' => 'login_form', 'value' => ''],
['key' => 'receiving_calculate_average_price', 'value' => ''],
['key' => 'payment_message', 'value' => '']
];
$this->db->table('app_config')->ignore(true)->insertBatch($image_values);
}
$this->db->table('app_config')->ignore(true)->insertBatch($image_values);
}
/**
* Revert a migration step.
*/
public function down(): void
{
// no need to remove necessary config values.
}
/**
* Revert a migration step.
*/
public function down(): void
{
// no need to remove necessary config values.
}
}

View File

@@ -6,21 +6,21 @@ use CodeIgniter\Database\Migration;
class Migration_drop_account_number_index extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' DROP INDEX account_number');
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' ADD INDEX account_number (account_number)');
}
/**
* Perform a migration step.
*/
public function up(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' DROP INDEX account_number');
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' ADD INDEX account_number (account_number)');
}
/**
* Revert a migration step.
*/
public function down(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' DROP INDEX account_number');
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' ADD UNIQUE account_number (account_number)');
}
/**
* Revert a migration step.
*/
public function down(): void
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' DROP INDEX account_number');
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('customers') . ' ADD UNIQUE account_number (account_number)');
}
}

View File

@@ -9,69 +9,69 @@ use Config\OSPOS;
class Migration_Convert_Barcode_Types extends Migration
{
private Appconfig $appconfig;
private array $config;
private Appconfig $appconfig;
private array $config;
public function __construct(?Forge $forge = null)
{
$this->appconfig = model(Appconfig::class);
$this->config = config(OSPOS::class)->settings;
public function __construct(?Forge $forge = null)
{
$this->appconfig = model(Appconfig::class);
$this->config = config(OSPOS::class)->settings;
parent::__construct($forge);
}
parent::__construct($forge);
}
/**
* Perform a migration step.
*/
public function up(): void
{
/**
* Perform a migration step.
*/
public function up(): void
{
$old_barcode_type = $this->config['barcode_type'];
$old_barcode_type = $this->config['barcode_type'];
switch($old_barcode_type)
{
case 'Code39':
$new_barcode_type = 'C39';
break;
case 'Ean13':
$new_barcode_type = 'EAN13';
break;
case 'Ean8':
$new_barcode_type = 'EAN8';
break;
default:
case 'Code128':
$new_barcode_type = 'C128';
break;
}
switch($old_barcode_type)
{
case 'Code39':
$new_barcode_type = 'C39';
break;
case 'Ean13':
$new_barcode_type = 'EAN13';
break;
case 'Ean8':
$new_barcode_type = 'EAN8';
break;
default:
case 'Code128':
$new_barcode_type = 'C128';
break;
}
$this->appconfig->save(['barcode_type' => $new_barcode_type]);
}
$this->appconfig->save(['barcode_type' => $new_barcode_type]);
}
/**
* Revert a migration step.
*/
public function down(): void
{
$new_barcode_type = $this->config['barcode_type'];
/**
* Revert a migration step.
*/
public function down(): void
{
$new_barcode_type = $this->config['barcode_type'];
switch($new_barcode_type)
{
case 'C39':
$old_barcode_type = 'Code39';
break;
case 'EAN13':
$old_barcode_type = 'Ean13';
break;
case 'EAN8':
$old_barcode_type = 'Ean8';
break;
default:
case 'C128':
$old_barcode_type = 'Code128';
break;
}
switch($new_barcode_type)
{
case 'C39':
$old_barcode_type = 'Code39';
break;
case 'EAN13':
$old_barcode_type = 'Ean13';
break;
case 'EAN8':
$old_barcode_type = 'Ean8';
break;
default:
case 'C128':
$old_barcode_type = 'Code128';
break;
}
$this->appconfig->save(['barcode_type' => $old_barcode_type]);
}
$this->appconfig->save(['barcode_type' => $old_barcode_type]);
}
}

View File

@@ -6,81 +6,81 @@ use CodeIgniter\Database\Migration;
use Config\Database;
class Migration_fix_keys_for_db_upgrade extends Migration {
/**
* Perform a migration step.
*/
public function up(): void
{
$this->db->query("ALTER TABLE `ospos_tax_codes` MODIFY `deleted` tinyint(1) DEFAULT 0 NOT NULL;");
/**
* Perform a migration step.
*/
public function up(): void
{
$this->db->query("ALTER TABLE `ospos_tax_codes` MODIFY `deleted` tinyint(1) DEFAULT 0 NOT NULL;");
if (!$this->index_exists('ospos_customers', 'company_name'))
{
$this->db->query("ALTER TABLE `ospos_customers` ADD INDEX(`company_name`)");
}
if (!$this->index_exists('ospos_customers', 'company_name'))
{
$this->db->query("ALTER TABLE `ospos_customers` ADD INDEX(`company_name`)");
}
$checkSql = "SELECT CONSTRAINT_NAME FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = DATABASE() AND TABLE_NAME = '" . $this->db->prefixTable('sales_items_taxes') . "' AND CONSTRAINT_NAME = 'ospos_sales_items_taxes_ibfk_1'";
$foreignKeyExists = $this->db->query($checkSql)->getRow();
$checkSql = "SELECT CONSTRAINT_NAME FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = DATABASE() AND TABLE_NAME = '" . $this->db->prefixTable('sales_items_taxes') . "' AND CONSTRAINT_NAME = 'ospos_sales_items_taxes_ibfk_1'";
$foreignKeyExists = $this->db->query($checkSql)->getRow();
if ($foreignKeyExists)
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('sales_items_taxes') . ' DROP FOREIGN KEY ospos_sales_items_taxes_ibfk_1');
}
if ($foreignKeyExists)
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('sales_items_taxes') . ' DROP FOREIGN KEY ospos_sales_items_taxes_ibfk_1');
}
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('sales_items_taxes')
. ' ADD CONSTRAINT ospos_sales_items_taxes_ibfk_1 FOREIGN KEY (sale_id, item_id, line) '
. ' REFERENCES ' . $this->db->prefixTable('sales_items') . ' (sale_id, item_id, line)');
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('sales_items_taxes')
. ' ADD CONSTRAINT ospos_sales_items_taxes_ibfk_1 FOREIGN KEY (sale_id, item_id, line) '
. ' REFERENCES ' . $this->db->prefixTable('sales_items') . ' (sale_id, item_id, line)');
$this->create_primary_key('customers', 'person_id');
$this->create_primary_key('employees', 'person_id');
$this->create_primary_key('suppliers', 'person_id');
}
$this->create_primary_key('customers', 'person_id');
$this->create_primary_key('employees', 'person_id');
$this->create_primary_key('suppliers', 'person_id');
}
/**
* Revert a migration step.
*/
public function down(): void
{
$checkSql = "SELECT CONSTRAINT_NAME FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = DATABASE() AND TABLE_NAME = '" . $this->db->prefixTable('sales_items_taxes') . "' AND CONSTRAINT_NAME = 'ospos_sales_items_taxes_ibfk_1'";
$foreignKeyExists = $this->db->query($checkSql)->getRow();
/**
* Revert a migration step.
*/
public function down(): void
{
$checkSql = "SELECT CONSTRAINT_NAME FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = DATABASE() AND TABLE_NAME = '" . $this->db->prefixTable('sales_items_taxes') . "' AND CONSTRAINT_NAME = 'ospos_sales_items_taxes_ibfk_1'";
$foreignKeyExists = $this->db->query($checkSql)->getRow();
if ($foreignKeyExists)
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('sales_items_taxes') . ' DROP CONSTRAINT ospos_sales_items_taxes_ibfk_1');
}
if ($foreignKeyExists)
{
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('sales_items_taxes') . ' DROP CONSTRAINT ospos_sales_items_taxes_ibfk_1');
}
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('sales_items_taxes')
. ' ADD CONSTRAINT ospos_sales_items_taxes_ibfk_1 FOREIGN KEY (sale_id) '
. ' REFERENCES ' . $this->db->prefixTable('sales_items') . ' (sale_id)');
}
$this->db->query('ALTER TABLE ' . $this->db->prefixTable('sales_items_taxes')
. ' ADD CONSTRAINT ospos_sales_items_taxes_ibfk_1 FOREIGN KEY (sale_id) '
. ' REFERENCES ' . $this->db->prefixTable('sales_items') . ' (sale_id)');
}
private function create_primary_key(string $table, string $index): void
{
$result = $this->db->query('SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name= \'' . $this->db->getPrefix() . "$table' AND column_key = '$index'");
private function create_primary_key(string $table, string $index): void
{
$result = $this->db->query('SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name= \'' . $this->db->getPrefix() . "$table' AND column_key = '$index'");
if ( ! $result->getRowArray())
{
$this->delete_index($table, $index);
$forge = Database::forge();
$forge->addPrimaryKey($table, '');
if ( ! $result->getRowArray())
{
$this->delete_index($table, $index);
$forge = Database::forge();
$forge->addPrimaryKey($table, '');
}
}
}
}
private function index_exists(string $table, string $index): bool
{
$result = $this->db->query('SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = \'' . $this->db->getPrefix() . "$table' AND index_name = '$index'");
$row_array = $result->getRowArray();
return $row_array && $row_array['COUNT(*)'] > 0;
}
private function index_exists(string $table, string $index): bool
{
$result = $this->db->query('SELECT COUNT(*) FROM information_schema.statistics WHERE table_schema = DATABASE() AND table_name = \'' . $this->db->getPrefix() . "$table' AND index_name = '$index'");
$row_array = $result->getRowArray();
return $row_array && $row_array['COUNT(*)'] > 0;
}
private function delete_index(string $table, string $index): void
{
private function delete_index(string $table, string $index): void
{
if ($this->index_exists($table, $index))
{
$forge = Database::forge();
$forge->dropKey($table, $index, FALSE);
}
}
if ($this->index_exists($table, $index))
{
$forge = Database::forge();
$forge->dropKey($table, $index, FALSE);
}
}
}

View File

@@ -8,69 +8,69 @@ use CodeIgniter\Database\ResultInterface;
class fix_duplicate_attributes extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
$rows_to_keep = $this->get_all_duplicate_attributes();
$this->remove_duplicate_attributes($rows_to_keep);
/**
* Perform a migration step.
*/
public function up(): void
{
$rows_to_keep = $this->get_all_duplicate_attributes();
$this->remove_duplicate_attributes($rows_to_keep);
helper('migration');
helper('migration');
$foreignKeys = [
'ospos_attribute_links_ibfk_1',
'ospos_attribute_links_ibfk_2',
'ospos_attribute_links_ibfk_3',
'ospos_attribute_links_ibfk_4',
'ospos_attribute_links_ibfk_5'
];
$foreignKeys = [
'ospos_attribute_links_ibfk_1',
'ospos_attribute_links_ibfk_2',
'ospos_attribute_links_ibfk_3',
'ospos_attribute_links_ibfk_4',
'ospos_attribute_links_ibfk_5'
];
drop_foreign_key_constraints($foreignKeys, 'ospos_attribute_links');
drop_foreign_key_constraints($foreignKeys, 'ospos_attribute_links');
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_attribute_links_unique_constraint.sql');
}
execute_script(APPPATH . 'Database/Migrations/sqlscripts/3.4.0_attribute_links_unique_constraint.sql');
}
/**
* Retrieves from the database all rows where the item_id and definition_id are the same AND the sale_id/receiving_id is null.
* It also excludes null item_id rows as those are dropdown items.
*
* @return ResultInterface Results containing item_id, definition_id and attribute_id in each row.
*/
private function get_all_duplicate_attributes(): ResultInterface
{
$builder = $this->db->table('attribute_links');
$builder->select('item_id, definition_id, MIN(attribute_id) as attribute_id');
$builder->where('sale_id IS NULL');
$builder->where('receiving_id IS NULL');
$builder->where('item_id IS NOT NULL');
$builder->groupBy('item_id, definition_id');
$builder->having('COUNT(attribute_id) > 1');
return $builder->get();
}
/**
* Retrieves from the database all rows where the item_id and definition_id are the same AND the sale_id/receiving_id is null.
* It also excludes null item_id rows as those are dropdown items.
*
* @return ResultInterface Results containing item_id, definition_id and attribute_id in each row.
*/
private function get_all_duplicate_attributes(): ResultInterface
{
$builder = $this->db->table('attribute_links');
$builder->select('item_id, definition_id, MIN(attribute_id) as attribute_id');
$builder->where('sale_id IS NULL');
$builder->where('receiving_id IS NULL');
$builder->where('item_id IS NOT NULL');
$builder->groupBy('item_id, definition_id');
$builder->having('COUNT(attribute_id) > 1');
return $builder->get();
}
/**
* Removes the duplicate attributes from the database.
*
* @param ResultInterface $rows_to_keep A multidimensional associative array containing item_id, definition_id and attribute_id in each row which should be kept in the database.
* @return void
*/
private function remove_duplicate_attributes(ResultInterface $rows_to_keep): void
{
$attribute = model(Attribute::class);
foreach($rows_to_keep->getResult() as $row)
{
$attribute->deleteAttributeLinks($row->item_id, $row->definition_id); //Deletes all attribute links for the item_id/definition_id combination
$attribute->saveAttributeLink($row->item_id, $row->definition_id, $row->attribute_id);
}
}
/**
* Removes the duplicate attributes from the database.
*
* @param ResultInterface $rows_to_keep A multidimensional associative array containing item_id, definition_id and attribute_id in each row which should be kept in the database.
* @return void
*/
private function remove_duplicate_attributes(ResultInterface $rows_to_keep): void
{
$attribute = model(Attribute::class);
foreach($rows_to_keep->getResult() as $row)
{
$attribute->deleteAttributeLinks($row->item_id, $row->definition_id); //Deletes all attribute links for the item_id/definition_id combination
$attribute->saveAttributeLink($row->item_id, $row->definition_id, $row->attribute_id);
}
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -8,22 +8,22 @@ use CodeIgniter\Database\ResultInterface;
class Migration_Attributes_fix_cascading_delete extends Migration
{
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
drop_foreign_key_constraints(['ospos_attribute_links_ibfk_1', 'ospos_attribute_links_ibfk_2'], 'ospos_attribute_links');
$this->db->query("ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_1` FOREIGN KEY (`definition_id`) REFERENCES `ospos_attribute_definitions` (`definition_id`) ON DELETE CASCADE;");
$this->db->query("ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_2` FOREIGN KEY (`attribute_id`) REFERENCES `ospos_attribute_values` (`attribute_id`) ON DELETE CASCADE;");
}
/**
* Perform a migration step.
*/
public function up(): void
{
helper('migration');
drop_foreign_key_constraints(['ospos_attribute_links_ibfk_1', 'ospos_attribute_links_ibfk_2'], 'ospos_attribute_links');
$this->db->query("ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_1` FOREIGN KEY (`definition_id`) REFERENCES `ospos_attribute_definitions` (`definition_id`) ON DELETE CASCADE;");
$this->db->query("ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_2` FOREIGN KEY (`attribute_id`) REFERENCES `ospos_attribute_values` (`attribute_id`) ON DELETE CASCADE;");
}
/**
* Revert a migration step.
*/
public function down(): void
{
/**
* Revert a migration step.
*/
public function down(): void
{
}
}
}

View File

@@ -22,20 +22,20 @@ INSERT INTO `ospos_app_config` (`key`, `value`) VALUES
('default_sales_discount_type', '0');
ALTER TABLE `ospos_item_kits`
CHANGE COLUMN `kit_discount_percent` `kit_discount` DECIMAL(15,2) NOT NULL DEFAULT 0 AFTER `item_id`,
ADD COLUMN `kit_discount_type` TINYINT(2) NOT NULL DEFAULT '0' AFTER `kit_discount`;
CHANGE COLUMN `kit_discount_percent` `kit_discount` DECIMAL(15,2) NOT NULL DEFAULT 0 AFTER `item_id`,
ADD COLUMN `kit_discount_type` TINYINT(2) NOT NULL DEFAULT '0' AFTER `kit_discount`;
ALTER TABLE `ospos_customers`
CHANGE COLUMN `discount_percent` `discount` DECIMAL(15,2) NOT NULL DEFAULT 0 AFTER `sales_tax_code`,
ADD COLUMN `discount_type` TINYINT(2) NOT NULL DEFAULT '0' AFTER `discount`;
CHANGE COLUMN `discount_percent` `discount` DECIMAL(15,2) NOT NULL DEFAULT 0 AFTER `sales_tax_code`,
ADD COLUMN `discount_type` TINYINT(2) NOT NULL DEFAULT '0' AFTER `discount`;
ALTER TABLE `ospos_sales_items`
CHANGE COLUMN `discount_percent` `discount` DECIMAL(15,2) NOT NULL DEFAULT 0 AFTER `item_unit_price`,
ADD COLUMN `discount_type` TINYINT(2) NOT NULL DEFAULT '0' AFTER `discount`;
CHANGE COLUMN `discount_percent` `discount` DECIMAL(15,2) NOT NULL DEFAULT 0 AFTER `item_unit_price`,
ADD COLUMN `discount_type` TINYINT(2) NOT NULL DEFAULT '0' AFTER `discount`;
ALTER TABLE `ospos_receivings_items`
CHANGE COLUMN `discount_percent` `discount` DECIMAL(15,2) NOT NULL DEFAULT 0 AFTER `item_unit_price`,
ADD COLUMN `discount_type` TINYINT(2) NOT NULL DEFAULT '0' AFTER `discount`;
CHANGE COLUMN `discount_percent` `discount` DECIMAL(15,2) NOT NULL DEFAULT 0 AFTER `item_unit_price`,
ADD COLUMN `discount_type` TINYINT(2) NOT NULL DEFAULT '0' AFTER `discount`;
--
-- Add support for module cashups

View File

@@ -9,86 +9,86 @@ INSERT INTO `ospos_app_config` (`key`, `value`) VALUES
('tax_id', '');
UPDATE `ospos_app_config`
SET `key` = 'use_destination_based_tax'
WHERE `key` = 'customer_sales_tax_support';
SET `key` = 'use_destination_based_tax'
WHERE `key` = 'customer_sales_tax_support';
UPDATE `ospos_app_config`
SET `key` = 'default_tax_code'
WHERE `key` = 'default_origin_tax_code';
SET `key` = 'default_tax_code'
WHERE `key` = 'default_origin_tax_code';
RENAME TABLE `ospos_tax_codes` TO `ospos_tax_codes_backup`;
CREATE TABLE IF NOT EXISTS `ospos_tax_codes` (
`tax_code_id` int(11) NOT NULL AUTO_INCREMENT,
`tax_code` varchar(32) NOT NULL,
`tax_code_name` varchar(255) NOT NULL DEFAULT '',
`city` varchar(255) NOT NULL DEFAULT '',
`state` varchar(255) NOT NULL DEFAULT '',
`deleted` int(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`tax_code_id`)
`tax_code_id` int(11) NOT NULL AUTO_INCREMENT,
`tax_code` varchar(32) NOT NULL,
`tax_code_name` varchar(255) NOT NULL DEFAULT '',
`city` varchar(255) NOT NULL DEFAULT '',
`state` varchar(255) NOT NULL DEFAULT '',
`deleted` int(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`tax_code_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `ospos_customers`
ADD COLUMN `tax_id` varchar(32) NOT NULL DEFAULT '' AFTER `taxable`,
ADD COLUMN `sales_tax_code_id` int(11) DEFAULT NULL AFTER `tax_id`;
ADD COLUMN `tax_id` varchar(32) NOT NULL DEFAULT '' AFTER `taxable`,
ADD COLUMN `sales_tax_code_id` int(11) DEFAULT NULL AFTER `tax_id`;
ALTER TABLE `ospos_items`
ADD COLUMN `hsn_code` varchar(32) NOT NULL DEFAULT '' AFTER `low_sell_item_id`;
ADD COLUMN `hsn_code` varchar(32) NOT NULL DEFAULT '' AFTER `low_sell_item_id`;
ALTER TABLE `ospos_sales_items_taxes`
ADD COLUMN `sales_tax_code_id` int(11) DEFAULT NULL AFTER `item_tax_amount`,
ADD COLUMN `jurisdiction_id` int(11) DEFAULT NULL AFTER `sales_tax_code_id`,
ADD COLUMN `tax_category_id` int(11) DEFAULT NULL AFTER `jurisdiction_id`,
DROP COLUMN `cascade_tax`;
ADD COLUMN `sales_tax_code_id` int(11) DEFAULT NULL AFTER `item_tax_amount`,
ADD COLUMN `jurisdiction_id` int(11) DEFAULT NULL AFTER `sales_tax_code_id`,
ADD COLUMN `tax_category_id` int(11) DEFAULT NULL AFTER `jurisdiction_id`,
DROP COLUMN `cascade_tax`;
RENAME TABLE `ospos_sales_taxes` TO `ospos_sales_taxes_backup`;
CREATE TABLE `ospos_sales_taxes` (
`sales_taxes_id` int(11) NOT NULL AUTO_INCREMENT,
`sale_id` int(10) NOT NULL,
`jurisdiction_id` int(11) DEFAULT NULL,
`tax_category_id` int(11) DEFAULT NULL,
`tax_type` smallint(2) NOT NULL,
`tax_group` varchar(32) NOT NULL,
`sale_tax_basis` decimal(15,4) NOT NULL,
`sale_tax_amount` decimal(15,4) NOT NULL,
`print_sequence` tinyint(2) NOT NULL DEFAULT 0,
`name` varchar(255) NOT NULL,
`tax_rate` decimal(15,4) NOT NULL,
`sales_tax_code_id` int(11) DEFAULT NULL,
`rounding_code` tinyint(2) NOT NULL DEFAULT 0,
PRIMARY KEY (`sales_taxes_id`),
KEY `print_sequence` (`sale_id`,`print_sequence`,`tax_group`)
`sales_taxes_id` int(11) NOT NULL AUTO_INCREMENT,
`sale_id` int(10) NOT NULL,
`jurisdiction_id` int(11) DEFAULT NULL,
`tax_category_id` int(11) DEFAULT NULL,
`tax_type` smallint(2) NOT NULL,
`tax_group` varchar(32) NOT NULL,
`sale_tax_basis` decimal(15,4) NOT NULL,
`sale_tax_amount` decimal(15,4) NOT NULL,
`print_sequence` tinyint(2) NOT NULL DEFAULT 0,
`name` varchar(255) NOT NULL,
`tax_rate` decimal(15,4) NOT NULL,
`sales_tax_code_id` int(11) DEFAULT NULL,
`rounding_code` tinyint(2) NOT NULL DEFAULT 0,
PRIMARY KEY (`sales_taxes_id`),
KEY `print_sequence` (`sale_id`,`print_sequence`,`tax_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `ospos_tax_jurisdictions` (
`jurisdiction_id` int(11) NOT NULL AUTO_INCREMENT,
`jurisdiction_name` varchar(255) DEFAULT NULL,
`tax_group` varchar(32) NOT NULL,
`tax_type` smallint(2) NOT NULL,
`reporting_authority` varchar(255) DEFAULT NULL,
`tax_group_sequence` tinyint(2) NOT NULL DEFAULT 0,
`cascade_sequence` tinyint(2) NOT NULL DEFAULT 0,
`deleted` int(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`jurisdiction_id`)
`jurisdiction_id` int(11) NOT NULL AUTO_INCREMENT,
`jurisdiction_name` varchar(255) DEFAULT NULL,
`tax_group` varchar(32) NOT NULL,
`tax_type` smallint(2) NOT NULL,
`reporting_authority` varchar(255) DEFAULT NULL,
`tax_group_sequence` tinyint(2) NOT NULL DEFAULT 0,
`cascade_sequence` tinyint(2) NOT NULL DEFAULT 0,
`deleted` int(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`jurisdiction_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
ALTER TABLE `ospos_suppliers`
ADD COLUMN `tax_id` varchar(32) DEFAULT NULL AFTER `account_number`;
ADD COLUMN `tax_id` varchar(32) DEFAULT NULL AFTER `account_number`;
ALTER TABLE `ospos_tax_categories`
ADD COLUMN `deleted` int(1) NOT NULL DEFAULT 0 AFTER `tax_group_sequence`;
ADD COLUMN `deleted` int(1) NOT NULL DEFAULT 0 AFTER `tax_group_sequence`;
RENAME TABLE `ospos_tax_code_rates` TO `ospos_tax_code_rates_backup`;
CREATE TABLE IF NOT EXISTS `ospos_tax_rates` (
`tax_rate_id` int(11) NOT NULL AUTO_INCREMENT,
`rate_tax_code_id` int(11) NOT NULL,
`rate_tax_category_id` int(10) NOT NULL,
`rate_jurisdiction_id` int(11) NOT NULL,
`tax_rate` decimal(15,4) NOT NULL DEFAULT 0.0000,
`tax_rounding_code` tinyint(2) NOT NULL DEFAULT 0,
PRIMARY KEY (`tax_rate_id`)
`tax_rate_id` int(11) NOT NULL AUTO_INCREMENT,
`rate_tax_code_id` int(11) NOT NULL,
`rate_tax_category_id` int(10) NOT NULL,
`rate_jurisdiction_id` int(11) NOT NULL,
`tax_rate` decimal(15,4) NOT NULL DEFAULT 0.0000,
`tax_rounding_code` tinyint(2) NOT NULL DEFAULT 0,
PRIMARY KEY (`tax_rate_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Add support for sales tax report

View File

@@ -1,4 +1,4 @@
ALTER TABLE `ospos_sales_payments`
ADD COLUMN `cash_refund` decimal(15,2) NOT NULL DEFAULT 0 AFTER `payment_amount`,
CHANGE `payment_user` `employee_id` int(11) DEFAULT NULL,
CHANGE `payment_date` `payment_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP;
ADD COLUMN `cash_refund` decimal(15,2) NOT NULL DEFAULT 0 AFTER `payment_amount`,
CHANGE `payment_user` `employee_id` int(11) DEFAULT NULL,
CHANGE `payment_date` `payment_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP;

View File

@@ -1,16 +1,16 @@
# Prevents duplicate attribute links with the same definition_id and item_id.
# This accounts for dropdown rows (null item_id) and rows associated with sales or receivings.
ALTER TABLE `ospos_attribute_links`
ADD COLUMN `generated_unique_column` VARCHAR(255) GENERATED ALWAYS AS (
CASE
WHEN `sale_id` IS NULL AND `receiving_id` IS NULL AND `item_id` IS NOT NULL THEN CONCAT(`definition_id`, '-', `item_id`)
ELSE NULL
END
) STORED,
ADD UNIQUE INDEX `attribute_links_uq3` (`generated_unique_column`);
ADD COLUMN `generated_unique_column` VARCHAR(255) GENERATED ALWAYS AS (
CASE
WHEN `sale_id` IS NULL AND `receiving_id` IS NULL AND `item_id` IS NOT NULL THEN CONCAT(`definition_id`, '-', `item_id`)
ELSE NULL
END
) STORED,
ADD UNIQUE INDEX `attribute_links_uq3` (`generated_unique_column`);
ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_1` FOREIGN KEY (`definition_id`) REFERENCES `ospos_attribute_definitions` (`definition_id`) ON DELETE RESTRICT;
ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_2` FOREIGN KEY (`attribute_id`) REFERENCES `ospos_attribute_values` (`attribute_id`) ON DELETE RESTRICT;
ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_3` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`);
ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_4` FOREIGN KEY (`receiving_id`) REFERENCES `ospos_receivings` (`receiving_id`);
ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_5` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales` (`sale_id`);
ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_1` FOREIGN KEY (`definition_id`) REFERENCES `ospos_attribute_definitions` (`definition_id`) ON DELETE RESTRICT;
ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_2` FOREIGN KEY (`attribute_id`) REFERENCES `ospos_attribute_values` (`attribute_id`) ON DELETE RESTRICT;
ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_3` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`);
ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_4` FOREIGN KEY (`receiving_id`) REFERENCES `ospos_receivings` (`receiving_id`);
ALTER TABLE `ospos_attribute_links` ADD CONSTRAINT `ospos_attribute_links_ibfk_5` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales` (`sale_id`);

View File

@@ -2,12 +2,12 @@
DROP TABLE `ospos_sessions`;
CREATE TABLE IF NOT EXISTS `ospos_sessions` (
`id` varchar(128) NOT NULL,
`ip_address` varchar(45) NOT NULL,
`timestamp` timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
`data` blob NOT NULL,
KEY `ospos_sessions_timestamp` (`timestamp`)
);
`id` varchar(128) NOT NULL,
`ip_address` varchar(45) NOT NULL,
`timestamp` timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
`data` blob NOT NULL,
KEY `ospos_sessions_timestamp` (`timestamp`)
);
ALTER TABLE ospos_sessions ADD PRIMARY KEY (id, ip_address);

View File

@@ -6,140 +6,140 @@
-- Constraints for table `ospos_customers`
--
ALTER TABLE `ospos_customers`
ADD CONSTRAINT `ospos_customers_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `ospos_people` (`person_id`);
ADD CONSTRAINT `ospos_customers_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `ospos_people` (`person_id`);
--
-- Constraints for table `ospos_employees`
--
ALTER TABLE `ospos_employees`
ADD CONSTRAINT `ospos_employees_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `ospos_people` (`person_id`);
ADD CONSTRAINT `ospos_employees_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `ospos_people` (`person_id`);
--
-- Constraints for table `ospos_inventory`
--
ALTER TABLE `ospos_inventory`
ADD CONSTRAINT `ospos_inventory_ibfk_1` FOREIGN KEY (`trans_items`) REFERENCES `ospos_items` (`item_id`),
ADD CONSTRAINT `ospos_inventory_ibfk_2` FOREIGN KEY (`trans_user`) REFERENCES `ospos_employees` (`person_id`),
ADD CONSTRAINT `ospos_inventory_ibfk_3` FOREIGN KEY (`trans_location`) REFERENCES `ospos_stock_locations` (`location_id`);
ADD CONSTRAINT `ospos_inventory_ibfk_1` FOREIGN KEY (`trans_items`) REFERENCES `ospos_items` (`item_id`),
ADD CONSTRAINT `ospos_inventory_ibfk_2` FOREIGN KEY (`trans_user`) REFERENCES `ospos_employees` (`person_id`),
ADD CONSTRAINT `ospos_inventory_ibfk_3` FOREIGN KEY (`trans_location`) REFERENCES `ospos_stock_locations` (`location_id`);
--
-- Constraints for table `ospos_items`
--
ALTER TABLE `ospos_items`
ADD CONSTRAINT `ospos_items_ibfk_1` FOREIGN KEY (`supplier_id`) REFERENCES `ospos_suppliers` (`person_id`);
ADD CONSTRAINT `ospos_items_ibfk_1` FOREIGN KEY (`supplier_id`) REFERENCES `ospos_suppliers` (`person_id`);
--
-- Constraints for table `ospos_items_taxes`
--
ALTER TABLE `ospos_items_taxes`
ADD CONSTRAINT `ospos_items_taxes_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`) ON DELETE CASCADE;
ADD CONSTRAINT `ospos_items_taxes_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`) ON DELETE CASCADE;
--
-- Constraints for table `ospos_item_kit_items`
--
ALTER TABLE `ospos_item_kit_items`
ADD CONSTRAINT `ospos_item_kit_items_ibfk_1` FOREIGN KEY (`item_kit_id`) REFERENCES `ospos_item_kits` (`item_kit_id`) ON DELETE CASCADE,
ADD CONSTRAINT `ospos_item_kit_items_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`) ON DELETE CASCADE;
ADD CONSTRAINT `ospos_item_kit_items_ibfk_1` FOREIGN KEY (`item_kit_id`) REFERENCES `ospos_item_kits` (`item_kit_id`) ON DELETE CASCADE,
ADD CONSTRAINT `ospos_item_kit_items_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`) ON DELETE CASCADE;
--
-- Constraints for table `ospos_permissions`
--
ALTER TABLE `ospos_permissions`
ADD CONSTRAINT `ospos_permissions_ibfk_1` FOREIGN KEY (`module_id`) REFERENCES `ospos_modules` (`module_id`) ON DELETE CASCADE,
ADD CONSTRAINT `ospos_permissions_ibfk_2` FOREIGN KEY (`location_id`) REFERENCES `ospos_stock_locations` (`location_id`) ON DELETE CASCADE;
ADD CONSTRAINT `ospos_permissions_ibfk_1` FOREIGN KEY (`module_id`) REFERENCES `ospos_modules` (`module_id`) ON DELETE CASCADE,
ADD CONSTRAINT `ospos_permissions_ibfk_2` FOREIGN KEY (`location_id`) REFERENCES `ospos_stock_locations` (`location_id`) ON DELETE CASCADE;
--
-- Constraints for table `ospos_grants`
--
ALTER TABLE `ospos_grants`
ADD CONSTRAINT `ospos_grants_ibfk_1` foreign key (`permission_id`) references `ospos_permissions` (`permission_id`) ON DELETE CASCADE,
ADD CONSTRAINT `ospos_grants_ibfk_2` foreign key (`person_id`) references `ospos_employees` (`person_id`) ON DELETE CASCADE;
ADD CONSTRAINT `ospos_grants_ibfk_1` foreign key (`permission_id`) references `ospos_permissions` (`permission_id`) ON DELETE CASCADE,
ADD CONSTRAINT `ospos_grants_ibfk_2` foreign key (`person_id`) references `ospos_employees` (`person_id`) ON DELETE CASCADE;
--
-- Constraints for table `ospos_receivings`
--
ALTER TABLE `ospos_receivings`
ADD CONSTRAINT `ospos_receivings_ibfk_1` FOREIGN KEY (`employee_id`) REFERENCES `ospos_employees` (`person_id`),
ADD CONSTRAINT `ospos_receivings_ibfk_2` FOREIGN KEY (`supplier_id`) REFERENCES `ospos_suppliers` (`person_id`);
ADD CONSTRAINT `ospos_receivings_ibfk_1` FOREIGN KEY (`employee_id`) REFERENCES `ospos_employees` (`person_id`),
ADD CONSTRAINT `ospos_receivings_ibfk_2` FOREIGN KEY (`supplier_id`) REFERENCES `ospos_suppliers` (`person_id`);
--
-- Constraints for table `ospos_receivings_items`
--
ALTER TABLE `ospos_receivings_items`
ADD CONSTRAINT `ospos_receivings_items_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`),
ADD CONSTRAINT `ospos_receivings_items_ibfk_2` FOREIGN KEY (`receiving_id`) REFERENCES `ospos_receivings` (`receiving_id`);
ADD CONSTRAINT `ospos_receivings_items_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`),
ADD CONSTRAINT `ospos_receivings_items_ibfk_2` FOREIGN KEY (`receiving_id`) REFERENCES `ospos_receivings` (`receiving_id`);
--
-- Constraints for table `ospos_sales`
--
ALTER TABLE `ospos_sales`
ADD CONSTRAINT `ospos_sales_ibfk_1` FOREIGN KEY (`employee_id`) REFERENCES `ospos_employees` (`person_id`),
ADD CONSTRAINT `ospos_sales_ibfk_2` FOREIGN KEY (`customer_id`) REFERENCES `ospos_customers` (`person_id`);
ADD CONSTRAINT `ospos_sales_ibfk_1` FOREIGN KEY (`employee_id`) REFERENCES `ospos_employees` (`person_id`),
ADD CONSTRAINT `ospos_sales_ibfk_2` FOREIGN KEY (`customer_id`) REFERENCES `ospos_customers` (`person_id`);
--
-- Constraints for table `ospos_sales_items`
--
ALTER TABLE `ospos_sales_items`
ADD CONSTRAINT `ospos_sales_items_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`),
ADD CONSTRAINT `ospos_sales_items_ibfk_2` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales` (`sale_id`),
ADD CONSTRAINT `ospos_sales_items_ibfk_3` FOREIGN KEY (`item_location`) REFERENCES `ospos_stock_locations` (`location_id`);
ADD CONSTRAINT `ospos_sales_items_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`),
ADD CONSTRAINT `ospos_sales_items_ibfk_2` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales` (`sale_id`),
ADD CONSTRAINT `ospos_sales_items_ibfk_3` FOREIGN KEY (`item_location`) REFERENCES `ospos_stock_locations` (`location_id`);
--
-- Constraints for table `ospos_sales_items_taxes`
--
ALTER TABLE `ospos_sales_items_taxes`
ADD CONSTRAINT `ospos_sales_items_taxes_ibfk_1` FOREIGN KEY (`sale_id`,`item_id`,`line`) REFERENCES `ospos_sales_items` (`sale_id`,`item_id`,`line`),
ADD CONSTRAINT `ospos_sales_items_taxes_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`);
ADD CONSTRAINT `ospos_sales_items_taxes_ibfk_1` FOREIGN KEY (`sale_id`,`item_id`,`line`) REFERENCES `ospos_sales_items` (`sale_id`,`item_id`,`line`),
ADD CONSTRAINT `ospos_sales_items_taxes_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`);
--
-- Constraints for table `ospos_sales_payments`
--
ALTER TABLE `ospos_sales_payments`
ADD CONSTRAINT `ospos_sales_payments_ibfk_1` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales` (`sale_id`);
ADD CONSTRAINT `ospos_sales_payments_ibfk_1` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales` (`sale_id`);
--
-- Constraints for table `ospos_sales_suspended`
--
ALTER TABLE `ospos_sales_suspended`
ADD CONSTRAINT `ospos_sales_suspended_ibfk_1` FOREIGN KEY (`employee_id`) REFERENCES `ospos_employees` (`person_id`),
ADD CONSTRAINT `ospos_sales_suspended_ibfk_2` FOREIGN KEY (`customer_id`) REFERENCES `ospos_customers` (`person_id`);
ADD CONSTRAINT `ospos_sales_suspended_ibfk_1` FOREIGN KEY (`employee_id`) REFERENCES `ospos_employees` (`person_id`),
ADD CONSTRAINT `ospos_sales_suspended_ibfk_2` FOREIGN KEY (`customer_id`) REFERENCES `ospos_customers` (`person_id`);
--
-- Constraints for table `ospos_sales_suspended_items`
--
ALTER TABLE `ospos_sales_suspended_items`
ADD CONSTRAINT `ospos_sales_suspended_items_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`),
ADD CONSTRAINT `ospos_sales_suspended_items_ibfk_2` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales_suspended` (`sale_id`),
ADD CONSTRAINT `ospos_sales_suspended_items_ibfk_3` FOREIGN KEY (`item_location`) REFERENCES `ospos_stock_locations` (`location_id`);
ADD CONSTRAINT `ospos_sales_suspended_items_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`),
ADD CONSTRAINT `ospos_sales_suspended_items_ibfk_2` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales_suspended` (`sale_id`),
ADD CONSTRAINT `ospos_sales_suspended_items_ibfk_3` FOREIGN KEY (`item_location`) REFERENCES `ospos_stock_locations` (`location_id`);
--
-- Constraints for table `ospos_sales_suspended_items_taxes`
--
ALTER TABLE `ospos_sales_suspended_items_taxes`
ADD CONSTRAINT `ospos_sales_suspended_items_taxes_ibfk_1` FOREIGN KEY (`sale_id`,`item_id`,`line`) REFERENCES `ospos_sales_suspended_items` (`sale_id`,`item_id`,`line`),
ADD CONSTRAINT `ospos_sales_suspended_items_taxes_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`);
ADD CONSTRAINT `ospos_sales_suspended_items_taxes_ibfk_1` FOREIGN KEY (`sale_id`,`item_id`,`line`) REFERENCES `ospos_sales_suspended_items` (`sale_id`,`item_id`,`line`),
ADD CONSTRAINT `ospos_sales_suspended_items_taxes_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`);
--
-- Constraints for table `ospos_sales_suspended_payments`
--
ALTER TABLE `ospos_sales_suspended_payments`
ADD CONSTRAINT `ospos_sales_suspended_payments_ibfk_1` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales_suspended` (`sale_id`);
ADD CONSTRAINT `ospos_sales_suspended_payments_ibfk_1` FOREIGN KEY (`sale_id`) REFERENCES `ospos_sales_suspended` (`sale_id`);
--
-- Constraints for table `ospos_item_quantities`
--
ALTER TABLE `ospos_item_quantities`
ADD CONSTRAINT `ospos_item_quantities_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`),
ADD CONSTRAINT `ospos_item_quantities_ibfk_2` FOREIGN KEY (`location_id`) REFERENCES `ospos_stock_locations` (`location_id`);
ADD CONSTRAINT `ospos_item_quantities_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `ospos_items` (`item_id`),
ADD CONSTRAINT `ospos_item_quantities_ibfk_2` FOREIGN KEY (`location_id`) REFERENCES `ospos_stock_locations` (`location_id`);
--
-- Constraints for table `ospos_suppliers`
--
ALTER TABLE `ospos_suppliers`
ADD CONSTRAINT `ospos_suppliers_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `ospos_people` (`person_id`);
ADD CONSTRAINT `ospos_suppliers_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `ospos_people` (`person_id`);
--
-- Constraints for table `ospos_giftcards`
--
ALTER TABLE `ospos_giftcards`
ADD CONSTRAINT `ospos_giftcards_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `ospos_people` (`person_id`);
ADD CONSTRAINT `ospos_giftcards_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `ospos_people` (`person_id`);

View File

@@ -1,19 +1,19 @@
[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
key_buffer = 16M
key_buffer = 16M
max_allowed_packet = 1M
tmp-table-size = 32M
max-heap-table-size = 32M
query_cache_limit = 4M
query_cache_limit = 4M
query_cache_size = 32M
query_cache_type = ON
log_slow_queries = OFF
innodb_buffer_pool_size = 56M
innodb_log_file_size = 15M
thread_cache_size = 4
expire_logs_days = 10
expire_logs_days = 10
max_binlog_size = 100M
innodb_file_per_table = 1
myisam_sort_buffer_size = 8M
@@ -25,9 +25,8 @@ table_cache = 64
key_buffer_size = 16M
[isamchk]
key_buffer = 16M
key_buffer = 16M
write_buffer = 2M
read_buffer = 2M
sort_buffer_size = 20M
key_buffer_size = 20M

View File

@@ -4,9 +4,9 @@
--
CREATE TABLE `ospos_app_config` (
`key` varchar(50) NOT NULL,
`value` varchar(500) NOT NULL,
PRIMARY KEY (`key`)
`key` varchar(50) NOT NULL,
`value` varchar(500) NOT NULL,
PRIMARY KEY (`key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -14,75 +14,75 @@ CREATE TABLE `ospos_app_config` (
--
INSERT INTO `ospos_app_config` (`key`, `value`) VALUES
('address', '123 Nowhere street'),
('company', 'Open Source Point of Sale'),
('default_tax_rate', '8'),
('email', 'changeme@example.com'),
('fax', ''),
('phone', '555-555-5555'),
('return_policy', 'Test'),
('timezone', 'America/New_York'),
('website', ''),
('company_logo', ''),
('tax_included', '0'),
('barcode_content', 'id'),
('barcode_type', 'Code39'),
('barcode_width', '250'),
('barcode_height', '50'),
('barcode_quality', '100'),
('barcode_font', 'Arial'),
('barcode_font_size', '10'),
('barcode_first_row', 'category'),
('barcode_second_row', 'item_code'),
('barcode_third_row', 'unit_price'),
('barcode_num_in_row', '2'),
('barcode_page_width', '100'),
('barcode_page_cellspacing', '20'),
('barcode_generate_if_empty', '0'),
('receipt_show_taxes', '0'),
('receipt_show_total_discount', '1'),
('receipt_show_description', '1'),
('receipt_show_serialnumber', '1'),
('invoice_enable', '1'),
('recv_invoice_format', '$CO'),
('sales_invoice_format', '$CO'),
('invoice_email_message', 'Dear $CU, In attachment the receipt for sale $INV'),
('invoice_default_comments', 'This is a default comment'),
('print_silently', '1'),
('print_header', '0'),
('print_footer', '0'),
('print_top_margin', '0'),
('print_left_margin', '0'),
('print_bottom_margin', '0'),
('print_right_margin', '0'),
('default_sales_discount', '0'),
('lines_per_page', '25'),
('dateformat', 'm/d/Y'),
('timeformat', 'H:i:s'),
('currency_symbol', '$'),
('number_locale', 'en_US'),
('thousands_separator', '1'),
('currency_decimals', '2'),
('tax_decimals', '2'),
('quantity_decimals', '0'),
('country_codes', 'us'),
('msg_msg', ''),
('msg_uid', ''),
('msg_src', ''),
('msg_pwd', ''),
('notify_horizontal_position', 'center'),
('notify_vertical_position', 'bottom'),
('payment_options_order', 'cashdebitcredit'),
('protocol', 'mail'),
('mailpath', '/usr/sbin/sendmail'),
('smtp_port', '465'),
('smtp_timeout', '5'),
('smtp_crypto', 'ssl'),
('receipt_template', 'receipt_default'),
('theme', 'flatly'),
('statistics', '1'),
('language', 'english'),
('language_code', 'en');
('address', '123 Nowhere street'),
('company', 'Open Source Point of Sale'),
('default_tax_rate', '8'),
('email', 'changeme@example.com'),
('fax', ''),
('phone', '555-555-5555'),
('return_policy', 'Test'),
('timezone', 'America/New_York'),
('website', ''),
('company_logo', ''),
('tax_included', '0'),
('barcode_content', 'id'),
('barcode_type', 'Code39'),
('barcode_width', '250'),
('barcode_height', '50'),
('barcode_quality', '100'),
('barcode_font', 'Arial'),
('barcode_font_size', '10'),
('barcode_first_row', 'category'),
('barcode_second_row', 'item_code'),
('barcode_third_row', 'unit_price'),
('barcode_num_in_row', '2'),
('barcode_page_width', '100'),
('barcode_page_cellspacing', '20'),
('barcode_generate_if_empty', '0'),
('receipt_show_taxes', '0'),
('receipt_show_total_discount', '1'),
('receipt_show_description', '1'),
('receipt_show_serialnumber', '1'),
('invoice_enable', '1'),
('recv_invoice_format', '$CO'),
('sales_invoice_format', '$CO'),
('invoice_email_message', 'Dear $CU, In attachment the receipt for sale $INV'),
('invoice_default_comments', 'This is a default comment'),
('print_silently', '1'),
('print_header', '0'),
('print_footer', '0'),
('print_top_margin', '0'),
('print_left_margin', '0'),
('print_bottom_margin', '0'),
('print_right_margin', '0'),
('default_sales_discount', '0'),
('lines_per_page', '25'),
('dateformat', 'm/d/Y'),
('timeformat', 'H:i:s'),
('currency_symbol', '$'),
('number_locale', 'en_US'),
('thousands_separator', '1'),
('currency_decimals', '2'),
('tax_decimals', '2'),
('quantity_decimals', '0'),
('country_codes', 'us'),
('msg_msg', ''),
('msg_uid', ''),
('msg_src', ''),
('msg_pwd', ''),
('notify_horizontal_position', 'center'),
('notify_vertical_position', 'bottom'),
('payment_options_order', 'cashdebitcredit'),
('protocol', 'mail'),
('mailpath', '/usr/sbin/sendmail'),
('smtp_port', '465'),
('smtp_timeout', '5'),
('smtp_crypto', 'ssl'),
('receipt_template', 'receipt_default'),
('theme', 'flatly'),
('statistics', '1'),
('language', 'english'),
('language_code', 'en');
-- --------------------------------------------------------
@@ -92,14 +92,14 @@ INSERT INTO `ospos_app_config` (`key`, `value`) VALUES
--
CREATE TABLE `ospos_customers` (
`person_id` int(10) NOT NULL,
`company_name` varchar(255) DEFAULT NULL,
`account_number` varchar(255) DEFAULT NULL,
`taxable` int(1) NOT NULL DEFAULT '1',
`discount_percent` decimal(15,2) NOT NULL DEFAULT '0',
`deleted` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY `person_id` (`person_id`),
UNIQUE KEY `account_number` (`account_number`)
`person_id` int(10) NOT NULL,
`company_name` varchar(255) DEFAULT NULL,
`account_number` varchar(255) DEFAULT NULL,
`taxable` int(1) NOT NULL DEFAULT '1',
`discount_percent` decimal(15,2) NOT NULL DEFAULT '0',
`deleted` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY `person_id` (`person_id`),
UNIQUE KEY `account_number` (`account_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -114,13 +114,13 @@ CREATE TABLE `ospos_customers` (
--
CREATE TABLE `ospos_employees` (
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`person_id` int(10) NOT NULL,
`deleted` int(1) NOT NULL DEFAULT '0',
`hash_version` int(1) NOT NULL DEFAULT '2',
PRIMARY KEY `person_id` (`person_id`),
UNIQUE KEY `username` (`username`)
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`person_id` int(10) NOT NULL,
`deleted` int(1) NOT NULL DEFAULT '0',
`hash_version` int(1) NOT NULL DEFAULT '2',
PRIMARY KEY `person_id` (`person_id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -128,7 +128,7 @@ CREATE TABLE `ospos_employees` (
--
INSERT INTO `ospos_employees` (`username`, `password`, `person_id`, `deleted`, `hash_version`) VALUES
('admin', '$2y$10$vJBSMlD02EC7ENSrKfVQXuvq9tNRHMtcOA8MSK2NYS748HHWm.gcG', 1, 0, 2);
('admin', '$2y$10$vJBSMlD02EC7ENSrKfVQXuvq9tNRHMtcOA8MSK2NYS748HHWm.gcG', 1, 0, 2);
-- --------------------------------------------------------
@@ -137,15 +137,15 @@ INSERT INTO `ospos_employees` (`username`, `password`, `person_id`, `deleted`, `
--
CREATE TABLE `ospos_giftcards` (
`record_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`giftcard_id` int(11) NOT NULL AUTO_INCREMENT,
`giftcard_number` int(10) NOT NULL,
`value` decimal(15,2) NOT NULL,
`deleted` int(1) NOT NULL DEFAULT '0',
`person_id` INT(10) DEFAULT NULL,
PRIMARY KEY (`giftcard_id`),
UNIQUE KEY `giftcard_number` (`giftcard_number`),
KEY `person_id` (`person_id`)
`record_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`giftcard_id` int(11) NOT NULL AUTO_INCREMENT,
`giftcard_number` int(10) NOT NULL,
`value` decimal(15,2) NOT NULL,
`deleted` int(1) NOT NULL DEFAULT '0',
`person_id` INT(10) DEFAULT NULL,
PRIMARY KEY (`giftcard_id`),
UNIQUE KEY `giftcard_number` (`giftcard_number`),
KEY `person_id` (`person_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -160,17 +160,17 @@ CREATE TABLE `ospos_giftcards` (
--
CREATE TABLE `ospos_inventory` (
`trans_id` int(11) NOT NULL AUTO_INCREMENT,
`trans_items` int(11) NOT NULL DEFAULT '0',
`trans_user` int(11) NOT NULL DEFAULT '0',
`trans_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`trans_comment` text NOT NULL,
`trans_location` int(11) NOT NULL,
`trans_inventory` decimal(15,3) NOT NULL DEFAULT '0',
PRIMARY KEY (`trans_id`),
KEY `trans_items` (`trans_items`),
KEY `trans_user` (`trans_user`),
KEY `trans_location` (`trans_location`)
`trans_id` int(11) NOT NULL AUTO_INCREMENT,
`trans_items` int(11) NOT NULL DEFAULT '0',
`trans_user` int(11) NOT NULL DEFAULT '0',
`trans_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`trans_comment` text NOT NULL,
`trans_location` int(11) NOT NULL,
`trans_inventory` decimal(15,3) NOT NULL DEFAULT '0',
PRIMARY KEY (`trans_id`),
KEY `trans_items` (`trans_items`),
KEY `trans_user` (`trans_user`),
KEY `trans_location` (`trans_location`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
--
@@ -185,33 +185,33 @@ CREATE TABLE `ospos_inventory` (
--
CREATE TABLE `ospos_items` (
`name` varchar(255) NOT NULL,
`category` varchar(255) NOT NULL,
`supplier_id` int(11) DEFAULT NULL,
`item_number` varchar(255) DEFAULT NULL,
`description` varchar(255) NOT NULL,
`cost_price` decimal(15,2) NOT NULL,
`unit_price` decimal(15,2) NOT NULL,
`reorder_level` decimal(15,3) NOT NULL DEFAULT '0',
`receiving_quantity` decimal(15,3) NOT NULL DEFAULT '1',
`item_id` int(10) NOT NULL AUTO_INCREMENT,
`pic_id` int(10) DEFAULT NULL,
`allow_alt_description` tinyint(1) NOT NULL,
`is_serialized` tinyint(1) NOT NULL,
`deleted` int(1) NOT NULL DEFAULT '0',
`custom1` VARCHAR(25) NOT NULL,
`custom2` VARCHAR(25) NOT NULL,
`custom3` VARCHAR(25) NOT NULL,
`custom4` VARCHAR(25) NOT NULL,
`custom5` VARCHAR(25) NOT NULL,
`custom6` VARCHAR(25) NOT NULL,
`custom7` VARCHAR(25) NOT NULL,
`custom8` VARCHAR(25) NOT NULL,
`custom9` VARCHAR(25) NOT NULL,
`custom10` VARCHAR(25) NOT NULL,
PRIMARY KEY (`item_id`),
UNIQUE KEY `item_number` (`item_number`),
KEY `supplier_id` (`supplier_id`)
`name` varchar(255) NOT NULL,
`category` varchar(255) NOT NULL,
`supplier_id` int(11) DEFAULT NULL,
`item_number` varchar(255) DEFAULT NULL,
`description` varchar(255) NOT NULL,
`cost_price` decimal(15,2) NOT NULL,
`unit_price` decimal(15,2) NOT NULL,
`reorder_level` decimal(15,3) NOT NULL DEFAULT '0',
`receiving_quantity` decimal(15,3) NOT NULL DEFAULT '1',
`item_id` int(10) NOT NULL AUTO_INCREMENT,
`pic_id` int(10) DEFAULT NULL,
`allow_alt_description` tinyint(1) NOT NULL,
`is_serialized` tinyint(1) NOT NULL,
`deleted` int(1) NOT NULL DEFAULT '0',
`custom1` VARCHAR(25) NOT NULL,
`custom2` VARCHAR(25) NOT NULL,
`custom3` VARCHAR(25) NOT NULL,
`custom4` VARCHAR(25) NOT NULL,
`custom5` VARCHAR(25) NOT NULL,
`custom6` VARCHAR(25) NOT NULL,
`custom7` VARCHAR(25) NOT NULL,
`custom8` VARCHAR(25) NOT NULL,
`custom9` VARCHAR(25) NOT NULL,
`custom10` VARCHAR(25) NOT NULL,
PRIMARY KEY (`item_id`),
UNIQUE KEY `item_number` (`item_number`),
KEY `supplier_id` (`supplier_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
--
@@ -226,10 +226,10 @@ CREATE TABLE `ospos_items` (
--
CREATE TABLE `ospos_items_taxes` (
`item_id` int(10) NOT NULL,
`name` varchar(255) NOT NULL,
`percent` decimal(15,3) NOT NULL,
PRIMARY KEY (`item_id`,`name`,`percent`)
`item_id` int(10) NOT NULL,
`name` varchar(255) NOT NULL,
`percent` decimal(15,3) NOT NULL,
PRIMARY KEY (`item_id`,`name`,`percent`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -244,10 +244,10 @@ CREATE TABLE `ospos_items_taxes` (
--
CREATE TABLE `ospos_item_kits` (
`item_kit_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`description` varchar(255) NOT NULL,
PRIMARY KEY (`item_kit_id`)
`item_kit_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`description` varchar(255) NOT NULL,
PRIMARY KEY (`item_kit_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
--
@@ -262,11 +262,11 @@ CREATE TABLE `ospos_item_kits` (
--
CREATE TABLE `ospos_item_kit_items` (
`item_kit_id` int(11) NOT NULL,
`item_id` int(11) NOT NULL,
`quantity` decimal(15,3) NOT NULL,
PRIMARY KEY (`item_kit_id`,`item_id`,`quantity`),
KEY `ospos_item_kit_items_ibfk_2` (`item_id`)
`item_kit_id` int(11) NOT NULL,
`item_id` int(11) NOT NULL,
`quantity` decimal(15,3) NOT NULL,
PRIMARY KEY (`item_kit_id`,`item_id`,`quantity`),
KEY `ospos_item_kit_items_ibfk_2` (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -280,12 +280,12 @@ CREATE TABLE `ospos_item_kit_items` (
--
CREATE TABLE IF NOT EXISTS `ospos_item_quantities` (
`item_id` int(11) NOT NULL,
`location_id` int(11) NOT NULL,
`quantity` decimal(15,3) NOT NULL DEFAULT '0',
PRIMARY KEY (`item_id`,`location_id`),
KEY `item_id` (`item_id`),
KEY `location_id` (`location_id`)
`item_id` int(11) NOT NULL,
`location_id` int(11) NOT NULL,
`quantity` decimal(15,3) NOT NULL DEFAULT '0',
PRIMARY KEY (`item_id`,`location_id`),
KEY `item_id` (`item_id`),
KEY `location_id` (`location_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
-- --------------------------------------------------------
@@ -295,13 +295,13 @@ CREATE TABLE IF NOT EXISTS `ospos_item_quantities` (
--
CREATE TABLE `ospos_modules` (
`name_lang_key` varchar(255) NOT NULL,
`desc_lang_key` varchar(255) NOT NULL,
`sort` int(10) NOT NULL,
`module_id` varchar(255) NOT NULL,
PRIMARY KEY (`module_id`),
UNIQUE KEY `desc_lang_key` (`desc_lang_key`),
UNIQUE KEY `name_lang_key` (`name_lang_key`)
`name_lang_key` varchar(255) NOT NULL,
`desc_lang_key` varchar(255) NOT NULL,
`sort` int(10) NOT NULL,
`module_id` varchar(255) NOT NULL,
PRIMARY KEY (`module_id`),
UNIQUE KEY `desc_lang_key` (`desc_lang_key`),
UNIQUE KEY `name_lang_key` (`name_lang_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -309,17 +309,17 @@ CREATE TABLE `ospos_modules` (
--
INSERT INTO `ospos_modules` (`name_lang_key`, `desc_lang_key`, `sort`, `module_id`) VALUES
('module_config', 'module_config_desc', 110, 'config'),
('module_customers', 'module_customers_desc', 10, 'customers'),
('module_employees', 'module_employees_desc', 80, 'employees'),
('module_giftcards', 'module_giftcards_desc', 90, 'giftcards'),
('module_items', 'module_items_desc', 20, 'items'),
('module_item_kits', 'module_item_kits_desc', 30, 'item_kits'),
('module_messages', 'module_messages_desc', 100, 'messages'),
('module_receivings', 'module_receivings_desc', 60, 'receivings'),
('module_reports', 'module_reports_desc', 50, 'reports'),
('module_sales', 'module_sales_desc', 70, 'sales'),
('module_suppliers', 'module_suppliers_desc', 40, 'suppliers');
('module_config', 'module_config_desc', 110, 'config'),
('module_customers', 'module_customers_desc', 10, 'customers'),
('module_employees', 'module_employees_desc', 80, 'employees'),
('module_giftcards', 'module_giftcards_desc', 90, 'giftcards'),
('module_items', 'module_items_desc', 20, 'items'),
('module_item_kits', 'module_item_kits_desc', 30, 'item_kits'),
('module_messages', 'module_messages_desc', 100, 'messages'),
('module_receivings', 'module_receivings_desc', 60, 'receivings'),
('module_reports', 'module_reports_desc', 50, 'reports'),
('module_sales', 'module_sales_desc', 70, 'sales'),
('module_suppliers', 'module_suppliers_desc', 40, 'suppliers');
-- --------------------------------------------------------
@@ -328,20 +328,20 @@ INSERT INTO `ospos_modules` (`name_lang_key`, `desc_lang_key`, `sort`, `module_i
--
CREATE TABLE `ospos_people` (
`first_name` varchar(255) NOT NULL,
`last_name` varchar(255) NOT NULL,
`gender` int(1) DEFAULT NULL,
`phone_number` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`address_1` varchar(255) NOT NULL,
`address_2` varchar(255) NOT NULL,
`city` varchar(255) NOT NULL,
`state` varchar(255) NOT NULL,
`zip` varchar(255) NOT NULL,
`country` varchar(255) NOT NULL,
`comments` text NOT NULL,
`person_id` int(10) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`person_id`)
`first_name` varchar(255) NOT NULL,
`last_name` varchar(255) NOT NULL,
`gender` int(1) DEFAULT NULL,
`phone_number` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`address_1` varchar(255) NOT NULL,
`address_2` varchar(255) NOT NULL,
`city` varchar(255) NOT NULL,
`state` varchar(255) NOT NULL,
`zip` varchar(255) NOT NULL,
`country` varchar(255) NOT NULL,
`comments` text NOT NULL,
`person_id` int(10) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`person_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
--
@@ -349,7 +349,7 @@ CREATE TABLE `ospos_people` (
--
INSERT INTO `ospos_people` (`first_name`, `last_name`, `phone_number`, `email`, `address_1`, `address_2`, `city`, `state`, `zip`, `country`, `comments`, `person_id`) VALUES
('John', 'Doe', '555-555-5555', 'changeme@example.com', 'Address 1', '', '', '', '', '', '', 1);
('John', 'Doe', '555-555-5555', 'changeme@example.com', 'Address 1', '', '', '', '', '', '', 1);
-- --------------------------------------------------------
@@ -358,11 +358,11 @@ INSERT INTO `ospos_people` (`first_name`, `last_name`, `phone_number`, `email`,
--
CREATE TABLE `ospos_permissions` (
`permission_id` varchar(255) NOT NULL,
`module_id` varchar(255) NOT NULL,
`location_id` int(10) DEFAULT NULL,
PRIMARY KEY (`permission_id`),
KEY `module_id` (`module_id`)
`permission_id` varchar(255) NOT NULL,
`module_id` varchar(255) NOT NULL,
`location_id` int(10) DEFAULT NULL,
PRIMARY KEY (`permission_id`),
KEY `module_id` (`module_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -370,33 +370,33 @@ CREATE TABLE `ospos_permissions` (
--
INSERT INTO `ospos_permissions` (`permission_id`, `module_id`) VALUES
('reports_customers', 'reports'),
('reports_receivings', 'reports'),
('reports_items', 'reports'),
('reports_employees', 'reports'),
('reports_suppliers', 'reports'),
('reports_sales', 'reports'),
('reports_discounts', 'reports'),
('reports_taxes', 'reports'),
('reports_inventory', 'reports'),
('reports_categories', 'reports'),
('reports_payments', 'reports'),
('customers', 'customers'),
('employees', 'employees'),
('giftcards', 'giftcards'),
('items', 'items'),
('item_kits', 'item_kits'),
('messages', 'messages'),
('receivings', 'receivings'),
('reports', 'reports'),
('sales', 'sales'),
('config', 'config'),
('suppliers', 'suppliers');
('reports_customers', 'reports'),
('reports_receivings', 'reports'),
('reports_items', 'reports'),
('reports_employees', 'reports'),
('reports_suppliers', 'reports'),
('reports_sales', 'reports'),
('reports_discounts', 'reports'),
('reports_taxes', 'reports'),
('reports_inventory', 'reports'),
('reports_categories', 'reports'),
('reports_payments', 'reports'),
('customers', 'customers'),
('employees', 'employees'),
('giftcards', 'giftcards'),
('items', 'items'),
('item_kits', 'item_kits'),
('messages', 'messages'),
('receivings', 'receivings'),
('reports', 'reports'),
('sales', 'sales'),
('config', 'config'),
('suppliers', 'suppliers');
INSERT INTO `ospos_permissions` (`permission_id`, `module_id`, `location_id`) VALUES
('items_stock', 'items', 1),
('sales_stock', 'sales', 1),
('receivings_stock', 'receivings', 1);
('items_stock', 'items', 1),
('sales_stock', 'sales', 1),
('receivings_stock', 'receivings', 1);
-- --------------------------------------------------------
@@ -405,9 +405,9 @@ INSERT INTO `ospos_permissions` (`permission_id`, `module_id`, `location_id`) VA
--
CREATE TABLE `ospos_grants` (
`permission_id` varchar(255) NOT NULL,
`person_id` int(10) NOT NULL,
PRIMARY KEY (`permission_id`,`person_id`)
`permission_id` varchar(255) NOT NULL,
`person_id` int(10) NOT NULL,
PRIMARY KEY (`permission_id`,`person_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -416,48 +416,48 @@ CREATE TABLE `ospos_grants` (
-- --------------------------------------------------------
INSERT INTO `ospos_grants` (`permission_id`, `person_id`) VALUES
('reports_customers', 1),
('reports_receivings', 1),
('reports_items', 1),
('reports_inventory', 1),
('reports_employees', 1),
('reports_suppliers', 1),
('reports_sales', 1),
('reports_discounts', 1),
('reports_taxes', 1),
('reports_categories', 1),
('reports_payments', 1),
('customers', 1),
('employees', 1),
('giftcards', 1),
('items', 1),
('item_kits', 1),
('messages', 1),
('receivings', 1),
('reports', 1),
('sales', 1),
('config', 1),
('items_stock', 1),
('sales_stock', 1),
('receivings_stock', 1),
('suppliers', 1);
('reports_customers', 1),
('reports_receivings', 1),
('reports_items', 1),
('reports_inventory', 1),
('reports_employees', 1),
('reports_suppliers', 1),
('reports_sales', 1),
('reports_discounts', 1),
('reports_taxes', 1),
('reports_categories', 1),
('reports_payments', 1),
('customers', 1),
('employees', 1),
('giftcards', 1),
('items', 1),
('item_kits', 1),
('messages', 1),
('receivings', 1),
('reports', 1),
('sales', 1),
('config', 1),
('items_stock', 1),
('sales_stock', 1),
('receivings_stock', 1),
('suppliers', 1);
--
-- Table structure for table `ospos_receivings`
--
CREATE TABLE `ospos_receivings` (
`receiving_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`supplier_id` int(10) DEFAULT NULL,
`employee_id` int(10) NOT NULL DEFAULT '0',
`comment` text NOT NULL,
`receiving_id` int(10) NOT NULL AUTO_INCREMENT,
`payment_type` varchar(20) DEFAULT NULL,
`reference` varchar(32) DEFAULT NULL,
PRIMARY KEY (`receiving_id`),
KEY `supplier_id` (`supplier_id`),
KEY `employee_id` (`employee_id`),
KEY `reference` (`reference`)
`receiving_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`supplier_id` int(10) DEFAULT NULL,
`employee_id` int(10) NOT NULL DEFAULT '0',
`comment` text NOT NULL,
`receiving_id` int(10) NOT NULL AUTO_INCREMENT,
`payment_type` varchar(20) DEFAULT NULL,
`reference` varchar(32) DEFAULT NULL,
PRIMARY KEY (`receiving_id`),
KEY `supplier_id` (`supplier_id`),
KEY `employee_id` (`employee_id`),
KEY `reference` (`reference`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
--
@@ -472,19 +472,19 @@ CREATE TABLE `ospos_receivings` (
--
CREATE TABLE `ospos_receivings_items` (
`receiving_id` int(10) NOT NULL DEFAULT '0',
`item_id` int(10) NOT NULL DEFAULT '0',
`description` varchar(30) DEFAULT NULL,
`serialnumber` varchar(30) DEFAULT NULL,
`line` int(3) NOT NULL,
`quantity_purchased` decimal(15,3) NOT NULL DEFAULT '0',
`item_cost_price` decimal(15,2) NOT NULL,
`item_unit_price` decimal(15,2) NOT NULL,
`discount_percent` decimal(15,2) NOT NULL DEFAULT '0',
`item_location` int(11) NOT NULL,
`receiving_quantity` decimal(15,3) NOT NULL DEFAULT '1',
PRIMARY KEY (`receiving_id`,`item_id`,`line`),
KEY `item_id` (`item_id`)
`receiving_id` int(10) NOT NULL DEFAULT '0',
`item_id` int(10) NOT NULL DEFAULT '0',
`description` varchar(30) DEFAULT NULL,
`serialnumber` varchar(30) DEFAULT NULL,
`line` int(3) NOT NULL,
`quantity_purchased` decimal(15,3) NOT NULL DEFAULT '0',
`item_cost_price` decimal(15,2) NOT NULL,
`item_unit_price` decimal(15,2) NOT NULL,
`discount_percent` decimal(15,2) NOT NULL DEFAULT '0',
`item_location` int(11) NOT NULL,
`receiving_quantity` decimal(15,3) NOT NULL DEFAULT '1',
PRIMARY KEY (`receiving_id`,`item_id`,`line`),
KEY `item_id` (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -499,17 +499,17 @@ CREATE TABLE `ospos_receivings_items` (
--
CREATE TABLE `ospos_sales` (
`sale_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`customer_id` int(10) DEFAULT NULL,
`employee_id` int(10) NOT NULL DEFAULT '0',
`comment` text NOT NULL,
`invoice_number` varchar(32) DEFAULT NULL,
`sale_id` int(10) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`sale_id`),
KEY `customer_id` (`customer_id`),
KEY `employee_id` (`employee_id`),
KEY `sale_time` (`sale_time`),
UNIQUE KEY `invoice_number` (`invoice_number`)
`sale_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`customer_id` int(10) DEFAULT NULL,
`employee_id` int(10) NOT NULL DEFAULT '0',
`comment` text NOT NULL,
`invoice_number` varchar(32) DEFAULT NULL,
`sale_id` int(10) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`sale_id`),
KEY `customer_id` (`customer_id`),
KEY `employee_id` (`employee_id`),
KEY `sale_time` (`sale_time`),
UNIQUE KEY `invoice_number` (`invoice_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
--
@@ -524,20 +524,20 @@ CREATE TABLE `ospos_sales` (
--
CREATE TABLE `ospos_sales_items` (
`sale_id` int(10) NOT NULL DEFAULT '0',
`item_id` int(10) NOT NULL DEFAULT '0',
`description` varchar(30) DEFAULT NULL,
`serialnumber` varchar(30) DEFAULT NULL,
`line` int(3) NOT NULL DEFAULT '0',
`quantity_purchased` decimal(15,3) NOT NULL DEFAULT '0',
`item_cost_price` decimal(15,2) NOT NULL,
`item_unit_price` decimal(15,2) NOT NULL,
`discount_percent` decimal(15,2) NOT NULL DEFAULT '0',
`item_location` int(11) NOT NULL,
PRIMARY KEY (`sale_id`,`item_id`,`line`),
KEY `sale_id` (`sale_id`),
KEY `item_id` (`item_id`),
KEY `item_location` (`item_location`)
`sale_id` int(10) NOT NULL DEFAULT '0',
`item_id` int(10) NOT NULL DEFAULT '0',
`description` varchar(30) DEFAULT NULL,
`serialnumber` varchar(30) DEFAULT NULL,
`line` int(3) NOT NULL DEFAULT '0',
`quantity_purchased` decimal(15,3) NOT NULL DEFAULT '0',
`item_cost_price` decimal(15,2) NOT NULL,
`item_unit_price` decimal(15,2) NOT NULL,
`discount_percent` decimal(15,2) NOT NULL DEFAULT '0',
`item_location` int(11) NOT NULL,
PRIMARY KEY (`sale_id`,`item_id`,`line`),
KEY `sale_id` (`sale_id`),
KEY `item_id` (`item_id`),
KEY `item_location` (`item_location`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -552,14 +552,14 @@ CREATE TABLE `ospos_sales_items` (
--
CREATE TABLE `ospos_sales_items_taxes` (
`sale_id` int(10) NOT NULL,
`item_id` int(10) NOT NULL,
`line` int(3) NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`percent` decimal(15,3) NOT NULL,
PRIMARY KEY (`sale_id`,`item_id`,`line`,`name`,`percent`),
KEY `sale_id` (`sale_id`),
KEY `item_id` (`item_id`)
`sale_id` int(10) NOT NULL,
`item_id` int(10) NOT NULL,
`line` int(3) NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`percent` decimal(15,3) NOT NULL,
PRIMARY KEY (`sale_id`,`item_id`,`line`,`name`,`percent`),
KEY `sale_id` (`sale_id`),
KEY `item_id` (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -573,11 +573,11 @@ CREATE TABLE `ospos_sales_items_taxes` (
--
CREATE TABLE `ospos_sales_payments` (
`sale_id` int(10) NOT NULL,
`payment_type` varchar(40) NOT NULL,
`payment_amount` decimal(15,2) NOT NULL,
PRIMARY KEY (`sale_id`,`payment_type`),
KEY `sale_id` (`sale_id`)
`sale_id` int(10) NOT NULL,
`payment_type` varchar(40) NOT NULL,
`payment_amount` decimal(15,2) NOT NULL,
PRIMARY KEY (`sale_id`,`payment_type`),
KEY `sale_id` (`sale_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -592,15 +592,15 @@ CREATE TABLE `ospos_sales_payments` (
--
CREATE TABLE `ospos_sales_suspended` (
`sale_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`customer_id` int(10) DEFAULT NULL,
`employee_id` int(10) NOT NULL DEFAULT '0',
`comment` text NOT NULL,
`invoice_number` varchar(32) DEFAULT NULL,
`sale_id` int(10) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`sale_id`),
KEY `customer_id` (`customer_id`),
KEY `employee_id` (`employee_id`)
`sale_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`customer_id` int(10) DEFAULT NULL,
`employee_id` int(10) NOT NULL DEFAULT '0',
`comment` text NOT NULL,
`invoice_number` varchar(32) DEFAULT NULL,
`sale_id` int(10) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`sale_id`),
KEY `customer_id` (`customer_id`),
KEY `employee_id` (`employee_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
--
@@ -615,19 +615,19 @@ CREATE TABLE `ospos_sales_suspended` (
--
CREATE TABLE `ospos_sales_suspended_items` (
`sale_id` int(10) NOT NULL DEFAULT '0',
`item_id` int(10) NOT NULL DEFAULT '0',
`description` varchar(30) DEFAULT NULL,
`serialnumber` varchar(30) DEFAULT NULL,
`line` int(3) NOT NULL DEFAULT '0',
`quantity_purchased` decimal(15,3) NOT NULL DEFAULT '0',
`item_cost_price` decimal(15,2) NOT NULL,
`item_unit_price` decimal(15,2) NOT NULL,
`discount_percent` decimal(15,2) NOT NULL DEFAULT '0',
`item_location` int(11) NOT NULL,
PRIMARY KEY (`sale_id`,`item_id`,`line`),
KEY `sale_id` (`sale_id`),
KEY `item_id` (`item_id`)
`sale_id` int(10) NOT NULL DEFAULT '0',
`item_id` int(10) NOT NULL DEFAULT '0',
`description` varchar(30) DEFAULT NULL,
`serialnumber` varchar(30) DEFAULT NULL,
`line` int(3) NOT NULL DEFAULT '0',
`quantity_purchased` decimal(15,3) NOT NULL DEFAULT '0',
`item_cost_price` decimal(15,2) NOT NULL,
`item_unit_price` decimal(15,2) NOT NULL,
`discount_percent` decimal(15,2) NOT NULL DEFAULT '0',
`item_location` int(11) NOT NULL,
PRIMARY KEY (`sale_id`,`item_id`,`line`),
KEY `sale_id` (`sale_id`),
KEY `item_id` (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -642,13 +642,13 @@ CREATE TABLE `ospos_sales_suspended_items` (
--
CREATE TABLE `ospos_sales_suspended_items_taxes` (
`sale_id` int(10) NOT NULL,
`item_id` int(10) NOT NULL,
`line` int(3) NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`percent` decimal(15,3) NOT NULL,
PRIMARY KEY (`sale_id`,`item_id`,`line`,`name`,`percent`),
KEY `item_id` (`item_id`)
`sale_id` int(10) NOT NULL,
`item_id` int(10) NOT NULL,
`line` int(3) NOT NULL DEFAULT '0',
`name` varchar(255) NOT NULL,
`percent` decimal(15,3) NOT NULL,
PRIMARY KEY (`sale_id`,`item_id`,`line`,`name`,`percent`),
KEY `item_id` (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -663,10 +663,10 @@ CREATE TABLE `ospos_sales_suspended_items_taxes` (
--
CREATE TABLE `ospos_sales_suspended_payments` (
`sale_id` int(10) NOT NULL,
`payment_type` varchar(40) NOT NULL,
`payment_amount` decimal(15,2) NOT NULL,
PRIMARY KEY (`sale_id`,`payment_type`)
`sale_id` int(10) NOT NULL,
`payment_type` varchar(40) NOT NULL,
`payment_amount` decimal(15,2) NOT NULL,
PRIMARY KEY (`sale_id`,`payment_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -681,11 +681,11 @@ CREATE TABLE `ospos_sales_suspended_payments` (
--
CREATE TABLE `ospos_sessions` (
`id` varchar(40) NOT NULL,
`ip_address` varchar(45) NOT NULL,
`timestamp` int(10) unsigned DEFAULT 0 NOT NULL,
`data` blob NOT NULL,
KEY `ci_sessions_timestamp` (`timestamp`)
`id` varchar(40) NOT NULL,
`ip_address` varchar(45) NOT NULL,
`timestamp` int(10) unsigned DEFAULT 0 NOT NULL,
`data` blob NOT NULL,
KEY `ci_sessions_timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
@@ -699,10 +699,10 @@ CREATE TABLE `ospos_sessions` (
--
CREATE TABLE `ospos_stock_locations` (
`location_id` int(11) NOT NULL AUTO_INCREMENT,
`location_name` varchar(255) DEFAULT NULL,
`deleted` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`location_id`)
`location_id` int(11) NOT NULL AUTO_INCREMENT,
`location_name` varchar(255) DEFAULT NULL,
`deleted` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`location_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
--
@@ -718,13 +718,13 @@ INSERT INTO `ospos_stock_locations` ( `deleted`, `location_name` ) VALUES ('0',
--
CREATE TABLE `ospos_suppliers` (
`person_id` int(10) NOT NULL,
`company_name` varchar(255) NOT NULL,
`agency_name` varchar(255) NOT NULL,
`account_number` varchar(255) DEFAULT NULL,
`deleted` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY `person_id` (`person_id`),
UNIQUE KEY `account_number` (`account_number`)
`person_id` int(10) NOT NULL,
`company_name` varchar(255) NOT NULL,
`agency_name` varchar(255) NOT NULL,
`account_number` varchar(255) DEFAULT NULL,
`deleted` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY `person_id` (`person_id`),
UNIQUE KEY `account_number` (`account_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--

View File

@@ -7,74 +7,74 @@ use Config\App;
class Db_log
{
private App $config;
private App $config;
/**
* @return void
*/
public function db_log_queries(): void
{
$this->config = config('App');
/**
* @return void
*/
public function db_log_queries(): void
{
$this->config = config('App');
if($this->config->db_log_enabled)
{
$filepath = WRITEPATH . 'logs/Query-log-' . date('Y-m-d') . '.log';
$handle = fopen($filepath, "a+");
$message = $this->generate_message();
if($this->config->db_log_enabled)
{
$filepath = WRITEPATH . 'logs/Query-log-' . date('Y-m-d') . '.log';
$handle = fopen($filepath, "a+");
$message = $this->generate_message();
if(strlen($message) > 0)
{
fwrite($handle, $message . "\n\n");
}
if(strlen($message) > 0)
{
fwrite($handle, $message . "\n\n");
}
// Close the file
fclose($handle);
}
}
// Close the file
fclose($handle);
}
}
/**
* @return string
*/
private function generate_message(): string
{
$db = Database::connect();
$last_query = $db->getLastQuery();
$affected_rows = $db->affectedRows();
$execution_time = $this->convert_time($last_query->getDuration());
/**
* @return string
*/
private function generate_message(): string
{
$db = Database::connect();
$last_query = $db->getLastQuery();
$affected_rows = $db->affectedRows();
$execution_time = $this->convert_time($last_query->getDuration());
$message = '*** Query: ' . date('Y-m-d H:i:s T') . ' *******************'
. "\n" . $last_query->getQuery()
. "\n Affected rows: $affected_rows"
. "\n Execution Time: " . $execution_time['time'] . ' ' . $execution_time['unit'];
$message = '*** Query: ' . date('Y-m-d H:i:s T') . ' *******************'
. "\n" . $last_query->getQuery()
. "\n Affected rows: $affected_rows"
. "\n Execution Time: " . $execution_time['time'] . ' ' . $execution_time['unit'];
$long_query = ($execution_time['unit'] === 's') && ($execution_time['time'] > 0.5);
if($long_query)
{
$message .= ' [LONG RUNNING QUERY]';
}
$long_query = ($execution_time['unit'] === 's') && ($execution_time['time'] > 0.5);
if($long_query)
{
$message .= ' [LONG RUNNING QUERY]';
}
return $this->config->db_log_only_long && !$long_query ? '' : $message;
}
return $this->config->db_log_only_long && !$long_query ? '' : $message;
}
/**
* @param float $time
* @return array
*/
private function convert_time(float $time): array
{
$unit = 's';
/**
* @param float $time
* @return array
*/
private function convert_time(float $time): array
{
$unit = 's';
if($time <= 0.1 && $time > 0.0001)
{
$time = $time * 1000;
$unit = 'ms';
}
elseif($time <= 0.0001)
{
$time = $time * 1000000;
$unit = 'µs';
}
if($time <= 0.1 && $time > 0.0001)
{
$time = $time * 1000;
$unit = 'ms';
}
elseif($time <= 0.0001)
{
$time = $time * 1000000;
$unit = 'µs';
}
return ['time' => $time, 'unit' => $unit];
}
return ['time' => $time, 'unit' => $unit];
}
}

View File

@@ -17,42 +17,42 @@ use Config\Services;
*/
class Load_config
{
public Session $session;
public Session $session;
/**
* Loads configuration from database into App CI config and then applies those settings
*/
public function load_config(): void
{
//Migrations
$migration_config = config('Migrations');
$migration = new MY_Migration($migration_config);
/**
* Loads configuration from database into App CI config and then applies those settings
*/
public function load_config(): void
{
//Migrations
$migration_config = config('Migrations');
$migration = new MY_Migration($migration_config);
$this->session = session();
$this->session = session();
//Database Configuration
$config = config(OSPOS::class);
//Database Configuration
$config = config(OSPOS::class);
if (!$migration->is_latest())
{
$this->session->destroy();
}
if (!$migration->is_latest())
{
$this->session->destroy();
}
//Language
$language_exists = file_exists('../app/Language/' . current_language_code());
//Language
$language_exists = file_exists('../app/Language/' . current_language_code());
if(current_language_code() == null || current_language() == null || !$language_exists) //TODO: current_language() is undefined
{
$config->settings['language'] = 'english';
$config->settings['language_code'] = 'en';
}
if(current_language_code() == null || current_language() == null || !$language_exists) //TODO: current_language() is undefined
{
$config->settings['language'] = 'english';
$config->settings['language_code'] = 'en';
}
$language = Services::language();
$language->setLocale($config->settings['language_code']);
$language = Services::language();
$language->setLocale($config->settings['language_code']);
//Time Zone
date_default_timezone_set($config->settings['timezone'] ?? ini_get('date.timezone'));
//Time Zone
date_default_timezone_set($config->settings['timezone'] ?? ini_get('date.timezone'));
bcscale(max(2, totals_decimals() + tax_decimals()));
}
bcscale(max(2, totals_decimals() + tax_decimals()));
}
}

View File

@@ -4,19 +4,19 @@ namespace App\Events;
class Method
{
/**
* @return void
*/
public static function validate_method(): void
{
$url = $_SERVER['REQUEST_URI'];
/**
* @return void
*/
public static function validate_method(): void
{
$url = $_SERVER['REQUEST_URI'];
$post_required = preg_match('/\/(save|delete*|remove*)\/?\d*?/', $url);
$post_required = preg_match('/\/(save|delete*|remove*)\/?\d*?/', $url);
if($post_required && $_SERVER["REQUEST_METHOD"] != "POST" && empty($_POST))
{
echo "Method not allowed";
die;
}
}
if($post_required && $_SERVER["REQUEST_METHOD"] != "POST" && empty($_POST))
{
echo "Method not allowed";
die;
}
}
}

View File

@@ -7,12 +7,12 @@
*/
function generate_import_items_csv(array $stock_locations, array $attributes): string
{
$csv_headers = pack('CCC',0xef,0xbb,0xbf); //Encode the Byte-Order Mark (BOM) so that UTF-8 File headers display properly in Microsoft Excel
$csv_headers .= 'Id,Barcode,"Item Name",Category,"Supplier ID","Cost Price","Unit Price","Tax 1 Name","Tax 1 Percent","Tax 2 Name","Tax 2 Percent","Reorder Level",Description,"Allow Alt Description","Item has Serial Number",Image,HSN';
$csv_headers .= generate_stock_location_headers($stock_locations);
$csv_headers .= generate_attribute_headers($attributes);
$csv_headers = pack('CCC',0xef,0xbb,0xbf); //Encode the Byte-Order Mark (BOM) so that UTF-8 File headers display properly in Microsoft Excel
$csv_headers .= 'Id,Barcode,"Item Name",Category,"Supplier ID","Cost Price","Unit Price","Tax 1 Name","Tax 1 Percent","Tax 2 Name","Tax 2 Percent","Reorder Level",Description,"Allow Alt Description","Item has Serial Number",Image,HSN';
$csv_headers .= generate_stock_location_headers($stock_locations);
$csv_headers .= generate_attribute_headers($attributes);
return $csv_headers;
return $csv_headers;
}
/**
@@ -21,14 +21,14 @@ function generate_import_items_csv(array $stock_locations, array $attributes): s
*/
function generate_stock_location_headers(array $locations): string
{
$location_headers = '';
$location_headers = '';
foreach($locations as $location_name)
{
$location_headers .= ',"location_' . $location_name . '"';
}
foreach($locations as $location_name)
{
$location_headers .= ',"location_' . $location_name . '"';
}
return $location_headers;
return $location_headers;
}
/**
@@ -37,15 +37,15 @@ function generate_stock_location_headers(array $locations): string
*/
function generate_attribute_headers(array $attribute_names): string
{
$attribute_headers = '';
unset($attribute_names[-1]);
$attribute_headers = '';
unset($attribute_names[-1]);
foreach($attribute_names as $attribute_name)
{
$attribute_headers .= ',"attribute_' . $attribute_name . '"';
}
foreach($attribute_names as $attribute_name)
{
$attribute_headers .= ',"attribute_' . $attribute_name . '"';
}
return $attribute_headers;
return $attribute_headers;
}
/**
@@ -55,34 +55,34 @@ function generate_attribute_headers(array $attribute_names): string
*/
function get_csv_file(string $file_name): array
{
$csv_rows = false;
$csv_rows = false;
if(($csv_file = fopen($file_name,'r')) !== false)
{
helper('security');
if(($csv_file = fopen($file_name,'r')) !== false)
{
helper('security');
$csv_rows = [];
$csv_rows = [];
//Skip Byte-Order Mark
if(bom_exists($csv_file))
{
fseek($csv_file, 3);
}
//Skip Byte-Order Mark
if(bom_exists($csv_file))
{
fseek($csv_file, 3);
}
$headers = fgetcsv($csv_file);
$headers = fgetcsv($csv_file);
while(($row = fgetcsv($csv_file)) !== false)
{
if($row !== [null])
{
$csv_rows[] = array_combine($headers, $row);
}
}
while(($row = fgetcsv($csv_file)) !== false)
{
if($row !== [null])
{
$csv_rows[] = array_combine($headers, $row);
}
}
fclose($csv_file);
}
fclose($csv_file);
}
return $csv_rows;
return $csv_rows;
}
/**
@@ -91,17 +91,17 @@ function get_csv_file(string $file_name): array
*/
function bom_exists(&$file_handle): bool
{
$result = false;
$candidate = fread($file_handle, 3);
$result = false;
$candidate = fread($file_handle, 3);
rewind($file_handle);
rewind($file_handle);
$bom = pack('CCC', 0xef, 0xbb, 0xbf);
$bom = pack('CCC', 0xef, 0xbb, 0xbf);
if (0 === strncmp($candidate, $bom, 3))
{
$result = true;
}
if (0 === strncmp($candidate, $bom, 3))
{
$result = true;
}
return $result;
return $result;
}

View File

@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>403 Forbidden</title>
<title>403 Forbidden</title>
</head>
<body>

View File

File diff suppressed because it is too large Load Diff

View File

@@ -7,29 +7,29 @@ use Config\Database;
*/
function execute_script(string $path): void
{
$version = preg_replace("/(.*_)?(.*).sql/", "$2", $path);
error_log("Migrating to $version (file: $path)");
$version = preg_replace("/(.*_)?(.*).sql/", "$2", $path);
error_log("Migrating to $version (file: $path)");
$sql = file_get_contents($path);
$sqls = explode(';', $sql);
array_pop($sqls);
$sql = file_get_contents($path);
$sqls = explode(';', $sql);
array_pop($sqls);
$db = Database::connect();
$db = Database::connect();
foreach($sqls as $statement)
{
$statement = "$statement;";
foreach($sqls as $statement)
{
$statement = "$statement;";
if(!$db->simpleQuery($statement))
{
foreach($db->error() as $error)
{
error_log("error: $error");
}
}
}
if(!$db->simpleQuery($statement))
{
foreach($db->error() as $error)
{
error_log("error: $error");
}
}
}
error_log("Migrated to $version");
error_log("Migrated to $version");
}
/**
@@ -40,27 +40,27 @@ function execute_script(string $path): void
*/
function drop_foreign_key_constraints(array $foreignKeys, string $table): void
{
$db = Database::connect();
$db = Database::connect();
$current_prefix = $db->getPrefix();
$db->setPrefix('');
$database_name = $db->database;
$current_prefix = $db->getPrefix();
$db->setPrefix('');
$database_name = $db->database;
foreach ($foreignKeys as $fk)
{
$builder = $db->table('INFORMATION_SCHEMA.TABLE_CONSTRAINTS');
$builder->select('CONSTRAINT_NAME');
$builder->where('TABLE_SCHEMA', $database_name);
$builder->where('TABLE_NAME', $table);
$builder->where('CONSTRAINT_TYPE', 'FOREIGN KEY');
$builder->where('CONSTRAINT_NAME', $fk);
$query = $builder->get();
foreach ($foreignKeys as $fk)
{
$builder = $db->table('INFORMATION_SCHEMA.TABLE_CONSTRAINTS');
$builder->select('CONSTRAINT_NAME');
$builder->where('TABLE_SCHEMA', $database_name);
$builder->where('TABLE_NAME', $table);
$builder->where('CONSTRAINT_TYPE', 'FOREIGN KEY');
$builder->where('CONSTRAINT_NAME', $fk);
$query = $builder->get();
if($query->getNumRows() > 0)
{
$db->query("ALTER TABLE `$table` DROP FOREIGN KEY `$fk`");
}
}
if($query->getNumRows() > 0)
{
$db->query("ALTER TABLE `$table` DROP FOREIGN KEY `$fk`");
}
}
$db->setPrefix($current_prefix);
$db->setPrefix($current_prefix);
}

View File

@@ -10,25 +10,25 @@ function get_report_link(string $report_name, string $report_prefix = '', string
{
$path = 'reports/';
if ($report_prefix !== '')
{
{
$path .= $report_prefix . '_';
}
/**
* Sanitize the report name in case it has come from the permissions table.
*/
$report_name = str_replace('reports_', '', $report_name);
$path .= $report_name;
$report_name = str_replace('reports_', '', $report_name);
$path .= $report_name;
if ($lang_key === '')
{
$lang_key = 'Reports.' . $report_name;
if ($lang_key === '')
{
$lang_key = 'Reports.' . $report_name;
}
return [
'path' => site_url($path),
'label' => lang($lang_key),
];
return [
'path' => site_url($path),
'label' => lang($lang_key),
];
}
/**
@@ -39,18 +39,18 @@ function get_report_link(string $report_name, string $report_prefix = '', string
*/
function can_show_report(string $permission_id, array $restrict_views = []): bool
{
if(!str_contains($permission_id, 'reports_'))
{
return false;
}
if(!str_contains($permission_id, 'reports_'))
{
return false;
}
foreach ($restrict_views as $restrict_view)
{
if (str_contains($permission_id, $restrict_view))
{
return false;
}
}
foreach ($restrict_views as $restrict_view)
{
if (str_contains($permission_id, $restrict_view))
{
return false;
}
}
return true;
return true;
}

View File

@@ -8,68 +8,68 @@ use Config\Services;
*/
function check_encryption(): bool
{
$old_key = config('Encryption')->key;
$old_key = config('Encryption')->key;
if((empty($old_key)) || (strlen($old_key) < 64))
{
//Create Key
$encryption = new Encryption();
$key = bin2hex($encryption->createKey());
config('Encryption')->key = $key;
if((empty($old_key)) || (strlen($old_key) < 64))
{
//Create Key
$encryption = new Encryption();
$key = bin2hex($encryption->createKey());
config('Encryption')->key = $key;
//Write to .env
$config_path = ROOTPATH . '.env';
$new_config_path = WRITEPATH . '/backup/.env' ;
$backup_path = WRITEPATH . '/backup/.env.bak';
//Write to .env
$config_path = ROOTPATH . '.env';
$new_config_path = WRITEPATH . '/backup/.env' ;
$backup_path = WRITEPATH . '/backup/.env.bak';
$backup_folder = WRITEPATH . '/backup';
$backup_folder = WRITEPATH . '/backup';
if (!file_exists($backup_folder) && !mkdir($backup_folder))
{
log_message('error', 'Could not create backup folder');
return false;
}
if (!file_exists($backup_folder) && !mkdir($backup_folder))
{
log_message('error', 'Could not create backup folder');
return false;
}
if(!copy($config_path, $backup_path))
{
log_message('error', "Unable to copy $config_path to $backup_path");
}
if(!copy($config_path, $backup_path))
{
log_message('error', "Unable to copy $config_path to $backup_path");
}
//Copy to backup
@chmod($config_path, 0660);
@chmod($backup_path, 0660);
//Copy to backup
@chmod($config_path, 0660);
@chmod($backup_path, 0660);
$config_file = file_get_contents($config_path);
$config_file = preg_replace("/(encryption\.key.*=.*)('.*')/", "$1'$key'", $config_file);
$config_file = file_get_contents($config_path);
$config_file = preg_replace("/(encryption\.key.*=.*)('.*')/", "$1'$key'", $config_file);
if(!empty($old_key))
{
$old_line = "# encryption.key = '$old_key' REMOVE IF UNNEEDED\r\n";
$insertion_point = stripos($config_file, 'encryption.key');
$config_file = substr_replace($config_file, $old_line, $insertion_point,0);
}
if(!empty($old_key))
{
$old_line = "# encryption.key = '$old_key' REMOVE IF UNNEEDED\r\n";
$insertion_point = stripos($config_file, 'encryption.key');
$config_file = substr_replace($config_file, $old_line, $insertion_point,0);
}
$handle = @fopen($config_path, 'w+');
$handle = @fopen($config_path, 'w+');
if(empty($handle))
{
log_message('error', "Unable to open $config_path for updating");
return false;
}
if(empty($handle))
{
log_message('error', "Unable to open $config_path for updating");
return false;
}
@chmod($config_path, 0660);
$write_failed = !fwrite($handle, $config_file);
fclose($handle);
@chmod($config_path, 0660);
$write_failed = !fwrite($handle, $config_file);
fclose($handle);
if($write_failed)
{
log_message('error', "Unable to write to $config_path for updating.");
return false;
}
log_message('info', "File $config_path has been updated.");
}
if($write_failed)
{
log_message('error', "Unable to write to $config_path for updating.");
return false;
}
log_message('info', "File $config_path has been updated.");
}
return true;
return true;
}
/**
@@ -77,30 +77,30 @@ function check_encryption(): bool
*/
function abort_encryption_conversion(): void
{
$config_path = ROOTPATH . '.env';
$backup_path = WRITEPATH . '/backup/.env.bak';
$config_path = ROOTPATH . '.env';
$backup_path = WRITEPATH . '/backup/.env.bak';
$config_file = file_get_contents($backup_path);
$config_file = file_get_contents($backup_path);
$handle = @fopen($config_path, 'w+');
$handle = @fopen($config_path, 'w+');
if(empty($handle))
{
log_message('error', "Unable to open $config_path to undo encryption conversion");
}
else
{
@chmod($config_path, 0660);
$write_failed = !fwrite($handle, $config_file);
fclose($handle);
if(empty($handle))
{
log_message('error', "Unable to open $config_path to undo encryption conversion");
}
else
{
@chmod($config_path, 0660);
$write_failed = !fwrite($handle, $config_file);
fclose($handle);
if($write_failed)
{
log_message('error', "Unable to write to $config_path to undo encryption conversion.");
return;
}
log_message('info', "File $config_path has been updated to undo encryption conversion");
}
if($write_failed)
{
log_message('error', "Unable to write to $config_path to undo encryption conversion.");
return;
}
log_message('info', "File $config_path has been updated to undo encryption conversion");
}
}
/**
@@ -108,29 +108,29 @@ function abort_encryption_conversion(): void
*/
function remove_backup(): void
{
$backup_path = WRITEPATH . '/backup/.env.bak';
if( ! file_exists($backup_path))
{
return;
}
if(!unlink($backup_path))
{
log_message('error', "Unable to remove $backup_path.");
return;
}
log_message('info', "File $backup_path has been removed");
$backup_path = WRITEPATH . '/backup/.env.bak';
if( ! file_exists($backup_path))
{
return;
}
if(!unlink($backup_path))
{
log_message('error', "Unable to remove $backup_path.");
return;
}
log_message('info', "File $backup_path has been removed");
}
function purifyHtml($data)
{
if(is_array($data))
{
return array_map('purifyHtml', $data);
}
elseif(is_string($data))
{
return Services::HtmlPurifier()->purify($data);
}
if(is_array($data))
{
return array_map('purifyHtml', $data);
}
elseif(is_string($data))
{
return Services::HtmlPurifier()->purify($data);
}
return $data;
return $data;
}

View File

File diff suppressed because it is too large Load Diff

View File

@@ -11,14 +11,14 @@ use App\Models\Enums\Rounding_mode;
*/
function get_tax_code_table_headers(): string
{
$headers = [
['tax_code' => lang('Taxes.tax_code')],
['tax_code_name' => lang('Taxes.tax_code_name')],
['city' => lang('Common.city')],
['state' => lang('Common.state')]
];
$headers = [
['tax_code' => lang('Taxes.tax_code')],
['tax_code_name' => lang('Taxes.tax_code_name')],
['city' => lang('Common.city')],
['state' => lang('Common.state')]
];
return transform_headers($headers);
return transform_headers($headers);
}
/**
@@ -26,24 +26,24 @@ function get_tax_code_table_headers(): string
*/
function get_tax_code_data_row($tax_code_row): array
{
$controller_name = 'tax_codes';
$controller_name = 'tax_codes';
return [
'tax_code' => $tax_code_row->tax_code,
'tax_code_name' => $tax_code_row->tax_code_name,
'tax_code_type' => $tax_code_row->tax_code_type,
'city' => $tax_code_row->city,
'state' => $tax_code_row->state,
'edit' => anchor(
"$controller_name/view_tax_codes/$tax_code_row->tax_code",
'<span class="glyphicon glyphicon-edit"></span>',
[
'class' => 'modal-dlg',
'data-btn-submit' => lang('Common.submit'),
'title'=>lang(ucfirst($controller_name) . ".update_tax_codes")
]
)
];
return [
'tax_code' => $tax_code_row->tax_code,
'tax_code_name' => $tax_code_row->tax_code_name,
'tax_code_type' => $tax_code_row->tax_code_type,
'city' => $tax_code_row->city,
'state' => $tax_code_row->state,
'edit' => anchor(
"$controller_name/view_tax_codes/$tax_code_row->tax_code",
'<span class="glyphicon glyphicon-edit"></span>',
[
'class' => 'modal-dlg',
'data-btn-submit' => lang('Common.submit'),
'title'=>lang(ucfirst($controller_name) . ".update_tax_codes")
]
)
];
}
/**
@@ -51,13 +51,13 @@ function get_tax_code_data_row($tax_code_row): array
*/
function get_tax_categories_table_headers(): string
{
$headers = [
['tax_category' => lang('Taxes.tax_category_name')],
['tax_category_code' => lang('Taxes.tax_category_code')],
['tax_group_sequence' => lang('Taxes.tax_group_sequence')],
];
$headers = [
['tax_category' => lang('Taxes.tax_category_name')],
['tax_category_code' => lang('Taxes.tax_category_code')],
['tax_group_sequence' => lang('Taxes.tax_group_sequence')],
];
return transform_headers($headers);
return transform_headers($headers);
}
/**
@@ -65,23 +65,23 @@ function get_tax_categories_table_headers(): string
*/
function get_tax_categories_data_row($tax_categories_row): array
{
$controller_name = 'tax_categories';
$controller_name = 'tax_categories';
return [
'tax_category_id' => $tax_categories_row->tax_category_id,
'tax_category' => $tax_categories_row->tax_category,
'tax_category_code' => $tax_categories_row->tax_category_code,
'tax_group_sequence' => $tax_categories_row->tax_group_sequence,
'edit' => anchor(
"$controller_name/view/$tax_categories_row->tax_category_id",
'<span class="glyphicon glyphicon-edit"></span>',
[
'class' => 'modal-dlg',
'data-btn-submit' => lang('Common.submit'),
'title'=>lang(ucfirst($controller_name) . ".update")
]
)
];
return [
'tax_category_id' => $tax_categories_row->tax_category_id,
'tax_category' => $tax_categories_row->tax_category,
'tax_category_code' => $tax_categories_row->tax_category_code,
'tax_group_sequence' => $tax_categories_row->tax_group_sequence,
'edit' => anchor(
"$controller_name/view/$tax_categories_row->tax_category_id",
'<span class="glyphicon glyphicon-edit"></span>',
[
'class' => 'modal-dlg',
'data-btn-submit' => lang('Common.submit'),
'title'=>lang(ucfirst($controller_name) . ".update")
]
)
];
}
/**
@@ -89,13 +89,13 @@ function get_tax_categories_data_row($tax_categories_row): array
*/
function get_tax_jurisdictions_table_headers(): string
{
$headers = [
['jurisdiction_id' => lang('Taxes.jurisdiction_id')],
['jurisdiction_name' => lang('Taxes.jurisdiction_name')],
['reporting_authority' => lang('Taxes.reporting_authority')]
];
$headers = [
['jurisdiction_id' => lang('Taxes.jurisdiction_id')],
['jurisdiction_name' => lang('Taxes.jurisdiction_name')],
['reporting_authority' => lang('Taxes.reporting_authority')]
];
return transform_headers($headers);
return transform_headers($headers);
}
/**
@@ -103,22 +103,22 @@ function get_tax_jurisdictions_table_headers(): string
*/
function get_tax_jurisdictions_data_row($tax_jurisdiction_row): array
{
$controller_name='tax_jurisdictions';
$controller_name='tax_jurisdictions';
return [
'jurisdiction_id' => $tax_jurisdiction_row->jurisdiction_id,
'jurisdiction_name' => $tax_jurisdiction_row->jurisdiction_name,
'reporting_authority' => $tax_jurisdiction_row->reporting_authority,
'edit' => anchor(
"$controller_name/view/$tax_jurisdiction_row->jurisdiction_id",
'<span class="glyphicon glyphicon-edit"></span>',
[
'class' => 'modal-dlg',
'data-btn-submit' => lang('Common.submit'),
'title'=>lang(ucfirst($controller_name) . ".update")
]
)
];
return [
'jurisdiction_id' => $tax_jurisdiction_row->jurisdiction_id,
'jurisdiction_name' => $tax_jurisdiction_row->jurisdiction_name,
'reporting_authority' => $tax_jurisdiction_row->reporting_authority,
'edit' => anchor(
"$controller_name/view/$tax_jurisdiction_row->jurisdiction_id",
'<span class="glyphicon glyphicon-edit"></span>',
[
'class' => 'modal-dlg',
'data-btn-submit' => lang('Common.submit'),
'title'=>lang(ucfirst($controller_name) . ".update")
]
)
];
}
/**
@@ -126,16 +126,16 @@ function get_tax_jurisdictions_data_row($tax_jurisdiction_row): array
*/
function get_tax_rates_manage_table_headers(): string
{
$headers = [
['tax_code' => lang('Taxes.tax_code')],
['tax_code_name' => lang('Taxes.tax_code_name')],
['jurisdiction_name' => lang('Taxes.jurisdiction_name')],
['tax_category' => lang('Taxes.tax_category')],
['tax_rate' => lang('Taxes.tax_rate')],
['rounding_code_name' => lang('Taxes.rounding_code')]
];
$headers = [
['tax_code' => lang('Taxes.tax_code')],
['tax_code_name' => lang('Taxes.tax_code_name')],
['jurisdiction_name' => lang('Taxes.jurisdiction_name')],
['tax_category' => lang('Taxes.tax_category')],
['tax_rate' => lang('Taxes.tax_rate')],
['rounding_code_name' => lang('Taxes.rounding_code')]
];
return transform_headers($headers);
return transform_headers($headers);
}
/**
@@ -143,26 +143,26 @@ function get_tax_rates_manage_table_headers(): string
*/
function get_tax_rates_data_row($tax_rates_row): array
{
$router = service('router');
$controller_name = strtolower($router->controllerName());
$router = service('router');
$controller_name = strtolower($router->controllerName());
return [
'tax_rate_id' => $tax_rates_row->tax_rate_id,
'tax_code' => $tax_rates_row->tax_code,
'tax_code_name' => $tax_rates_row->tax_code_name,
'tax_category' => $tax_rates_row->tax_category,
'tax_rate' => $tax_rates_row->tax_rate,
'jurisdiction_name' => $tax_rates_row->jurisdiction_name,
'tax_rounding_code' =>$tax_rates_row->tax_rounding_code,
'rounding_code_name' => Rounding_mode::get_rounding_code_name($tax_rates_row->tax_rounding_code),
'edit' => anchor(
"$controller_name/view/$tax_rates_row->tax_rate_id",
'<span class="glyphicon glyphicon-edit"></span>',
[
'class' => 'modal-dlg',
'data-btn-submit' => lang('Common.submit'),
'title'=>lang(ucfirst($controller_name) . ".update")
]
)
];
return [
'tax_rate_id' => $tax_rates_row->tax_rate_id,
'tax_code' => $tax_rates_row->tax_code,
'tax_code_name' => $tax_rates_row->tax_code_name,
'tax_category' => $tax_rates_row->tax_category,
'tax_rate' => $tax_rates_row->tax_rate,
'jurisdiction_name' => $tax_rates_row->jurisdiction_name,
'tax_rounding_code' =>$tax_rates_row->tax_rounding_code,
'rounding_code_name' => Rounding_mode::get_rounding_code_name($tax_rates_row->tax_rounding_code),
'edit' => anchor(
"$controller_name/view/$tax_rates_row->tax_rate_id",
'<span class="glyphicon glyphicon-edit"></span>',
[
'class' => 'modal-dlg',
'data-btn-submit' => lang('Common.submit'),
'title'=>lang(ucfirst($controller_name) . ".update")
]
)
];
}

View File

@@ -1,166 +1,166 @@
ISO Language Code Table
-----------------------
Code Name
af-ZA Afrikaans (South Africa)
ar-AE Arabic (U.A.E.)
ar-BH Arabic (Bahrain)
ar-DZ Arabic (Algeria)
ar-EG Arabic (Egypt)
ar-IQ Arabic (Iraq)
ar-JO Arabic (Jordan)
ar-KW Arabic (Kuwait)
ar-LB Arabic (Lebanon)
ar-LY Arabic (Libya)
ar-MA Arabic (Morocco)
ar-OM Arabic (Oman)
ar-QA Arabic (Qatar)
ar-SA Arabic (Saudi Arabia)
ar-SY Arabic (Syria)
ar-TN Arabic (Tunisia)
ar-YE Arabic (Yemen)
az-AZ Azeri (Latin) (Azerbaijan)
az-AZ Azeri (Cyrillic) (Azerbaijan)
be-BY Belarusian (Belarus)
bg-BG Bulgarian (Bulgaria)
bs-BA Bosnian (Bosnia and Herzegovina)
ca-ES Catalan (Spain)
cs-CZ Czech (Czech Republic)
cy-GB Welsh (United Kingdom)
da-DK Danish (Denmark)
de-AT German (Austria)
de-CH German (Switzerland)
de-DE German (Germany)
de-LI German (Liechtenstein)
de-LU German (Luxembourg)
dv-MV Divehi (Maldives)
el-GR Greek (Greece)
en-AU English (Australia)
en-BZ English (Belize)
en-CA English (Canada)
en-CB English (Caribbean)
en-GB English (United Kingdom)
en-IE English (Ireland)
en-JM English (Jamaica)
en-NZ English (New Zealand)
en-PH English (Republic of the Philippines)
en-TT English (Trinidad and Tobago)
en-US English (United States)
en-ZA English (South Africa)
en-ZW English (Zimbabwe)
es-AR Spanish (Argentina)
es-BO Spanish (Bolivia)
es-CL Spanish (Chile)
es-CO Spanish (Colombia)
es-CR Spanish (Costa Rica)
es-DO Spanish (Dominican Republic)
es-EC Spanish (Ecuador)
es-ES Spanish (Castilian)
es-ES Spanish (Spain)
es-GT Spanish (Guatemala)
es-HN Spanish (Honduras)
es-MX Spanish (Mexico)
es-NI Spanish (Nicaragua)
es-PA Spanish (Panama)
es-PE Spanish (Peru)
es-PR Spanish (Puerto Rico)
es-PY Spanish (Paraguay)
es-SV Spanish (El Salvador)
es-UY Spanish (Uruguay)
es-VE Spanish (Venezuela)
et-EE Estonian (Estonia)
eu-ES Basque (Spain)
fa-IR Farsi (Iran)
fi-FI Finnish (Finland)
fo-FO Faroese (Faroe Islands)
fr-BE French (Belgium)
fr-CA French (Canada)
fr-CH French (Switzerland)
fr-FR French (France)
fr-LU French (Luxembourg)
fr-MC French (Principality of Monaco)
gl-ES Galician (Spain)
gu-IN Gujarati (India)
he-IL Hebrew (Israel)
hi-IN Hindi (India)
hr-BA Croatian (Bosnia and Herzegovina)
hr-HR Croatian (Croatia)
hu-HU Hungarian (Hungary)
hy-AM Armenian (Armenia)
id-ID Indonesian (Indonesia)
is-IS Icelandic (Iceland)
it-CH Italian (Switzerland)
it-IT Italian (Italy)
ja-JP Japanese (Japan)
ka-GE Georgian (Georgia)
kk-KZ Kazakh (Kazakhstan)
kn-IN Kannada (India)
ko-KR Korean (Korea)
kok-IN Konkani (India)
ky-KG Kyrgyz (Kyrgyzstan)
lt-LT Lithuanian (Lithuania)
lv-LV Latvian (Latvia)
mi-NZ Maori (New Zealand)
mk-MK FYRO Macedonian (Former Yugoslav Republic of Macedonia)
mn-MN Mongolian (Mongolia)
mr-IN Marathi (India)
ms-BN Malay (Brunei Darussalam)
ms-MY Malay (Malaysia)
mt-MT Maltese (Malta)
nb-NO Norwegian (Bokm?l) (Norway)
nl-BE Dutch (Belgium)
nl-NL Dutch (Netherlands)
nn-NO Norwegian (Nynorsk) (Norway)
ns-ZA Northern Sotho (South Africa)
pa-IN Punjabi (India)
pl-PL Polish (Poland)
ps-AR Pashto (Afghanistan)
pt-BR Portuguese (Brazil)
pt-PT Portuguese (Portugal)
qu-BO Quechua (Bolivia)
qu-EC Quechua (Ecuador)
qu-PE Quechua (Peru)
ro-RO Romanian (Romania)
ru-RU Russian (Russia)
sa-IN Sanskrit (India)
se-FI Sami (Northern) (Finland)
se-FI Sami (Skolt) (Finland)
se-FI Sami (Inari) (Finland)
se-NO Sami (Northern) (Norway)
se-NO Sami (Lule) (Norway)
se-NO Sami (Southern) (Norway)
se-SE Sami (Northern) (Sweden)
se-SE Sami (Lule) (Sweden)
se-SE Sami (Southern) (Sweden)
sk-SK Slovak (Slovakia)
sl-SI Slovenian (Slovenia)
sq-AL Albanian (Albania)
sr-BA Serbian (Latin) (Bosnia and Herzegovina)
sr-BA Serbian (Cyrillic) (Bosnia and Herzegovina)
sr-SP Serbian (Latin) (Serbia and Montenegro)
sr-SP Serbian (Cyrillic) (Serbia and Montenegro)
sv-FI Swedish (Finland)
sv-SE Swedish (Sweden)
sw-KE Swahili (Kenya)
syr-SY Syriac (Syria)
ta-IN Tamil (India)
te-IN Telugu (India)
th-TH Thai (Thailand)
tl-PH Tagalog (Philippines)
tn-ZA Tswana (South Africa)
tr-TR Turkish (Turkey)
tt-RU Tatar (Russia)
uk-UA Ukrainian (Ukraine)
ur-PK Urdu (Islamic Republic of Pakistan)
uz-UZ Uzbek (Latin) (Uzbekistan)
uz-UZ Uzbek (Cyrillic) (Uzbekistan)
vi-VN Vietnamese (Viet Nam)
xh-ZA Xhosa (South Africa)
zh-CN Chinese (S)
zh-Hans Chinese in the simplified scrip
zh-Hant Chinese in the traditional script
zh-HK Chinese (Hong Kong)
zh-MO Chinese (Macau)
zh-SG Chinese (Singapore)
zh-TW Chinese (T)
zu-ZA Zulu (South Africa)
Code Name
af-ZA Afrikaans (South Africa)
ar-AE Arabic (U.A.E.)
ar-BH Arabic (Bahrain)
ar-DZ Arabic (Algeria)
ar-EG Arabic (Egypt)
ar-IQ Arabic (Iraq)
ar-JO Arabic (Jordan)
ar-KW Arabic (Kuwait)
ar-LB Arabic (Lebanon)
ar-LY Arabic (Libya)
ar-MA Arabic (Morocco)
ar-OM Arabic (Oman)
ar-QA Arabic (Qatar)
ar-SA Arabic (Saudi Arabia)
ar-SY Arabic (Syria)
ar-TN Arabic (Tunisia)
ar-YE Arabic (Yemen)
az-AZ Azeri (Latin) (Azerbaijan)
az-AZ Azeri (Cyrillic) (Azerbaijan)
be-BY Belarusian (Belarus)
bg-BG Bulgarian (Bulgaria)
bs-BA Bosnian (Bosnia and Herzegovina)
ca-ES Catalan (Spain)
cs-CZ Czech (Czech Republic)
cy-GB Welsh (United Kingdom)
da-DK Danish (Denmark)
de-AT German (Austria)
de-CH German (Switzerland)
de-DE German (Germany)
de-LI German (Liechtenstein)
de-LU German (Luxembourg)
dv-MV Divehi (Maldives)
el-GR Greek (Greece)
en-AU English (Australia)
en-BZ English (Belize)
en-CA English (Canada)
en-CB English (Caribbean)
en-GB English (United Kingdom)
en-IE English (Ireland)
en-JM English (Jamaica)
en-NZ English (New Zealand)
en-PH English (Republic of the Philippines)
en-TT English (Trinidad and Tobago)
en-US English (United States)
en-ZA English (South Africa)
en-ZW English (Zimbabwe)
es-AR Spanish (Argentina)
es-BO Spanish (Bolivia)
es-CL Spanish (Chile)
es-CO Spanish (Colombia)
es-CR Spanish (Costa Rica)
es-DO Spanish (Dominican Republic)
es-EC Spanish (Ecuador)
es-ES Spanish (Castilian)
es-ES Spanish (Spain)
es-GT Spanish (Guatemala)
es-HN Spanish (Honduras)
es-MX Spanish (Mexico)
es-NI Spanish (Nicaragua)
es-PA Spanish (Panama)
es-PE Spanish (Peru)
es-PR Spanish (Puerto Rico)
es-PY Spanish (Paraguay)
es-SV Spanish (El Salvador)
es-UY Spanish (Uruguay)
es-VE Spanish (Venezuela)
et-EE Estonian (Estonia)
eu-ES Basque (Spain)
fa-IR Farsi (Iran)
fi-FI Finnish (Finland)
fo-FO Faroese (Faroe Islands)
fr-BE French (Belgium)
fr-CA French (Canada)
fr-CH French (Switzerland)
fr-FR French (France)
fr-LU French (Luxembourg)
fr-MC French (Principality of Monaco)
gl-ES Galician (Spain)
gu-IN Gujarati (India)
he-IL Hebrew (Israel)
hi-IN Hindi (India)
hr-BA Croatian (Bosnia and Herzegovina)
hr-HR Croatian (Croatia)
hu-HU Hungarian (Hungary)
hy-AM Armenian (Armenia)
id-ID Indonesian (Indonesia)
is-IS Icelandic (Iceland)
it-CH Italian (Switzerland)
it-IT Italian (Italy)
ja-JP Japanese (Japan)
ka-GE Georgian (Georgia)
kk-KZ Kazakh (Kazakhstan)
kn-IN Kannada (India)
ko-KR Korean (Korea)
kok-IN Konkani (India)
ky-KG Kyrgyz (Kyrgyzstan)
lt-LT Lithuanian (Lithuania)
lv-LV Latvian (Latvia)
mi-NZ Maori (New Zealand)
mk-MK FYRO Macedonian (Former Yugoslav Republic of Macedonia)
mn-MN Mongolian (Mongolia)
mr-IN Marathi (India)
ms-BN Malay (Brunei Darussalam)
ms-MY Malay (Malaysia)
mt-MT Maltese (Malta)
nb-NO Norwegian (Bokm?l) (Norway)
nl-BE Dutch (Belgium)
nl-NL Dutch (Netherlands)
nn-NO Norwegian (Nynorsk) (Norway)
ns-ZA Northern Sotho (South Africa)
pa-IN Punjabi (India)
pl-PL Polish (Poland)
ps-AR Pashto (Afghanistan)
pt-BR Portuguese (Brazil)
pt-PT Portuguese (Portugal)
qu-BO Quechua (Bolivia)
qu-EC Quechua (Ecuador)
qu-PE Quechua (Peru)
ro-RO Romanian (Romania)
ru-RU Russian (Russia)
sa-IN Sanskrit (India)
se-FI Sami (Northern) (Finland)
se-FI Sami (Skolt) (Finland)
se-FI Sami (Inari) (Finland)
se-NO Sami (Northern) (Norway)
se-NO Sami (Lule) (Norway)
se-NO Sami (Southern) (Norway)
se-SE Sami (Northern) (Sweden)
se-SE Sami (Lule) (Sweden)
se-SE Sami (Southern) (Sweden)
sk-SK Slovak (Slovakia)
sl-SI Slovenian (Slovenia)
sq-AL Albanian (Albania)
sr-BA Serbian (Latin) (Bosnia and Herzegovina)
sr-BA Serbian (Cyrillic) (Bosnia and Herzegovina)
sr-SP Serbian (Latin) (Serbia and Montenegro)
sr-SP Serbian (Cyrillic) (Serbia and Montenegro)
sv-FI Swedish (Finland)
sv-SE Swedish (Sweden)
sw-KE Swahili (Kenya)
syr-SY Syriac (Syria)
ta-IN Tamil (India)
te-IN Telugu (India)
th-TH Thai (Thailand)
tl-PH Tagalog (Philippines)
tn-ZA Tswana (South Africa)
tr-TR Turkish (Turkey)
tt-RU Tatar (Russia)
uk-UA Ukrainian (Ukraine)
ur-PK Urdu (Islamic Republic of Pakistan)
uz-UZ Uzbek (Latin) (Uzbekistan)
uz-UZ Uzbek (Cyrillic) (Uzbekistan)
vi-VN Vietnamese (Viet Nam)
xh-ZA Xhosa (South Africa)
zh-CN Chinese (S)
zh-Hans Chinese in the simplified scrip
zh-Hant Chinese in the traditional script
zh-HK Chinese (Hong Kong)
zh-MO Chinese (Macau)
zh-SG Chinese (Singapore)
zh-TW Chinese (T)
zu-ZA Zulu (South Africa)

View File

@@ -1,32 +1,32 @@
<?php
return [
"attribute_value_invalid_chars" => "الميزات لا يمكن أن تحتوي على ':' أو'|'",
"confirm_delete" => "هل أنت متأكد من أنك تريد حذف الميزات المحددة ؟",
"confirm_restore" => "هل أنت متأكد من أنك تريد استعادة السمة (السمات) المحددة؟",
"definition_cannot_be_deleted" => "لا يمكن حذف السمات المحددة",
"definition_error_adding_updating" => "لا يمكن إضافة السمة {0} أو تحديثها. يرجى التحقق من سجل الخطأ.",
"definition_flags" => "رؤية الميزات",
"definition_group" => "المجموعة",
"definition_id" => "كود",
"definition_name" => "إضافة ميزة",
"definition_name_required" => "اسم الميزة هي خانة اجبارية",
"definition_one_or_multiple" => "ميزة/ميزات",
"definition_successful_adding" => "لقد تم إضافة صنف بنجاح",
"definition_successful_deleted" => "لقد تم حذف ميزة بنجاح",
"definition_successful_updating" => "تم تعديل الميزة بنجاح",
"definition_type" => "نوع الميزة",
"definition_type_required" => "نوع الميزة هي خانة إجبارية",
"definition_unit" => "وحدة قياس",
"definition_values" => "قيمة الميزة",
"new" => "اضافة ميزة جديده",
"no_attributes_to_display" => "لا يوجد اصناف للعرض",
"receipt_visibility" => "وصل",
"show_in_items" => "اظهار في الصنف",
"show_in_items_visibility" => "الصنف",
"show_in_receipt" => "اظهار على الوصل",
"show_in_receivings" => "اظهار في استلام البضائع",
"show_in_receivings_visibility" => "استلام البضائع",
"show_in_sales" => "اظهار خلال البيع",
"show_in_sales_visibility" => "البيع",
"update" => "تحديث الميزات",
"attribute_value_invalid_chars" => "الميزات لا يمكن أن تحتوي على ':' أو'|'",
"confirm_delete" => "هل أنت متأكد من أنك تريد حذف الميزات المحددة ؟",
"confirm_restore" => "هل أنت متأكد من أنك تريد استعادة السمة (السمات) المحددة؟",
"definition_cannot_be_deleted" => "لا يمكن حذف السمات المحددة",
"definition_error_adding_updating" => "لا يمكن إضافة السمة {0} أو تحديثها. يرجى التحقق من سجل الخطأ.",
"definition_flags" => "رؤية الميزات",
"definition_group" => "المجموعة",
"definition_id" => "كود",
"definition_name" => "إضافة ميزة",
"definition_name_required" => "اسم الميزة هي خانة اجبارية",
"definition_one_or_multiple" => "ميزة/ميزات",
"definition_successful_adding" => "لقد تم إضافة صنف بنجاح",
"definition_successful_deleted" => "لقد تم حذف ميزة بنجاح",
"definition_successful_updating" => "تم تعديل الميزة بنجاح",
"definition_type" => "نوع الميزة",
"definition_type_required" => "نوع الميزة هي خانة إجبارية",
"definition_unit" => "وحدة قياس",
"definition_values" => "قيمة الميزة",
"new" => "اضافة ميزة جديده",
"no_attributes_to_display" => "لا يوجد اصناف للعرض",
"receipt_visibility" => "وصل",
"show_in_items" => "اظهار في الصنف",
"show_in_items_visibility" => "الصنف",
"show_in_receipt" => "اظهار على الوصل",
"show_in_receivings" => "اظهار في استلام البضائع",
"show_in_receivings_visibility" => "استلام البضائع",
"show_in_sales" => "اظهار خلال البيع",
"show_in_sales_visibility" => "البيع",
"update" => "تحديث الميزات",
];

View File

@@ -1,11 +1,11 @@
<?php
return [
"all" => "الجميع",
"columns" => "أعمدة",
"hide_show_pagination" => "عرض/إخفاء أرقام الصفحات",
"loading" => "جارى التحميل، برجاء الإنتظار ...",
"page_from_to" => "عرض {0} إلى {1} من {2} صفوف",
"refresh" => "إعادة تحميل",
"rows_per_page" => "{0} صف بالصفحة",
"toggle" => "تغيير",
"all" => "الجميع",
"columns" => "أعمدة",
"hide_show_pagination" => "عرض/إخفاء أرقام الصفحات",
"loading" => "جارى التحميل، برجاء الإنتظار ...",
"page_from_to" => "عرض {0} إلى {1} من {2} صفوف",
"refresh" => "إعادة تحميل",
"rows_per_page" => "{0} صف بالصفحة",
"toggle" => "تغيير",
];

Some files were not shown because too many files have changed in this diff Show More