# Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
__PACKAGE__->meta->make_manager_class;
+sub unparsed_value {
+ my ($self, $new) = @_;
+
+ $self->{__unparsed_value} = $new;
+}
+
+sub _ensure_config {
+ my ($self) = @_;
+
+ return $self->config if $self->config;
+ return undef if !defined $self->config_id;
+ $self->config( SL::DB::CustomVariableConfig->new(id => $self->config_id)->load );
+}
+
+sub parse_value {
+ my ($self) = @_;
+ my $type = $self->_ensure_config->type;
+
+ return unless exists $self->{__unparsed_value};
+
+ my $unparsed = delete $self->{__unparsed_value};
+
+ if ($type =~ m{^(?:customer|vendor|part|bool|number)}) {
+ return $self->number_value(defined($unparsed) ? $unparsed * 1 : undef);
+ }
+
+ if ($type =~ m{^(?:date|timestamp)}) {
+ return $self->timestamp_value(defined($unparsed) ? DateTime->from_kivi($unparsed) : undef);
+ }
+
+ # text, textfield, select
+ $self->text_value($unparsed);
+}
+
sub value {
my $self = $_[0];
- my $type = $self->config->type;
+ my $type = $self->_ensure_config->type;
+
+ if (scalar(@_) > 1) {
+ $self->unparsed_value($_[1]);
+ $self->parse_value;
+ }
goto &bool_value if $type eq 'bool';
goto ×tamp_value if $type eq 'timestamp';
goto &number_value if $type eq 'number';
- if ( $_[1] && ($type eq 'customer' || $type eq 'vendor' || $type eq 'part') ) {
- $self->number_value($_[1]);
- }
-
if ( $type eq 'customer' ) {
require SL::DB::Customer;
make_cvar_by_configs($caller_package, %params);
make_cvar_by_name($caller_package, %params);
make_cvar_as_hashref($caller_package, %params);
+ make_cvar_value_parser($caller_package, %params);
}
sub save_meta_info {
}
}
+sub make_cvar_value_parser {
+ my ($caller_package) = @_;
+ no strict 'refs';
+ *{ $caller_package . '::parse_custom_variable_values' } = sub {
+ my ($self) = @_;
+
+ $_->parse_value for @{ $self->custom_variables || [] };
+
+ return $self;
+ };
+
+ $caller_package->before_save('parse_custom_variable_values');
+}
+
sub _all_configs {
my (%params) = @_;
Useful for print templates. If the requested cvar is not present, it will be
vivified with the same rules as in C<cvars_by_config>.
+=item C<parse_custom_variable_values>
+
+When you want to edit custom variables in a form then you have
+unparsed values from the user. These should be written to the
+variable's C<unparsed_value> field.
+
+This function then processes all variables and parses their
+C<unparsed_value> field into the proper field. It returns C<$self> for
+easy chaining.
+
+This is automatically called in a C<before_save> hook so you don't
+have to do it manually if you save directly after assigning the
+values.
+
+In an HTML form you could e.g. use something like the following:
+
+ [%- FOREACH var = SELF.project.cvars_by_config.as_list %]
+ [% HTML.escape(var.config.description) %]:
+ [% L.hidden_tag('project.custom_variables[+].config_id', var.config.id) %]
+ [% PROCESS 'common/render_cvar_input.html' var_name='project.custom_variables[].unparsed_value' %]
+ [%- END %]
+
+Later in the controller when you want to save this project you don't
+have to do anything special:
+
+ my $project = SL::DB::Project->new;
+ my $params = $::form->{project} || {};
+
+ $project->assign_attributes(%{ $params });
+
+ $project->parse_custom_variable_values->save;
+
+However, if you need access to a variable's value before saving in
+some way then you have to call this function manually. For example:
+
+ my $project = SL::DB::Project->new;
+ my $params = $::form->{project} || {};
+
+ $project->assign_attributes(%{ $params });
+
+ $project->parse_custom_variable_values;
+
+ print STDERR "CVar[0] value: " . $project->custom_variables->[0]->value . "\n";
+
=back
=head1 AUTHOR