god help me
This commit is contained in:
parent
6178fdd15d
commit
34eac3d954
86
alembic/versions/28cfdbde1796_idk_lol.py
Normal file
86
alembic/versions/28cfdbde1796_idk_lol.py
Normal file
@ -0,0 +1,86 @@
|
||||
"""idk lol
|
||||
|
||||
Revision ID: 28cfdbde1796
|
||||
Revises: d4d3f43ce86a
|
||||
Create Date: 2025-04-19 16:17:07.109451
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '28cfdbde1796'
|
||||
down_revision: Union[str, None] = 'd4d3f43ce86a'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
"""Upgrade schema."""
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_index('ix_cost_basis_id', table_name='cost_basis')
|
||||
op.drop_table('cost_basis')
|
||||
op.drop_index('ix_cards_id', table_name='cards')
|
||||
op.drop_index('ix_cards_name', table_name='cards')
|
||||
op.drop_index('ix_cards_set_name', table_name='cards')
|
||||
op.drop_index('ix_cards_tcgplayer_sku', table_name='cards')
|
||||
op.drop_table('cards')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
"""Downgrade schema."""
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('cards',
|
||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
||||
sa.Column('name', sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
sa.Column('rarity', sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
sa.Column('set_name', sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
sa.Column('price', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True),
|
||||
sa.Column('quantity', sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column('tcgplayer_sku', sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
sa.Column('product_line', sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
sa.Column('product_name', sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
sa.Column('title', sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
sa.Column('number', sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
sa.Column('condition', sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
sa.Column('tcg_market_price', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True),
|
||||
sa.Column('tcg_direct_low', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True),
|
||||
sa.Column('tcg_low_price_with_shipping', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True),
|
||||
sa.Column('tcg_low_price', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True),
|
||||
sa.Column('total_quantity', sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column('add_to_quantity', sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column('tcg_marketplace_price', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True),
|
||||
sa.Column('photo_url', sa.VARCHAR(), autoincrement=False, nullable=True),
|
||||
sa.Column('created_at', postgresql.TIMESTAMP(timezone=True), server_default=sa.text('now()'), autoincrement=False, nullable=True),
|
||||
sa.Column('updated_at', postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=True),
|
||||
sa.PrimaryKeyConstraint('id', name='cards_pkey')
|
||||
)
|
||||
op.create_index('ix_cards_tcgplayer_sku', 'cards', ['tcgplayer_sku'], unique=True)
|
||||
op.create_index('ix_cards_set_name', 'cards', ['set_name'], unique=False)
|
||||
op.create_index('ix_cards_name', 'cards', ['name'], unique=False)
|
||||
op.create_index('ix_cards_id', 'cards', ['id'], unique=False)
|
||||
op.create_table('cost_basis',
|
||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
||||
sa.Column('transaction_item_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column('sealed_case_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column('sealed_box_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column('open_box_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column('open_card_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
||||
sa.Column('quantity', sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
sa.Column('unit_cost', sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=False),
|
||||
sa.Column('created_at', postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=True),
|
||||
sa.Column('updated_at', postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=True),
|
||||
sa.Column('deleted_at', postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=True),
|
||||
sa.ForeignKeyConstraint(['open_box_id'], ['open_boxes.id'], name='cost_basis_open_box_id_fkey'),
|
||||
sa.ForeignKeyConstraint(['open_card_id'], ['open_cards.id'], name='cost_basis_open_card_id_fkey'),
|
||||
sa.ForeignKeyConstraint(['sealed_box_id'], ['sealed_boxes.id'], name='cost_basis_sealed_box_id_fkey'),
|
||||
sa.ForeignKeyConstraint(['sealed_case_id'], ['sealed_cases.id'], name='cost_basis_sealed_case_id_fkey'),
|
||||
sa.ForeignKeyConstraint(['transaction_item_id'], ['transaction_items.id'], name='cost_basis_transaction_item_id_fkey'),
|
||||
sa.PrimaryKeyConstraint('id', name='cost_basis_pkey')
|
||||
)
|
||||
op.create_index('ix_cost_basis_id', 'cost_basis', ['id'], unique=False)
|
||||
# ### end Alembic commands ###
|
94
app.log
94
app.log
@ -1,28 +1,66 @@
|
||||
2025-04-19 13:56:40,410 - INFO - app.main - Application starting up...
|
||||
2025-04-19 13:56:40,492 - INFO - app.main - Database initialized successfully
|
||||
2025-04-19 13:56:40,492 - INFO - app.services.service_manager - Service OrderManagementService registered
|
||||
2025-04-19 13:56:40,492 - INFO - app.services.service_manager - Service TCGPlayerInventoryService registered
|
||||
2025-04-19 13:56:40,492 - INFO - app.services.service_manager - Service LabelPrinterService registered
|
||||
2025-04-19 13:56:40,492 - INFO - app.services.service_manager - Service RegularPrinterService registered
|
||||
2025-04-19 13:56:40,495 - INFO - app.services.service_manager - Service AddressLabelService registered
|
||||
2025-04-19 13:56:40,497 - INFO - app.services.service_manager - Service PullSheetService registered
|
||||
2025-04-19 13:56:40,497 - INFO - app.services.service_manager - Service SetLabelService registered
|
||||
2025-04-19 13:56:40,497 - INFO - app.services.service_manager - Service DataInitializationService registered
|
||||
2025-04-19 13:56:40,498 - INFO - app.services.service_manager - Service SchedulerService registered
|
||||
2025-04-19 13:56:40,498 - INFO - app.services.service_manager - Service FileService registered
|
||||
2025-04-19 13:56:40,498 - INFO - app.services.service_manager - Service TCGCSVService registered
|
||||
2025-04-19 13:56:40,498 - INFO - app.services.service_manager - Service MTGJSONService registered
|
||||
2025-04-19 13:56:40,499 - INFO - app.services.service_manager - All services initialized successfully
|
||||
2025-04-19 13:56:40,499 - INFO - app.services.data_initialization - Starting data initialization process
|
||||
2025-04-19 13:56:40,499 - INFO - app.services.data_initialization - Data initialization completed
|
||||
2025-04-19 13:56:40,499 - INFO - app.main - Data initialization results: {}
|
||||
2025-04-19 13:56:40,499 - INFO - apscheduler.scheduler - Adding job tentatively -- it will be properly scheduled when the scheduler starts
|
||||
2025-04-19 13:56:40,499 - INFO - app.services.scheduler.base_scheduler - Scheduled task update_open_orders_hourly to run every 3600 seconds
|
||||
2025-04-19 13:56:40,499 - INFO - apscheduler.scheduler - Adding job tentatively -- it will be properly scheduled when the scheduler starts
|
||||
2025-04-19 13:56:40,499 - INFO - app.services.scheduler.base_scheduler - Scheduled task update_all_orders_daily to run every 86400 seconds
|
||||
2025-04-19 13:56:40,499 - INFO - apscheduler.scheduler - Added job "SchedulerService.start_scheduled_tasks.<locals>.<lambda>" to job store "default"
|
||||
2025-04-19 13:56:40,500 - INFO - apscheduler.scheduler - Added job "SchedulerService.start_scheduled_tasks.<locals>.<lambda>" to job store "default"
|
||||
2025-04-19 13:56:40,500 - INFO - apscheduler.scheduler - Scheduler started
|
||||
2025-04-19 13:56:40,500 - INFO - app.services.scheduler.base_scheduler - Scheduler started
|
||||
2025-04-19 13:56:40,500 - INFO - app.services.scheduler.scheduler_service - All scheduled tasks started
|
||||
2025-04-19 13:56:40,500 - INFO - app.main - Scheduler started successfully
|
||||
2025-04-19 21:40:53,869 - INFO - app.main - Application starting up...
|
||||
2025-04-19 21:40:53,914 - INFO - app.main - Database initialized successfully
|
||||
2025-04-19 21:40:53,914 - INFO - app.services.service_manager - Service OrderManagementService registered
|
||||
2025-04-19 21:40:53,914 - INFO - app.services.service_manager - Service TCGPlayerInventoryService registered
|
||||
2025-04-19 21:40:53,915 - INFO - app.services.service_manager - Service LabelPrinterService registered
|
||||
2025-04-19 21:40:53,915 - INFO - app.services.service_manager - Service RegularPrinterService registered
|
||||
2025-04-19 21:40:53,918 - INFO - app.services.service_manager - Service AddressLabelService registered
|
||||
2025-04-19 21:40:53,920 - INFO - app.services.service_manager - Service PullSheetService registered
|
||||
2025-04-19 21:40:53,920 - INFO - app.services.service_manager - Service SetLabelService registered
|
||||
2025-04-19 21:40:53,920 - INFO - app.services.service_manager - Service DataInitializationService registered
|
||||
2025-04-19 21:40:53,920 - DEBUG - tzlocal - /etc/localtime found
|
||||
2025-04-19 21:40:53,921 - DEBUG - tzlocal - 1 found:
|
||||
{'/etc/localtime is a symlink to': 'US/Michigan'}
|
||||
2025-04-19 21:40:53,921 - INFO - app.services.service_manager - Service SchedulerService registered
|
||||
2025-04-19 21:40:53,921 - INFO - app.services.service_manager - Service FileService registered
|
||||
2025-04-19 21:40:53,921 - INFO - app.services.service_manager - Service TCGCSVService registered
|
||||
2025-04-19 21:40:53,921 - INFO - app.services.service_manager - Service MTGJSONService registered
|
||||
2025-04-19 21:40:53,921 - INFO - app.services.service_manager - All services initialized successfully
|
||||
2025-04-19 21:40:53,921 - INFO - app.services.data_initialization - Starting data initialization process
|
||||
2025-04-19 21:40:53,921 - INFO - app.services.data_initialization - Initializing MTGJSON data...
|
||||
2025-04-19 21:40:53,921 - INFO - app.services.data_initialization - Starting MTGJSON initialization
|
||||
2025-04-19 21:40:53,947 - DEBUG - app.services.external_api.mtgjson.mtgjson_service - Loaded SKUs from cache: app/data/cache/mtgjson/skus/TcgplayerSkus.json
|
||||
2025-04-19 22:38:54,248 - INFO - app.services.data_initialization - Data initialization completed
|
||||
2025-04-19 22:38:54,249 - INFO - app.main - Data initialization results: {'mtgjson': {'identifiers_processed': 0, 'skus_processed': 4764017}}
|
||||
2025-04-19 22:38:54,249 - INFO - apscheduler.scheduler - Adding job tentatively -- it will be properly scheduled when the scheduler starts
|
||||
2025-04-19 22:38:54,249 - INFO - app.services.scheduler.base_scheduler - Scheduled task update_open_orders_hourly to run every 3600 seconds
|
||||
2025-04-19 22:38:54,249 - INFO - apscheduler.scheduler - Adding job tentatively -- it will be properly scheduled when the scheduler starts
|
||||
2025-04-19 22:38:54,249 - INFO - app.services.scheduler.base_scheduler - Scheduled task update_all_orders_daily to run every 86400 seconds
|
||||
2025-04-19 22:38:54,250 - INFO - apscheduler.scheduler - Added job "SchedulerService.start_scheduled_tasks.<locals>.<lambda>" to job store "default"
|
||||
2025-04-19 22:38:54,250 - INFO - apscheduler.scheduler - Added job "SchedulerService.start_scheduled_tasks.<locals>.<lambda>" to job store "default"
|
||||
2025-04-19 22:38:54,250 - INFO - apscheduler.scheduler - Scheduler started
|
||||
2025-04-19 22:38:54,250 - INFO - app.services.scheduler.base_scheduler - Scheduler started
|
||||
2025-04-19 22:38:54,250 - INFO - app.services.scheduler.scheduler_service - All scheduled tasks started
|
||||
2025-04-19 22:38:54,250 - INFO - app.main - Scheduler started successfully
|
||||
2025-04-19 22:38:54,251 - DEBUG - apscheduler.scheduler - Looking for jobs to run
|
||||
2025-04-19 22:38:54,251 - DEBUG - apscheduler.scheduler - Next wakeup is due at 2025-04-19 23:38:54.249141-04:00 (in 3599.997778 seconds)
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service MTGJSONService cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service mtgjson cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service TCGCSVService cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service tcgcsv cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service FileService cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service file cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.scheduler.base_scheduler - Scheduler stopped
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.scheduler.scheduler_service - Scheduler services closed
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service SchedulerService cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.scheduler.scheduler_service - Scheduler services closed
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service scheduler cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service DataInitializationService cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service data_initialization cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service SetLabelService cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service set_label cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service PullSheetService cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service pull_sheet cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service AddressLabelService cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service address_label cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service RegularPrinterService cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service regular_printer cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service LabelPrinterService cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service label_printer cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service TCGPlayerInventoryService cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service tcgplayer_inventory cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service OrderManagementService cleaned up
|
||||
2025-04-19 22:53:56,053 - INFO - app.services.service_manager - Service order_management cleaned up
|
||||
2025-04-19 22:53:56,054 - INFO - app.services.service_manager - All services cleaned up successfully
|
||||
2025-04-19 22:53:56,054 - INFO - app.main - All services cleaned up successfully
|
||||
2025-04-19 22:53:56,054 - INFO - apscheduler.scheduler - Scheduler has been shut down
|
||||
|
@ -30,7 +30,7 @@ file_handler.setFormatter(formatter)
|
||||
|
||||
# Configure root logger
|
||||
root_logger = logging.getLogger()
|
||||
root_logger.setLevel(logging.INFO)
|
||||
root_logger.setLevel(logging.DEBUG)
|
||||
root_logger.addHandler(console_handler)
|
||||
root_logger.addHandler(file_handler)
|
||||
|
||||
@ -58,7 +58,7 @@ async def lifespan(app: FastAPI):
|
||||
db = SessionLocal()
|
||||
try:
|
||||
data_init_service = service_manager.get_service('data_initialization')
|
||||
data_init = await data_init_service.initialize_data(db, game_ids=[1, 3], use_cache=False, init_categories=False, init_products=False, init_groups=False, init_archived_prices=False, init_mtgjson=False, archived_prices_start_date="2024-03-05", archived_prices_end_date="2025-04-17")
|
||||
data_init = await data_init_service.initialize_data(db, game_ids=[1, 3], use_cache=True, init_categories=False, init_products=False, init_groups=False, init_archived_prices=False, init_mtgjson=True, archived_prices_start_date="2024-03-05", archived_prices_end_date="2025-04-17")
|
||||
logger.info(f"Data initialization results: {data_init}")
|
||||
|
||||
# Start the scheduler
|
||||
|
@ -6,8 +6,7 @@ from app.models.inventory_management import (
|
||||
OpenEvent,
|
||||
Vendor,
|
||||
Customer,
|
||||
Transaction,
|
||||
CostBasis
|
||||
Transaction
|
||||
)
|
||||
from app.models.mtgjson_card import MTGJSONCard
|
||||
from app.models.mtgjson_sku import MTGJSONSKU
|
||||
@ -34,7 +33,6 @@ __all__ = [
|
||||
'Vendor',
|
||||
'Customer',
|
||||
'Transaction',
|
||||
'CostBasis',
|
||||
'MTGJSONCard',
|
||||
'MTGJSONSKU',
|
||||
'Product',
|
||||
|
@ -1,8 +1,4 @@
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from typing import List, Optional
|
||||
from datetime import datetime
|
||||
from sqlalchemy import Column, Integer, String, DateTime, JSON
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.sql import func
|
||||
from app.db.database import Base
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey, Table
|
||||
from sqlalchemy import Column, Integer, String, Float, DateTime, ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from app.db.database import Base
|
||||
|
||||
@ -32,7 +32,7 @@ class SealedCase(PhysicalItem):
|
||||
}
|
||||
|
||||
# Relationships
|
||||
boxes = relationship("SealedBox", back_populates="case")
|
||||
boxes = relationship("SealedBox", back_populates="case", foreign_keys="[SealedBox.case_id]")
|
||||
open_event = relationship("OpenEvent", uselist=False, back_populates="sealed_case")
|
||||
|
||||
class SealedBox(PhysicalItem):
|
||||
@ -46,7 +46,7 @@ class SealedBox(PhysicalItem):
|
||||
}
|
||||
|
||||
# Relationships
|
||||
case = relationship("SealedCase", back_populates="boxes")
|
||||
case = relationship("SealedCase", back_populates="boxes", foreign_keys=[case_id])
|
||||
open_event = relationship("OpenEvent", uselist=False, back_populates="sealed_box")
|
||||
|
||||
class OpenBox(PhysicalItem):
|
||||
@ -62,8 +62,8 @@ class OpenBox(PhysicalItem):
|
||||
|
||||
# Relationships
|
||||
open_event = relationship("OpenEvent", back_populates="resulting_boxes")
|
||||
sealed_box = relationship("SealedBox")
|
||||
cards = relationship("OpenCard", back_populates="box")
|
||||
sealed_box = relationship("SealedBox", foreign_keys=[sealed_box_id])
|
||||
cards = relationship("OpenCard", back_populates="box", foreign_keys="[OpenCard.box_id]")
|
||||
|
||||
class OpenCard(PhysicalItem):
|
||||
__tablename__ = "open_cards"
|
||||
@ -78,7 +78,7 @@ class OpenCard(PhysicalItem):
|
||||
|
||||
# Relationships
|
||||
open_event = relationship("OpenEvent", back_populates="resulting_cards")
|
||||
box = relationship("OpenBox", back_populates="cards")
|
||||
box = relationship("OpenBox", back_populates="cards", foreign_keys=[box_id])
|
||||
|
||||
class InventoryItem(Base):
|
||||
__tablename__ = "inventory_items"
|
||||
@ -93,8 +93,8 @@ class InventoryItem(Base):
|
||||
|
||||
# Relationships
|
||||
physical_item = relationship("PhysicalItem", back_populates="inventory_item")
|
||||
parent = relationship("InventoryItem", remote_side=[id])
|
||||
children = relationship("InventoryItem")
|
||||
parent = relationship("InventoryItem", remote_side=[id], back_populates="children")
|
||||
children = relationship("InventoryItem", back_populates="parent", overlaps="parent")
|
||||
|
||||
class TransactionItem(Base):
|
||||
__tablename__ = "transaction_items"
|
||||
@ -161,25 +161,3 @@ class Transaction(Base):
|
||||
|
||||
# Relationships
|
||||
transaction_items = relationship("TransactionItem", back_populates="transaction")
|
||||
|
||||
class CostBasis(Base):
|
||||
__tablename__ = "cost_basis"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
transaction_item_id = Column(Integer, ForeignKey("transaction_items.id"))
|
||||
sealed_case_id = Column(Integer, ForeignKey("sealed_cases.id"), nullable=True)
|
||||
sealed_box_id = Column(Integer, ForeignKey("sealed_boxes.id"), nullable=True)
|
||||
open_box_id = Column(Integer, ForeignKey("open_boxes.id"), nullable=True)
|
||||
open_card_id = Column(Integer, ForeignKey("open_cards.id"), nullable=True)
|
||||
quantity = Column(Integer, nullable=False, default=1)
|
||||
unit_cost = Column(Float, nullable=False)
|
||||
created_at = Column(DateTime(timezone=True))
|
||||
updated_at = Column(DateTime(timezone=True))
|
||||
deleted_at = Column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
# Relationships
|
||||
transaction_item = relationship("TransactionItem")
|
||||
sealed_case = relationship("SealedCase")
|
||||
sealed_box = relationship("SealedBox")
|
||||
open_box = relationship("OpenBox")
|
||||
open_card = relationship("OpenCard")
|
||||
|
@ -1,17 +1,13 @@
|
||||
from fastapi import APIRouter, HTTPException, Depends, Query, UploadFile, File
|
||||
from fastapi import APIRouter, HTTPException, Depends, UploadFile, File
|
||||
from typing import List
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from app.schemas.tcgplayer import TCGPlayerAPIOrderSummary, TCGPlayerAPIOrder
|
||||
from app.schemas.generate import GenerateAddressLabelsRequest, GeneratePackingSlipsRequest, GeneratePullSheetsRequest, GenerateResponse, GenerateReturnLabelsRequest
|
||||
from app.schemas.file import FileUpload
|
||||
from app.services.service_manager import ServiceManager
|
||||
from app.services.file_service import FileService
|
||||
from sqlalchemy.orm import Session
|
||||
from app.db.database import get_db
|
||||
import os
|
||||
import tempfile
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -223,3 +219,24 @@ async def print_pirate_ship_label(
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Failed to print Pirate Ship label: {str(e)}")
|
||||
|
||||
@router.post("/process-manabox-csv")
|
||||
async def process_manabox_csv(
|
||||
file: UploadFile = File(...),
|
||||
db: Session = Depends(get_db)
|
||||
) -> GenerateResponse:
|
||||
try:
|
||||
# ensure csv
|
||||
if file.content_type != "text/csv":
|
||||
raise HTTPException(status_code=400, detail="File must be a CSV")
|
||||
# read file
|
||||
content = await file.read()
|
||||
# save file
|
||||
file_service = service_manager.get_service('file')
|
||||
stored_file = await file_service.save_file(db, content, f'manabox_upload_{datetime.now().strftime("%Y%m%d_%H%M%S")}.csv', "manabox_csvs", "csv")
|
||||
# process csv
|
||||
manabox_service = service_manager.get_service('manabox')
|
||||
success = await manabox_service.process_manabox_csv(db, stored_file)
|
||||
return {"success": success, "message": "Manabox CSV processed successfully"}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Failed to process Manabox CSV: {str(e)}")
|
||||
|
@ -1,7 +1,7 @@
|
||||
import os
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional, List, Dict, Any, Union, Generator, Callable
|
||||
from typing import Optional, List, Dict, Any, Union, Generator, Callable, AsyncGenerator
|
||||
from sqlalchemy.orm import Session
|
||||
from app.models.tcgplayer_group import TCGPlayerGroup
|
||||
from app.models.tcgplayer_product import TCGPlayerProduct
|
||||
@ -462,111 +462,37 @@ class DataInitializationService(BaseService):
|
||||
identifiers_count = 0
|
||||
skus_count = 0
|
||||
|
||||
# Process identifiers
|
||||
if use_cache:
|
||||
cached_file = await self.file_service.get_file_by_filename(db, "mtgjson_identifiers.json")
|
||||
if cached_file and os.path.exists(cached_file.path):
|
||||
logger.info("MTGJSON identifiers initialized from cache")
|
||||
identifiers_count = await self._process_streamed_data(
|
||||
db,
|
||||
self._stream_json_file(cached_file.path),
|
||||
"mtgjson_identifiers.json",
|
||||
"mtgjson",
|
||||
self.sync_mtgjson_identifiers
|
||||
)
|
||||
else:
|
||||
logger.info("Downloading MTGJSON identifiers from API")
|
||||
identifiers_count = await self._process_streamed_data(
|
||||
db,
|
||||
await mtgjson_service.get_identifiers(db),
|
||||
"mtgjson_identifiers.json",
|
||||
"mtgjson",
|
||||
self.sync_mtgjson_identifiers
|
||||
)
|
||||
else:
|
||||
logger.info("Downloading MTGJSON identifiers from API")
|
||||
identifiers_count = await self._process_streamed_data(
|
||||
db,
|
||||
await mtgjson_service.get_identifiers(db),
|
||||
"mtgjson_identifiers.json",
|
||||
"mtgjson",
|
||||
self.sync_mtgjson_identifiers
|
||||
)
|
||||
# Get identifiers data
|
||||
identifiers_data = await mtgjson_service.get_identifiers(db, use_cache)
|
||||
if identifiers_data and "data" in identifiers_data:
|
||||
identifiers_count = await self.sync_mtgjson_identifiers(db, list(identifiers_data["data"].values()))
|
||||
|
||||
# Process SKUs
|
||||
if use_cache:
|
||||
cached_file = await self.file_service.get_file_by_filename(db, "mtgjson_skus.json")
|
||||
if cached_file and os.path.exists(cached_file.path):
|
||||
logger.info("MTGJSON SKUs initialized from cache")
|
||||
skus_count = await self._process_streamed_data(
|
||||
db,
|
||||
self._stream_json_file(cached_file.path),
|
||||
"mtgjson_skus.json",
|
||||
"mtgjson",
|
||||
self.sync_mtgjson_skus
|
||||
)
|
||||
else:
|
||||
logger.info("Downloading MTGJSON SKUs from API")
|
||||
skus_count = await self._process_streamed_data(
|
||||
db,
|
||||
await mtgjson_service.get_skus(db),
|
||||
"mtgjson_skus.json",
|
||||
"mtgjson",
|
||||
self.sync_mtgjson_skus
|
||||
)
|
||||
else:
|
||||
logger.info("Downloading MTGJSON SKUs from API")
|
||||
skus_count = await self._process_streamed_data(
|
||||
db,
|
||||
await mtgjson_service.get_skus(db),
|
||||
"mtgjson_skus.json",
|
||||
"mtgjson",
|
||||
self.sync_mtgjson_skus
|
||||
)
|
||||
# Get SKUs data
|
||||
skus_data = await mtgjson_service.get_skus(db, use_cache)
|
||||
if skus_data and "data" in skus_data:
|
||||
skus_count = await self.sync_mtgjson_skus(db, list(skus_data["data"].values()))
|
||||
|
||||
return {
|
||||
"identifiers_processed": identifiers_count,
|
||||
"skus_processed": skus_count
|
||||
}
|
||||
|
||||
async def _process_streamed_data(
|
||||
self,
|
||||
db: Session,
|
||||
data_stream: Generator[Dict[str, Any], None, None],
|
||||
filename: str,
|
||||
subdir: str,
|
||||
sync_func: Callable
|
||||
) -> int:
|
||||
"""Process streamed data and sync to database"""
|
||||
count = 0
|
||||
items = []
|
||||
batch_size = 1000
|
||||
|
||||
for item in data_stream:
|
||||
if item["type"] == "meta":
|
||||
# Handle meta data separately
|
||||
continue
|
||||
|
||||
count += 1
|
||||
items.append(item["data"])
|
||||
|
||||
# Process in batches
|
||||
if len(items) >= batch_size:
|
||||
await sync_func(db, items)
|
||||
items = []
|
||||
|
||||
# Process any remaining items
|
||||
if items:
|
||||
await sync_func(db, items)
|
||||
|
||||
return count
|
||||
|
||||
async def sync_mtgjson_identifiers(self, db: Session, identifiers_data: dict):
|
||||
async def sync_mtgjson_identifiers(self, db: Session, identifiers_data: List[dict]) -> int:
|
||||
"""Sync MTGJSON identifiers data to the database"""
|
||||
from app.models.mtgjson_card import MTGJSONCard
|
||||
|
||||
count = 0
|
||||
with transaction(db):
|
||||
for card_id, card_data in identifiers_data.items():
|
||||
for card_data in identifiers_data:
|
||||
if not isinstance(card_data, dict):
|
||||
logger.debug(f"Skipping non-dict item: {card_data}")
|
||||
continue
|
||||
|
||||
card_id = card_data.get("uuid")
|
||||
if not card_id:
|
||||
logger.debug(f"Skipping item without UUID: {card_data}")
|
||||
continue
|
||||
|
||||
existing_card = db.query(MTGJSONCard).filter(MTGJSONCard.card_id == card_id).first()
|
||||
if existing_card:
|
||||
# Update existing card
|
||||
@ -636,53 +562,47 @@ class DataInitializationService(BaseService):
|
||||
tnt_id=card_data.get("identifiers", {}).get("tntId")
|
||||
)
|
||||
db.add(new_card)
|
||||
count += 1
|
||||
|
||||
async def sync_mtgjson_skus(self, db: Session, skus_data: dict):
|
||||
return count
|
||||
|
||||
async def sync_mtgjson_skus(self, db: Session, skus_data: List[List[dict]]) -> int:
|
||||
"""Sync MTGJSON SKUs data to the database"""
|
||||
from app.models.mtgjson_sku import MTGJSONSKU
|
||||
|
||||
count = 0
|
||||
with transaction(db):
|
||||
for card_uuid, sku_list in skus_data.items():
|
||||
for sku in sku_list:
|
||||
# Handle case where sku is a string (skuId)
|
||||
if isinstance(sku, str):
|
||||
sku_id = sku
|
||||
existing_sku = db.query(MTGJSONSKU).filter(MTGJSONSKU.sku_id == sku_id).first()
|
||||
if existing_sku:
|
||||
# Update existing SKU
|
||||
existing_sku.card_id = card_uuid
|
||||
else:
|
||||
new_sku = MTGJSONSKU(
|
||||
sku_id=sku_id,
|
||||
card_id=card_uuid
|
||||
)
|
||||
db.add(new_sku)
|
||||
# Handle case where sku is a dictionary
|
||||
else:
|
||||
sku_id = str(sku.get("skuId"))
|
||||
existing_sku = db.query(MTGJSONSKU).filter(MTGJSONSKU.sku_id == sku_id).first()
|
||||
for product_data in skus_data:
|
||||
for sku_data in product_data:
|
||||
sku_id = sku_data.get("skuId")
|
||||
if not sku_id:
|
||||
logger.debug(f"Skipping item without SKU ID: {sku_data}")
|
||||
continue
|
||||
|
||||
existing_sku = db.query(MTGJSONSKU).filter(MTGJSONSKU.sku_id == str(sku_id)).first()
|
||||
if existing_sku:
|
||||
# Update existing SKU
|
||||
for key, value in {
|
||||
"product_id": str(sku.get("productId")),
|
||||
"condition": sku.get("condition"),
|
||||
"finish": sku.get("finish"),
|
||||
"language": sku.get("language"),
|
||||
"printing": sku.get("printing"),
|
||||
"card_id": card_uuid
|
||||
"product_id": sku_data.get("productId"),
|
||||
"condition": sku_data.get("condition"),
|
||||
"finish": sku_data.get("finish"),
|
||||
"language": sku_data.get("language"),
|
||||
"printing": sku_data.get("printing"),
|
||||
}.items():
|
||||
setattr(existing_sku, key, value)
|
||||
else:
|
||||
new_sku = MTGJSONSKU(
|
||||
sku_id=sku_id,
|
||||
product_id=str(sku.get("productId")),
|
||||
condition=sku.get("condition"),
|
||||
finish=sku.get("finish"),
|
||||
language=sku.get("language"),
|
||||
printing=sku.get("printing"),
|
||||
card_id=card_uuid
|
||||
product_id=sku_data.get("productId"),
|
||||
condition=sku_data.get("condition"),
|
||||
finish=sku_data.get("finish"),
|
||||
language=sku_data.get("language"),
|
||||
printing=sku_data.get("printing"),
|
||||
)
|
||||
db.add(new_sku)
|
||||
count += 1
|
||||
|
||||
return count
|
||||
|
||||
async def initialize_data(
|
||||
self,
|
||||
|
@ -2,7 +2,8 @@ import os
|
||||
import json
|
||||
import zipfile
|
||||
import time
|
||||
from typing import Dict, Any, Optional, Generator
|
||||
import shutil
|
||||
from typing import Dict, Any, Optional
|
||||
from sqlalchemy.orm import Session
|
||||
from app.services.external_api.base_external_service import BaseExternalService
|
||||
from app.schemas.file import FileInDB
|
||||
@ -11,32 +12,10 @@ import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class MTGJSONService(BaseExternalService):
|
||||
def __init__(self, cache_dir: str = "app/data/cache/mtgjson"):
|
||||
def __init__(self):
|
||||
super().__init__(base_url="https://mtgjson.com/api/v5/")
|
||||
# Ensure the cache directory exists
|
||||
os.makedirs(cache_dir, exist_ok=True)
|
||||
self.cache_dir = cache_dir
|
||||
self.identifiers_dir = os.path.join(cache_dir, "identifiers")
|
||||
self.skus_dir = os.path.join(cache_dir, "skus")
|
||||
# Ensure subdirectories exist
|
||||
os.makedirs(self.identifiers_dir, exist_ok=True)
|
||||
os.makedirs(self.skus_dir, exist_ok=True)
|
||||
|
||||
def _format_progress(self, current: int, total: int, start_time: float) -> str:
|
||||
"""Format a progress message with percentage and timing information"""
|
||||
elapsed = time.time() - start_time
|
||||
if total > 0:
|
||||
percent = (current / total) * 100
|
||||
items_per_second = current / elapsed if elapsed > 0 else 0
|
||||
eta = (total - current) / items_per_second if items_per_second > 0 else 0
|
||||
return f"[{current}/{total} ({percent:.1f}%)] {items_per_second:.1f} items/sec, ETA: {eta:.1f}s"
|
||||
return f"[{current} items] {current/elapsed:.1f} items/sec"
|
||||
|
||||
def _print_progress(self, message: str, end: str = "\n") -> None:
|
||||
"""Print progress message with flush"""
|
||||
print(message, end=end, flush=True)
|
||||
|
||||
async def _download_file(self, db: Session, url: str, filename: str, subdir: str) -> FileInDB:
|
||||
async def _download_and_unzip_file(self, db: Session, url: str, filename: str, subdir: str) -> FileInDB:
|
||||
"""Download a file from the given URL and save it using FileService"""
|
||||
print(f"Downloading {url}...")
|
||||
start_time = time.time()
|
||||
@ -49,7 +28,7 @@ class MTGJSONService(BaseExternalService):
|
||||
)
|
||||
|
||||
# Save the file using the file service
|
||||
return await self.file_service.save_file(
|
||||
file_record = await self.file_service.save_file(
|
||||
db=db,
|
||||
file_data=file_data,
|
||||
filename=filename,
|
||||
@ -58,17 +37,23 @@ class MTGJSONService(BaseExternalService):
|
||||
content_type="application/zip"
|
||||
)
|
||||
|
||||
async def _unzip_file(self, file_record: FileInDB, subdir: str, db: Session) -> str:
|
||||
# Unzip the file
|
||||
await self._unzip_file(file_record, subdir, db)
|
||||
|
||||
return file_record
|
||||
|
||||
|
||||
async def _unzip_file(self, file_record: FileInDB, subdir: str, db: Session) -> FileInDB:
|
||||
"""Unzip a file to the specified subdirectory and return the path to the extracted JSON file"""
|
||||
try:
|
||||
# Use the appropriate subdirectory based on the type
|
||||
extract_path = self.identifiers_dir if subdir == "identifiers" else self.skus_dir
|
||||
os.makedirs(extract_path, exist_ok=True)
|
||||
|
||||
file_service = self.get_service('file')
|
||||
cache_dir = file_service.base_cache_dir
|
||||
temp_dir = os.path.join(cache_dir,'mtgjson', subdir, 'temp')
|
||||
os.makedirs(temp_dir, exist_ok=True)
|
||||
with zipfile.ZipFile(file_record.path, 'r') as zip_ref:
|
||||
json_filename = zip_ref.namelist()[0]
|
||||
zip_ref.extractall(extract_path)
|
||||
json_path = os.path.join(extract_path, json_filename)
|
||||
zip_ref.extractall(temp_dir)
|
||||
json_path = os.path.join(temp_dir, json_filename)
|
||||
|
||||
# Create a file record for the extracted JSON file
|
||||
with open(json_path, 'r') as f:
|
||||
@ -82,127 +67,57 @@ class MTGJSONService(BaseExternalService):
|
||||
content_type="application/json"
|
||||
)
|
||||
|
||||
return str(json_file_record.path)
|
||||
# remove the temp directory
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
return json_file_record
|
||||
except Exception as e:
|
||||
logger.error(f"Error unzipping file: {e}")
|
||||
raise
|
||||
|
||||
def _stream_json_file(self, file_path: str) -> Generator[Dict[str, Any], None, None]:
|
||||
"""Stream a JSON file and yield items one at a time using a streaming parser"""
|
||||
logger.info(f"Starting to stream JSON file: {file_path}")
|
||||
try:
|
||||
with open(file_path, 'r') as f:
|
||||
# First, we need to find the start of the data section
|
||||
data_started = False
|
||||
current_key = None
|
||||
current_value = []
|
||||
brace_count = 0
|
||||
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
if not data_started:
|
||||
if '"data":' in line:
|
||||
data_started = True
|
||||
# Skip the opening brace of the data object
|
||||
line = line[line.find('"data":') + 7:].strip()
|
||||
if line.startswith('{'):
|
||||
line = line[1:].strip()
|
||||
else:
|
||||
# Yield meta data if found
|
||||
if '"meta":' in line:
|
||||
meta_start = line.find('"meta":') + 7
|
||||
meta_end = line.rfind('}')
|
||||
if meta_end > meta_start:
|
||||
meta_json = line[meta_start:meta_end + 1]
|
||||
try:
|
||||
meta_data = json.loads(meta_json)
|
||||
yield {"type": "meta", "data": meta_data}
|
||||
except json.JSONDecodeError as e:
|
||||
logger.warning(f"Failed to parse meta data: {e}")
|
||||
continue
|
||||
|
||||
# Process the data section
|
||||
if data_started:
|
||||
if not current_key:
|
||||
# Look for a new key
|
||||
if '"' in line:
|
||||
key_start = line.find('"') + 1
|
||||
key_end = line.find('"', key_start)
|
||||
if key_end > key_start:
|
||||
current_key = line[key_start:key_end]
|
||||
# Get the rest of the line after the key
|
||||
line = line[key_end + 1:].strip()
|
||||
if ':' in line:
|
||||
line = line[line.find(':') + 1:].strip()
|
||||
|
||||
if current_key:
|
||||
# Accumulate the value
|
||||
current_value.append(line)
|
||||
brace_count += line.count('{') - line.count('}')
|
||||
|
||||
if brace_count == 0 and line.endswith(','):
|
||||
# We have a complete value
|
||||
value_str = ''.join(current_value).rstrip(',')
|
||||
try:
|
||||
value = json.loads(value_str)
|
||||
yield {"type": "item", "data": {current_key: value}}
|
||||
except json.JSONDecodeError as e:
|
||||
logger.warning(f"Failed to parse value for key {current_key}: {e}")
|
||||
current_key = None
|
||||
current_value = []
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error streaming JSON file: {e}")
|
||||
raise
|
||||
|
||||
async def get_identifiers(self, db: Session) -> Generator[Dict[str, Any], None, None]:
|
||||
async def get_identifiers(self, db: Session, use_cache: bool = True) -> Dict[str, Any]:
|
||||
"""Download and get MTGJSON identifiers data"""
|
||||
# Check if we have a cached version
|
||||
cached_file = await self.file_service.get_file_by_filename(db, "AllIdentifiers.json")
|
||||
if cached_file:
|
||||
# Ensure the file exists at the path
|
||||
if os.path.exists(cached_file.path):
|
||||
return self._stream_json_file(cached_file.path)
|
||||
|
||||
if cached_file and os.path.exists(cached_file.path) and use_cache:
|
||||
with open(cached_file.path, 'r') as f:
|
||||
logger.debug(f"Loaded identifiers from cache: {cached_file.path}")
|
||||
return json.load(f)
|
||||
else:
|
||||
# Download and process the file
|
||||
file_record = await self._download_file(
|
||||
logger.debug(f"Downloading identifiers from MTGJSON")
|
||||
file_record = await self._download_and_unzip_file(
|
||||
db=db,
|
||||
url="https://mtgjson.com/api/v5/AllIdentifiers.json.zip",
|
||||
filename="AllIdentifiers.json.zip",
|
||||
subdir="identifiers"
|
||||
)
|
||||
|
||||
# Unzip and process the file
|
||||
json_path = await self._unzip_file(file_record, "identifiers", db)
|
||||
with open(file_record.path, 'r') as f:
|
||||
logger.debug(f"Loaded identifiers from MTGJSON: {file_record.path}")
|
||||
return json.load(f)
|
||||
|
||||
# Return a generator that streams the JSON file
|
||||
return self._stream_json_file(json_path)
|
||||
|
||||
async def get_skus(self, db: Session) -> Generator[Dict[str, Any], None, None]:
|
||||
async def get_skus(self, db: Session, use_cache: bool = True) -> Dict[str, Any]:
|
||||
"""Download and get MTGJSON SKUs data"""
|
||||
# Check if we have a cached version
|
||||
cached_file = await self.file_service.get_file_by_filename(db, "TcgplayerSkus.json")
|
||||
if cached_file:
|
||||
# Ensure the file exists at the path
|
||||
if os.path.exists(cached_file.path):
|
||||
return self._stream_json_file(cached_file.path)
|
||||
|
||||
if cached_file and os.path.exists(cached_file.path) and use_cache:
|
||||
with open(cached_file.path, 'r') as f:
|
||||
logger.debug(f"Loaded SKUs from cache: {cached_file.path}")
|
||||
return json.load(f)
|
||||
else:
|
||||
# Download and process the file
|
||||
file_record = await self._download_file(
|
||||
logger.debug(f"Downloading SKUs from MTGJSON")
|
||||
file_record = await self._download_and_unzip_file(
|
||||
db=db,
|
||||
url="https://mtgjson.com/api/v5/TcgplayerSkus.json.zip",
|
||||
filename="TcgplayerSkus.json.zip",
|
||||
subdir="skus"
|
||||
)
|
||||
|
||||
# Unzip and process the file
|
||||
json_path = await self._unzip_file(file_record, "skus", db)
|
||||
|
||||
# Return a generator that streams the JSON file
|
||||
return self._stream_json_file(json_path)
|
||||
with open(file_record.path, 'r') as f:
|
||||
logger.debug(f"Loaded SKUs from MTGJSON: {file_record.path}")
|
||||
return json.load(f)
|
||||
|
||||
async def clear_cache(self, db: Session) -> None:
|
||||
"""Clear all cached data"""
|
||||
|
@ -153,7 +153,8 @@ class FileService:
|
||||
|
||||
async def get_file_by_filename(self, db: Session, filename: str) -> Optional[FileInDB]:
|
||||
"""Get a file record from the database by filename"""
|
||||
file_record = db.query(File).filter(File.name == filename).first()
|
||||
# get most recent file by filename
|
||||
file_record = db.query(File).filter(File.name == filename).order_by(File.created_at.desc()).first()
|
||||
if file_record:
|
||||
return FileInDB.model_validate(file_record)
|
||||
return None
|
||||
|
15
app/services/manabox_service.py
Normal file
15
app/services/manabox_service.py
Normal file
@ -0,0 +1,15 @@
|
||||
from app.services.base_service import BaseService
|
||||
from sqlalchemy.orm import Session
|
||||
from app.schemas.file import FileInDB
|
||||
from typing import Dict, Any
|
||||
import csv
|
||||
|
||||
class ManaboxService(BaseService):
|
||||
def __init__(self):
|
||||
super().__init__(None)
|
||||
|
||||
async def process_manabox_csv(self, db: Session, csv_file: FileInDB) -> bool:
|
||||
|
||||
return True
|
||||
|
||||
# Name,Set code,Set name,Collector number,Foil,Rarity,Quantity,ManaBox ID,Scryfall ID,Purchase price,Misprint,Altered,Condition,Language,Purchase price currency
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": [{"productId": 38444, "lowPrice": 154.95, "midPrice": 223.55, "highPrice": 275.98, "marketPrice": 218.59, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 38445, "lowPrice": 349.49, "midPrice": 374.75, "highPrice": 400.0, "marketPrice": 385.0, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 38446, "lowPrice": 97.71, "midPrice": 120.99, "highPrice": 255.61, "marketPrice": 258.98, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 38447, "lowPrice": 80.0, "midPrice": 109.99, "highPrice": 214.45, "marketPrice": 99.92, "directLowPrice": 94.98, "subTypeName": "Foil"}, {"productId": 57653, "lowPrice": 71.99, "midPrice": 75.99, "highPrice": 100.0, "marketPrice": 69.44, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 67401, "lowPrice": 28.01, "midPrice": 78.72, "highPrice": 119.99, "marketPrice": 33.73, "directLowPrice": 114.99, "subTypeName": "Foil"}, {"productId": 71898, "lowPrice": 167.25, "midPrice": 183.34, "highPrice": 223.35, "marketPrice": 167.25, "directLowPrice": 168.28, "subTypeName": "Foil"}, {"productId": 78237, "lowPrice": 36.0, "midPrice": 89.24, "highPrice": 159.91, "marketPrice": 47.42, "directLowPrice": 59.99, "subTypeName": "Foil"}, {"productId": 95046, "lowPrice": 43.0, "midPrice": 62.92, "highPrice": 97.57, "marketPrice": 64.98, "directLowPrice": 44.0, "subTypeName": "Foil"}, {"productId": 110267, "lowPrice": 23.75, "midPrice": 31.21, "highPrice": 48.4, "marketPrice": 27.89, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 125324, "lowPrice": 18.0, "midPrice": 25.99, "highPrice": 53.45, "marketPrice": 25.86, "directLowPrice": 28.58, "subTypeName": "Foil"}, {"productId": 154792, "lowPrice": 16.73, "midPrice": 25.43, "highPrice": 49.0, "marketPrice": 17.47, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 181788, "lowPrice": 23.57, "midPrice": 27.83, "highPrice": 51.0, "marketPrice": 23.83, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 205180, "lowPrice": 16.99, "midPrice": 29.99, "highPrice": 70.2, "marketPrice": 18.3, "directLowPrice": 70.58, "subTypeName": "Foil"}, {"productId": 228752, "lowPrice": 24.99, "midPrice": 29.98, "highPrice": 224.99, "marketPrice": 29.43, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 257182, "lowPrice": 30.6, "midPrice": 75.0, "highPrice": 141.0, "marketPrice": 30.6, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 455848, "lowPrice": 15.0, "midPrice": 27.98, "highPrice": 134.0, "marketPrice": 20.73, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 527738, "lowPrice": 14.69, "midPrice": 19.31, "highPrice": 80.0, "marketPrice": 16.28, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 600517, "lowPrice": 47.97, "midPrice": 61.22, "highPrice": 75.0, "marketPrice": 61.22, "directLowPrice": null, "subTypeName": "Foil"}]}
|
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": [{"productId": 21705, "lowPrice": 0.18, "midPrice": 0.57, "highPrice": 29.99, "marketPrice": 0.56, "directLowPrice": 0.43, "subTypeName": "Foil"}, {"productId": 37765, "lowPrice": 0.1, "midPrice": 0.25, "highPrice": 1.6, "marketPrice": 0.14, "directLowPrice": 0.18, "subTypeName": "Normal"}, {"productId": 37767, "lowPrice": 0.18, "midPrice": 0.41, "highPrice": 4.99, "marketPrice": 0.25, "directLowPrice": 0.6, "subTypeName": "Normal"}, {"productId": 37772, "lowPrice": 0.14, "midPrice": 0.39, "highPrice": 4.99, "marketPrice": 0.15, "directLowPrice": 0.17, "subTypeName": "Normal"}, {"productId": 37773, "lowPrice": 0.05, "midPrice": 0.24, "highPrice": 3.99, "marketPrice": 0.12, "directLowPrice": 0.07, "subTypeName": "Normal"}, {"productId": 37778, "lowPrice": 0.09, "midPrice": 0.25, "highPrice": 3.13, "marketPrice": 0.22, "directLowPrice": 0.18, "subTypeName": "Normal"}, {"productId": 37780, "lowPrice": 0.04, "midPrice": 0.37, "highPrice": 4.99, "marketPrice": 0.13, "directLowPrice": 0.19, "subTypeName": "Normal"}, {"productId": 37784, "lowPrice": 0.15, "midPrice": 0.3, "highPrice": 4.99, "marketPrice": 0.22, "directLowPrice": 0.2, "subTypeName": "Normal"}, {"productId": 37785, "lowPrice": 0.15, "midPrice": 0.37, "highPrice": 3.99, "marketPrice": 0.19, "directLowPrice": 0.09, "subTypeName": "Normal"}, {"productId": 37788, "lowPrice": 0.14, "midPrice": 0.3, "highPrice": 3.0, "marketPrice": 0.31, "directLowPrice": 0.2, "subTypeName": "Normal"}, {"productId": 37789, "lowPrice": 0.15, "midPrice": 0.35, "highPrice": 4.99, "marketPrice": 0.31, "directLowPrice": 0.15, "subTypeName": "Normal"}, {"productId": 37790, "lowPrice": 0.14, "midPrice": 0.39, "highPrice": 3.99, "marketPrice": 0.22, "directLowPrice": 0.14, "subTypeName": "Normal"}, {"productId": 37793, "lowPrice": 0.05, "midPrice": 0.25, "highPrice": 3.99, "marketPrice": 0.08, "directLowPrice": 0.08, "subTypeName": "Normal"}, {"productId": 37799, "lowPrice": 0.1, "midPrice": 0.25, "highPrice": 3.0, "marketPrice": 0.2, "directLowPrice": 0.19, "subTypeName": "Normal"}, {"productId": 37802, "lowPrice": 0.1, "midPrice": 0.25, "highPrice": 5.0, "marketPrice": 0.17, "directLowPrice": 0.1, "subTypeName": "Normal"}, {"productId": 37809, "lowPrice": 0.1, "midPrice": 0.25, "highPrice": 1.67, "marketPrice": 0.19, "directLowPrice": 0.07, "subTypeName": "Normal"}, {"productId": 37810, "lowPrice": 0.09, "midPrice": 0.35, "highPrice": 5.25, "marketPrice": 0.28, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 37812, "lowPrice": 0.18, "midPrice": 0.51, "highPrice": 4.99, "marketPrice": 0.83, "directLowPrice": 0.18, "subTypeName": "Normal"}, {"productId": 37813, "lowPrice": 0.15, "midPrice": 0.25, "highPrice": 2.99, "marketPrice": 0.22, "directLowPrice": 0.14, "subTypeName": "Normal"}, {"productId": 37814, "lowPrice": 0.14, "midPrice": 0.28, "highPrice": 1.76, "marketPrice": 0.18, "directLowPrice": null, "subTypeName": "Normal"}]}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": [{"productId": 70757, "lowPrice": 0.8, "midPrice": 2.48, "highPrice": 54.0, "marketPrice": 2.61, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 70758, "lowPrice": 1.14, "midPrice": 1.74, "highPrice": 12.88, "marketPrice": 1.37, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 70759, "lowPrice": 0.75, "midPrice": 2.05, "highPrice": 8.99, "marketPrice": 2.51, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 70760, "lowPrice": 0.79, "midPrice": 1.61, "highPrice": 6.0, "marketPrice": 1.17, "directLowPrice": 1.6, "subTypeName": "Foil"}, {"productId": 70761, "lowPrice": 8.0, "midPrice": 11.12, "highPrice": 49.95, "marketPrice": 11.01, "directLowPrice": 11.96, "subTypeName": "Foil"}, {"productId": 70762, "lowPrice": 0.66, "midPrice": 1.34, "highPrice": 3.99, "marketPrice": 1.22, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 70763, "lowPrice": 4.1, "midPrice": 6.0, "highPrice": 19.99, "marketPrice": 5.09, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 70764, "lowPrice": 15.53, "midPrice": 19.96, "highPrice": 159.99, "marketPrice": 19.05, "directLowPrice": 21.69, "subTypeName": "Foil"}, {"productId": 70765, "lowPrice": 100.0, "midPrice": 119.99, "highPrice": 400.0, "marketPrice": 85.88, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 70782, "lowPrice": 7.26, "midPrice": 13.24, "highPrice": 20.57, "marketPrice": 13.16, "directLowPrice": 17.05, "subTypeName": "Foil"}, {"productId": 70783, "lowPrice": 4.0, "midPrice": 6.15, "highPrice": 11.84, "marketPrice": 5.69, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 70784, "lowPrice": 3.86, "midPrice": 5.41, "highPrice": 19.55, "marketPrice": 4.66, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 70785, "lowPrice": 1.25, "midPrice": 1.9, "highPrice": 7.4, "marketPrice": 1.6, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 70786, "lowPrice": 3.0, "midPrice": 4.4, "highPrice": 10.0, "marketPrice": 3.42, "directLowPrice": 4.39, "subTypeName": "Foil"}, {"productId": 70787, "lowPrice": 9.25, "midPrice": 11.47, "highPrice": 49.88, "marketPrice": 11.19, "directLowPrice": 19.37, "subTypeName": "Foil"}, {"productId": 70789, "lowPrice": 0.5, "midPrice": 1.04, "highPrice": 16.99, "marketPrice": 0.8, "directLowPrice": 1.07, "subTypeName": "Foil"}, {"productId": 70790, "lowPrice": 0.39, "midPrice": 0.99, "highPrice": 16.45, "marketPrice": 0.68, "directLowPrice": 0.6, "subTypeName": "Foil"}, {"productId": 70791, "lowPrice": 0.23, "midPrice": 0.59, "highPrice": 3.99, "marketPrice": 0.45, "directLowPrice": 0.49, "subTypeName": "Foil"}, {"productId": 70792, "lowPrice": 1.5, "midPrice": 2.49, "highPrice": 9.99, "marketPrice": 2.26, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 70793, "lowPrice": 49.0, "midPrice": 59.02, "highPrice": 200.0, "marketPrice": 59.02, "directLowPrice": 51.49, "subTypeName": "Foil"}, {"productId": 70794, "lowPrice": 1.8, "midPrice": 3.91, "highPrice": 88.0, "marketPrice": 3.69, "directLowPrice": 2.94, "subTypeName": "Foil"}]}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": [{"productId": 21603, "lowPrice": 11.0, "midPrice": 16.55, "highPrice": 97.99, "marketPrice": 17.1, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21604, "lowPrice": 4.95, "midPrice": 10.97, "highPrice": 14.97, "marketPrice": 6.99, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21605, "lowPrice": 10.0, "midPrice": 13.95, "highPrice": 79.45, "marketPrice": 14.97, "directLowPrice": 5.01, "subTypeName": "Normal"}, {"productId": 21606, "lowPrice": 18.95, "midPrice": 21.88, "highPrice": 86.37, "marketPrice": 17.0, "directLowPrice": 43.94, "subTypeName": "Normal"}, {"productId": 21607, "lowPrice": 0.38, "midPrice": 2.46, "highPrice": 5.7, "marketPrice": 1.5, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21608, "lowPrice": 1.55, "midPrice": 2.47, "highPrice": 4.95, "marketPrice": 2.0, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21609, "lowPrice": 98.95, "midPrice": 103.94, "highPrice": 108.93, "marketPrice": 57.85, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21610, "lowPrice": 4.73, "midPrice": 7.87, "highPrice": 11.0, "marketPrice": 7.61, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21611, "lowPrice": 9.0, "midPrice": 16.58, "highPrice": 22.17, "marketPrice": 14.16, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21612, "lowPrice": 5.99, "midPrice": 6.91, "highPrice": 15.74, "marketPrice": 6.29, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21613, "lowPrice": 9.55, "midPrice": 14.61, "highPrice": 18.95, "marketPrice": 13.98, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21614, "lowPrice": 1.7, "midPrice": 2.5, "highPrice": 4.95, "marketPrice": 1.4, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21615, "lowPrice": 3.86, "midPrice": 5.5, "highPrice": 8.0, "marketPrice": 6.07, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21616, "lowPrice": 8.84, "midPrice": 19.97, "highPrice": 24.95, "marketPrice": 8.5, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21617, "lowPrice": 6.92, "midPrice": 8.0, "highPrice": 13.99, "marketPrice": 7.23, "directLowPrice": 5.23, "subTypeName": "Normal"}, {"productId": 21618, "lowPrice": 25.0, "midPrice": 29.91, "highPrice": 50.0, "marketPrice": 27.0, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21619, "lowPrice": 8.0, "midPrice": 11.41, "highPrice": 18.61, "marketPrice": 9.89, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21620, "lowPrice": 15.0, "midPrice": 18.95, "highPrice": 20.59, "marketPrice": 8.76, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21621, "lowPrice": 18.5, "midPrice": 22.49, "highPrice": 49.95, "marketPrice": 25.0, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21622, "lowPrice": 7.99, "midPrice": 16.72, "highPrice": 19.95, "marketPrice": 11.91, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21623, "lowPrice": 12.0, "midPrice": 15.0, "highPrice": 16.99, "marketPrice": 15.95, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21624, "lowPrice": 0.59, "midPrice": 1.87, "highPrice": 9.95, "marketPrice": 2.5, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21625, "lowPrice": 49.95, "midPrice": 71.67, "highPrice": 99.95, "marketPrice": 66.45, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21626, "lowPrice": 3.99, "midPrice": 4.87, "highPrice": 8.12, "marketPrice": 5.5, "directLowPrice": 3.0, "subTypeName": "Normal"}, {"productId": 21627, "lowPrice": 6.77, "midPrice": 9.03, "highPrice": 24.99, "marketPrice": 5.16, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21628, "lowPrice": 1.1, "midPrice": 2.25, "highPrice": 4.23, "marketPrice": 1.5, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21629, "lowPrice": 5.0, "midPrice": 5.22, "highPrice": 13.97, "marketPrice": 5.0, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21630, "lowPrice": 16.8, "midPrice": 27.54, "highPrice": 45.0, "marketPrice": 15.95, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21631, "lowPrice": 114.95, "midPrice": 150.0, "highPrice": 154.97, "marketPrice": 42.5, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21632, "lowPrice": 16.99, "midPrice": 55.98, "highPrice": 150.0, "marketPrice": 14.79, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 21633, "lowPrice": 10.99, "midPrice": 13.84, "highPrice": 23.95, "marketPrice": 15.49, "directLowPrice": 19.88, "subTypeName": "Normal"}, {"productId": 21634, "lowPrice": 49.97, "midPrice": 74.36, "highPrice": 98.75, "marketPrice": 49.97, "directLowPrice": null, "subTypeName": "Normal"}]}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": [{"productId": 82198, "lowPrice": 79.26, "midPrice": 94.13, "highPrice": 249.99, "marketPrice": 89.08, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82732, "lowPrice": 0.74, "midPrice": 1.03, "highPrice": 3.01, "marketPrice": 0.98, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82733, "lowPrice": 13.4, "midPrice": 18.14, "highPrice": 38.5, "marketPrice": 14.09, "directLowPrice": 35.1, "subTypeName": "Normal"}, {"productId": 82734, "lowPrice": 0.99, "midPrice": 1.62, "highPrice": 9.9, "marketPrice": 1.36, "directLowPrice": 1.58, "subTypeName": "Normal"}, {"productId": 82735, "lowPrice": 0.46, "midPrice": 0.85, "highPrice": 4.91, "marketPrice": 0.69, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82736, "lowPrice": 0.54, "midPrice": 0.82, "highPrice": 3.88, "marketPrice": 0.83, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82737, "lowPrice": 0.99, "midPrice": 2.25, "highPrice": 19.99, "marketPrice": 2.15, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82738, "lowPrice": 0.15, "midPrice": 0.5, "highPrice": 2.0, "marketPrice": 0.39, "directLowPrice": 0.25, "subTypeName": "Normal"}, {"productId": 82739, "lowPrice": 1.5, "midPrice": 2.96, "highPrice": 8.87, "marketPrice": 2.32, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82740, "lowPrice": 0.15, "midPrice": 0.47, "highPrice": 2.99, "marketPrice": 0.34, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82741, "lowPrice": 0.45, "midPrice": 0.9, "highPrice": 8.53, "marketPrice": 0.56, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82742, "lowPrice": 0.25, "midPrice": 0.75, "highPrice": 27.99, "marketPrice": 0.5, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82743, "lowPrice": 0.09, "midPrice": 0.33, "highPrice": 1.99, "marketPrice": 0.21, "directLowPrice": 0.25, "subTypeName": "Normal"}, {"productId": 82744, "lowPrice": 0.18, "midPrice": 0.48, "highPrice": 1.83, "marketPrice": 0.45, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82745, "lowPrice": 0.77, "midPrice": 1.25, "highPrice": 18.99, "marketPrice": 0.95, "directLowPrice": 1.71, "subTypeName": "Normal"}, {"productId": 82746, "lowPrice": 0.03, "midPrice": 0.25, "highPrice": 1.5, "marketPrice": 0.11, "directLowPrice": 0.1, "subTypeName": "Normal"}, {"productId": 82747, "lowPrice": 0.2, "midPrice": 0.38, "highPrice": 1.99, "marketPrice": 0.26, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82748, "lowPrice": 0.22, "midPrice": 0.39, "highPrice": 1.52, "marketPrice": 0.29, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82749, "lowPrice": 20.14, "midPrice": 27.69, "highPrice": 79.99, "marketPrice": 22.14, "directLowPrice": 25.63, "subTypeName": "Normal"}, {"productId": 82750, "lowPrice": 0.06, "midPrice": 0.3, "highPrice": 2.99, "marketPrice": 0.07, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82751, "lowPrice": 4.97, "midPrice": 7.93, "highPrice": 17.38, "marketPrice": 7.63, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82752, "lowPrice": 0.12, "midPrice": 0.4, "highPrice": 2.99, "marketPrice": 0.16, "directLowPrice": 0.15, "subTypeName": "Normal"}, {"productId": 82753, "lowPrice": 2.09, "midPrice": 3.5, "highPrice": 11.99, "marketPrice": 2.76, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82754, "lowPrice": 0.05, "midPrice": 0.26, "highPrice": 1.5, "marketPrice": 0.17, "directLowPrice": 0.14, "subTypeName": "Normal"}, {"productId": 82755, "lowPrice": 0.25, "midPrice": 0.75, "highPrice": 3.59, "marketPrice": 0.58, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 82756, "lowPrice": 0.9, "midPrice": 1.75, "highPrice": 11.97, "marketPrice": 1.36, "directLowPrice": 1.5, "subTypeName": "Normal"}, {"productId": 82757, "lowPrice": 3.97, "midPrice": 6.25, "highPrice": 13.5, "marketPrice": 3.97, "directLowPrice": 7.99, "subTypeName": "Normal"}, {"productId": 83374, "lowPrice": 8.96, "midPrice": 13.5, "highPrice": 19.99, "marketPrice": 11.77, "directLowPrice": 19.97, "subTypeName": "Normal"}, {"productId": 83376, "lowPrice": 0.19, "midPrice": 0.5, "highPrice": 5.0, "marketPrice": 0.7, "directLowPrice": 0.49, "subTypeName": "Normal"}, {"productId": 83377, "lowPrice": 0.05, "midPrice": 0.25, "highPrice": 1.5, "marketPrice": 0.17, "directLowPrice": 0.5, "subTypeName": "Normal"}]}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": []}
|
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": [{"productId": 91636, "lowPrice": 29.85, "midPrice": 45.99, "highPrice": 495.95, "marketPrice": 30.89, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 91637, "lowPrice": 14.19, "midPrice": 14.94, "highPrice": 34.8, "marketPrice": 14.73, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 91638, "lowPrice": 3.29, "midPrice": 4.86, "highPrice": 16.78, "marketPrice": 4.65, "directLowPrice": 4.0, "subTypeName": "Foil"}, {"productId": 91639, "lowPrice": 3.67, "midPrice": 5.55, "highPrice": 15.99, "marketPrice": 5.57, "directLowPrice": 5.99, "subTypeName": "Foil"}, {"productId": 91640, "lowPrice": 2.92, "midPrice": 4.0, "highPrice": 19.99, "marketPrice": 3.4, "directLowPrice": 3.99, "subTypeName": "Foil"}, {"productId": 91641, "lowPrice": 2.04, "midPrice": 3.0, "highPrice": 9.99, "marketPrice": 2.47, "directLowPrice": 2.64, "subTypeName": "Foil"}, {"productId": 92296, "lowPrice": 0.4, "midPrice": 0.94, "highPrice": 4.78, "marketPrice": 0.53, "directLowPrice": 0.69, "subTypeName": "Foil"}, {"productId": 92297, "lowPrice": 0.82, "midPrice": 1.43, "highPrice": 29.98, "marketPrice": 1.19, "directLowPrice": 1.29, "subTypeName": "Foil"}, {"productId": 92298, "lowPrice": 1.63, "midPrice": 4.48, "highPrice": 15.0, "marketPrice": 5.31, "directLowPrice": 3.29, "subTypeName": "Foil"}, {"productId": 92299, "lowPrice": 0.63, "midPrice": 1.0, "highPrice": 3.99, "marketPrice": 0.83, "directLowPrice": 0.96, "subTypeName": "Foil"}, {"productId": 92300, "lowPrice": 0.72, "midPrice": 2.06, "highPrice": 19.99, "marketPrice": 2.5, "directLowPrice": 2.5, "subTypeName": "Foil"}, {"productId": 92301, "lowPrice": 0.96, "midPrice": 1.65, "highPrice": 19.99, "marketPrice": 1.16, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 92302, "lowPrice": 2.85, "midPrice": 4.29, "highPrice": 39.99, "marketPrice": 4.29, "directLowPrice": 3.99, "subTypeName": "Foil"}, {"productId": 92303, "lowPrice": 2.49, "midPrice": 3.61, "highPrice": 16.99, "marketPrice": 2.86, "directLowPrice": 3.08, "subTypeName": "Foil"}, {"productId": 92304, "lowPrice": 0.25, "midPrice": 0.93, "highPrice": 19.99, "marketPrice": 0.74, "directLowPrice": 1.53, "subTypeName": "Foil"}, {"productId": 92305, "lowPrice": 0.38, "midPrice": 0.81, "highPrice": 6.85, "marketPrice": 0.63, "directLowPrice": null, "subTypeName": "Foil"}]}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": [{"productId": 95578, "lowPrice": 40.0, "midPrice": 48.63, "highPrice": 150.0, "marketPrice": 40.66, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95579, "lowPrice": 23.58, "midPrice": 31.72, "highPrice": 55.21, "marketPrice": 31.84, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95580, "lowPrice": 0.69, "midPrice": 1.38, "highPrice": 6.0, "marketPrice": 1.06, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95581, "lowPrice": 1.0, "midPrice": 2.79, "highPrice": 6.95, "marketPrice": 1.91, "directLowPrice": 2.35, "subTypeName": "Normal"}, {"productId": 95582, "lowPrice": 7.59, "midPrice": 12.19, "highPrice": 24.66, "marketPrice": 10.49, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95583, "lowPrice": 0.25, "midPrice": 1.16, "highPrice": 4.0, "marketPrice": 0.84, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95584, "lowPrice": 0.45, "midPrice": 1.5, "highPrice": 6.31, "marketPrice": 0.8, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95585, "lowPrice": 0.8, "midPrice": 1.55, "highPrice": 4.79, "marketPrice": 0.85, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95586, "lowPrice": 0.1, "midPrice": 0.44, "highPrice": 1.5, "marketPrice": 0.23, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95587, "lowPrice": 0.15, "midPrice": 0.5, "highPrice": 1.5, "marketPrice": 0.49, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95588, "lowPrice": 0.25, "midPrice": 0.54, "highPrice": 2.43, "marketPrice": 0.3, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95589, "lowPrice": 0.25, "midPrice": 0.75, "highPrice": 4.25, "marketPrice": 0.82, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95590, "lowPrice": 0.1, "midPrice": 0.37, "highPrice": 11.5, "marketPrice": 0.25, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95591, "lowPrice": 0.18, "midPrice": 0.39, "highPrice": 2.0, "marketPrice": 0.19, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95592, "lowPrice": 0.14, "midPrice": 0.49, "highPrice": 1.77, "marketPrice": 0.22, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95593, "lowPrice": 0.15, "midPrice": 0.4, "highPrice": 7.0, "marketPrice": 0.23, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95594, "lowPrice": 0.07, "midPrice": 0.39, "highPrice": 3.0, "marketPrice": 0.22, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95595, "lowPrice": 0.2, "midPrice": 0.48, "highPrice": 2.0, "marketPrice": 0.22, "directLowPrice": 0.25, "subTypeName": "Normal"}, {"productId": 95596, "lowPrice": 1.18, "midPrice": 2.62, "highPrice": 10.49, "marketPrice": 2.36, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95597, "lowPrice": 1.93, "midPrice": 2.96, "highPrice": 6.0, "marketPrice": 2.96, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95598, "lowPrice": 0.19, "midPrice": 0.44, "highPrice": 2.91, "marketPrice": 0.21, "directLowPrice": 0.42, "subTypeName": "Normal"}, {"productId": 95599, "lowPrice": 0.15, "midPrice": 0.5, "highPrice": 2.0, "marketPrice": 0.23, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95600, "lowPrice": 0.24, "midPrice": 0.89, "highPrice": 3.0, "marketPrice": 0.65, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95601, "lowPrice": 0.14, "midPrice": 0.5, "highPrice": 2.91, "marketPrice": 0.2, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 95602, "lowPrice": 0.14, "midPrice": 0.5, "highPrice": 2.5, "marketPrice": 0.21, "directLowPrice": 0.35, "subTypeName": "Normal"}, {"productId": 95603, "lowPrice": 0.15, "midPrice": 0.49, "highPrice": 3.0, "marketPrice": 0.43, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 99943, "lowPrice": 14.32, "midPrice": 20.0, "highPrice": 39.99, "marketPrice": 13.81, "directLowPrice": null, "subTypeName": "Normal"}]}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": [{"productId": 96436, "lowPrice": 0.41, "midPrice": 0.93, "highPrice": 20.0, "marketPrice": 0.84, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 96437, "lowPrice": 0.39, "midPrice": 0.62, "highPrice": 5.0, "marketPrice": 0.57, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 96438, "lowPrice": 0.1, "midPrice": 0.33, "highPrice": 3.0, "marketPrice": 0.34, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 96439, "lowPrice": 0.05, "midPrice": 0.26, "highPrice": 5.0, "marketPrice": 0.26, "directLowPrice": null, "subTypeName": "Normal"}]}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": [{"productId": 100611, "lowPrice": 4.33, "midPrice": 6.37, "highPrice": 123.0, "marketPrice": 4.76, "directLowPrice": 6.4, "subTypeName": "Foil"}, {"productId": 100612, "lowPrice": 3.0, "midPrice": 4.17, "highPrice": 15.99, "marketPrice": 3.88, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 100667, "lowPrice": 119.99, "midPrice": 142.49, "highPrice": 999.95, "marketPrice": 124.0, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 101468, "lowPrice": 35.0, "midPrice": 41.65, "highPrice": 75.68, "marketPrice": 43.6, "directLowPrice": 37.15, "subTypeName": "Foil"}, {"productId": 101469, "lowPrice": 5.0, "midPrice": 7.25, "highPrice": 19.99, "marketPrice": 7.0, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 102777, "lowPrice": 0.51, "midPrice": 1.73, "highPrice": 20.03, "marketPrice": 1.7, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 102778, "lowPrice": 7.51, "midPrice": 10.11, "highPrice": 22.72, "marketPrice": 9.96, "directLowPrice": 14.28, "subTypeName": "Foil"}, {"productId": 102779, "lowPrice": 2.54, "midPrice": 3.43, "highPrice": 8.25, "marketPrice": 2.94, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 102780, "lowPrice": 1.99, "midPrice": 3.42, "highPrice": 14.99, "marketPrice": 3.28, "directLowPrice": 2.0, "subTypeName": "Foil"}, {"productId": 102781, "lowPrice": 1.03, "midPrice": 2.0, "highPrice": 8.0, "marketPrice": 1.75, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 102782, "lowPrice": 0.7, "midPrice": 1.07, "highPrice": 3.41, "marketPrice": 0.99, "directLowPrice": 1.02, "subTypeName": "Foil"}, {"productId": 102783, "lowPrice": 0.26, "midPrice": 0.99, "highPrice": 5.0, "marketPrice": 0.82, "directLowPrice": null, "subTypeName": "Foil"}, {"productId": 102784, "lowPrice": 0.21, "midPrice": 0.82, "highPrice": 2.59, "marketPrice": 0.66, "directLowPrice": 0.44, "subTypeName": "Foil"}, {"productId": 102785, "lowPrice": 6.02, "midPrice": 7.52, "highPrice": 19.0, "marketPrice": 7.17, "directLowPrice": 9.99, "subTypeName": "Foil"}, {"productId": 102786, "lowPrice": 0.74, "midPrice": 2.74, "highPrice": 49.99, "marketPrice": 2.61, "directLowPrice": 2.48, "subTypeName": "Foil"}, {"productId": 102787, "lowPrice": 0.98, "midPrice": 2.49, "highPrice": 12.01, "marketPrice": 2.58, "directLowPrice": null, "subTypeName": "Foil"}]}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": []}
|
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": []}
|
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": []}
|
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": []}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
||||
{"success": true, "errors": [], "results": [{"productId": 116780, "lowPrice": 0.25, "midPrice": 0.5, "highPrice": 6.99, "marketPrice": 0.29, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 116781, "lowPrice": 0.01, "midPrice": 0.19, "highPrice": 1.32, "marketPrice": 0.07, "directLowPrice": 0.03, "subTypeName": "Normal"}, {"productId": 116782, "lowPrice": 0.01, "midPrice": 0.15, "highPrice": 5.0, "marketPrice": 0.02, "directLowPrice": 0.02, "subTypeName": "Normal"}, {"productId": 116783, "lowPrice": 0.01, "midPrice": 0.2, "highPrice": 16.0, "marketPrice": 0.04, "directLowPrice": 0.14, "subTypeName": "Normal"}, {"productId": 116784, "lowPrice": 0.01, "midPrice": 0.19, "highPrice": 1.32, "marketPrice": 0.04, "directLowPrice": 0.1, "subTypeName": "Normal"}, {"productId": 116785, "lowPrice": 0.01, "midPrice": 0.2, "highPrice": 1.32, "marketPrice": 0.08, "directLowPrice": 0.1, "subTypeName": "Normal"}, {"productId": 116786, "lowPrice": 0.01, "midPrice": 0.2, "highPrice": 1.32, "marketPrice": 0.04, "directLowPrice": 0.25, "subTypeName": "Normal"}, {"productId": 116787, "lowPrice": 0.01, "midPrice": 0.18, "highPrice": 5.0, "marketPrice": 0.13, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 116788, "lowPrice": 0.04, "midPrice": 0.25, "highPrice": 4.99, "marketPrice": 0.13, "directLowPrice": 0.13, "subTypeName": "Normal"}, {"productId": 116789, "lowPrice": 0.01, "midPrice": 0.15, "highPrice": 2.0, "marketPrice": 0.03, "directLowPrice": 0.16, "subTypeName": "Normal"}, {"productId": 116790, "lowPrice": 0.01, "midPrice": 0.2, "highPrice": 1.35, "marketPrice": 0.1, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 116791, "lowPrice": 0.03, "midPrice": 0.2, "highPrice": 1.53, "marketPrice": 0.12, "directLowPrice": 0.1, "subTypeName": "Normal"}, {"productId": 116792, "lowPrice": 0.02, "midPrice": 0.25, "highPrice": 5.06, "marketPrice": 0.12, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 116793, "lowPrice": 0.98, "midPrice": 1.2, "highPrice": 4.99, "marketPrice": 1.03, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 116794, "lowPrice": 0.01, "midPrice": 0.25, "highPrice": 4.99, "marketPrice": 0.16, "directLowPrice": null, "subTypeName": "Normal"}, {"productId": 116795, "lowPrice": 0.01, "midPrice": 0.15, "highPrice": 5.0, "marketPrice": 0.02, "directLowPrice": 0.06, "subTypeName": "Normal"}]}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user