diff options
-rw-r--r-- | extensions/BMO/Extension.pm | 252 | ||||
-rw-r--r-- | extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl | 320 |
2 files changed, 379 insertions, 193 deletions
diff --git a/extensions/BMO/Extension.pm b/extensions/BMO/Extension.pm index dba54eab0..c3c337ec5 100644 --- a/extensions/BMO/Extension.pm +++ b/extensions/BMO/Extension.pm @@ -971,88 +971,194 @@ sub _syslog { sub post_bug_after_creation { my ($self, $args) = @_; - my $vars = $args->{vars}; - my $bug = $vars->{bug}; + return unless my $format = Bugzilla->input_params->{format}; + my $bug = $args->{vars}->{bug}; - if (Bugzilla->input_params->{format} - && Bugzilla->input_params->{format} eq 'employee-incident' + if ($format eq 'employee-incident' && $bug->component eq 'Server Operations: Desktop Issues') { - my $error_mode_cache = Bugzilla->error_mode; - Bugzilla->error_mode(ERROR_MODE_DIE); + $self->_post_employee_incident_bug($args); + } + elsif ($format eq 'swag') { + $self->_post_gear_bug($args); + } +} - my $template = Bugzilla->template; - my $cgi = Bugzilla->cgi; +sub _post_employee_incident_bug { + my ($self, $args) = @_; + my $vars = $args->{vars}; + my $bug = $vars->{bug}; - my ($investigate_bug, $ssh_key_bug); - my $old_user = Bugzilla->user; - eval { - Bugzilla->set_user(Bugzilla::User->new({ name => 'nobody@mozilla.org' })); - my $new_user = Bugzilla->user; - - # HACK: User needs to be in the editbugs and primary bug's group to allow - # setting of dependencies. - $new_user->{'groups'} = [ Bugzilla::Group->new({ name => 'editbugs' }), - Bugzilla::Group->new({ name => 'infra' }), - Bugzilla::Group->new({ name => 'infrasec' }) ]; - - my $recipients = { changer => $new_user }; - $vars->{original_reporter} = $old_user; - - my $comment; - $cgi->param('display_action', ''); - $template->process('bug/create/comment-employee-incident.txt.tmpl', $vars, \$comment) - || ThrowTemplateError($template->error()); - - $investigate_bug = Bugzilla::Bug->create({ - short_desc => 'Investigate Lost Device', - product => 'mozilla.org', - component => 'Security Assurance: Incident', - status_whiteboard => '[infrasec:incident]', - bug_severity => 'critical', - cc => [ 'jstevensen@mozilla.com' ], - groups => [ 'infrasec' ], - comment => $comment, - op_sys => 'All', - rep_platform => 'All', - version => 'other', - dependson => $bug->bug_id, - }); - $bug->set_all({ blocked => { add => [ $investigate_bug->bug_id ] }}); - Bugzilla::BugMail::Send($investigate_bug->id, $recipients); - - Bugzilla->set_user($old_user); - $vars->{original_reporter} = ''; - $comment = ''; - $cgi->param('display_action', 'ssh'); - $template->process('bug/create/comment-employee-incident.txt.tmpl', $vars, \$comment) - || ThrowTemplateError($template->error()); - - $ssh_key_bug = Bugzilla::Bug->create({ - short_desc => 'Disable/Regenerate SSH Key', - product => $bug->product, - component => $bug->component, - bug_severity => 'critical', - cc => $bug->cc, - groups => [ map { $_->{name} } @{ $bug->groups } ], - comment => $comment, - op_sys => 'All', - rep_platform => 'All', - version => 'other', - dependson => $bug->bug_id, - }); - $bug->set_all({ blocked => { add => [ $ssh_key_bug->bug_id ] }}); - Bugzilla::BugMail::Send($ssh_key_bug->id, $recipients); - }; - my $error = $@; + my $error_mode_cache = Bugzilla->error_mode; + Bugzilla->error_mode(ERROR_MODE_DIE); + + my $template = Bugzilla->template; + my $cgi = Bugzilla->cgi; + + my ($investigate_bug, $ssh_key_bug); + my $old_user = Bugzilla->user; + eval { + Bugzilla->set_user(Bugzilla::User->new({ name => 'nobody@mozilla.org' })); + my $new_user = Bugzilla->user; + + # HACK: User needs to be in the editbugs and primary bug's group to allow + # setting of dependencies. + $new_user->{'groups'} = [ Bugzilla::Group->new({ name => 'editbugs' }), + Bugzilla::Group->new({ name => 'infra' }), + Bugzilla::Group->new({ name => 'infrasec' }) ]; + + my $recipients = { changer => $new_user }; + $vars->{original_reporter} = $old_user; + + my $comment; + $cgi->param('display_action', ''); + $template->process('bug/create/comment-employee-incident.txt.tmpl', $vars, \$comment) + || ThrowTemplateError($template->error()); + + $investigate_bug = Bugzilla::Bug->create({ + short_desc => 'Investigate Lost Device', + product => 'mozilla.org', + component => 'Security Assurance: Incident', + status_whiteboard => '[infrasec:incident]', + bug_severity => 'critical', + cc => [ 'jstevensen@mozilla.com' ], + groups => [ 'infrasec' ], + comment => $comment, + op_sys => 'All', + rep_platform => 'All', + version => 'other', + dependson => $bug->bug_id, + }); + $bug->set_all({ blocked => { add => [ $investigate_bug->bug_id ] }}); + Bugzilla::BugMail::Send($investigate_bug->id, $recipients); Bugzilla->set_user($old_user); - Bugzilla->error_mode($error_mode_cache); + $vars->{original_reporter} = ''; + $comment = ''; + $cgi->param('display_action', 'ssh'); + $template->process('bug/create/comment-employee-incident.txt.tmpl', $vars, \$comment) + || ThrowTemplateError($template->error()); + + $ssh_key_bug = Bugzilla::Bug->create({ + short_desc => 'Disable/Regenerate SSH Key', + product => $bug->product, + component => $bug->component, + bug_severity => 'critical', + cc => $bug->cc, + groups => [ map { $_->{name} } @{ $bug->groups } ], + comment => $comment, + op_sys => 'All', + rep_platform => 'All', + version => 'other', + dependson => $bug->bug_id, + }); + $bug->set_all({ blocked => { add => [ $ssh_key_bug->bug_id ] }}); + Bugzilla::BugMail::Send($ssh_key_bug->id, $recipients); + }; + my $error = $@; + + Bugzilla->set_user($old_user); + Bugzilla->error_mode($error_mode_cache); + + if ($error || !$investigate_bug || !$ssh_key_bug) { + warn "Failed to create additional employee-incident bug: $error" if $error; + $vars->{'message'} = 'employee_incident_creation_failed'; + } +} + +sub _post_gear_bug { + my ($self, $args) = @_; + my $vars = $args->{vars}; + my $bug = $vars->{bug}; + my $input = Bugzilla->input_params; + + my ($team, $code) = $input->{teamcode} =~ /^(.+?) \((\d+)\)$/; + my @request = ( + "Date Required: $input->{date_required}", + "$input->{firstname} $input->{lastname}", + $input->{email}, + $input->{mozspace}, + $team, + $code, + $input->{purpose}, + ); + my @recipient = ( + "$input->{shiptofirstname} $input->{shiptolastname}", + $input->{shiptoemail}, + $input->{shiptoaddress1}, + $input->{shiptoaddress2}, + $input->{shiptocity}, + $input->{shiptostate}, + $input->{shiptopostcode}, + $input->{shiptocountry}, + "Phone: $input->{shiptophone}", + $input->{shiptoidrut}, + ); + + # the csv has 14 item fields + my @items = map { trim($_) } split(/\n/, $input->{items}); + my @csv; + while (@items) { + my @batch; + if (scalar(@items) > 14) { + @batch = splice(@items, 0, 14); + } + else { + @batch = @items; + push @batch, '' for scalar(@items)..13; + @items = (); + } + push @csv, [ @request, @batch, @recipient ]; + } - if ($error || !$investigate_bug || !$ssh_key_bug) { - warn "Failed to create additional employee-incident bug: $error" if $error; - $vars->{'message'} = 'employee_incident_creation_failed'; + # csv quoting and concat + foreach my $line (@csv) { + foreach my $field (@$line) { + if ($field =~ s/"/""/g || $field =~ /,/) { + $field = qq#"$field"#; + } } + $line = join(',', @$line); + } + + $self->_add_attachment($args, { + data => join("\n", @csv), + description => "Items (CSV)", + filename => "gear_" . $bug->id . ".csv", + mimetype => "text/csv", + }); +} + +sub _add_attachment { + my ($self, $args, $attachment_args) = @_; + + my $bug = $args->{vars}->{bug}; + $attachment_args->{bug} = $bug; + $attachment_args->{creation_ts} = $bug->creation_ts; + $attachment_args->{ispatch} = 0 unless exists $attachment_args->{ispatch}; + $attachment_args->{isprivate} = 0 unless exists $attachment_args->{isprivate}; + + # If the attachment cannot be successfully added to the bug, + # we notify the user, but we don't interrupt the bug creation process. + my $old_error_mode = Bugzilla->error_mode; + Bugzilla->error_mode(ERROR_MODE_DIE); + my $attachment; + eval { + $attachment = Bugzilla::Attachment->create($attachment_args); + }; + warn "$@" if $@; + Bugzilla->error_mode($old_error_mode); + + if ($attachment) { + # Insert comment for attachment + $bug->add_comment('', { isprivate => 0, + type => CMT_ATTACHMENT_CREATED, + extra_data => $attachment->id }); + $bug->update($bug->creation_ts); + delete $bug->{attachments}; + } + else { + $args->{vars}->{'message'} = 'attachment_creation_failed'; } } diff --git a/extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl index a3bf854ea..90f50a089 100644 --- a/extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl +++ b/extensions/BMO/template/en/default/bug/create/create-swag.html.tmpl @@ -10,67 +10,81 @@ [% items = [ - { id => '', name => 'splendidest gear', }, - { id => '#157454S', name => 'very splendid package, men, s' }, - { id => '#157454M', name => 'very splendid package, men, m' }, - { id => '#157454L', name => 'very splendid package, men, l' }, - { id => '#157454X', name => 'very splendid package, men, xl' }, - { id => '#157452S', name => 'very splendid package, women, s' }, - { id => '#157452M', name => 'very splendid package, women, m' }, - { id => '#157452L', name => 'very splendid package, women, l' }, - { id => '#157452X', name => 'very splendid package, women, xl' }, - { id => '#157451S', name => 'most splendid package, s' }, - { id => '#157451M', name => 'most splendid package, m ' }, - { id => '#157451L', name => 'most splendid package, l' }, - { id => '#157451X', name => 'most splendid package, xl' }, - { id => '#155415S', name => 'sweatshirt, s' }, - { id => '#155415M', name => 'sweatshirt, m' }, - { id => '#155415L', name => 'sweatshirt, l' }, - { id => '#155415X', name => 'sweatshirt, xl' }, - { id => '#1554152', name => 'sweatshirt, 2x' }, - { id => '#155749', name => 'rickshaw messenger bag' }, - { id => '#155752', name => 'moleskine notebook (black)' }, - { id => '', name => 'splendider gear', }, - { id => '#155341S', name => 'unisex t, poppy, s' }, - { id => '#155341M', name => 'unisex t, poppy, m' }, - { id => '#155341L', name => 'unisex t, poppy, l' }, - { id => '#155341X', name => 'unisex t, poppy, xl' }, - { id => '#1553412', name => 'unisex t, poppy, 2x' }, - { id => '#155344S', name => 'ladies t, poppy, s' }, - { id => '#155344M', name => 'ladies t, poppy, m' }, - { id => '#155344L', name => 'ladies t, poppy, l' }, - { id => '#155342S', name => 'unisex t, navy, s' }, - { id => '#155342M', name => 'unisex t, navy, m' }, - { id => '#155342L', name => 'unisex t, navy, l' }, - { id => '#155342X', name => 'unisex t, navy, xl' }, - { id => '#1553422', name => 'unisex t, navy, 2x' }, - { id => '#1553423', name => 'unisex t, navy, 3x' }, - { id => '#155413S', name => 'ladies t, navy, s' }, - { id => '#155413M', name => 'ladies t, navy, m' }, - { id => '#155413L', name => 'ladies t, navy, l' }, - { id => '#155413X', name => 'ladies t, navy, xl' }, - { id => '#155343M', name => 'unisex t, lapis, m' }, - { id => '#155343L', name => 'unisex t, lapis, l' }, - { id => '#155343X', name => 'unisex t, lapis, xl' }, - { id => '#155414S', name => 'ladies t, lapis, s' }, - { id => '#155414M', name => 'ladies t, lapis, m' }, - { id => '#155414L', name => 'ladies t, lapis, l' }, - { id => '#155339', name => 'black cap w/tote' }, - { id => '#155340', name => 'beanie' }, - { id => '#155751', name => 'drawstring tote' }, - { id => '#155758', name => 'glossy finish ceramic mug' }, - { id => '', name => 'splendid gear', }, - { id => '#155755', name => 'vertical laminated badge' }, - { id => '#155754', name => 'lanyard w/bulldog clip' }, - { id => '#155756', name => 'silicone wristband' }, - { id => '#155753', name => '3" round stickers (single)' }, - { id => '#155757', name => 'mozilla tattoos (pkg 50)' }, + { id => '' , name => 'Splendidest Gear' }, + { id => '#155752' , name => 'Moleskine Notebook' }, + { id => '#155749' , name => 'Rickshaw Messenger Bag' }, + { id => '#155415S', name => 'Champion Hooded Sweatshirt S' }, + { id => '#155415M', name => 'Champion Hooded Sweatshirt M' }, + { id => '#155415L', name => 'Champion Hooded Sweatshirt L' }, + { id => '#155415X', name => 'Champion Hooded Sweatshirt XL' }, + { id => '#1554152', name => 'Champion Hooded Sweatshirt 2XL' }, + { id => '#157454S', name => 'Very Splendid Package, Men\'s S' }, + { id => '#157454M', name => 'Very Splendid Package, Men\'s M' }, + { id => '#157454L', name => 'Very Splendid Package, Men\'s L' }, + { id => '#157454X', name => 'Very Splendid Package, Men\'s XL' }, + { id => '#157452S', name => 'Very Splendid Package, Ladies S' }, + { id => '#157452M', name => 'Very Splendid Package, Ladies M' }, + { id => '#157452L', name => 'Very Splendid Package, Ladies L' }, + { id => '#157452X', name => 'Very Splendid Package, Ladies XL' }, + { id => '#157451S', name => 'Most Splendid Package, S' }, + { id => '#157451M', name => 'Most Splendid Package, M' }, + { id => '#157451L', name => 'Most Splendid Package, L' }, + { id => '#157451X', name => 'Most Splendid Package, XL' }, + { id => '' , name => 'Splendider' }, + { id => '#155341S', name => 'Unisex T-shirt Poppy S' }, + { id => '#155341M', name => 'Unisex T-shirt Poppy M' }, + { id => '#155341X', name => 'Unisex T-shirt Poppy XL' }, + { id => '#1553412', name => 'Unisex T-shirt Poppy 2XL' }, + { id => '#155344S', name => 'Ladies\' T-shirt Poppy S' }, + { id => '#155344M', name => 'Ladies\' T-shirt Poppy M' }, + { id => '#155344L', name => 'Ladies\' T-shirt Poppy L' }, + { id => '#190928S', name => 'Unisex T-shirt Navy S' }, + { id => '#190928M', name => 'Unisex T-shirt Navy M' }, + { id => '#190928L', name => 'Unisex T-shirt Navy L' }, + { id => '#190928X', name => 'Unisex T-shirt Navy XL' }, + { id => '#1553422', name => 'Unisex T-shirt Navy 2XL' }, + { id => '#1553423', name => 'Unisex T-shirt Navy 3XL' }, + { id => '#155413S', name => 'Ladies\' T-shirt Navy S' }, + { id => '#155413M', name => 'Ladies\' T-shirt Navy M' }, + { id => '#155413L', name => 'Ladies\' T-shirt Navy L' }, + { id => '#155413X', name => 'Ladies\' T-shirt Navy XL' }, + { id => '#155343M', name => 'Unisex T-shirt Lapis M' }, + { id => '#155343L', name => 'Unisex T-shirt Lapis L' }, + { id => '#155343X', name => 'Unisex T-shirt Lapis XL' }, + { id => '#155414S', name => 'Ladies\' T-shirt Lapis S' }, + { id => '#155414M', name => 'Ladies\' T-shirt Lapis M' }, + { id => '#155414L', name => 'Ladies\' T-shirt Lapis L' }, + { id => '#155339' , name => 'Black Cap with Tote' }, + { id => '#155340' , name => 'Beanie' }, + { id => '#155751' , name => 'Drawstring Tote' }, + { id => '#155758' , name => 'Glossy Finish Ceramic Mug' }, + { id => '' , name => 'Splendid' }, + { id => '#155753' , name => '3" Round Sticker, Firefox logo' }, + { id => '#155754' , name => 'Mozilla Lanyard with Bulldog Clip' }, + { id => '#155755' , name => 'Vertical Laminated Badge' }, + { id => '#155756' , name => 'Silicone Wristband' }, + { id => '#155757' , name => 'Custom Tattoos - Pkg50' }, + { id => '#192150' , name => '1.25" Firefox Button-PKG25' }, + { id => '' , name => 'Firefox OS items' }, + { id => '#185686' , name => '3" Firefox OS Sticker Look Ahead' }, + { id => '#189674' , name => '3" Firefox OS Mobilizer' }, + { id => '#187062' , name => 'OS Lanyard w/ Bulldog Clip' }, + { id => '#180589' , name => 'Sunglasses Firefox OS' }, + { id => '#180595' , name => 'Rubber Grip Pens Firefox OS' }, + { id => '#180593' , name => 'Firefox OS Moleskine Notebook' }, ] -%] -[% mozspaces = [ { + name => 'Beijing', + address1 => 'Mozilla Online Ltd, International Club Office Tower 800A', + address2 => '21 Jian Guo Men Wai Avenue', + city => 'Beijing', + state => 'Chaoyang District', + country => 'China', + postcode => '100020', + }, + { name => 'Berlin', address1 => 'MZ Denmark ApS - Germany', address2 => 'Rungestrasse 22 - 24', @@ -125,6 +139,24 @@ mozspaces = [ postcode => '94105', }, { + name => 'Taipei', + address1 => '4F-A1, No. 106, Sec.5, Xinyi Rd', + address2 => '', + city => 'Taipei City', + state => 'Xinyi District', + country => 'Taiwan', + postcode => '11047', + }, + { + name => 'Tokyo', + address1 => '7-5-6 Roppongi', + address2 => '', + city => 'Minato-ku', + state => 'Tokyo', + country => 'Japan', + postcode => '106-0032', + }, + { name => 'Toronto', address1 => 'Mozilla Canada', address2 => '366 Adelaide Street W, Suite 500', @@ -143,6 +175,104 @@ mozspaces = [ postcode => 'V6B 1H5', }, ] + +cost_centers = [ + 'Accounting (1210)', + 'Add Ons (7500)', + 'Advanced Techology Lab (6400)', + 'Brand Engagement (2400)', + 'Business Affairs (1100)', + 'Business Development (1150)', + 'Business Development Programs (7700)', + 'Business Support Services (1000)', + 'Cloud & Services (3000)', + 'Community Engagement (2300)', + 'Design (4400)', + 'Dev Infra (3130)', + 'Engagement (2000)', + 'Engineering Platform (8000)', + 'Engineering Program Management (8300)', + 'Facilities (1250)', + 'Finance Planning & Analysis (1211)', + 'Firefox (5000)', + 'Firefox Android Engineering (5310)', + 'Firefox Android Product Management (5330)', + 'Firefox Android UX (5320)', + 'Firefox Desktop (5200)', + 'Firefox Desktop Engineering (5210)', + 'Firefox Desktop Platform Integration (5240)', + 'Firefox Desktop Product Management (5230)', + 'Firefox Desktop UX (5220)', + 'Firefox Dev Tools (5400)', + 'Firefox Mobile (5300)', + 'Firefox OS Engineering I (6110)', + 'Firefox OS Engineering II (6120)', + 'Firefox OS Product Management (6200)', + 'Firefox OS UX (6300)', + 'Identity Eng (3210)', + 'Identity Infra (3110)', + 'Infrastructure (servers) (3100)', + 'Insights and Strategy (4000)', + 'IT & Network (1400)', + 'Labs (7600)', + 'Legal (1120)', + 'Localization (L10n) (5100)', + 'Location Engineering (3230)', + 'Location Infra (3150)', + 'Marketplace (7000)', + 'Marketplace Apps Engineering (7110)', + 'Marketplace Bus. Development (7400)', + 'Marketplace Engineering / AMO (7120)', + 'Marketplace Engineering /Dev Ecosystem (7130)', + 'Marketplace Product Management (7200)', + 'Marketplace UX (7300)', + 'Market Strategy (4200)', + 'Metrics (4300)', + 'Misc Infra (3160)', + 'Mobile (6000)', + 'Mobile Business Development (1130)', + 'Mobile Engineering (6130)', + 'Operations (3600)', + 'People (1340)', + 'People Ops (1320)', + 'Platform Accessibility (8490)', + 'Platform Content (8440)', + 'Platform Integration (8480)', + 'Platform Network (8410)', + 'Platform Network & Security (8400)', + 'Platform Performance (8470)', + 'Platform Rendering & Media (8450)', + 'Platform Security (8420)', + 'Platform Security Assurance (8430)', + 'Platform Stability & Plugin (8460)', + 'PR (2200)', + 'Product Marketing (2100)', + 'QA (8500)', + 'QA Android (8550)', + 'QA Automation (8520)', + 'QA Firefox Desktop (8510)', + 'QA FirefoxOS (8560)', + 'QA Mobile (8540)', + 'QA Services (8570)', + 'QA Web (8530)', + 'Release Engineering (8100)', + 'Release Management (5010)', + 'Research (6900)', + 'Services Engineering (3200)', + 'Services Product Management (3400)', + 'Services UX (3300)', + 'SUMO (2600)', + 'Sync Engineering (3220)', + 'Sync Infra (3120)', + 'UP (5500)', + 'User Research (4100)', + 'Web Engineering (8200)', + 'WebRTC (1160)', + 'WebRTC Infra (3140)', + 'Web Security and Security Automation (3500)', + 'Websites & Developer Engagement (2500)', +] + %] [% inline_style = BLOCK %] @@ -466,18 +596,20 @@ function showGear() { <h1>Mozilla Gear</h1> <p> - Want gear? Here's what to do: + Want gear? Follow the steps below and click Submit Request. +</p> +<p> + Requests are reviewed and processed on Monday morning (US/Pacific). Any + requests received after 9am Monday will be processed the following week. </p> <ul> <li> - Follow the steps below and click Submit Request. + If approved, your request will either be sent to our gear partner, Staples, + for shipment or it will be available for pick-up from your Mozilla space. </li> <li> - Requests are reviewed every Monday. If approved, we'll let you know. Then - your order will either be filled from your Mozilla space for pick-up or - sent to our gear partner, Staples, for processing and shipment. If it can't - be approved, we'll email you with details (or possibly ask for more - information). + If your request is not approved, we will let you know why or possibly ask + for more information. </li> </ul> @@ -619,7 +751,7 @@ function showGear() { <tr> <th>First Name</th> - <td><input name="firsrname" id="firstname" size="50" maxlength="30"></td> + <td><input name="firstname" id="firstname" size="50" maxlength="30"></td> </tr> <tr> @@ -653,61 +785,9 @@ function showGear() { <td> <select name="teamcode" id="teamcode"> <option value="">Please select..</option> - <option value="Applications (350)">Applications (350)</option> - <option value="Business Affairs (110)">Business Affairs (110)</option> - <option value="Engagement Brand Management (240)">Engagement Brand Management (240)</option> - <option value="Engagement Contributor (230)">Engagement Contributor (230)</option> - <option value="Engagement General (200)">Engagement General (200)</option> - <option value="Engagement PR (220)">Engagement PR (220)</option> - <option value="Engagement Product Mktg (210)">Engagement Product Mktg (210)</option> - <option value="Engagement Product Strategy (250)">Engagement Product Strategy (250)</option> - <option value="Engagement User (232)">Engagement User (232)</option> - <option value="Engagement Websites & Developer (235)">Engagement Websites & Developer (235)</option> - <option value="Engr B2G (720)">Engr B2G (720)</option> - <option value="Engr Development Tools & Auto (769)">Engr Development Tools & Auto (769)</option> - <option value="Engr Firefox (770)">Engr Firefox (770)</option> - <option value="Engr Firefox Dev Tools (775)">Engr Firefox Dev Tools (775)</option> - <option value="Engr General Admin (700)">Engr General Admin (700)</option> - <option value="Engr Jetpack (780)">Engr Jetpack (780)</option> - <option value="Engr Localization - L10N (740)">Engr Localization - L10N (740)</option> - <option value="Engr Ops Build & Release (440)">Engr Ops Build & Release (440)</option> - <option value="Engr Ops Network & IT (410)">Engr Ops Network & IT (410)</option> - <option value="Engr Ops Stats & Metrics (420)">Engr Ops Stats & Metrics (420)</option> - <option value="Engr Ops Support/SUMO (450)">Engr Ops Support/SUMO (450)</option> - <option value="Engr Ops Weave & Services (460)">Engr Ops Weave & Services (460)</option> - <option value="Engr Ops Web Dev (430)">Engr Ops Web Dev (430)</option> - <option value="Engr Platform Content (810)">Engr Platform Content (810)</option> - <option value="Engr Platform General (800)">Engr Platform General (800)</option> - <option value="Engr Platform Graphics (820)">Engr Platform Graphics (820)</option> - <option value="Engr Platform Integration (880)">Engr Platform Integration (880)</option> - <option value="Engr Platform JS (830)">Engr Platform JS (830)</option> - <option value="Engr Platform Layout (840)">Engr Platform Layout (840)</option> - <option value="Engr Platform Network (855)">Engr Platform Network (855)</option> - <option value="Engr Platform Performance (870)">Engr Platform Performance (870)</option> - <option value="Engr Platform Stability Plugins (850)">Engr Platform Stability Plugins (850)</option> - <option value="Engr Project Mgmt (710)">Engr Project Mgmt (710)</option> - <option value="Engr QA Automation (760)">Engr QA Automation (760)</option> - <option value="Engr QA Browser Technologies (767)">Engr QA Browser Technologies (767)</option> - <option value="Engr QA Firefox Desktop (755)">Engr QA Firefox Desktop (755)</option> - <option value="Engr QA Services (750)">Engr QA Services (750)</option> - <option value="Engr QA Web (765)">Engr QA Web (765)</option> - <option value="Engr Research (860)">Engr Research (860)</option> - <option value="Engr Security (730)">Engr Security (730)</option> - <option value="Facility (150)">Facility (150)</option> - <option value="Finance (120)">Finance (120)</option> - <option value="G&A (100)">G&A (100)</option> - <option value="Innovations (300)">Innovations (300)</option> - <option value="Mobile (600)">Mobile (600)</option> - <option value="Mobile UI (610)">Mobile UI (610)</option> - <option value="Pancake (530)">Pancake (530)</option> - <option value="People (140)">People (140)</option> - <option value="People Ops (130)">People Ops (130)</option> - <option value="Product Add-Ons (550)">Product Add-Ons (550)</option> - <option value="Product UX (510)">Product UX (510)</option> - <option value="Products General (500)">Products General (500)</option> - <option value="Products User Research (520)">Products User Research (520)</option> - <option value="Security Assurance (470)">Security Assurance (470)</option> - <option value="Thunderbird (320)">Thunderbird (320)</option> + [% FOREACH cost IN cost_centers %] + <option value="[% cost FILTER html %]">[% cost FILTER html %]</option> + [% END %] </select> </td> </tr> |