Skip to content

Commit

Permalink
Merge pull request #1573 from boxwise/minor-fixes
Browse files Browse the repository at this point in the history
Minor fixes
  • Loading branch information
pylipp authored Oct 1, 2024
2 parents 0ac9f6b + 43d1954 commit 725c969
Show file tree
Hide file tree
Showing 15 changed files with 81 additions and 11 deletions.
10 changes: 10 additions & 0 deletions back/boxtribute_server/business_logic/beneficiary/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,13 @@ def resolve_beneficiary_active(beneficiary_obj, _):
def resolve_beneficiary_base(beneficiary_obj, info):
authorize(permission="base:read", base_id=beneficiary_obj.base_id)
return info.context["base_loader"].load(beneficiary_obj.base_id)


@beneficiary.field("createdBy")
def resolve_beneficiary_created_by(beneficiary_obj, info):
return info.context["user_loader"].load(beneficiary_obj.created_by_id)


@beneficiary.field("lastModifiedBy")
def resolve_beneficiary_last_modified_by(beneficiary_obj, info):
return info.context["user_loader"].load(beneficiary_obj.last_modified_by_id)
20 changes: 10 additions & 10 deletions back/boxtribute_server/business_logic/box_transfer/shipment/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,22 +264,22 @@ def _update_shipment_with_prepared_boxes(
)
)
details = [
{
"shipment": shipment.id,
"box": box.id,
"source_product": box.product_id,
"source_location": box.location_id,
"source_size": box.size_id,
"source_quantity": box.number_of_items,
"created_by": user_id,
}
ShipmentDetail(
shipment=shipment.id,
box=box.id,
source_product=box.product_id,
source_location=box.location_id,
source_size=box.size_id,
source_quantity=box.number_of_items,
created_by=user_id,
)
for box in boxes
]

_bulk_update_box_state(
boxes=boxes, state=BoxState.MarkedForShipment, user_id=user_id, now=now
)
ShipmentDetail.insert_many(details).execute()
ShipmentDetail.bulk_create(details, batch_size=BATCH_SIZE)


def _remove_boxes_from_shipment(
Expand Down
10 changes: 10 additions & 0 deletions back/boxtribute_server/business_logic/warehouse/box/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ def resolve_box_shipment_detail(box_obj, info):
return info.context["shipment_detail_for_box_loader"].load(box_obj.id)


@box.field("createdBy")
def resolve_box_created_by(box_obj, info):
return info.context["user_loader"].load(box_obj.created_by_id)


@box.field("lastModifiedBy")
def resolve_box_last_modified_by(box_obj, info):
return info.context["user_loader"].load(box_obj.last_modified_by_id)


@history_entry.field("user")
def resolve_history_entry_user(history_entry_obj, info):
return info.context["user_loader"].load(history_entry_obj.user_id)
10 changes: 10 additions & 0 deletions back/boxtribute_server/business_logic/warehouse/location/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,13 @@ def resolve_location_boxes(location_obj, _, pagination_input=None, filter_input=
def resolve_location_base(location_obj, info):
authorize(permission="base:read", base_id=location_obj.base_id)
return info.context["base_loader"].load(location_obj.base_id)


@classic_location.field("createdBy")
def resolve_location_created_by(location_obj, info):
return info.context["user_loader"].load(location_obj.created_by_id)


@classic_location.field("lastModifiedBy")
def resolve_location_last_modified_by(location_obj, info):
return info.context["user_loader"].load(location_obj.last_modified_by_id)
10 changes: 10 additions & 0 deletions back/boxtribute_server/business_logic/warehouse/product/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,13 @@ def resolve_product_type(product_obj, _):
if product_obj.standard_product_id is None:
return ProductType.Custom
return ProductType.StandardInstantiation


@product.field("createdBy")
def resolve_product_created_by(product_obj, info):
return info.context["user_loader"].load(product_obj.created_by_id)


@product.field("lastModifiedBy")
def resolve_product_last_modified_by(product_obj, info):
return info.context["user_loader"].load(product_obj.last_modified_by_id)
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ type Box implements ItemsCollection {
id: ID!
" Sequence of numbers for identifying the box, usually written on box label "
labelIdentifier: String!
" If the client is not authorized to access the location's base, return `null` instead of raising an authorization error. This enables the target side of a shipment to scan boxes that are not yet reconciliated into their stock (but still registered at the source side) "
location: Location
distributionEvent: DistributionEvent
numberOfItems: Int
" If the client is not authorized to access the product's base, return `null` instead of raising an authorization error. This enables the target side of a shipment to scan boxes that are not yet reconciliated into their stock (but still registered at the source side) "
product: Product
size: Size!
state: BoxState!
Expand Down
1 change: 1 addition & 0 deletions back/boxtribute_server/models/definitions/beneficiary.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class Beneficiary(db.Model): # type: ignore
null=True,
on_delete="SET NULL",
on_update="CASCADE",
object_id_name="last_modified_by_id",
)
not_registered = IntegerField(
column_name="notregistered", constraints=[SQL("DEFAULT 0")], default=False
Expand Down
1 change: 1 addition & 0 deletions back/boxtribute_server/models/definitions/box.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class Box(db.Model): # type: ignore
null=True,
on_delete="SET NULL",
on_update="CASCADE",
object_id_name="last_modified_by_id",
)
product = UIntForeignKeyField(
column_name="product_id",
Expand Down
1 change: 1 addition & 0 deletions back/boxtribute_server/models/definitions/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class Location(db.Model): # type: ignore
null=True,
on_delete="SET NULL",
on_update="CASCADE",
object_id_name="last_modified_by_id",
)
seq = IntegerField(null=True)
visible = IntegerField(constraints=[SQL("DEFAULT 1")])
Expand Down
1 change: 1 addition & 0 deletions back/boxtribute_server/models/definitions/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class Product(db.Model): # type: ignore
null=True,
on_delete="SET NULL",
on_update="CASCADE",
object_id_name="last_modified_by_id",
)
name = CharField()
size_range = UIntForeignKeyField(
Expand Down
7 changes: 6 additions & 1 deletion back/test/endpoint_tests/test_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def test_box_query_by_label_identifier(
state
qrCode {{ id }}
createdBy {{ id }}
lastModifiedBy {{ id }}
deletedOn
comment
tags {{
Expand All @@ -56,6 +57,7 @@ def test_box_query_by_label_identifier(
"state": BoxState.InStock.name,
"qrCode": {"id": str(default_box["qr_code"])},
"createdBy": {"id": str(default_box["created_by"])},
"lastModifiedBy": {"id": str(default_box["last_modified_by"])},
"deletedOn": None,
"comment": None,
"tags": [
Expand Down Expand Up @@ -584,7 +586,10 @@ def test_box_mutations(
"updatedBoxes": [
{"id": str(another_box["id"]), "location": {"id": another_location_id}}
],
"invalidBoxLabelIdentifiers": [created_box["labelIdentifier"], "99119911"],
# Identifiers will be alphabetically sorted in the response
"invalidBoxLabelIdentifiers": sorted(
[created_box["labelIdentifier"], "99119911"]
),
}

# Test cases 8.2.1, 8.2.2., 8.2.11, 8.2.25
Expand Down
4 changes: 4 additions & 0 deletions back/test/endpoint_tests/test_classic_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def test_location_query(
defaultBoxState
createdOn
createdBy {{ id }}
lastModifiedOn
lastModifiedBy {{ id }}
}}
}}"""
queried_location = assert_successful_request(read_only_client, query)
Expand All @@ -44,6 +46,8 @@ def test_location_query(
"defaultBoxState": BoxState(default_location["box_state"]).name,
"createdOn": None,
"createdBy": {"id": str(default_location["created_by"])},
"lastModifiedOn": None,
"lastModifiedBy": None,
}

query = f"""query {{ location(id: "{distribution_spot['id']}") {{ id }} }}"""
Expand Down
9 changes: 9 additions & 0 deletions back/test/endpoint_tests/test_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,15 @@ def test_invalid_permission_for_box_field(read_only_client, mocker, default_box,
assert_forbidden_request(read_only_client, query, value={field: None})


def test_invalid_permission_for_box_size(read_only_client, mocker, default_box):
# Test case 8.1.9
# verify missing size:read permission
mock_user_for_request(mocker, permissions=["stock:read"])
query = f"""query {{ box(labelIdentifier: "{default_box["label_identifier"]}")
{{ size {{ id }} }} }}"""
assert_forbidden_request(read_only_client, query)


@pytest.mark.parametrize(
"field", ["sourceLocation", "targetLocation", "sourceProduct", "targetProduct"]
)
Expand Down
4 changes: 4 additions & 0 deletions back/test/endpoint_tests/test_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def test_product_query(read_only_client, default_product, default_size, another_
gender
comment
createdBy {{ id }}
lastModifiedOn
lastModifiedBy {{ id }}
deletedOn
}}
}}"""
Expand All @@ -43,6 +45,8 @@ def test_product_query(read_only_client, default_product, default_size, another_
"comment": default_product["comment"],
"gender": "Women",
"createdBy": {"id": str(default_product["created_by"])},
"lastModifiedOn": None,
"lastModifiedBy": None,
"deletedOn": default_product["deleted_on"],
}

Expand Down
2 changes: 2 additions & 0 deletions front/src/types/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,10 @@ export type Box = ItemsCollection & {
labelIdentifier: Scalars['String'];
lastModifiedBy?: Maybe<User>;
lastModifiedOn?: Maybe<Scalars['Datetime']>;
/** If the client is not authorized to access the location's base, return `null` instead of raising an authorization error. This enables the target side of a shipment to scan boxes that are not yet reconciliated into their stock (but still registered at the source side) */
location?: Maybe<Location>;
numberOfItems?: Maybe<Scalars['Int']>;
/** If the client is not authorized to access the product's base, return `null` instead of raising an authorization error. This enables the target side of a shipment to scan boxes that are not yet reconciliated into their stock (but still registered at the source side) */
product?: Maybe<Product>;
qrCode?: Maybe<QrCode>;
/** Returns null if box is not part of an active shipment */
Expand Down

0 comments on commit 725c969

Please sign in to comment.