File Coverage

blib/lib/Interchange6/Test/Role/Fixtures.pm
Criterion Covered Total %
statement 19 21 90.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 28 92.8


line stmt bran cond sub pod time code
1             package Interchange6::Test::Role::Fixtures;
2 2     2   22794 use utf8;
  2         18  
  2         9  
3              
4             =head1 NAME
5              
6             Interchange6::Test::Role::Fixtures
7              
8             =cut
9              
10 2     2   727 use Interchange6::Schema::Populate::CountryLocale;
  2         6  
  2         83  
11 2     2   1074 use Interchange6::Schema::Populate::MessageType;
  2         4  
  2         50  
12 2     2   758 use Interchange6::Schema::Populate::StateLocale;
  2         5  
  2         64  
13 2     2   1026 use Interchange6::Schema::Populate::Zone;
  2         5  
  2         60  
14 2     2   10 use Sub::Quote qw/quote_sub/;
  2         2  
  2         112  
15 2     2   461 use DateTime;
  0            
  0            
16              
17             use Moo::Role;
18              
19             # accessors are ordered in this array based on the order in which
20             # clear_all_fixtures needs to receive them so that there are no FK issues in
21             # the database during row deletion
22              
23             my @accessors = qw(orders addresses shipment_rates taxes zones states
24             countries navigation price_modifiers roles inventory media products
25             attributes users message_types shipment_carriers);
26              
27             # Create all of the accessors and clearers. Builders should be defined later.
28              
29             foreach my $accessor (@accessors) {
30             has $accessor => (
31             is => 'lazy',
32             clearer => "_clear_$accessor",
33             predicate => 1,
34             );
35              
36             next if $accessor eq 'media'; # see below
37             next if $accessor eq 'orders'; # see below
38             next if $accessor eq 'products'; # see below
39              
40             my $cref = q{
41             my $self = shift;
42             $self->$accessor->delete_all;
43             my $_clear_accessor = "_clear_$accessor";
44             $self->$_clear_accessor;
45             };
46             quote_sub "main::clear_$accessor", $cref, { '$accessor' => \$accessor };
47             }
48              
49             # clearing products is not so simple...
50              
51             sub clear_media {
52             my $self = shift;
53              
54             my $schema = $self->ic6s_schema;
55             $schema->resultset('Media')->delete;
56             $schema->resultset('MediaDisplay')->delete;
57             $schema->resultset('MediaType')->delete;
58              
59             $self->_clear_media;
60             }
61              
62             sub clear_orders {
63             my $self = shift;
64             my $schema = $self->ic6s_schema;
65             $schema->resultset('OrderlinesShipping')->delete;
66             $schema->resultset('Shipment')->delete;
67             $schema->resultset('Orderline')->delete;
68             $schema->resultset('Order')->delete;
69             $self->_clear_orders;
70             }
71              
72             sub clear_products {
73             my $self = shift;
74              
75             # find canonical products
76             my $rset = $self->products->search( { canonical_sku => undef } );
77             while ( my $product = $rset->next ) {
78             my $rset = $product->variants;
79              
80             # delete variants before canonical product
81             $product->variants->delete_all;
82             $product->delete;
83             }
84             $self->_clear_products;
85             }
86              
87             =head1 ATTRIBUTES
88              
89             Fixtures are not installed in the database until the attribute is called. This is achieved by all accessors being lazy and so builders exist for each accessor to install the fixtures on demand.
90              
91             =head2 addresses
92              
93             Depends on users, states (possibly) and countries.
94              
95             =cut
96              
97             sub _build_addresses {
98             my $self = shift;
99             my $rset = $self->ic6s_schema->resultset('Address');
100              
101             my $user;
102              
103             # we must have users and countries before we can proceed
104             $self->users unless $self->has_users;
105             $self->countries unless $self->has_countries;
106              
107             my $customers =
108             $self->users->search( { username => { like => 'customer%' } },
109             { order_by => 'username' } );
110              
111             $user = $customers->next;
112              
113             scalar $rset->populate(
114             [
115             [qw(users_id type address address_2 city country_iso_code)],
116             [ $user->id, 'billing', '42', 'Triq il-Kbira', 'Qormi', 'MT' ],
117             [ $user->id, 'shipping', '11', 'The Mall', 'London', 'GB' ],
118             [ $user->id, 'shipping', '143', 'Place Blanche', 'Paris', 'FR' ],
119             ]
120             );
121              
122             $user = $customers->next;
123              
124             my $state_on = $self->states->search(
125             {
126             country_iso_code => 'CA',
127             state_iso_code => 'ON'
128             },
129             { rows => 1 }
130             )->single;
131              
132             my $state_ny = $self->states->search(
133             {
134             country_iso_code => 'US',
135             state_iso_code => 'NY'
136             },
137             { rows => 1 }
138             )->single;
139              
140             scalar $rset->populate(
141             [
142             [
143             qw(users_id type address address_2 city states_id country_iso_code)
144             ],
145             [
146             $user->id, 'billing', '10', 'Yale Street',
147             'London', $state_on->id, 'CA'
148             ],
149             [
150             $user->id, 'billing', '2', 'Time Square',
151             'New York', $state_ny->id, 'US'
152             ],
153             [
154             $user->id, 'shipping', '134', 'Mill Street',
155             'Hancock', $state_ny->id, 'US'
156             ],
157             ]
158             );
159              
160             $user = $customers->next;
161              
162             scalar $rset->populate(
163             [
164             [qw(users_id type address address_2 city country_iso_code)],
165             [ $user->id, 'billing', '17', 'Allerhop', 'Wedemark', 'DE' ],
166             [ $user->id, 'shipping', '276', 'Büchel', 'Aachen', 'DE' ],
167             ]
168             );
169              
170             return $rset;
171             }
172              
173             =head2 countries
174              
175             Populated via L.
176              
177             =cut
178              
179             sub _build_countries {
180             my $self = shift;
181             my $rset = $self->ic6s_schema->resultset('Country');
182             if ( $rset->count == 0 ) {
183             my $pop = Interchange6::Schema::Populate::CountryLocale->new->records;
184             $rset->populate($pop) or die "Failed to populate Country";
185             }
186             return $rset;
187             }
188              
189             =head2 roles
190              
191             =cut
192              
193             sub _build_roles {
194             my $self = shift;
195             my $rset = $self->ic6s_schema->resultset("Role");
196              
197             if ( $rset->count == 0 ) {
198             my $pop = Interchange6::Schema::Populate::Role->new->records;
199             $rset->populate($pop) or die "Failed to populate Role";
200             }
201              
202             # Add a few additional roles
203             scalar $rset->populate(
204             [
205             { name => 'editor', label => 'Editor', description => 'Editor' },
206             { name => 'wholesale', label => 'Wholesale customer', description => 'Wholesale Customer.' },
207             { name => 'trade', label => 'Trade customer', description => 'Trade Customer.' },
208             ]
209             );
210             return $rset;
211             }
212              
213             =head2 orders
214              
215             =cut
216              
217             sub _build_orders {
218             my $self = shift;
219             my $schema = $self->ic6s_schema;
220              
221             # prereqs
222             $self->products unless $self->has_products;
223             $self->addresses unless $self->has_addresses;
224              
225             my $rset = $schema->resultset('Order');
226              
227             my $customer1 = $self->users->find( { username => 'customer1' } );
228              
229             my $billing_address =
230             $customer1->addresses->search( { type => 'billing' }, { rows => 1 } )
231             ->single;
232              
233             my $shipping_address =
234             $customer1->addresses->search( { type => 'shipping' }, { rows => 1 } )
235             ->single;
236              
237             my @orderlines = (
238             {
239             sku => 'os28112',
240             name => 'Garden Shovel',
241             description => '',
242             quantity => 1,
243             price => 13.99,
244             subtotal => 13.99,
245             },
246             {
247             sku => 'os28113',
248             name => 'The Claw Hand Rake',
249             description => '',
250             quantity => 2,
251             price => 14.99,
252             subtotal => 29.98,
253             },
254             );
255              
256             my $payment_order = {
257             users_id => $customer1->id,
258             amount => 56.47,
259             };
260              
261             $rset->create(
262             {
263             order_number => '122334',
264             order_date => DateTime->now,
265             users_id => $customer1->id,
266             email => $customer1->email,
267             shipping_addresses_id => $shipping_address->id,
268             billing_addresses_id => $billing_address->id,
269             orderlines => \@orderlines,
270             subtotal => 43.97,
271             shipping => 12.50,
272             total_cost => 56.47,
273             payment_orders => [$payment_order],
274             }
275             );
276              
277             my $customer2 = $self->users->find( { username => 'customer2' });
278              
279             $billing_address =
280             $customer2->addresses->search( { type => 'billing' }, { rows => 1 } )
281             ->single;
282              
283             $shipping_address =
284             $customer2->addresses->search( { type => 'shipping' }, { rows => 1 } )
285             ->single;
286              
287             $payment_order = {
288             users_id => $customer2->id,
289             amount => 56.47,
290             };
291              
292             $rset->create(
293             {
294             order_number => '122339',
295             order_date => DateTime->now,
296             users_id => $customer2->id,
297             email => $customer2->email,
298             shipping_addresses_id => $shipping_address->id,
299             billing_addresses_id => $billing_address->id,
300             orderlines => \@orderlines,
301             subtotal => 43.97,
302             shipping => 12.50,
303             total_cost => 56.47,
304             payment_orders => [$payment_order],
305             }
306             );
307              
308             return $rset;
309             }
310              
311             =head2 shipment_carriers
312              
313             =cut
314              
315             sub _build_shipment_carriers {
316             my $self = shift;
317             my $rset = $self->ic6s_schema->resultset('ShipmentCarrier');
318              
319             $rset->create(
320             {
321             name => 'UPS',
322             account_number => '1U99999',
323             shipment_methods => [
324             {
325             name => '1DM',
326             title => 'Next Day Air Early AM',
327             max_weight => '150',
328              
329             },
330             {
331             name => 'GNDRES',
332             title => 'Ground Residential',
333             max_weight => '150',
334             }
335             ]
336             }
337             );
338             $rset->create(
339             {
340             name => 'KISS',
341             account_number => '1K99999',
342             shipment_methods => [
343             {
344             name => 'KISSFAST',
345             title => 'Keep it Simple and Stupid',
346             max_weight => '60',
347             },
348             ]
349             }
350             );
351             return $rset;
352             }
353              
354             =head2 shipment_rates
355              
356             =cut
357              
358             sub _build_shipment_rates {
359             my $self = shift;
360             my $schema = $self->ic6s_schema;
361             my $rset = $schema->resultset('ShipmentRate');
362              
363             # prereqs
364             $self->shipment_carriers unless $self->has_shipment_carriers;
365             $self->zones unless $self->has_zones;
366              
367             $rset->create(
368             {
369             zones_id => $self->zones->find( { zone => 'US lower 48' } )->id,
370             shipment_methods_id => $schema->resultset('ShipmentMethod')
371             ->search( { name => 'GNDRES' }, { rows => 1 } )->single->id,
372             min_weight => 0,
373             max_weight => 0,
374             price => 9.95,
375             },
376             );
377             $rset->create(
378             {
379             zones_id => $self->zones->find( { zone => 'US lower 48' } )->id,
380             shipment_methods_id => $schema->resultset('ShipmentMethod')
381             ->search( { name => '1DM' }, { rows => 1 } )->single->id,
382             min_weight => 0,
383             max_weight => 0,
384             price => 29.95,
385             },
386             );
387             return $rset;
388             }
389              
390             =head2 price_modifiers
391              
392             =cut
393              
394             sub _build_price_modifiers {
395             my $self = shift;
396             my $rset = $self->ic6s_schema->resultset('PriceModifier');
397              
398             # we must have roles and products before we can proceed
399             $self->products unless $self->has_products;
400             $self->roles unless $self->has_roles;
401              
402             my $start = DateTime->new( year => 2000, month => 1, day => 1 );
403             my $end = DateTime->new( year => 2000, month => 12, day => 31 );
404              
405             my $product = $self->products->find(
406             { sku => 'G0001' });
407             my $role_user = $self->roles->find(
408             { name => 'user' });
409             my $role_trade = $self->roles->find(
410             { name => 'trade' });
411             my $role_wholesale = $self->roles->find(
412             { name => 'wholesale' });
413              
414             scalar $rset->populate(
415             [
416             [qw/sku quantity roles_id price start_date end_date/],
417             [ 'os28005', 10, undef, 8.49, undef, undef ],
418             [ 'os28005', 10, $role_user->id, 8.20, undef, undef ],
419             [ 'os28005', 20, $role_user->id, 8.00, undef, undef ],
420             [ 'os28005', 30, $role_user->id, 7.80, undef, undef ],
421             [ 'os28005', 1, $role_trade->id, 8, undef, undef ],
422             [ 'os28005', 10, $role_trade->id, 7.80, undef, undef ],
423             [ 'os28005', 20, $role_trade->id, 7.50, undef, undef ],
424             [ 'os28005', 50, $role_trade->id, 7, undef, undef ],
425             [ 'os28005', 1, $role_wholesale->id, 7, undef, undef ],
426             [ 'os28005', 10, $role_wholesale->id, 6.80, undef, undef ],
427             [ 'os28005', 20, $role_wholesale->id, 6.70, undef, undef ],
428             [ 'os28005', 50, $role_wholesale->id, 6.50, undef, undef ],
429             [ 'os28005', 200, $role_wholesale->id, 6.10, undef, undef ],
430             [ 'os28005', 1, undef, 7.50, $start, $end ],
431             [ 'os28005', 1, $role_trade->id, 6.90, $start, $end ],
432             [ 'os28006', 1, undef, 24.99, undef, undef ],
433             ]
434             );
435             return $rset;
436             }
437              
438             =head2 products
439              
440             =cut
441              
442             sub _build_products {
443             my $self = shift;
444             my $rset = $self->ic6s_schema->resultset('Product');
445              
446             # we must have attributes and message_types (for reviews)
447             $self->attributes unless $self->has_attributes;
448             $self->message_types unless $self->has_message_types;
449              
450             my @products = (
451             [qw(sku name short_description description price uri weight)],
452             [
453             "os28004",
454             qq(Ergo Roller),
455             qq(Ergo Roller),
456             qq(The special ergonomic design of our paint rollers has been recommended by physicians to ease the strain of repetitive movements. This unique roller design features "pores" to hold and evenly distribute more paint per wetting than any other brush.),
457             21.99,
458             "ergo-roller",
459             1
460             ],
461             [
462             "os28005",
463             qq(Trim Brush),
464             qq(Trim Brush),
465             qq(Our trim paint brushes are perfectly designed. The ergonomic look and feel will save hours of pain and the unique brush design allows paint to flow evenly and consistently.),
466             8.99,
467             "trim-brush",
468             1
469             ],
470             [
471             "os28006",
472             qq(Painters Brush Set),
473             qq(Painters Brush Set),
474             qq(This set includes 2" and 3" trim brushes and our ergonomically designer paint roller. A perfect choice for any painting project.),
475             29.99,
476             "painters-brush-set",
477             1
478             ],
479             [
480             "os28007",
481             qq(Disposable Brush Set),
482             qq(Disposable Brush Set),
483             qq(This set of disposable foam brushes is ideal for any staining project. The foam design holds the maximum amount of stain and the wood handle allows you to preview the color before you apply it. This set includes a brush for all needs. 1/2", 1", 2", 3" are included.),
484             14.99,
485             "disposable-brush-set",
486             1
487             ],
488             [
489             "os28008",
490             qq(Painters Ladder),
491             qq(Painters Ladder),
492             qq(This 6' painters ladder is perfect for getting around in almost any room. The paint tray is reinforced to hold up to a 5 gallon paint bucket. The only time you'll have to get down is to move your ladder!),
493             29.99,
494             "painters-ladder",
495             3
496             ],
497             [
498             "os28009",
499             qq(Brush Set),
500             qq(Brush Set),
501             qq(This Hand Brush set includes our carpenters hand brush and a flat handled brush for the bigger cleanups. Both brushes are made of the finest horsehair and are ideal for all surfaces.),
502             9.99,
503             "brush-set",
504             1
505             ],
506             [
507             "os28011",
508             qq(Spackling Knife),
509             qq(Spackling Knife),
510             qq(A must have for all painters! This spackling knife is ergonomically designed for ease of use and boasts a newly designed finish to allow easy clean up.),
511             14.99,
512             "spackling-knife",
513             1
514             ],
515             [
516             "os28044",
517             qq(Framing Hammer),
518             qq(Framing Hammer),
519             qq(Enjoy the perfect feel and swing of our line of hammers. This framing hammer is ideal for the most discriminating of carpenters. The handle is perfectly shaped to fit the hand and the head is weighted to get the most out of each swing.),
520             19.99,
521             "framing-hammer",
522             2
523             ],
524             [
525             "os28057a",
526             qq(16 Penny Nails),
527             qq(16 Penny Nails),
528             qq(Try our high quality 16 penny titanium nails for a lifetime of holding power. Box count about 100 nails.),
529             14.99,
530             "16-penny-nails",
531             1
532             ],
533             [
534             "os28057b",
535             qq(8 Penny Nails),
536             qq(8 Penny Nails),
537             qq(Our 8 penny nails are perfect for those hard to reach spots. Made of titanium they are guaranteed to last as long as your project. Box count about 200 nails.),
538             12.99,
539             "8-penny-nails",
540             1
541             ],
542             [
543             "os28057c",
544             qq(10 Penny Nails),
545             qq(10 Penny Nails),
546             qq(Perfect for all situations our titanium 10 Penny nails should be a part of every project. Box count about 100 nails.),
547             13.99,
548             "10-penny-nails",
549             1
550             ],
551             [
552             "os28062",
553             qq(Electricians Plier Set),
554             qq(Electricians Plier Set),
555             qq(This electricians set includes heavy duty needle-nose pliers and wire cutters. The needle-nose pliers have an extended tip making them easy to get into those hard to reach places, and the cutters are equipped with spring action so they bounce back ready for the next cut.),
556             24.99,
557             "electricians-plier-set",
558             1
559             ],
560             [
561             "os28064",
562             qq(Mechanics Wrench Set),
563             qq(Mechanics Wrench Set),
564             qq(This 5 piece set is ideal for all mechanics. Available in standard and metric sizes these tools are guaranteed to cover all of your needs.),
565             19.99,
566             "mechanics-wrench-set",
567             2
568             ],
569             [
570             "os28065",
571             qq(Mechanics Pliers),
572             qq(Mechanics Pliers),
573             qq(Our mechanics pliers are available in multiple sizes for all of your needs. From 1/4" to 3" in diameter.),
574             18.99,
575             "mechanics-pliers",
576             2
577             ],
578             [
579             "os28066",
580             qq(Big L Carpenters Square),
581             qq(Big L Carpenters Square),
582             qq(The "Big L" is a must for every carpenter. Designed for ease of use, this square is perfect for measuring and marking cuts, ensuring that you get the right cut every time!),
583             14.99,
584             "big-l-carpenters-square",
585             1
586             ],
587             [
588             "os28068a",
589             qq(Breathe Right Face Mask),
590             qq(Breathe Right Face Mask),
591             qq(The unique design of our "Breathe Right" face mask is a must for all applications. Our patented micro-fiber insures that 90% of all dust and harmful materials are filtered out before you breathe them in. EDITED),
592             5.99,
593             "breathe-right-face-mask",
594             1
595             ],
596             [
597             "os28068b",
598             qq(The Bug Eye Wear),
599             qq(The Bug Eye Wear),
600             qq(Nothing protects your vision like "The Bug". The unique design of these safety goggles is practically impenetrable and our special venting technology will make you forget you even have them on.),
601             12.00,
602             "the-bug-eye-wear",
603             1
604             ],
605             [
606             "os28069",
607             qq(Flat Top Toolbox),
608             qq(Flat Top Toolbox),
609             qq(This heavy weight tool box is perfect for any handy person. The lift out top is perfect for a carry along, and there is plenty of open space for larger tool storage.),
610             44.99,
611             "flat-top-toolbox",
612             2
613             ],
614             [
615             "os28070",
616             qq(Electricians Tool Belt),
617             qq(Electricians Tool Belt),
618             qq(This tool belt is perfectly designed for the specialized tools of the electrical trade. There is even a pocket for your voltage meter in this 100% leather belt!),
619             39.99,
620             "electricians-tool-belt",
621             1
622             ],
623             [
624             "os28072",
625             qq(Deluxe Hand Saw),
626             qq(Deluxe Hand Saw),
627             qq(Our deluxe hand saw is perfect for precision work. This saw features an ergonomic handle and carbide tipped teeth. Available in 2', 2.5', and 3' lengths.),
628             17.99,
629             "deluxe-hand-saw",
630             1
631             ],
632             [
633             "os28073",
634             qq(Mini-Sledge),
635             qq(Mini-Sledge),
636             qq(Our mini-sledge hammer is superior for smaller jobs that require a little more power. Give this one a try on landscaping stakes and concrete frames.),
637             24.99,
638             "mini-sledge",
639             3
640             ],
641             [
642             "os28074",
643             qq(Rubber Mallet),
644             qq(Rubber Mallet),
645             qq(Perfectly weighted and encased in rubber this mallet is designed for ease of use in all applications.),
646             24.99,
647             "rubber-mallet",
648             2
649             ],
650             [
651             "os28075",
652             qq(Modeling Hammer),
653             qq(Modeling Hammer),
654             qq(Ideal for the hobbiest this modeling hammer is made for the delicate work. Fits easily into small spaces and the smaller head size is perfect for intricate projects.),
655             14.99,
656             "modeling-hammer",
657             2
658             ],
659             [
660             "os28076",
661             qq(Digger Hand Trencher),
662             qq(Digger Hand Trencher),
663             qq(The "Digger" is a gardeners dream. Specially designed for moving dirt it boasts two different styles of blade. Use the one side for trenching, or use the other side with it's wider angle to get hard to handle roots out of the ground. Available in 3" size only.),
664             18.99,
665             "digger-hand-trencher",
666             1
667             ],
668             [
669             "os28077",
670             qq(Carpenter's Tool Belt),
671             qq(Carpenter's Tool Belt),
672             qq(Specially designed this tool belt comes with all of the carpenter's necessities. Made of 100% leather this tool belt boasts a hammer hockey, tape measure hockey, and cordless drill holster. Multiple pockets will allow you to eliminate those extra trips back to the tool box.),
673             39.99,
674             "carpenter-foots-tool-belt",
675             1
676             ],
677             [
678             "os28080",
679             qq(The Blade Hand Planer),
680             qq(The Blade Hand Planer),
681             qq(The perfect precision hand planer. Our patented blade technology insures that you will never have to change or sharpen the blade. Available in 1", 1.5", and 2" widths.),
682             19.99,
683             "the-blade-hand-planer",
684             1
685             ],
686             [
687             "os28081",
688             qq(Steel Wool),
689             qq(Steel Wool),
690             qq(Available in all different weights this steel wool is more durable than any other. Perfect for stain removal or smoothing hard to reach surfaces.),
691             8.99,
692             "steel-wool",
693             1
694             ],
695             [
696             "os28082",
697             qq(24" Level),
698             qq(24" Level),
699             qq(Certified accuracy, High strength, long life, Built-in rubber grips for usefulness. Easy to clean.),
700             34.99,
701             "24-inch-level",
702             1
703             ],
704             [
705             "os28084",
706             qq(Tape Measure),
707             qq(Tape Measure),
708             qq(No matter what you need to measure you are sure to find the ideal tape measure here. All of our tape measures are spring loaded for fast retraction and all lock in place for extended measuring. Available in 10', 16', 24', and 36'.),
709             19.99,
710             "tape-measure",
711             1
712             ],
713             [
714             "os28085",
715             qq(Big A A-Frame Ladder),
716             qq(Big A A-Frame Ladder),
717             qq(The "Big A" is the ideal A-Frame ladder. Available in both 6' and 12' heights you are sure to find the one that meets your needs. The treads of both sides are reinforced for climbing making placement a breeze.),
718             36.99,
719             "big-a-a-frame-ladder",
720             3
721             ],
722             [
723             "os28086",
724             qq(Folding Ruler),
725             qq(Folding Ruler),
726             qq(This 6' folding ruler is a perfect fit in almost any toolbox. Only 12" folded this measuring tool is handy and portable.),
727             12.99,
728             "folding-ruler",
729             1
730             ],
731             [
732             "os28087",
733             qq(Sanders Multi-Pac),
734             qq(Sanders Multi-Pac),
735             qq(This multi-pack of sand paper includes all levels of sand paper from a very fine grit to a very course grit. Ideal for all applications!),
736             11.99,
737             "sanders-multi-pac",
738             1
739             ],
740             [
741             "os28108",
742             qq(Hand Brush),
743             qq(Hand Brush),
744             qq(This carpenters hand brush is ideal for the small clean ups needed for precision work. Made of refined horse hair it is perfect for even the most sensitive of materials.),
745             5.99,
746             "hand-brush",
747             1
748             ],
749             [
750             "os28109",
751             qq(Mini-Spade),
752             qq(Mini-Spade),
753             qq(This mini-spade is perfect hole digging, tree planting, or trenching. The easy grip handle allows more control over thrust and direction. Available in 4' only),
754             24.99,
755             "mini-spade",
756             2
757             ],
758             [
759             "os28110",
760             qq(Mighty Mouse Tin Snips),
761             qq(Mighty Mouse Tin Snips),
762             qq(Small and ready to go these tin snips are ideal for cutting patches and vent holes. With the patented blades they are also perfect for cutting aluminum flashing. Available in 3" length only.),
763             14.99,
764             "mighty-mouse-tin-snips",
765             1
766             ],
767             [
768             "os28111",
769             qq(Hedge Shears),
770             qq(Hedge Shears),
771             qq(A perfect fit for all users these 10" hedge shears are designed to make the most out of every cut. The ergonomic handle design will allow hours of cutting time so you can tackle those really big projects. One size only),
772             19.99,
773             "hedge-shears",
774             1
775             ],
776             [
777             "os28112",
778             qq(Garden Shovel),
779             qq(Garden Shovel),
780             qq(The blade on this garden shovel is 7" inches long making it ideal for the potting enthusiast. Ergonomic design makes for ease of use with this tool.),
781             13.99,
782             "garden-shovel",
783             2
784             ],
785             [
786             "os28113",
787             qq(The Claw Hand Rake),
788             qq(The Claw Hand Rake),
789             qq(Extend the reach of your potting with "The Claw". Perfect for agitating soil in the most difficult places this 3 tine tool is ideal for every gardener. Small and Large sizes available.),
790             14.99,
791             "the-claw-hand-rake",
792             1
793             ],
794             [
795             "os29000", qq(3' Step Ladder),
796             qq(3' Step Ladder), qq(),
797             44.99, "3-foot-step-ladder",
798             0
799             ],
800             [
801             "sv13213",
802             "Painting Service",
803             "Let our professional painters do the work for you",
804             "If you don't have time for DIY then why not take advantage of our professional painting service. Fixed hourly rates for any job",
805             75,
806             "professional-painting-service",
807             0
808             ]
809             );
810              
811             scalar $rset->populate( [@products] );
812              
813             # sv13213 is inventory_exempt
814             $rset->find( { sku => "sv13213" } )->update( { inventory_exempt => 1 } );
815              
816             $rset->find( { sku => "os28057a" } )
817             ->add_attribute( { type => 'simple', name => 'length' }, '3.5 inches' );
818              
819             $rset->find( { sku => "os28057b" } )
820             ->add_attribute( { type => 'simple', name => 'length' }, '2.5 inches' );
821              
822             $rset->find( { sku => "os28057c" } )
823             ->add_attribute( { type => 'simple', name => 'length' }, '3.0 inches' );
824              
825             $rset->find( { sku => "os28057a" } )
826             ->add_attribute( { type => 'simple', name => 'box_quantity' }, '100' );
827              
828             $rset->find( { sku => "os28057b" } )
829             ->add_attribute( { type => 'simple', name => 'box_quantity' }, '200' );
830              
831             $rset->find( { sku => "os28057c" } )
832             ->add_attribute( { type => 'simple', name => 'box_quantity' }, '100' );
833              
834             $rset->find( { sku => "os28085" } )->add_variants(
835             {
836             sku => 'os28085-6',
837             price => 36.99,
838             uri => 'big-a-a-frame-ladder-6-foot-high',
839             height => '6 foot',
840             },
841             {
842             sku => 'os28085-12',
843             price => 54.99,
844             uri => 'big-a-a-frame-ladder-12-foot-high',
845             height => '12 foot',
846             },
847             );
848             $rset->find( { sku => "os28080" } )->add_variants(
849             {
850             sku => 'os28080-1',
851             price => 19.99,
852             uri => 'the-blade-hand-planer-one-inch-wide',
853             width => '1.0 inch',
854             },
855             {
856             sku => 'os28080-1HLF',
857             price => 20.99,
858             uri => 'the-blade-hand-planer-one-and-a-half-inches-wide',
859             width => '1.5 inch',
860             },
861             {
862             sku => 'os28080-2',
863             price => 21.99,
864             uri => 'the-blade-hand-planer-two-inches-wide',
865             width => '2.0 inch',
866             },
867             );
868             $rset->find( { sku => "os28072" } )->add_variants(
869             {
870             sku => 'os28072-2',
871             price => 16.99,
872             uri => 'deluxe-hand-saw-two-foot',
873             length => '2 foot',
874             },
875             {
876             sku => 'os28072-2HLF',
877             price => 17.99,
878             uri => 'deluxe-hand-saw-two-and-a-half-foot',
879             length => '2.5 foot',
880             },
881             {
882             sku => 'os28072-3',
883             price => 18.99,
884             uri => 'deluxe-hand-saw-three-foot',
885             length => '3 foot',
886             },
887             );
888             $rset->find( { sku => "os28065" } )->add_variants(
889             {
890             diameter => '1/4 inch',
891             sku => 'os28065-QTR',
892             uri => 'mechanics-pliers-quarter-inch-diameter',
893             },
894             {
895             diameter => '1/2 inch',
896             sku => 'os28065-HLF',
897             uri => 'mechanics-pliers-half-inch-diameter',
898             },
899             {
900             diameter => '1 inch',
901             sku => 'os28065-1',
902             uri => 'mechanics-pliers-1-inch-diameter',
903             },
904             {
905             diameter => '2 inches',
906             sku => 'os28065-2',
907             uri => 'mechanics-pliers-2-inch-diameter',
908             },
909             {
910             diameter => '3 inches',
911             sku => 'os28065-3',
912             uri => 'mechanics-pliers-3-inch-diameter',
913             },
914             );
915             $rset->find( { sku => "os28084" } )->add_variants(
916             {
917             length => '10 foot',
918             sku => 'os28084-10',
919             uri => 'tape-measure-10-foot-long',
920             price => 10.99,
921             },
922             {
923             length => '16 foot',
924             sku => 'os28084-16',
925             uri => 'tape-measure-16-foot-long',
926             price => 12.99,
927             },
928             {
929             length => '24 foot',
930             sku => 'os28084-24',
931             uri => 'tape-measure-24-foot-long',
932             price => 15.99,
933             },
934             {
935             length => '36 foot',
936             sku => 'os28084-36',
937             uri => 'tape-measure-36-foot-long',
938             price => 19.99,
939             },
940             );
941             $rset->find( { sku => "os28004" } )->add_variants(
942             {
943             roller => 'camel',
944             color => 'black',
945             sku => 'os28004-CAM-BLK',
946             uri => 'ergo-roller-camel-hair-black',
947             price => 16,
948             },
949             {
950             roller => 'camel',
951             color => 'white',
952             sku => 'os28004-CAM-WHT',
953             uri => 'ergo-roller-camel-hair-white',
954             price => 16,
955             },
956             {
957             roller => 'human',
958             color => 'black',
959             sku => 'os28004-HUM-BLK',
960             uri => 'ergo-roller-human-hair-black',
961             price => 16.5,
962             },
963             {
964             roller => 'human',
965             color => 'white',
966             sku => 'os28004-HUM-WHT',
967             uri => 'ergo-roller-human-hair-white',
968             price => 16.5,
969             },
970             {
971             roller => 'synthetic',
972             color => 'black',
973             sku => 'os28004-SYN-BLK',
974             uri => 'ergo-roller-synthetic-black',
975             price => 12.25,
976             },
977             {
978             roller => 'synthetic',
979             color => 'white',
980             sku => 'os28004-SYN-WHT',
981             uri => 'ergo-roller-synthetic-white',
982             price => 12.25,
983             },
984             );
985              
986             $rset->find( { sku => "os28066" } )->add_variants(
987             {
988             handle => 'ebony',
989             blade => 'plastic',
990             sku => 'os28066-E-P',
991             uri => 'big-l-carpenters-square-ebony-handle-plastic-blade',
992             price => 32.55,
993             },
994             {
995             handle => 'ebony',
996             blade => 'steel',
997             sku => 'os28066-E-S',
998             uri => 'big-l-carpenters-square-ebony-handle-steel-blade',
999             price => 33.99,
1000             },
1001             {
1002             handle => 'ebony',
1003             blade => 'titanium',
1004             sku => 'os28066-E-T',
1005             uri => 'big-l-carpenters-square-ebony-handle-titanium-blade',
1006             price => 133.99,
1007             },
1008             {
1009             handle => 'wood',
1010             blade => 'plastic',
1011             sku => 'os28066-W-P',
1012             uri => 'big-l-carpenters-square-wood-handle-plastic-blade',
1013             price => 12.55,
1014             },
1015             {
1016             handle => 'wood',
1017             blade => 'steel',
1018             sku => 'os28066-W-S',
1019             uri => 'big-l-carpenters-square-wood-handle-steel-blade',
1020             price => 11.99,
1021             },
1022             {
1023             handle => 'wood',
1024             blade => 'titanium',
1025             sku => 'os28066-W-T',
1026             uri => 'big-l-carpenters-square-wood-handle-titanium-blade',
1027             price => 113.99,
1028             },
1029             );
1030              
1031             # add some reviews
1032              
1033             my $product = $rset->find('os28066');
1034             my $customer1 =
1035             $self->users->search( { username => 'customer1' }, { rows => 1 } )
1036             ->single;
1037              
1038             $product->set_reviews(
1039             {
1040             title => "fantastic",
1041             content => "really amazing",
1042             rating => 5,
1043             author_users_id => $customer1->id,
1044             public => 1,
1045             approved => 1,
1046             },
1047             {
1048             title => "great",
1049             content => "there is so much I wan to say",
1050             rating => 4.8,
1051             author_users_id => $customer1->id,
1052             public => 1,
1053             approved => 1,
1054             },
1055             {
1056             title => "brilliant",
1057             content => "let me carp on about this great product",
1058             rating => 4.7,
1059             author_users_id => $customer1->id,
1060             public => 1,
1061             approved => 1,
1062             },
1063             {
1064             title => "fantastic",
1065             content => "public but not approved",
1066             rating => 4,
1067             author_users_id => $customer1->id,
1068             public => 1,
1069             approved => 0,
1070             },
1071             {
1072             title => "fantastic",
1073             content => "approved but not public",
1074             rating => 4,
1075             author_users_id => $customer1->id,
1076             public => 0,
1077             approved => 1,
1078             },
1079             {
1080             title => "really good",
1081             content => "does what it says on the tin",
1082             rating => 4.3,
1083             author_users_id => $customer1->id,
1084             public => 1,
1085             approved => 1,
1086             },
1087             {
1088             title => "amazing",
1089             content => "so good I bought one for my dad",
1090             rating => 3.8,
1091             author_users_id => $customer1->id,
1092             public => 1,
1093             approved => 1,
1094             },
1095             {
1096             title => "not bad",
1097             content => "better available on the market but not at this price",
1098             rating => 3,
1099             author_users_id => $customer1->id,
1100             public => 1,
1101             approved => 1,
1102             },
1103             {
1104             title => "total junk",
1105             content => "product is completely worthless",
1106             rating => 0,
1107             author_users_id => $customer1->id,
1108             public => 0,
1109             approved => 0,
1110             },
1111             );
1112              
1113             return $rset;
1114             }
1115              
1116             =head2 attributes
1117              
1118             Colours, sizes and heights for products.
1119              
1120             FIXME: attributes for other things to be added?
1121              
1122             =cut
1123              
1124             sub _build_attributes {
1125             my $self = shift;
1126             my $rset = $self->ic6s_schema->resultset('Attribute');
1127              
1128             # generic product attributes
1129             $rset->create(
1130             {
1131             name => 'box_quantity',
1132             title => 'Qty in box',
1133             type => 'simple',
1134             attribute_values => [
1135             { value => '100', title => '100' },
1136             { value => '200', title => '200' },
1137             ]
1138             }
1139             );
1140             $rset->create(
1141             {
1142             name => 'length',
1143             title => 'Length',
1144             type => 'simple',
1145             attribute_values => [
1146             { value => '2.5 inches', title => q(2½") },
1147             { value => '3.0 inches', title => q(3") },
1148             { value => '3.5 inches', title => q(3½") },
1149             ]
1150             }
1151             );
1152              
1153             # variants
1154             $rset->create(
1155             {
1156             name => 'width',
1157             title => 'Width',
1158             type => 'variant',
1159             priority => 1,
1160             attribute_values => [
1161             { priority => 40, value => '1.0 inch', title => q(1") },
1162             { priority => 30, value => '1.5 inch', title => q(1.5") },
1163             { priority => 20, value => '2.0 inch', title => q(2") },
1164             ]
1165             }
1166             );
1167             $rset->create(
1168             {
1169             name => 'diameter',
1170             title => 'Diameter',
1171             type => 'variant',
1172             priority => 1,
1173             attribute_values => [
1174             { priority => 80, value => '1/4 inch', title => q(1/4") },
1175             { priority => 70, value => '1/2 inch', title => q(1/2") },
1176             { priority => 60, value => '1 inch', title => q(1") },
1177             { priority => 50, value => '2 inches', title => q(2") },
1178             { priority => 40, value => '3 inches', title => q(3") },
1179             ]
1180             }
1181             );
1182             $rset->create(
1183             {
1184             name => 'height',
1185             title => 'Height',
1186             type => 'variant',
1187             priority => 2,
1188             attribute_values => [
1189             { priority => 800, value => '2 foot', title => "2'" },
1190             { priority => 750, value => '2.5 foot', title => "2.5'" },
1191             { priority => 700, value => '3 foot', title => "3'" },
1192             { priority => 650, value => '6 foot', title => "6'" },
1193             { priority => 600, value => '10 foot', title => "10'" },
1194             { priority => 550, value => '12 foot', title => "12'" },
1195             { priority => 500, value => '16 foot', title => "16'" },
1196             { priority => 450, value => '24 foot', title => "24'" },
1197             { priority => 400, value => '36 foot', title => "36'" },
1198             ]
1199             }
1200             );
1201             $rset->create(
1202             {
1203             name => 'length',
1204             title => 'Length',
1205             type => 'variant',
1206             priority => 1,
1207             attribute_values => [
1208             { priority => 80, value => '2 foot', title => "2'" },
1209             { priority => 85, value => '2.5 foot', title => "2.5'" },
1210             { priority => 80, value => '3 foot', title => "3'" },
1211             { priority => 75, value => '10 foot', title => "10'" },
1212             { priority => 70, value => '16 foot', title => "16'" },
1213             { priority => 65, value => '24 foot', title => "24'" },
1214             { priority => 60, value => '36 foot', title => "36'" },
1215             ]
1216             }
1217             );
1218             $rset->create(
1219             {
1220             name => 'color',
1221             title => 'Color',
1222             type => 'variant',
1223             priority => 1,
1224             attribute_values => [
1225             { value => 'black', title => 'Black' },
1226             { value => 'white', title => 'White' },
1227             ]
1228             }
1229             );
1230             $rset->create(
1231             {
1232             name => 'roller',
1233             title => 'Roller',
1234             type => 'variant',
1235             priority => 2,
1236             attribute_values => [
1237             { value => 'camel', title => 'Camel hair' },
1238             { value => 'human', title => 'Human hair' },
1239             { value => 'synthetic', title => 'Synthetic' },
1240             ]
1241             }
1242             );
1243             $rset->create(
1244             {
1245             name => 'handle',
1246             title => 'Handle',
1247             type => 'variant',
1248             priority => 2,
1249             attribute_values => [
1250             { value => 'ebony', title => 'Ebony' },
1251             { value => 'wood', title => 'Wood' },
1252             ]
1253             }
1254             );
1255             $rset->create(
1256             {
1257             name => 'blade',
1258             title => 'Blade',
1259             type => 'variant',
1260             priority => 1,
1261             attribute_values => [
1262             { value => 'plastic', title => 'Plastic' },
1263             { value => 'steel', title => 'Steel' },
1264             { value => 'titanium', title => 'Titanium' },
1265             ]
1266             }
1267             );
1268              
1269             return $rset;
1270             }
1271              
1272             =head2 inventory
1273              
1274             =cut
1275              
1276             sub _build_inventory {
1277             my $self = shift;
1278             my $rset = $self->ic6s_schema->resultset('Inventory');
1279              
1280             # we must have products before we can proceed
1281             $self->products unless $self->has_products;
1282              
1283             my @inventory = (
1284             [qw(sku quantity )],
1285             [ "os28004-CAM-BLK", 34, ],
1286             [ "os28004-CAM-WHT", 27, ],
1287             [ "os28004-HUM-BLK", 19, ],
1288             [ "os28004-HUM-WHT", 131, ],
1289             [ "os28004-SYN-BLK", 0, ],
1290             [ "os28004-SYN-WHT", 42, ],
1291             [ "os28005", 100, ],
1292             [ "os28006", 90, ],
1293             [ "os28007", 85, ],
1294             [ "os28008", 100, ],
1295             [ "os28009", 0, ],
1296             [ "os28011", 40, ],
1297             [ "os28044", 3, ],
1298             [ "os28057a", 100, ],
1299             [ "os28057b", 29, ],
1300             [ "os28057c", 50, ],
1301             [ "os28062", 88, ],
1302             [ "os28064", 94, ],
1303             [ 'os28065-QTR', 103, ],
1304             [ 'os28065-HLF', 87, ],
1305             [ 'os28065-1', 3, ],
1306             [ 'os28065-2', 0, ],
1307             [ 'os28065-3', 49, ],
1308             [ "os28066-E-P", 98, ],
1309             [ "os28066-E-S", 67, ],
1310             [ "os28066-E-T", 42, ],
1311             [ "os28066-W-P", 103, ],
1312             [ "os28066-W-S", 7, ],
1313             # os28066-W-T intentionally not added to inventory
1314             [ "os28068a", 100, ],
1315             [ "os28068b", 99, ],
1316             [ "os28069", 100, ],
1317             [ "os28070", 0, ],
1318             [ 'os28072-2', 19, ],
1319             [ 'os28072-2HLF', 47, ],
1320             [ 'os28072-3', 23, ],
1321             [ "os28073", 0, ],
1322             [ "os28074", 95, ],
1323             [ "os28075", 100, ],
1324             [ "os28076", 100, ],
1325             [ "os28077", 97, ],
1326             [ 'os28080-1', 67, ],
1327             [ 'os28080-1HLF', 32, ],
1328             [ 'os28080-2', 145, ],
1329             [ "os28081", 100, ],
1330             [ "os28082", 99, ],
1331             [ "os28084-10", 56, ],
1332             [ "os28084-16", 9, ],
1333             [ "os28084-24", 0, ],
1334             [ "os28084-36", 45, ],
1335             [ 'os28085-6', 3, ],
1336             [ 'os28085-12', 0, ],
1337             [ "os28086", 100, ],
1338             [ "os28087", 30, ],
1339             [ "os28108", 90, ],
1340             [ "os28109", 100, ],
1341             [ "os28110", 99, ],
1342             [ "os28111", 99, ],
1343             [ "os28112", 100, ],
1344             [ "os28113", 100, ],
1345             # os29000 intentionally not added to inventory
1346             );
1347              
1348             scalar $rset->populate( [@inventory] );
1349              
1350             return $rset;
1351             }
1352              
1353             =head2 media
1354              
1355             =cut
1356              
1357             sub _build_media {
1358             my $self = shift;
1359             my $schema = $self->ic6s_schema;
1360              
1361             my $imagetype =
1362             $schema->resultset('MediaType')->create( { type => 'image' } );
1363              
1364             foreach my $display (qw/image_detail image_thumb/) {
1365             $imagetype->add_to_media_displays(
1366             {
1367             type => $display,
1368             name => $display,
1369             path => "/images/$display",
1370             }
1371             );
1372             }
1373              
1374             my $products = $self->products;
1375             while ( my $product = $products->next ) {
1376             $product->add_to_media(
1377             {
1378             file => $product->sku . ".gif",
1379             uri => $product->sku . ".gif",
1380             mime_type => 'image/gif',
1381             media_type => { type => 'image' }
1382             }
1383             );
1384             }
1385              
1386             return $schema->resultset('Media');
1387             }
1388              
1389             =head2 message_types
1390              
1391             Populated via L.
1392              
1393             =cut
1394              
1395             sub _build_message_types {
1396             my $self = shift;
1397             my $rset = $self->ic6s_schema->resultset('MessageType');
1398              
1399             if ( $rset->count == 0 ) {
1400             my $pop = Interchange6::Schema::Populate::MessageType->new->records;
1401             scalar $rset->populate($pop)
1402             or die "Failed to populate MessageType";
1403             }
1404             return $rset;
1405             }
1406              
1407             =head2 navigation
1408              
1409             =cut
1410              
1411             sub _build_navigation {
1412             my $self = shift;
1413             my $rset = $self->ic6s_schema->resultset('Navigation');
1414              
1415             # we must have products before we can proceed
1416             $self->products unless $self->has_products;
1417              
1418             scalar $rset->populate(
1419             [
1420             [ 'uri', 'type', 'scope', 'name', 'priority' ],
1421             [ 'hand-tools', 'nav', 'menu-main', 'Hand Tools', 90 ],
1422             [ 'hardware', 'nav', 'menu-main', 'Hardware', 80 ],
1423             [ 'ladders', 'nav', 'menu-main', 'Ladders', 70 ],
1424             [ 'measuring-tools', 'nav', 'menu-main', 'Measuring Tools', 60 ],
1425             [
1426             'painting-supplies', 'nav', 'menu-main', 'Painting Supplies',
1427             50
1428             ],
1429             [ 'safety-equipment', 'nav', 'menu-main', 'Safety Equipment', 40 ],
1430             [ 'tool-storage', 'nav', 'menu-main', 'Tool Storage', 30 ],
1431             ]
1432             );
1433              
1434             my %navs;
1435             while ( my $nav = $rset->next ) {
1436             $nav->add_attribute( template => 'category' );
1437             $navs{ $nav->uri } = $nav->id;
1438             }
1439              
1440             my @navigation = (
1441             [
1442             'hand-tools/brushes', 'nav',
1443             'menu-main', 'Brushes',
1444             $navs{'hand-tools'}, [qw( os28009 os28108 )]
1445             ],
1446             [
1447             'hand-tools/hammers', 'nav',
1448             'menu-main', 'Hammers',
1449             $navs{'hand-tools'}, [qw( os28044 os28073 os28075 os28074 )]
1450             ],
1451             [
1452             'hand-tools/hand-planes', 'nav',
1453             'menu-main', 'Hand Planes',
1454             $navs{'hand-tools'}, [qw( os28080 )]
1455             ],
1456             [
1457             'hand-tools/hand-saws', 'nav',
1458             'menu-main', 'Hand Saws',
1459             $navs{'hand-tools'}, [qw( os28072 )]
1460             ],
1461             [
1462             'hand-tools/picks-and-hatchets', 'nav',
1463             'menu-main', 'Picks & Hatchets',
1464             $navs{'hand-tools'}, [qw( os28076 os28113 )]
1465             ],
1466             [
1467             'hand-tools/pliers', 'nav',
1468             'menu-main', 'Pliers',
1469             $navs{'hand-tools'}, [qw( os28062 os28065 )]
1470             ],
1471             [
1472             'hand-tools/shears', 'nav',
1473             'menu-main', 'Shears',
1474             $navs{'hand-tools'}, [qw( os28111 os28110 )]
1475             ],
1476             [
1477             'hand-tools/shovels', 'nav',
1478             'menu-main', 'Shovels',
1479             $navs{'hand-tools'}, [qw( os28112 os28109 )]
1480             ],
1481             [
1482             'hand-tools/wrenches', 'nav',
1483             'menu-main', 'Wrenches',
1484             $navs{'hand-tools'}, [qw( os28064 )]
1485             ],
1486             [
1487             'hardware/nails', 'nav',
1488             'menu-main', 'Nails',
1489             $navs{'hardware'}, [qw( os28057c os28057a os28057b )]
1490             ],
1491             [
1492             'ladders/ladders', 'nav',
1493             'menu-main', 'Ladders',
1494             $navs{'ladders'}, [qw( os28085 os28008 )]
1495             ],
1496             [
1497             'ladders/step-tools', 'nav',
1498             'menu-main', 'Step Tools',
1499             $navs{'ladders'}, [qw( os29000 )]
1500             ],
1501             [
1502             'measuring-tools/levels', 'nav',
1503             'menu-main', 'Levels',
1504             $navs{'measuring-tools'}, [qw( os28082 )]
1505             ],
1506             [
1507             'measuring-tools/rulers', 'nav',
1508             'menu-main', 'Rulers',
1509             $navs{'measuring-tools'}, [qw( os28086 )]
1510             ],
1511             [
1512             'measuring-tools/squares', 'nav',
1513             'menu-main', 'Squares',
1514             $navs{'measuring-tools'}, [qw( os28066 )]
1515             ],
1516             [
1517             'measuring-tools/tape-measures', 'nav',
1518             'menu-main', 'Tape Measures',
1519             $navs{'measuring-tools'}, [qw( os28084 )]
1520             ],
1521             [
1522             'painting-supplies/paintbrushes', 'nav',
1523             'menu-main', 'Paintbrushes',
1524             $navs{'painting-supplies'}, [qw( os28007 os28006 os28005 )]
1525             ],
1526             [
1527             'painting-supplies/putty-knives', 'nav',
1528             'menu-main', 'Putty Knives',
1529             $navs{'painting-supplies'}, [qw( os28011 )]
1530             ],
1531             [
1532             'painting-supplies/rollers', 'nav',
1533             'menu-main', 'Rollers',
1534             $navs{'painting-supplies'}, [qw( os28004 )]
1535             ],
1536             [
1537             'painting-supplies/sandpaper', 'nav',
1538             'menu-main', 'Sand Paper',
1539             $navs{'painting-supplies'}, [qw( os28087 os28081 )]
1540             ],
1541             [
1542             'safety-equipment/breathing-protection', 'nav',
1543             'menu-main', 'Breathing Protection',
1544             $navs{'safety-equipment'}, [qw( os28068a )]
1545             ],
1546             [
1547             'safety-equipment/eye-protection', 'nav',
1548             'menu-main', 'Eye Protection',
1549             $navs{'safety-equipment'}, [qw( os28068b )]
1550             ],
1551             [
1552             'tool-storage/tool-belts', 'nav',
1553             'menu-main', 'Tool Belts',
1554             $navs{'tool-storage'}, [qw( os28077 os28070 )]
1555             ],
1556             [
1557             'tool-storage/toolboxes', 'nav',
1558             'menu-main', 'Toolboxes',
1559             $navs{'tool-storage'}, [qw( os28069 )]
1560             ],
1561             );
1562              
1563             foreach my $nav (@navigation) {
1564             my $nav_result = $rset->create(
1565             {
1566             uri => $nav->[0],
1567             type => $nav->[1],
1568             scope => $nav->[2],
1569             name => $nav->[3],
1570             parent_id => $nav->[4],
1571             navigation_products =>
1572             [ map { { "sku" => $_, priority => 100 } } @{ $nav->[5] } ],
1573             }
1574             );
1575              
1576             # add navigation_product links to parent nav as well
1577             my $parent = $nav_result->parent;
1578             foreach my $sku ( @{ $nav->[5] } ) {
1579             $parent->add_to_navigation_products(
1580             { sku => $sku, navigation_id => $parent->id } );
1581             }
1582             }
1583              
1584             return $rset;
1585             }
1586              
1587             =head2 states
1588              
1589             Populated via L.
1590              
1591             =cut
1592              
1593             sub _build_states {
1594             my $self = shift;
1595             my $rset = $self->ic6s_schema->resultset('State');
1596              
1597             # we must have countries before we can proceed
1598             $self->countries unless $self->has_countries;
1599              
1600             if ( $rset->count == 0 ) {
1601             my $pop = Interchange6::Schema::Populate::StateLocale->new->records;
1602             scalar $rset->populate($pop) or die "Failed to populate State";
1603             }
1604             return $rset;
1605             }
1606              
1607             =head2 taxes
1608              
1609             =cut
1610              
1611             sub _build_taxes {
1612             my $self = shift;
1613             my %countries;
1614             my $rset = $self->ic6s_schema->resultset('Tax');
1615              
1616             # we must have countries and states before we can proceed
1617             $self->countries unless $self->has_countries;
1618             $self->states unless $self->has_states;
1619              
1620             # EU Standard rate VAT
1621             my @data = (
1622             [ 'BE', 21, '1996-01-01' ],
1623             [ 'BG', 20, '1999-01-01' ],
1624             [ 'CZ', 21, '2013-01-01' ],
1625             [ 'DK', 25, '1992-01-01' ],
1626             [ 'DE', 19, '2007-01-01' ],
1627             [ 'EE', 20, '2009-07-01' ],
1628             [ 'GR', 23, '2011-01-01' ],
1629             [ 'ES', 21, '2012-09-01' ],
1630             [ 'FR', 20, '2014-01-01' ],
1631             [ 'HR', 25, '2012-03-01' ],
1632             [ 'IE', 23, '2012-01-01' ],
1633             [ 'IT', 22, '2013-10-01' ],
1634             [ 'CY', 19, '2014-01-13' ],
1635             [ 'LV', 21, '2009-01-01' ],
1636             [ 'LT', 21, '2009-09-01' ],
1637             [ 'LU', 15, '1992-01-01' ],
1638             [ 'HU', 27, '2012-01-01' ],
1639             [ 'MT', 18, '2004-01-01' ],
1640             [ 'NL', 21, '2012-10-01' ],
1641             [ 'AT', 20, '1984-01-01' ],
1642             [ 'PL', 23, '2011-01-01' ],
1643             [ 'PT', 23, '2011-01-01' ],
1644             [ 'RO', 24, '2010-07-01' ],
1645             [ 'SI', 22, '2013-07-01' ],
1646             [ 'SK', 20, '2011-01-01' ],
1647             [ 'FI', 24, '2013-01-01' ],
1648             [ 'SE', 25, '1990-07-01' ],
1649             [ 'GB', 20, '2011-01-04' ],
1650             );
1651             foreach my $aref (@data) {
1652              
1653             my ( $code, $rate, $from ) = @{$aref};
1654              
1655             my $c_name =
1656             $self->countries->find( { country_iso_code => $code } )->name;
1657              
1658             $rset->create(
1659             {
1660             tax_name => "$code VAT Standard",
1661             description => "$c_name VAT Standard Rate",
1662             percent => $rate,
1663             country_iso_code => $code,
1664             valid_from => $from,
1665             }
1666             );
1667             }
1668              
1669             # Canada GST/PST/HST/QST
1670             my %data = (
1671             BC => [ 'PST', 7 ],
1672             MB => [ 'RST', 8 ],
1673             NB => [ 'HST', 13 ],
1674             NL => [ 'HST', 13 ],
1675             NS => [ 'HST', 15 ],
1676             ON => [ 'HST', 13 ],
1677             PE => [ 'HST', 14 ],
1678             QC => [ 'QST', 9.975 ],
1679             SK => [ 'PST', 10 ],
1680             );
1681             foreach my $code ( sort keys %data ) {
1682              
1683             my $state = $self->states->find(
1684             { country_iso_code => 'CA', state_iso_code => $code } );
1685              
1686             $rset->create(
1687             {
1688             tax_name => "CA $code $data{$code}[0]",
1689             description => "CA " . $state->name . " $data{$code}[0]",
1690             percent => $data{$code}[1],
1691             country_iso_code => 'CA',
1692             states_id => $state->states_id
1693             }
1694             );
1695             }
1696              
1697             return $rset;
1698             }
1699              
1700             =head2 users
1701              
1702             [qw( username email password )],
1703             [ 'customer1', 'customer1@example.com', 'c1passwd' ],
1704             [ 'customer2', 'customer2@example.com', 'c1passwd' ],
1705             [ 'customer3', 'customer3@example.com', 'c1passwd' ],
1706             [ 'admin1', 'admin1@example.com', 'a1passwd' ],
1707             [ 'admin2', 'admin2@example.com', 'a2passwd' ],
1708              
1709             =cut
1710              
1711             sub _build_users {
1712             my $self = shift;
1713             my $rset = $self->ic6s_schema->resultset('User');
1714              
1715             # we must have roles before we can proceed
1716             $self->roles unless $self->has_roles;
1717              
1718             scalar $rset->populate(
1719             [
1720             [qw( username email password first_name last_name)],
1721             [
1722             'customer1', 'customer1@example.com',
1723             'c1passwd', "Customer",
1724             "One"
1725             ],
1726             [
1727             'customer2', 'customer2@example.com',
1728             'c1passwd', "Customer",
1729             "Two"
1730             ],
1731             [
1732             'customer3', 'customer3@example.com',
1733             'c1passwd', "Customer",
1734             "Three"
1735             ],
1736             [ 'admin1', 'admin1@example.com', 'a1passwd', "Admin", "One" ],
1737             [ 'admin2', 'admin2@example.com', 'a2passwd', "Admin", "Two" ],
1738             ]
1739             );
1740             return $rset;
1741             }
1742              
1743             =head2 zones
1744              
1745             Populated via L.
1746              
1747             =cut
1748              
1749             sub _build_zones {
1750             my $self = shift;
1751             my $rset = $self->ic6s_schema->resultset('Zone');
1752              
1753             if ( $rset->count == 0 ) {
1754             # we need to pass min value of states_id to ::Populate::Zone
1755             # also kicks in states and countries builders if not already set
1756              
1757             my $min_states_id = $self->states->search(
1758             {},
1759             {
1760             select => [ { min => 'states_id' } ],
1761             as => ['min_id'],
1762             }
1763             )->first->get_column('min_id');
1764              
1765             my $pop =
1766             Interchange6::Schema::Populate::Zone->new(
1767             states_id_initial_value => $min_states_id )->records;
1768              
1769             scalar $rset->populate($pop) or die "Failed to populate Zone";
1770             }
1771             return $rset;
1772             }
1773              
1774             =head1 METHODS
1775              
1776             All attributes have a corresponding C method which deletes all rows from the corresponding table and clears the accessor. Each also has a C accessor which returns true if the accessor has been set and false otherwise. All attributes are created lazy and are set on access. The full list of clear/has methods are:
1777              
1778             =over
1779              
1780             =item * clear_addresses
1781              
1782             =item * clear_attributes
1783              
1784             =item * clear_countries
1785              
1786             =item * clear_inventory
1787              
1788             =item * clear_media
1789              
1790             =item * clear_message_types
1791              
1792             =item * clear_navigation
1793              
1794             =item * clear_orders
1795              
1796             =item * clear_price_modifiers
1797              
1798             =item * clear_products
1799              
1800             =item * clear_roles
1801              
1802             =item * clear_shipment_carriers
1803              
1804             =item * clear_shipment_rates
1805              
1806             =item * clear_states
1807              
1808             =item * clear_taxes
1809              
1810             =item * clear_users
1811              
1812             =item * clear_zones
1813              
1814             =item * has_addresses
1815              
1816             =item * has_attributes
1817              
1818             =item * has_countries
1819              
1820             =item * has_inventory
1821              
1822             =item * has_media
1823              
1824             =item * has_message_types
1825              
1826             =item * has_navigation
1827              
1828             =item * has_orders
1829              
1830             =item * has_price_modifiers
1831              
1832             =item * has_products
1833              
1834             =item * has_roles
1835              
1836             =item * has_shipment_carriers
1837              
1838             =item * has_shipment_rates
1839              
1840             =item * has_states
1841              
1842             =item * has_taxes
1843              
1844             =item * has_users
1845              
1846             =item * has_zones
1847              
1848             =back
1849              
1850             =head2 clear_all_fixtures
1851              
1852             This additional method calls all of the clear_$accessor methods.
1853              
1854             =cut
1855              
1856             sub clear_all_fixtures {
1857             my $self = shift;
1858             foreach my $accessor (@accessors) {
1859             my $clear_accessor = "clear_$accessor";
1860             $self->$clear_accessor;
1861             }
1862             }
1863              
1864             =head2 load_all_fixtures
1865              
1866             Loads all fixtures.
1867              
1868             =cut
1869              
1870             sub load_all_fixtures {
1871             my $self = shift;
1872             # do this in reverse orser
1873             my @a = @accessors;
1874             while ( scalar @a > 0 ) {
1875             my $accessor = pop @a;
1876             $self->$accessor;
1877             }
1878             }
1879              
1880             1;