

## Install Project

1. setup .env 
2. composer install
3. php artisan migrate
4. php artisan storage:link
    create "vouchers" folder in "public/storage/" ("public/storage/vouchers/")
5. php artisan db:seed
    or (php artisan migrate:refresh --seed) - migrate databases table and insert dummy data
6. php artisan key:generate
7. npm run dev (refresh the script)
8. php artisan translations:import
9. php artisan translations:export --all
10. php artisan event:clear
11. php artisan event:cache (only execute for production. Each times any changes make to the EventServiceProvider.php, have to rerun together with artisan command in 10.)
12. php artisan user:reset_summaries (only run this command if there is inaccuracy in table user_summaries. For more info, suffix -h to read the help.)
13. php artisan queue:work --stop-when-empty (setup cron job to execute queueable job, timer decide based on project level. Have to declare env variable as 'QUEUE_CONNECTION=database'. For localhost development environment, can just use 'php artisan queue:work' to ease the process)

## Install google ads API

1. brew install automake
2. https://grpc.io/docs/quickstart/php/

## CLI based Object Creation (Starting from the commit after 24 Feb 2023)

1. To make our codebase more safety, you must inject the object \App\Models\BusinessAccounts manually for those classes requires!
2. Please do not make it AUTO INJECT on production mode!
3. For each of the BusinessAccount loaded on CLI mode, you have to manually trigger the method 'forceReloadEnvConfigByDomain' to init the env variable belongs to the account selected.


## Development
 1. Javascript Language
 See [here](https://github.com/rmariuzzo/lang.js) to check how to use.
    - Getting a message
        - Lang.get('messages.home');
        - Lang.get('heading.label_valid_until', { date: '2019-08-07' });
 2. To create new table run command "php artisan make:model Models/Stores -mcr" to create model, migration and controller in one shoot         

## Notes 
1. Everytime you edit the language file need to generate the lang.js `php artisan lang:js public/js/lang.js`, or use `npm run watch`, or use `npm run dev`

## Updates
1. 20210422 Laravel version have upgraded to Version 8.x.x ( 8.38.0 )
   use command: `php -d memory_limit=-1 composer.phar update` 
   to update the project laravel version

## Setup GCP logging [Only on GCP Server]
1. Library already added in composer.json. "google/cloud-error-reporting"

   Run `composer install`
2. Add `auto_prepend_file='PROJECT_DIR/vendor/google/cloud-error-reporting/src/prepend.php'` in the php.ini file
3. Reference: https://cloud.google.com/error-reporting/docs/setup/php
Troubleshooting: If hit the error file vendor/google/cloud-error-reporting/src/prepend.php not found, remove the line from php.ini file then install the library again.
   

## Setup GCP KMS
1. Library already added in composer.json. "google/cloud-kms"
   
   Run `composer install`
2. Upload the "GCP_SERVICE_ACCOUNT_KEY_PATH" file to the Storage folder.
3. Setup the environment variable 


## Setup Domain (Business Account) Based Application Env File (20220316)
1. Setup .env by using .env.example
2. If the DB Name are same across all the Domain, then should set the database name under variable DB_DATABASE. 
   Otherwise, just leave it blank
3. If there is only one module activation for the project, need to ensure only one module variable are set to true under # Module Activation
4. If there are multiple module activation belong to the same project, then default all the variables under # Module Activation should be false 
5. Copy the .env.example.common and name it as .env.common. 
   The variable inside this environment file will shared and loaded across to all the domain.
6. Copy the respective module environment file and setup the variable properly. 
   The naming convention for module based env file should be .env.{host_name}. 
   If hostname is 'https:skale.today' then the module based env file should name it as '.env.skale.today'. 
   Note that the port number will be ignore
7. If there are multiple module activation throughout the project, copy respective module activation variable and put inside the module based env file. 
   By default, the module based env variable will override all the variable value inside .env and .env.example
8. The ordering of env file be loaded into system as follows:- (Higher order take higher priority)
   - Module Based Env File
   - Common Env File
   - Default Env File
9. If there are multiple DB for each of the module, the php artisan must loaded with variable --env=.env.{host_name}. 
   Need to ensure only the CLI version of PHP are used to execute the command. 
   For CPanel, default the Cron Job will not using CLI PHP, need to load the CLI PHP by using path /usr/local/bin/php. 
   Sample: '/usr/local/bin/php artisan migrate --env=.env.skale.today'
10. All the variables under Common Env and Domain Based Env are allowed to be modified by the end-user through Admin Dashboard. 
   However, developer can decide the visibility to the variable if it is not modificable. 
   Will explain it on following section ## Prepare Variable Setting Info used for Admin Dashboard


## Setup Domain (Business Account) Based Application Database (20220316)
1. Select table 'business_accounts' and add a new entry respective to the current domain name used to load the application
2. Select table 'business_account_domains' and add a entry respective to the current domain name used to load the application
3. By default, system will load the Business Account belong to the current domain that load the application
4. To get the Bussiness Account model for current domain, can use 'app(\App\Models\BusinessAccounts)'


## Folder Seperation by Business Account with asset/view/resource that having same name (20220316)
1. To be able to customize the view/asset/resource based on the same naming, domain based folder are provided for dev to do the customization
2. To achive this customization, need to setup the column 'slug' in business_account table.
   The naming are important and must be unique because dev need to use the naming to create the folder manually under respective folder level
3. For example:
   - if one having a common image under folder 'asset/image/something.jpg'.
   - However, a client want to have different image but with same UI layout. 
   - Dev can create a folder under asset folder level or sub level of asset folder. 
   - For example, 'asset/image/client_a/something.jpg' will store the customization resources whereas 'cliant_a' refer to the slug naming. 
   - In this case, this resource will be loaded regardless only the actual common path are provided to helper function.
   - As long as there is a folder naming match exactly same as the slug in business account and there is the resource exist inside that folder.
   - If the resource are not found inside the business account folder level, default asset file name will be used ('asset/image/something.jpg').
4. Whatever the resources/view/asset want to have this customization, need to set the helper function parameter '$base' as false.
5. In order to identify and better understanfing on which helper function are able to do the customization, dev can refer to the custom helpers.php under folder app/Helpers.


## (20230223 DEPRECATED) Prepare Variable Setting Info used for Admin Dashboard (20220316)
1. All the modification setting variable under Common Env & Domain Based Env are allowed to be setup by end-user through admin dashboard
2. To have user understandable label and field selection through an user-friendly html form, dev need to prepare all the info related to new variables added on either one of the mentioned Env.
3. All the Env Variable info will store under .env.label file
4. Edit the .env.label file to add in the new variable and define all the info related to variable
5. Each of the info belong to a single variable are seperated by |
6. Most of the setting parrent are defined as literal_keyword[value]
7. If a variable is not modificable by end user, 'hidden' should be setup inside the variable info
8. List of the variable info as follows:-
   - hidden => hide the value and user are not allow to modify and see it like those sensitive variable such as DB_DATABASE
   - required => set the component as compulsory field to be fill up by end user
   - label[label_name] => 'label' refer as literal while value inside '[]' will treat as actual naming
   - text => refer to input component with 'text' type
      - HTML Form Element
   - textarea => refer to textarea component
      - HTML Form Element
   - checkbox[opt1,opt2] => refer to checkbox component while value inside '[]' will treat as checkbox options (separated by ,)
      - HTML Form Element
      - If want to have a proper naming and hidden value, @ will be separator where format as hidden_value@label_name
      - If only single value present without @, the value will treat as hidden value and label naming
   - radio[opt1,opt2] => refer to radio component while value inside '[]' will treat as checkbox options (separated by ,)
      - HTML Form Element
      - If want to have a proper naming and hidden value, @ will be separator where format as hidden_value@label_name
      - If only single value present without @, the value will treat as hidden value and label naming
   - select[opt1,opt2] => refer to select component while value inside '[]' will treat as checkbox options (separated by ,)
      - HTML Form Element
      - If want to have a proper naming and hidden value, @ will be separator where format as hidden_value@label_name
      - If only single value present without @, the value will treat as hidden value and label naming
   - placeholder[something] => 'placeholder' refer as literal while value inside '[]' will treat as placeholder value
      - Subject to the element component are support with html placeholder
      - This literal will work exactly like normal HTML placeholder since it is an attibute from HTML Form Element
      - The purpose of this literal is to showing some sample value for user to understand what are the expected value
   - title[something] => 'title' refer as literal while value inside '[]' will treat as string information.
      - The literal use to explain the usage of variable 
      - It will display the message inside the information-icon for user to hover
   - importantMsg[any message] => 'importantMsg' refer as literal while value inside '[]' will treat as string information.
      - This literal use to display the important message just below the HTML Form component 
      - The purpose is to lets user aware the important message
9. All the logic on info data parsing in admin dashboard, dev can refer to EnvConfigsController::_ParseEnvLabelExtractAsHtmlInfo 


## Translations Setting (20220316)
1. By default Laravel will store all the translations under folder resources/lang. In order to allows end-user to modify the value at the same time remain original translation for initial setup. A custom lang folder will auto created to store all the user-defined translations. The path for custom lang folder is resources/lang-custom
2. During initial setup, need to execute php artisan translations:import to do the initial lang import into database
3. After importing, user are allows to modify the lang value in database level settings
4. If the modification are confirmed, command php artisan translations:export --all will used to export the modified version of lang value from database into Laravel lang script folder
5. What if want to revert all the modified translation value, three commands will used which are
   - php artisan translations:reset
   - php artisan translations:import
   - php artisan translations:export --all
6. To ease the end-user on this matter, the UI are provided through Admin Dashboard Site Setting


## PHPStorm IDE Helper 
We use composer to install a package barryvdh/laravel-ide-helper to help the developer in IDE autocomplete
See: https://github.com/barryvdh/laravel-ide-helper