diff --git a/lib/WebGUI/Shop/Products.pm b/lib/WebGUI/Shop/Products.pm index 25327394a..bb5585f7b 100644 --- a/lib/WebGUI/Shop/Products.pm +++ b/lib/WebGUI/Shop/Products.pm @@ -123,6 +123,7 @@ sub importProducts { unless -r $filePath; open my $table, '<', $filePath or WebGUI::Error->throw(error => qq{Unable to open $filePath for reading: $!\n}); + my $headers; $headers = <$table>; chomp $headers; @@ -130,6 +131,7 @@ sub importProducts { WebGUI::Error::InvalidFile->throw(error => qq{Bad header found in the CSV file}, brokenFile => $filePath) unless (join(q{-}, sort @headers) eq 'mastersku-price-quantity-shortdescription-sku-title-weight') and (scalar @headers == 7); + my @productData = (); my $line = 1; while (my $productRow = <$table>) { @@ -142,41 +144,52 @@ sub importProducts { unless scalar @productRow == 7; push @productData, [ @productRow ]; } - ##Okay, if we got this far, then the data looks fine. + return unless scalar @productData; + + ##Okay, if we got this far, then the data looks fine. my $fetchProductId = $session->db->prepare('select p.assetId from Product as p join sku as s on p.assetId=s.assetId and p.revisionDate=s.revisionDate where s.sku=? order by p.revisionDate DESC limit 1'); my $node = WebGUI::Asset::Sku::Product->getProductImportNode($session); @headers = map { $_ eq 'shortdescription' ? 'shortdesc' : $_ } @headers; + my @collateralFields = grep { $_ ne 'title' and $_ ne 'mastersku' } @headers; PRODUCT: foreach my $productRow (@productData) { my %productRow; ##Order the data according to the headers, in whatever order they exist. @productRow{ @headers } = @{ $productRow }; + ##Isolate just the collateral from the other product information + my %productCollateral; + @productCollateral{ @collateralFields } = @productRow{ @collateralFields }; + $fetchProductId->execute([$productRow{mastersku}]); my $asset = $fetchProductId->hashRef; + ##If the assetId exists, we update data for it if ($asset->{assetId}) { $session->log->warn("Modifying an existing product: $productRow{sku} = $asset->{assetId}\n"); my $assetId = $asset->{assetId}; my $product = WebGUI::Asset->newPending($session, $assetId); + + ##Error handling for locked assets + if ($product->isLocked) { + $session->log->warn("Product is locked"); + next PRODUCT if $product->isLocked; + } + if ($productRow{title} ne $product->getTitle) { $product->update({ title => $product->fixTitle($productRow{title}) }); } - ##Error handling for locked assets - $session->log->warn("Product is locked") if $product->isLocked; - delete $productRow{ title }; - delete $productRow{ mastersku }; - next PRODUCT if $product->isLocked; + my $collaterals = $product->getAllCollateral('variantsJSON'); my $collateralSet = 0; ROW: foreach my $collateral (@{ $collaterals }) { next ROW unless $collateral->{sku} eq $productRow{sku}; - @{ $collateral}{@headers} = @productRow{ @headers }; + @{ $collateral}{ @collateralFields } = @productCollateral{ @collateralFields }; ##preserve the variant Id field, assign all others $product->setCollateral('variantsJSON', 'variantId', $collateral->{variantId}, $collateral); $collateralSet=1; } if (!$collateralSet) { ##It must be a new variant - $product->setCollateral('variantsJSON', 'variantId', 'new', \%productRow); + $product->setCollateral('variantsJSON', 'variantId', 'new', \%productCollateral); } } else { @@ -187,9 +200,7 @@ sub importProducts { title => $newProduct->fixTitle($productRow{title}), sku => $productRow{mastersku}, }); - delete $productRow{ title }; - delete $productRow{ mastersku }; - $newProduct->setCollateral('variantsJSON', 'variantId', 'new', \%productRow); + $newProduct->setCollateral('variantsJSON', 'variantId', 'new', \%productCollateral); $newProduct->commit; } } diff --git a/t/Shop/Products.t b/t/Shop/Products.t index d806a6380..76627f42f 100644 --- a/t/Shop/Products.t +++ b/t/Shop/Products.t @@ -33,7 +33,7 @@ my $session = WebGUI::Test->session; #---------------------------------------------------------------------------- # Tests -my $tests = 27; +my $tests = 36; plan tests => 1 + $tests; #---------------------------------------------------------------------------- @@ -203,7 +203,101 @@ SKIP: { my @productData = split /\n/, $productData; is(scalar @productData, 4, 'productData should have 4 entries, 1 header + 3 data'); is($productData[0], 'mastersku,title,sku,shortdescription,price,weight,quantity', 'header line is okay'); - diag $productData; + my @productData = map { [ WebGUI::Text::splitCSV($_) ] } @productData[1..3]; + my ($sodas, $shirts); + foreach my $productData (@productData) { + if ($productData->[0] eq 'soda') { + push @{ $sodas }, $productData; + } + elsif ($productData->[0] eq 't-shirt') { + push @{ $shirts }, $productData; + } + } + is(scalar @{ $sodas }, 1, 'just 1 soda'); + is(scalar @{ $shirts }, 2, '2 shirts'); + + cmp_deeply( + $sodas, + [ ['soda', 'Sweet Soda-bottled in Oregon', + 'soda-sweet', 'Sweet Soda', 0.95, 0.95, 500] ], + 'soda data is okay' + ); + + ####################################################################### + # + # export, part 2 + # + ####################################################################### + + my $pass = WebGUI::Shop::Products::importProducts( + $session, + WebGUI::Test->getTestCollateralPath('productTables/secondProductTable.csv'), + ); + ok($pass, 'Products imported'); + + my $count = $session->db->quickScalar('select count(*) from Product'); + is($count, 3, 'three products were imported'); + + my $soda = WebGUI::Asset::Sku->newBySku($session, 'soda'); + my $sodaCollateral = $soda->getAllCollateral('variantsJSON'); + cmp_deeply( + $sodaCollateral, + [ + { + sku => 'soda-sweet', + shortdesc => 'Sweet Soda', + price => '1.00', + weight => 0.85, + quantity => 500, + variantId => ignore(), + }, + ], + 'collateral updated correctly for soda' + ); + + $shirt = WebGUI::Asset::Sku->newBySku($session, 't-shirt'); + my $shirtCollateral = $shirt->getAllCollateral('variantsJSON'); + cmp_deeply( + $shirtCollateral, + [ + { + sku => 'red-t-shirt', + shortdesc => 'Red T-Shirt', + price => '5.00', + weight => '1.33', + quantity => '500', + variantId => ignore(), + }, + { + sku => 'blue-t-shirt', + shortdesc => 'Blue T-Shirt', + price => '5.25', + weight => '1.33', + quantity => '2000', + variantId => ignore(), + }, + ], + 'collateral updated correctly for shirt' + ); + + my $record = WebGUI::Asset::Sku->newBySku($session, 'classical-records-1'); + isa_ok($record, 'WebGUI::Asset::Sku::Product'); + my $recordCollateral = $record->getAllCollateral('variantsJSON'); + cmp_deeply( + $recordCollateral, + [ + { + sku => 'track-16', + shortdesc => 'Track 16', + price => '3.25', + weight => '0.00', + quantity => 50, + variantId => ignore(), + }, + ], + 'collateral set correctly for classical record' + ); + }