Yii2: Format currency with thousands separator - yii2

I use PhpOffice\PhpWord for my Yii2 and Microsoft word 2016.
value data type decimal(15,2) when i download microsoftwordfile.docx from my project field value decimal show 10000.00 but i need 10,000.00
how to config/coding them to show 10,000.00
here myController.php
public function actionWord($id)
{
Settings::setTempDir(Yii::getAlias('#webroot').'/temp/');
$templateProcessor = new TemplateProcessor(Yii::getAlias('#webroot').'/path/to/microsoftwordfile.docx');
$model = Dataexample::findOne($id);
$templateProcessor->setValue(
[
'amount',
],
[
$model->amount,
]);
$templateProcessor->saveAs(Yii::getAlias('#webroot').'/path/to/microsoftwordfile.docx');
echo Html::a('download', Url::to(Yii::getAlias('#web').'/path/to/microsoftwordfile.docx'), ['class' => 'btn btn-danger']);
}

Well you can use yii\i18n\Formatter to format the currency and it provides you the
thousandSeparator : The character displayed as the thousands
separator (also called grouping separator) character when formatting a
number.
Go to your common\config\main.php if you are using app-advanced or the app/config/main.php if app-basic nad add the following under components array.
'formatter' => [
'thousandSeparator' => ',',
'currencyCode' => 'USD',
],
Now you can format any given number like below
Yii::$app->formatter->asCurrency(100.25);
//will output
$100.25
Yii::$app->formatter->asCurrency(1000.25);
//will output
$1,000.25
Yii::$app->formatter->asCurrency(100000.25);
//will output
$100,000.25
You should change your function like below
public function actionWord($id)
{
Settings::setTempDir(Yii::getAlias('#webroot').'/temp/');
$templateProcessor = new TemplateProcessor(Yii::getAlias('#webroot').'/path/to/microsoftwordfile.docx');
$model = Dataexample::findOne($id);
$templateProcessor->setValue(
[
'amount',
],
[
Yii::$app->formatter->asCurrency($model->amount),
]);
$templateProcessor->saveAs(Yii::getAlias('#webroot').'/path/to/microsoftwordfile.docx');
echo Html::a('download', Url::to(Yii::getAlias('#web').'/path/to/microsoftwordfile.docx'), ['class' => 'btn btn-danger']);
}
Hope this helps.

Related

I want to modify array-column output when fetched

This is my data table image
my blade file
#table([
'id' => 'Persons.index',
'xhr' => route('api.manage-dup-api'),
'ns' => 'PersonsIndex',
'columns' => $columns ?? [],
'filters' => $filterTable ?? [],
'params' => [
'filters_live' => false,
'selectable' => true,
'toolbar_style' => 'fixed'
]
])
this is a query which passes data to a data table [API]
$q->with('user')
->with('user.roles')
->select(
'persons.*',
'birth->date as birthdate'
)->`enter code here`whereIn('id', $id)->orWhereIn('old_id_CONINET', $coninet_ids);
return $this->outputList($q, $request);
as shown in the picture I want to remove ["] from the CONINET_ID table
you are storing an array of strings in the DB.
you can convert the array values to int:
array_map('intval', $array);
you can also create an accessor on your eloquent model
public function getOldIdConinetAttribute($value)
{
return array_map('intval', $value);
}
It would better if you give some detailed info. As of now details mentioned above can not explain your code. As of my understanding, I suggest you to check Yajra datatable plugin which will help you solving your issue.
or you can cast coninet_id to array by adding below code in your model.
protected $casts = [
'coninet_id' => 'array'
];

Custom filter in Gridview (Regular or Overdue)

I have a registration_date column where I store the date that the customer was registered in the company (example: 2015-06-12). You'll need to filter if the customer has a failed or overdue registration (if registration_date is longer than 365 days).
In the preview screen I can display this condition, but I need to display as a filter in Gridview with 2 options (Regular or Overdue).
[
'attribute' => 'registration_date',
'format' => 'raw',
'value' => function ($model) {
return $model->getRegistration($model->registration_date);
},
'filter' => [Regular or Overdue], ????
'contentOptions' => $contentOptions,
'headerOptions' => $headerOptions,
],
How do I make this check in model ClientSearch?
What I understand is that you want to add a filter on the column registration_date which is as a Date type column, which should have 2 options Regular and Overdue and should filter the records based on
Regular
The option should filter out all the records that have the registration_date difference smaller than or equal to 365 days.
Overdue
The option should filter out all the records that have the registration_date difference from the current date greater than 365 days.
Your gridview column will look like below
GridView Changes
If the above is correct then, first of all, add the following configuration in your gridview column configuration. we will provide an active-dropdown in the filter option and assign it a name registration_status.
Note: I have used select2 for the dropdown you can use the default if you do not want, and change the $searchModel to the exact name for the client search model that you are passing to the filterModel option in your gridview.
[
'filter' => \kartik\widgets\Select2::widget ( [
'data' => $searchModel->statusOptions(),
'model' => $searchModel ,
'attribute' => 'registration_status' ,
'options' => [
'placeholder' => 'Registration Status' ,
'class' => 'form-control' ,
'id' => 'registration_status' ,
] ,
'theme' => \kartik\widgets\Select2::THEME_BOOTSTRAP ,
'pluginOptions' => [
'allowClear' => true ,
] ,
] ) ,
'attribute' => 'created_at' ,
'label' => Yii::t ( 'app' , 'Registration Date' ) ,
] ,
Without Select2
[
'filter' => Html::activeDropDownList ( $searchModel , 'registration_status' , $searchModel->statusOptions () , [ 'prompt' => 'Select Registration status' ] ) ,
'attribute' => 'created_at' ,
'label' => Yii::t ( 'app' , 'Registration Date' ) ,
] ,
ClientSearch Changes
Add the constants on top of your ClientSearch model.
const STATUS_OVERDUE = 'overdue';
const STATUS_REGULAR = 'regular';
Add the function statusOptions() inside the ClientSearch model.
public function statusOptions() {
return [
self::STATUS_OVERDUE => 'Overdue' ,
self::STATUS_REGULAR => 'Regular'
];
}
Add a public property registration_status inside the search model.
public $registration_status
Add this field we created to the safe list inside the rules()
function.
function rules(){
return [
//other rules
[ [.... , 'registration_status' ] , 'safe' ] ,
];
}
Then the next thing is to accomplish the SQL condition which would filter out the records, you can use MySQL functions, DATEDIFF() and CURDATE(), like DATEDIFF(CURDATE(),registration_date)>365.
So add the following inside the search() function of the search model before the last line return $dataProvider.
if ( $this->registration_status === self::STATUS_OVERDUE ) {
$query->andFilterWhere ( [ '>' , 'DATEDIFF(NOW(),registration_date)' , 365 ] );
} else if ( $this->registration_status === self::STATUS_REGULAR ) {
$query->andFilterWhere ( [ '<=' , 'DATEDIFF(NOW(),registration_date)' , 365 ] );
}
Now you can filter the records based on the selected option and if you clear out the options in the drop-down it will show all of the records.

Yii2 : Display the phone mask as text

Tell me how to make the phone output in a readable way?
It is stored in the database as 1234567890, but you need to display the user - (123) 456-78-90.
I do not want to make a garden, obvio,usly there are already ready solutions.
In Controller
public function actionShowPhone()
{
$phone = "1234567890";
return $this->render('show-phone', ['phone' => $phone,]);
}
In View show-phone.php
<?= Html::encode($phone) ?>
Formatting phone numbers in Forms
If you are looking to format the phone number inside the ActiveForm you can use the \yii\widgets\MaskInput in the following way
<?=
$form->field($model, 'landline_phone')->widget(\yii\widgets\MaskedInput::className(), [
'mask' => '(999)-999-99-99'
]);
?>
or without ActiveForm
echo \yii\widgets\MaskedInput::widget([
'name' => 'phone',
'mask' => '(999)-999-99-99',
]);
Note: when saving the phone field you must save it as a number only in the database like 1234567890 so before you save you can use $this->landline_phone= preg_replace('/[^0-9]+/', '', $this->landline_phone); inside the beforeSave().
Formatting Phone Numbers as Text
Extending the \yii\i18n\Formatter
But if you want to print the phone number as text in the above format then a good way is to extend the yii\i18n\Formatter and create a custom component/helper in lets say common\components\ or app\components\ with the following code.
Note : change the namespace for the class accordingly
<?php
namespace common\components;
use yii\i18n\Formatter;
class FormatterHelper extends Formatter {
public function asPhone($value) {
return preg_replace("/^(\d{3})(\d{3})(\d{2})(\d{2})$/", "($1)-$2-$3-$4", $value);
}
}
and then in the common\config\main.php or app\config\web.php add the following under components.
'formatter' => [
'class' => '\common\components\FormatterHelper',
'locale' => 'en-US',
'dateFormat' => 'yyyy-MM-dd',
'datetimeFormat' => 'yyyy-MM-dd HH:mm:ss',
'decimalSeparator' => '.',
'thousandSeparator' => ',',
'currencyCode' => 'USD'
],
then you can use it like below
echo Yii::$app->formatter->asPhone('123456789')
and it will output the following as text
(123)-456-78-90
Using \yii\widgets\MaskedInputAssets
Another simplest and easiest way is to register the available MaskedInputAssets that uses RobinHerbots/Inputmask bundled and use javascript to mask the text
<?php
\yii\widgets\MaskedInputAsset::register($this);
$js = <<<SCRIPT
var selector = document.getElementById("mask");
var im = new Inputmask("(999)-999-99-99");
im.mask(selector);
SCRIPT;
// Register tooltip/popover initialization javascript
$this->registerJs ( $js , \yii\web\View::POS_READY);
?>
<div id="mask">
1234567890
</div>

2amigos/yii2-date-picker-widget year validation

I am using 2amigos/yii2-date-picker-widget.After selecting the date, user can edit the year which can be invalid like 10/30/0233. (m/d/Y)
I want to restrict user to enter invalid year, or to allow the date between specific year range only. without making the datefield readonly. How can I achieve this.
echo $form->field($model, 'date')->widget(DatePicker::className(), [
'addon' => '<i class="fa fa-calendar" aria-hidden="true"></i>',
'class' => 'form-control',
'clientOptions' => [
'autoclose' => true,
'format' => Yii::$app->params['dateFormat'],
],
]);
I have solved it using custom validator as follows
add rule for date as follows
['my_date', 'validYear'], // custom validator to check year range
Then define custom rule as follows
public function validYear($attribute, $params) {
$date = DateTime::createFromFormat("m/d/Y", $this->my_date);
$year = $date->format("Y");
$year_range = range(date('Y'), date('Y')+20, 1);
if(!empty($year) && !in_array($year, $year_range)){
$this->addError($attribute,"Please select valid date");
}
}
Though it works perfectly for me, If anyone has more appropriate solution, please suggest.

Handle Image update in yii2

Hi everyone i am using FileInput kartik widget in yii2 project and uploading and saving works fine but i am having problem while updating the images
I can get the images path on the update form and create and array and display in as initialpreview in the widget but the problem is that my files field is required field so even there are some values in initialpreview the form gives error to upload image as its required field. So what should i do here?
I only want to give preview of their uploaded pics to the user but if they dont make any changes than i dont want to update anything for images
Following is my view code and model code
return [
[[ 'price', 'created_date', 'created_by', 'updated_date', 'updated_by','file','address'], 'required'],
[['price'], 'number'],
[['address'], 'string', 'max' => 255],
[['file'], 'file', 'extensions'=>'jpg, gif, png', 'maxFiles' => 4],
];
<?php
$initalpreview = array();
foreach($model->adsImages as $images) {
$initalpreview[] = Html::img('/upload/'.$images->image, ['class'=>'file-preview-image']);
}
?>
<?=$form->field($model, 'file[]')->widget(FileInput::classname(), [
'options' => ['accept' => 'image/*',
'multiple'=>true],
'pluginOptions' => [
'maxFileCount' => 5,
'initialPreview'=> $initalpreview,
'showUpload' => false,
]
]); ?>
So what should i do here?
Thank you
try this
In Model create a scenario named 'update' and mention the fields that are required when update action works
return [
[['price', 'created_date', 'created_by','updated_date','updated_by','address'], 'required', 'on' => 'update'],
];
Now inside controller action update call the scenario
public function actionUpdate(){
//Model Declaration
$model->scenario = 'update';
// update code
}