From 47c6aaa9948711ad52a9898d1e479462a372167e Mon Sep 17 00:00:00 2001 From: Doug Bell Date: Wed, 15 Jul 2009 04:58:33 +0000 Subject: [PATCH] added thingyrecord per-field pricing --- docs/upgrades/upgrade_7.7.13-7.7.14.pl | 16 ++++ lib/WebGUI/Asset/Sku/ThingyRecord.pm | 79 ++++++++++++++--- lib/WebGUI/i18n/English/Asset_ThingyRecord.pm | 12 +++ .../build/thingyRecord/thingyRecord.js | 85 ++++++++++++++++++- 4 files changed, 179 insertions(+), 13 deletions(-) diff --git a/docs/upgrades/upgrade_7.7.13-7.7.14.pl b/docs/upgrades/upgrade_7.7.13-7.7.14.pl index a0eaf8635..3eb50425f 100644 --- a/docs/upgrades/upgrade_7.7.13-7.7.14.pl +++ b/docs/upgrades/upgrade_7.7.13-7.7.14.pl @@ -27,6 +27,7 @@ use WebGUI::Asset; my $toVersion = '7.7.14'; my $quiet; # this line required +addFieldPriceToThingyRecord( $session ); my $session = start(); # this line required @@ -45,6 +46,21 @@ finish($session); # this line required #} +#---------------------------------------------------------------------------- +# Add the field price storage to ThingyRecord +sub addFieldPriceToThingyRecord { + my $session = shift; + print "\tAdd field prices to ThingyRecord... " unless $quiet; + + $session->db->write( + "ALTER TABLE ThingyRecord ADD COLUMN fieldPrice LONGTEXT", + ); + + print "DONE!\n" unless $quiet; +} + + + # -------------- DO NOT EDIT BELOW THIS LINE -------------------------------- #---------------------------------------------------------------------------- diff --git a/lib/WebGUI/Asset/Sku/ThingyRecord.pm b/lib/WebGUI/Asset/Sku/ThingyRecord.pm index c1572c44f..33039013f 100644 --- a/lib/WebGUI/Asset/Sku/ThingyRecord.pm +++ b/lib/WebGUI/Asset/Sku/ThingyRecord.pm @@ -18,6 +18,7 @@ use strict; use Tie::IxHash; use base 'WebGUI::Asset::Sku'; use WebGUI::Utility; +use HTML::Entities qw( encode_entities ); # Collateral data class... very long name. Zoffix eat your heart out. my $RECORD_CLASS = 'WebGUI::AssetCollateral::Sku::ThingyRecord::Record'; @@ -72,8 +73,6 @@ sub definition { options => $class->getThingOptions($session), label => $i18n->get('thingId label'), hoverHelp => $i18n->get('thingId description'), - extras => - q{onchange="WebGUI.ThingyRecord.getThingFields(this.options[this.selectedIndex].value,'thingFields_formId')"}, }, thingFields => { tab => "properties", @@ -95,6 +94,13 @@ sub definition { label => $i18n->get( '10', "Asset_Product" ), #Price hoverHelp => $i18n->get( 'price', 'Asset_Product' ), }, + fieldPrice => { + tab => "properties", + fieldType => "text", + customDrawMethod => 'drawEditFieldPrice', + label => $i18n->get( 'fieldPrice label' ), + hoverHelp => $i18n->get( 'fieldPrice hoverHelp '), + }, duration => { tab => "properties", fieldType => "interval", @@ -125,9 +131,10 @@ the header or footer! sub appendVarsEditRecord { my ( $self, $var, $recordId ) = @_; - my $session = $self->session; - my $thingy = $self->getThingy; - my $record = {}; + my $session = $self->session; + my $thingy = $self->getThingy; + my $fieldPrice = JSON->new->decode( $self->get('fieldPrice') ); + my $record = {}; if ($recordId) { # Get an existing record @@ -141,7 +148,16 @@ sub appendVarsEditRecord { my @allowed = split "\n", $self->get('thingFields'); for my $field ( @{$fields} ) { next unless grep { $_ eq $field->{fieldId} } @allowed; + + # Don't allow user to edit fields they didn't purchase + next if ( + $recordId + && $fieldPrice->{ $field->{fieldId} } > 0 + && not defined $record->{ 'field_' . $field->{fieldId} } + ); + $field->{value} = $record->{ 'field_' . $field->{fieldId} } || $field->{defaultValue}; + my $price = $fieldPrice->{ $field->{fieldId} }; my %fieldProperties = ( "input" => $thingy->getFormElement($field), "value" => $thingy->getFieldValue( $field->{value}, $field ), @@ -151,6 +167,7 @@ sub appendVarsEditRecord { "isRequired" => ( $field->{status} eq "required" ), "pretext" => $field->{pretext}, "subtext" => $field->{subtext}, + "price" => $price > 0 ? $price : "", ); push @{ $var->{form_fields} }, { map { "field_" . $_ => $fieldProperties{$_} } keys %fieldProperties }; @@ -179,6 +196,24 @@ sub deleteThingRecord { #------------------------------------------------------------------- +=head2 drawEditFieldPrice ( ) + +Draw the field to edit field prices. Add appropriate javascript. + +=cut + +sub drawEditFieldPrice { + my ( $self ) = @_; + + my $fieldHtml = sprintf <<'ENDHTML', encode_entities( $self->get('fieldPrice') ); +
+ENDHTML + + return $fieldHtml; +} + +#------------------------------------------------------------------- + =head2 getEditForm ( ) Add the javascript needed for the edit form @@ -257,7 +292,21 @@ Get the price sub getPrice { my ($self) = @_; - return $self->get('price'); + my $price = $self->get('price'); + my $fieldPrice = JSON->new->decode( $self->get('fieldPrice') ); + my $option = $self->getOptions; + my $record = $RECORD_CLASS->new( $self->session, $option->{recordId} ); + my $fields = JSON->new->decode( $record->get('fields') ); + + # Calculate field price + for my $key ( keys %{$fields} ) { + my $fieldId = substr $key, length("field_"); + if ( $fieldPrice->{ $fieldId } > 0 ) { + $price += $fieldPrice->{ $fieldId }; + } + } + + return $price; } #---------------------------------------------------------------------------- @@ -366,9 +415,9 @@ sub onCompletePurchase { # Update record $record->update( { - expires => $now + $self->get('duration'), - transactionId => $item->transaction->getId, - isHidden => 0, + expires => $now + $self->get('duration'), + transactionId => $item->transaction->getId, + isHidden => 0, } ); @@ -445,14 +494,22 @@ Process the edit record form and return the record sub processEditRecordForm { my ($self) = @_; - my $var = {}; + my $var = {}; + my $fieldPrice = JSON->new->decode( $self->get('fieldPrice') ); my $fields = $self->getThingFields( $self->get('thingId') ); for my $field ( @{$fields} ) { my $fieldName = 'field_' . $field->{fieldId}; my $fieldType = $field->{fieldType}; $fieldType = "" if ( $fieldType =~ m/^otherThing/x ); - $var->{$fieldName} = $self->session->form->get( $fieldName, $fieldType, $field->{defaultValue}, $field ); + my $value = $self->session->form->get( $fieldName, $fieldType, $field->{defaultValue}, $field ); + + # Don't save fields we didn't pay for + if ( $fieldPrice->{ $field->{fieldId} } > 0 && !$value ) { + next; + } + + $var->{ $fieldName } = $value; } return $var; diff --git a/lib/WebGUI/i18n/English/Asset_ThingyRecord.pm b/lib/WebGUI/i18n/English/Asset_ThingyRecord.pm index e5e7fc96a..6d91cf051 100644 --- a/lib/WebGUI/i18n/English/Asset_ThingyRecord.pm +++ b/lib/WebGUI/i18n/English/Asset_ThingyRecord.pm @@ -75,6 +75,18 @@ our $I18N = { lastUpdated => 0, context => "Description of asset property", }, + + 'fieldPrice label' => { + message => "Field Add-on Price", + lastUpdated => 0, + context => "Label for asset property", + }, + + 'fieldPrice description' => { + message => "Add to the base price if a user decides to fill-in this field.", + lastUpdated => 0, + context => "Description of asset property", + }, }; 1; diff --git a/www/extras/yui-webgui/build/thingyRecord/thingyRecord.js b/www/extras/yui-webgui/build/thingyRecord/thingyRecord.js index 43f55a22b..7c631359b 100644 --- a/www/extras/yui-webgui/build/thingyRecord/thingyRecord.js +++ b/www/extras/yui-webgui/build/thingyRecord/thingyRecord.js @@ -9,12 +9,13 @@ if ( typeof WebGUI.ThingyRecord == "undefined" ) { } WebGUI.ThingyRecord.getThingFields -= function ( thingId, elementId ) { += function ( thingId ) { // Callback to populate the form element var callback = { success : function (o) { - var el = document.getElementById(elementId); + // Add fields to select list + var el = document.forms[0].elements['thingFields']; while ( el.options.length >= 1 ) el.remove(0); var fields = YAHOO.lang.JSON.parse( o.responseText ); @@ -22,6 +23,9 @@ WebGUI.ThingyRecord.getThingFields el.options[el.options.length] = new Option( fields[key], key, 1, 1 ); } + + // Add fields to field price + WebGUI.ThingyRecord.updateFieldPrices(); } }; @@ -30,3 +34,80 @@ WebGUI.ThingyRecord.getThingFields ; YAHOO.util.Connect.asyncRequest( 'GET', url, callback ); }; + +WebGUI.ThingyRecord.updateFieldPrices += function ( ) { + var form = document.forms[0]; + var fieldList = form.elements["thingFields"]; + var selected = []; + var div = document.getElementById( 'fieldPrice' ); + var currentPrices = {}; + try { + currentPrices = YAHOO.lang.JSON.parse( form.elements["fieldPrice"].value ); + } + catch (e) { + // Initialize if there's a parse error + form.elements["fieldPrice"].value = "{}"; + } + + // Get the selected fields + for ( var i = 0; i < fieldList.options.length; i++ ) { + var opt = fieldList.options[i]; + if ( opt.selected ) { + selected.push( opt ); + } + else { + currentPrices[ opt.value ] = 0; + } + } + form.elements['fieldPrice'].value = YAHOO.lang.JSON.stringify( currentPrices ); + + // Clear out old records + while ( div.childNodes.length ) + div.removeChild( div.childNodes[0] ); + + for ( var i = 0; i < selected.length; i++ ) { + var opt = selected[i]; + var label = document.createElement( 'label' ); + label.style.display = "block"; + label.style.width = "50%"; + var price = document.createElement( 'input' ); + price.name = "fieldPrice_" + opt.value; + price.type = "text"; + price.size = "5"; + price.value = currentPrices[ opt.value ] ? currentPrices[ opt.value ] : "0.00"; + YAHOO.util.Event.addListener( price, "change", function () { + var fieldName = this.name.substr( "fieldPrice_".length ); + var json = YAHOO.lang.JSON.parse( form.elements["fieldPrice"].value ); + json[fieldName] = this.value; + form.elements["fieldPrice"].value = YAHOO.lang.JSON.stringify( json ); + alert( json ); + alert( form.elements["fieldPrice"].value ); + } ); + + label.appendChild( price ); + + label.appendChild( document.createTextNode( opt.text ) ); + div.appendChild( label ); + } +}; + + +// Load the columns and field prices +YAHOO.util.Event.onDOMReady( function () { + var form = document.forms[0]; + + // Add events to form fields + YAHOO.util.Event.addListener( form.elements["thingId"], "change", function () { + WebGUI.ThingyRecord.getThingFields( this.value ); + } ); + + YAHOO.util.Event.addListener( form.elements['thingFields'], "change", function () { + WebGUI.ThingyRecord.updateFieldPrices(); + } ); + + // Populate the fields list if necessary + if ( form.elements[ "thingId" ].value ) { + WebGUI.ThingyRecord.getThingFields( form.elements[ "thingId"].value ); + } +} );