I am using a mySql DECIMAL(12,4) column to hold price values (seeing how that's what Magento uses). I want to validate them in my ActiveRecord model using Yii's CValidator rules, but I'm not quite sure how to do it.
I assume I can do it with the CTypeValidator set to "float", but I wanted to see how other folks are doing this. I don't see an actual "currency" validator. Maybe I should just validate the length?
array('price', 'type', 'type'=>'float'),
or
array('price', 'length', 'max'=>17), // 12 + 4 + . = 17?
Suggestions and examples? Thanks!
I myself used the:
array('price', 'type', 'type'=>'float'),
rule... if needed, you can also use or combine the previous with the 'match' validator
array('price', 'match', 'pattern'=>'fancy regex magic here'),
To add a working example, as this is common question (with no good answer in SO)"
public function rules(){
...
array('price', 'match', 'pattern'=>'/^[0-9]{1,12}(\.[0-9]{0,4})?$/'),
...
where {1,12} is the range of whole digits , and {0,4} is the range of "sub" units.
For a normal price range of 0.01 to 9999.99 use the regex like this:
'/^[0-9]{1,0}(\.[0-9]{0,2})?$/'
ref: kitune in Yii forums
For number validation you can use:
array('price', 'numerical', 'integerOnly' => false, 'min' => 0),
If you need to restrict digits before and after decimal mark then use regex as others have suggested.
Related
I would like to set a due date (dynamic), the person can register if it is 17to 60 years old.
I have tried this:
'date_naissance' => 'required|date|after:1960|before:2003-01-01'
But, I have to change the values each years.It is possible to improve this?
Thank you
You can try something like this:
$year = (int)date("Y");
'date_naissance' =>
'required|date|after:'.($year - 59).'|before:'.($year - 16).'-01-01'
Or a bit more precise:
'date_naissance' =>
'required|date|after:'.date('Y-m-d', strtotime('-59 year')).'|before:'.date('Y-m-d', strtotime('-16 year'))
It should work also with this:
'date_naissance' =>
'required|date|after:-59 year|before:-16 year'))
You would need to make custom validation rule. Here is example how to do it:
LINK
You will need to make method that takes person birth date and calculate his age. If age is greater then 17 it should return true.
I have a registration form. I need to validate zipcode. Validation rules must be integer, Max length not greater than 7.
I had tried validation but it validate zip must be 5. But some countries has 6 or 4 zipcode. Any help would be appreciated.
'zipcode' => 'required|regex:/^[0-9]{5}(\-[0-9]{4})?$/',
If what you want is numeric digits only, at least 3 but no more than 7, you should use
'zipcode' => 'required|regex:/^[0-9]{3,7}$/'
How can I add an optional 10% fee over the whole order? I want my customers to be able to choose between no fee or a optional 10% fee (with some advantages for them).
At this moment, I've tried to represent this by enabling "Free shipping" and "Flat rate".
So at System/Configuration/Shipping Methods I've put the following values:
- 'Handling Fee' => '0.10'
- 'Calculate Handling Fee'=>'Percent'
- 'Type' => 'Per order'
As a result, the generated orders have a '10 cents' fee, instead of a percentage over its value.
How does can I represent this with Magento? Should I use Flat rates?
PS: I'm testing it only with back-end, should I face any difference compared with end user?
I have achieved what I was looking for by editing app/code/core/Mage/Shipping/Model/Carrier/Flatrate.php by adding the following method
protected function _getPerorderPrice($cost, $handlingType, $handlingFee){
if ($handlingType == self::HANDLING_TYPE_PERCENT) {
$val = ($cost * $this->_numBoxes * $handlingFee);
return $val;
}
return ($cost * $this->_numBoxes) $handlingFee;
}
and by changing the line 78 to:
$shippingPrice = $request->getPackageValue();
I'm not sure if this will cause any side-effect, so please comment if you identify any :)
At this moment everything seems to be working fine.
Is it possible to retrieve a count of distinct records based on a field value if the field needs to be interrogated (ideally, using ActiveRecord alone)?
For example, the following returns a count of unique records based on the 'created_at' field:
Record.count('created_at', :distinct => true)
However, is it possible to get a count of, say, unique days based on the 'created_at' field in a similar way?
A naive ActiveRecord example to explain my intent being:
Record.count('created_at'.day, :distinct => true)
(I know the string 'created_at' isn't a 'Time', but that's the sort of query I'd like to ask ActiveRecord.)
You need to group the records. For example
Record.group('DATE(created_at)').count('created_at')
tells you the number of rows created on each particular date, or
Record.group('DAYOFWEEK(created_at)').count('created_at')
would tell you the number of rows created on individual days of the week.
Beware that this with the usual active record setup this will do date calculations in UTC, if you want to do your calculations in a specific timezone you'll have to add that conversion to the group statement.
I am building a financial reporting app with Ruby on Rails. In the app I have monthly financial statement objects (with 'revenue' as an attribute). For any single financial statement, I want show (1) year-to-date revenue, and (2) last-year-to-date revenue (calendar years are fine). Each object also has a Date (not Datetime) attribute called 'month' (watch out for 'month' variable name vs. 'month' method name confusion...maybe I should change that variable name).
So...
I think I need to (1) 'find' the array of financial statements (i.e., objects) in the appropriate date range, then (2) sum the 'revenue' fields. My code so far is...
def ytd_revenue
# Get all financial_statements for year-to-date.
financial_statements_ytd = self.company.financial_statements.find(:all,
:conditions => ["month BETWEEN ? and ?", "self.month.year AND month.month = 1",
"self.month.year AND self.month.month" ])
# Sum the 'revenue' attribute
financial_statements_ytd.inject(0) {|sum, revenue| sum + revenue }
end
This does not break the app, but returns '0' which cannot be correct.
Any ideas or help would be appreciated!
This statement may do what you want:
financial_statements_ytd.inject(0) {|sum, statement| sum + statement.revenue }
You can also look into ActiveRecord's sum class method - you can pass in the field name and conditions to get the sum.
What is the name of the field in financial_statement object that holds the value you want?
Supposing that the field name is ammount then just modify the inject statement to be:
financial_statements_ytd.inject {|sum, revenue| sum + revenue.ammount }