Skip to content

Commit

Permalink
Merge pull request #59 from MauriceBoendermaker/Locations-stock-tracking
Browse files Browse the repository at this point in the history
Locations stock tracking
  • Loading branch information
MauriceBoendermaker authored Jan 7, 2025
2 parents 0f85557 + a2056a4 commit 1c087ff
Show file tree
Hide file tree
Showing 27 changed files with 527 additions and 426 deletions.
Binary file modified .coverage
Binary file not shown.
4 changes: 4 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[run]
omit =
CargoHubV2/app/services/loader_service.py
CargoHubV2/app/services/reporting_service.py
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ htmlcov/
.nox/
.cache
nosetests.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
Expand Down
Binary file modified CargoHubV2/Cargo_Database.db
Binary file not shown.
13 changes: 13 additions & 0 deletions CargoHubV2/app/controllers/clients_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ def get_clients(
return get_all_clients(db, offset, limit, sort_by, order)


@router.get("/{country}")
def get_clients_by_country(
country: str,
offset: int = 0,
limit: int = 100,
sort_by: Optional[str] = "id",
order: Optional[str] = "asc",
db: Session = Depends(get_db),
api_key: str = Header(...),
):
return get_country_clients(db, country, offset, limit, sort_by, order)


@router.put("/{id}", response_model=ClientResponse)
def update_client_endpoint(
id: int,
Expand Down
9 changes: 0 additions & 9 deletions CargoHubV2/app/models/inventories_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,6 @@
from datetime import datetime
from ..database import Base

'''
# many-to-many relatie voor inventory en locaties
inventory_location_association = Table(
'inventory_location', Base.metadata,
Column('inventory_id', Integer, ForeignKey('inventory.id'), primary_key=True),
Column('location_id', Integer, ForeignKey('location.id'), primary_key=True)
)
'''


class Inventory(Base):
__tablename__ = 'inventories'
Expand Down
12 changes: 5 additions & 7 deletions CargoHubV2/app/models/items_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ class Item(Base):
upc_code = Column(String)
model_number = Column(String)
commodity_code = Column(String)
item_line = Column(Integer, ForeignKey("item_lines.id")) # Foreign Key to ItemLine
item_group = Column(Integer, ForeignKey("item_groups.id")) # Foreign Key to ItemGroup
item_type = Column(Integer, ForeignKey("item_types.id")) # Foreign Key to ItemType
hazard_classification = Column(String)
item_line = Column(Integer, ForeignKey("item_lines.id"))
item_group = Column(Integer, ForeignKey("item_groups.id"))
item_type = Column(Integer, ForeignKey("item_types.id"))
unit_purchase_quantity = Column(Integer)
unit_order_quantity = Column(Integer)
pack_order_quantity = Column(Integer)
Expand All @@ -27,14 +28,11 @@ class Item(Base):
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
is_deleted = Column(Boolean, default=False, nullable=False, server_default='0')


item_group_rel = relationship("ItemGroup", back_populates="items")
item_type_rel = relationship("ItemType", back_populates="items")
item_line_rel = relationship("ItemLine", back_populates="items")

# Specify foreign_keys argument to disambiguate
suppliers_rel = relationship(
"Supplier",
back_populates="items",
foreign_keys=[supplier_id], # Explicitly reference supplier_id
foreign_keys=[supplier_id],
)
6 changes: 4 additions & 2 deletions CargoHubV2/app/models/locations_model.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from sqlalchemy import Column, Integer, String, DateTime, Boolean
from sqlalchemy import Column, Integer, String, DateTime, Boolean, JSON, Float
from typing import Dict
from ..database import Base
from sqlalchemy.orm import relationship

Expand All @@ -14,4 +15,5 @@ class Location(Base):
created_at = Column(DateTime, index=True)
updated_at = Column(DateTime, index=True)
is_deleted = Column(Boolean, default=False, nullable=False, server_default='0')

stock: Dict[str, int] = Column(JSON)
max_weight = Column(Float)
1 change: 1 addition & 0 deletions CargoHubV2/app/models/warehouses_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Warehouse(Base):
province = Column(String, index=True)
country = Column(String, index=True)
contact = Column(JSON, index=True)
forbidden_classifications = Column(JSON, nullable=True)
created_at = Column(DateTime, default=datetime.now)
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
is_deleted = Column(Boolean, default=False, nullable=False, server_default='0')
Expand Down
2 changes: 2 additions & 0 deletions CargoHubV2/app/schemas/items_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class ItemBase(BaseModel):
upc_code: UpcType
model_number: str
commodity_code: str
hazard_classification: str
item_line: int = None
item_group: int = None
item_type: int = None
Expand All @@ -44,6 +45,7 @@ class ItemUpdate(BaseModel):
upc_code: Optional[UpcType] = None
model_number: Optional[str] = None
commodity_code: Optional[str] = None
hazard_classification: Optional[str] = None
item_line: Optional[int] = None
item_group: Optional[int] = None
item_type: Optional[int] = None
Expand Down
4 changes: 4 additions & 0 deletions CargoHubV2/app/schemas/locations_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ class LocationBase(BaseModel):
warehouse_id: int
code: CodeType
name: str
max_weight: Optional[float] = None
stock: list[dict]


class LocationUpdate(BaseModel):
warehouse_id: Optional[int] = None
code: Optional[CodeType] = None
name: Optional[str] = None
max_weight: Optional[float] = None
stock: Optional[list[dict]] = None


class LocationCreate(LocationBase):
Expand Down
4 changes: 3 additions & 1 deletion CargoHubV2/app/schemas/warehouses_schema.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from pydantic import BaseModel, StringConstraints
from typing_extensions import Annotated
from datetime import datetime
from typing import Optional
from typing import Optional, List

CountryType = Annotated[
str,
Expand All @@ -20,6 +20,7 @@ class WarehouseBase(BaseModel):
province: str
country: CountryType
contact: dict
forbidden_classifications: Optional[List[str]] = None


class WarehouseUpdate(BaseModel):
Expand All @@ -31,6 +32,7 @@ class WarehouseUpdate(BaseModel):
province: Optional[str] = None
country: Optional[CountryType] = None
contact: Optional[dict] = None
forbidden_classifications: Optional[List[str]] = None


class WarehouseCreate(WarehouseBase):
Expand Down
27 changes: 24 additions & 3 deletions CargoHubV2/app/services/clients_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from typing import Optional



def create_client(db: Session, client_data: dict):
client = Client(**client_data)
db.add(client)
Expand Down Expand Up @@ -43,6 +42,29 @@ def get_client(db: Session, client_id: int):
)


def get_country_clients(
db: Session,
country: str,
offset: int = 0,
limit: int = 100,
sort_by: Optional[str] = "id",
order: Optional[str] = "asc"
):
try:
query = db.query(Client).filter(Client.country == country, Client.is_deleted == False)
if sort_by:
query = apply_sorting(query, Client, sort_by, order)
clients = query.offset(offset).limit(limit).all()
if not clients:
raise HTTPException(status_code=404, detail="No clients from this country")
return clients
except SQLAlchemyError:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="An error occurred while retrieving the clients."
)


def get_all_clients(
db: Session,
offset: int = 0,
Expand All @@ -64,7 +86,6 @@ def get_all_clients(
)



def update_client(db: Session, client_id: int, client_data: ClientUpdate):
try:
client = db.query(Client).filter(Client.id == client_id).first()
Expand Down Expand Up @@ -96,7 +117,7 @@ def delete_client(db: Session, client_id: int):
client = db.query(Client).filter(Client.id == client_id, Client.is_deleted == False).first()
if not client:
raise HTTPException(status_code=404, detail="Client not found")

client.is_deleted = True # Soft delete by marking the record
db.commit()
except SQLAlchemyError:
Expand Down
72 changes: 37 additions & 35 deletions CargoHubV2/app/services/items_service.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from sqlalchemy.orm import Session
from sqlalchemy.exc import IntegrityError, SQLAlchemyError
from CargoHubV2.app.models.items_model import Item
from CargoHubV2.app.models.warehouses_model import Warehouse
from CargoHubV2.app.schemas.items_schema import ItemUpdate
from CargoHubV2.app.services.sorting_service import apply_sorting

Expand All @@ -9,27 +10,6 @@
from typing import Optional


def create_item(db: Session, item_data: dict):
item = Item(**item_data)
db.add(item)
try:
db.commit()
db.refresh(item)
except IntegrityError:
db.rollback()
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="An item with this code already exists."
)
except SQLAlchemyError:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="An error occurred while creating the item."
)
return item


def get_item(db: Session, code: str):
try:
item = db.query(Item).filter(Item.code == code, Item.is_deleted == False).first()
Expand Down Expand Up @@ -57,29 +37,52 @@ def get_all_items(db: Session, offset: int = 0, limit: int = 100, sort_by: Optio
)


def create_item(db: Session, item_data: dict):
warehouse = db.query(Warehouse).filter(Warehouse.id == item_data.get("warehouse_id")).first()
if warehouse and warehouse.forbidden_classifications:
if item_data.get("hazard_classification") in warehouse.forbidden_classifications:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Item's hazard classification is not allowed in the warehouse."
)

def update_item(db: Session, code: str, item_data: ItemUpdate):
item = Item(**item_data)
db.add(item)
try:
item = db.query(Item).filter(Item.code == code).first()
if not item:
raise HTTPException(status_code=404, detail="Item not found")
update_data = item_data.model_dump(exclude_unset=True)
for key, value in update_data.items():
setattr(item, key, value)
item.updated_at = datetime.now()
db.commit()
db.refresh(item)
except IntegrityError:
db.rollback()
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="An integrity error occurred while updating the item."
detail="An item with this code already exists."
)
except SQLAlchemyError:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="An error occurred while updating the item."
detail="An error occurred while creating the item."
)
return item


def update_item(db: Session, code: str, item_data: ItemUpdate):
item = db.query(Item).filter(Item.code == code).first()
if not item:
raise HTTPException(status_code=404, detail="Item not found")

update_data = item_data.model_dump(exclude_unset=True)
for key, value in update_data.items():
setattr(item, key, value)
item.updated_at = datetime.now()
try:
db.commit()
db.refresh(item)
except IntegrityError:
db.rollback()
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="An item with this code already exists."
)
return item

Expand All @@ -88,15 +91,14 @@ def delete_item(db: Session, code: str):
try:
item = db.query(Item).filter(Item.code == code, Item.is_deleted == False).first()
if not item:
return None # Return None if not found
return None
item.is_deleted = True
db.commit()
db.refresh(item)
return item # Return the *item* object
return item
except SQLAlchemyError:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="An error occurred while deleting the item."
)

)
2 changes: 2 additions & 0 deletions CargoHubV2/app/services/locations_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ def create_location(db: Session, location_data: LocationCreate):
warehouse_id=location_data.warehouse_id,
code=location_data.code,
name=location_data.name,
stock=location_data.stock,
max_weight=location_data.max_weight,
created_at=datetime.now(),
updated_at=datetime.now()
)
Expand Down
Loading

1 comment on commit 1c087ff

@github-actions
Copy link

Please sign in to comment.