Skip to content
This repository has been archived by the owner on Jun 21, 2022. It is now read-only.

Commit

Permalink
Add button to remove ingredients from purchase list
Browse files Browse the repository at this point in the history
Fixes #41.
  • Loading branch information
dboehmer committed Dec 23, 2017
1 parent 62edda8 commit ae55aa4
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 4 deletions.
25 changes: 25 additions & 0 deletions lib/Coocook/Controller/PurchaseList.pm
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,34 @@ sub edit : GET Chained('base') PathPart('') Args(0) {
units => $list->units,
);

for my $sections ( @{ $c->stash->{sections} } ) {
for my $item ( @{ $sections->{items} } ) {
for my $ingredient ( @{ $item->{ingredients} } ) {
$ingredient->{remove_url} =
$c->project_uri( '/purchase_list/remove_ingredient', $ingredient->{id} );
}
}
}

$c->escape_title( "Purchase list" => $c->stash->{list}->name );
}

sub remove_ingredient : POST Chained('/project/base') PathPart('purchase_list/remove_ingredient')
Args(1) {
my ( $self, $c, $ingredient_id ) = @_;

my $ingredient = $c->project->dishes->ingredients->find($ingredient_id)
or die "ingredient not found";

my $item = $ingredient->item
or die "item not found";

$ingredient->remove_from_purchase_list();

$c->response->redirect(
$c->project_uri( $self->action_for('edit'), $item->get_column('purchase_list') ) );
}

sub create : POST Chained('/project/base') PathPart('purchase_lists/create') Args(0) {
my ( $self, $c ) = @_;

Expand Down
2 changes: 2 additions & 0 deletions lib/Coocook/Schema/Result/Article.pm
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ __PACKAGE__->belongs_to(
undef, { join_type => 'LEFT' }
);

__PACKAGE__->has_many( items => 'Coocook::Schema::Result::Item' );

__PACKAGE__->has_many( articles_tags => 'Coocook::Schema::Result::ArticleTag' );
__PACKAGE__->many_to_many( tags => articles_tags => 'tag' );

Expand Down
42 changes: 41 additions & 1 deletion lib/Coocook/Schema/Result/DishIngredient.pm
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ __PACKAGE__->meta->make_immutable;
sub assign_to_purchase_list {
my ( $self, $list ) = @_;

my $item;

$self->result_source->schema->txn_do(
sub {
my $item = $self->result_source->schema->resultset('Item')->add_or_create(
$item = $self->result_source->schema->resultset('Item')->add_or_create(
{
purchase_list => $list,
article => $self->get_column('article'),
Expand All @@ -58,6 +60,44 @@ sub assign_to_purchase_list {
$self->update( { item => $item->id } );
}
);

return $item;
}

sub remove_from_purchase_list {
my $self = shift;

$self->result_source->schema->txn_do(
sub {
my $item = $self->item
or return
warn "Trying to remove ingredient " . $self->id . " that's not assigned to any purchase list";

$self->update( { item => undef } );

if ( $item->ingredients->count > 0 ) {
my $value = $self->value;

# if item got converted to other unit, convert $value, too
if ( $self->get_column('unit') != $item->get_column('unit') ) {
my $unit1 = $self->unit;
my $unit2 = $item->unit;

$unit1->get_column('quantity') == $unit2->get_column('quantity')
or die "Units not of same quantity";

$value *= $unit1->to_quantity_default / $unit2->to_quantity_default;
}

$item->update( { value => $item->value - $value } );
}
else { # item belongs to other ingredients
$item->delete;
}
}
);

return 1;
}

1;
1 change: 1 addition & 0 deletions lib/Coocook/Schema/ResultSet/Item.pm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ sub add_or_create {
{
value => $args->{value},
comment => "", # no argument because existing items have comments
offset => 0, # instantly apply default_value
}
);
}
Expand Down
8 changes: 7 additions & 1 deletion root/templates/purchase_list/edit.tt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@
<td>[% item.article.name | html %]</td>
<td class="small-font"><ul>
[% FOREACH ingredient IN item.ingredients %]
<li>[% ingredient.value; display_unit(ingredient.unit) %] [% ingredient.dish.meal.date.strftime('%a, %F') %] [% ingredient.dish.name | html %] [% IF ingredient.comment; '('; ingredient.comment | html; ')'; END %]</li>
<li>
[% ingredient.value; display_unit(ingredient.unit) %]
[% ingredient.dish.meal.date.strftime('%a, %F') %]
[% ingredient.dish.name | html %]
[% IF ingredient.comment; '('; ingredient.comment | html; ')'; END %]
<form class="inline" method="POST" action="[% ingredient.remove_url %]"><input type="submit" value="Remove"></form>
</li>
[% END %]
</ul></td>
<td>[% item.comment %]</td>
Expand Down
2 changes: 1 addition & 1 deletion share/test_data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ INSERT INTO 'dish_ingredients' VALUES(8,2,3,1,2,1,25.0,'',NULL);
INSERT INTO 'dish_ingredients' VALUES(9,3,3,1,3,3,1.0,'',NULL);
INSERT INTO 'dish_ingredients' VALUES(10,4,3,0,4,1,500.0,'',NULL);
INSERT INTO 'purchase_lists' VALUES(1,1,'all at once','1999-12-31');
INSERT INTO 'items' VALUES(1,1,1000,0.0,1,1,0,'');
INSERT INTO 'items' VALUES(1,1,500,0.0,1,1,0,'');
UPDATE 'dish_ingredients' SET 'item' = 1 WHERE id IN (1,3);
INSERT INTO 'tag_groups' VALUES(1,1,0xff0000,'allergens','may harm');
INSERT INTO 'tags' VALUES(1,1,1,'gluten');
Expand Down
2 changes: 1 addition & 1 deletion t/model_PurchaseList.t
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ cmp_deeply $sections => [
comment => '',
purchase_list => 1,
purchased => 0,
value => 1000,
value => 500,
offset => 0.0,
unit => {
can_be_quantity_default => 1,
Expand Down
50 changes: 50 additions & 0 deletions t/schema_DishIngredient.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use strict;
use warnings;

use FindBin '$Bin';
use lib "$Bin/lib";

use TestDB;
use Test::Most;

my $db = TestDB->new;

sub article_has_items { # value + unit->short_name joined with space: "420g 42kg"
my ( $article, $expected, $name ) = @_;

my @items;

for my $item ( $article->items->search( undef, { order_by => 'short_name' } )->all ) {
push @items, $item->value . $item->unit->short_name;
}

my $items = join " ", @items;

is $items => $expected, $name || sprintf( "article %i has items '%s'", $article->id, $expected );
}

my $list = $db->resultset('PurchaseList')->single || die;
my $next_ingredient = $db->resultset('DishIngredient')->find(4) || die;
my $article = $next_ingredient->article;

ok my $item = $next_ingredient->assign_to_purchase_list($list), "assign_to_purchase_list";

article_has_items $article => "500g 0.5kg";

{
my $liters = $db->resultset('Unit')->find( { short_name => 'l' } );
throws_ok { $item->convert($liters) } qr/quantity/;
}

my $grams = $db->resultset('Unit')->find( { short_name => 'g' } );
ok $item->convert($grams), "convert item to grams";

$next_ingredient->discard_changes;

article_has_items $article => "1000g";

ok $next_ingredient->remove_from_purchase_list, "remove_from_purchase_list";

article_has_items $article => "500g";

done_testing;

0 comments on commit ae55aa4

Please sign in to comment.