123
This commit is contained in:
@@ -1,15 +1,41 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
import queries.general
|
||||
from database import Marketplace
|
||||
from updaters.stocks_updater import StockUpdate
|
||||
from marketplaces import MarketplaceApiFactory
|
||||
from marketplaces.base import BaseMarketplaceApi
|
||||
from queries.general import StockData
|
||||
from schemas.general import StockUpdate
|
||||
|
||||
|
||||
class BaseMarketplaceUpdater(ABC):
|
||||
@abstractmethod
|
||||
def __init__(self, marketplace: Marketplace):
|
||||
pass
|
||||
marketplace: Marketplace
|
||||
marketplace_api: BaseMarketplaceApi
|
||||
session: AsyncSession
|
||||
|
||||
def __init__(self, marketplace: Marketplace, session: AsyncSession):
|
||||
self.marketplace = marketplace
|
||||
self.session = session
|
||||
self.marketplace_api = MarketplaceApiFactory.get_marketplace_api(marketplace)
|
||||
|
||||
@abstractmethod
|
||||
async def update(self, updates: List[StockUpdate]):
|
||||
def get_update_for_marketplace(self,
|
||||
stock_data: StockData) -> dict:
|
||||
pass
|
||||
|
||||
async def update(self, updates: List[StockUpdate]):
|
||||
product_ids = list(set([update.product_id for update in updates]))
|
||||
stock_data_list = await queries.general.get_stocks_data(
|
||||
session=self.session,
|
||||
marketplace=self.marketplace,
|
||||
product_ids=product_ids
|
||||
)
|
||||
return
|
||||
marketplace_updates = []
|
||||
for stock_data in stock_data_list:
|
||||
marketplace_update = self.get_update_for_marketplace(stock_data)
|
||||
marketplace_updates.append(marketplace_update)
|
||||
await self.marketplace_api.update_stocks(marketplace_updates)
|
||||
|
||||
18
updaters/factory.py
Normal file
18
updaters/factory.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from typing import Union
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from database import Marketplace
|
||||
from database.sipro.enums.general import BaseMarketplace
|
||||
from updaters.ozon_updater import OzonUpdater
|
||||
from updaters.wildberries_updater import WildberriesUpdater
|
||||
|
||||
|
||||
class UpdaterFactory:
|
||||
@staticmethod
|
||||
def get_updater(session: AsyncSession, marketplace: Marketplace) -> Union[OzonUpdater, WildberriesUpdater]:
|
||||
match marketplace.base_marketplace:
|
||||
case BaseMarketplace.WILDBERRIES:
|
||||
return WildberriesUpdater(marketplace, session)
|
||||
case BaseMarketplace.OZON:
|
||||
return OzonUpdater(marketplace, session)
|
||||
@@ -1,14 +1,11 @@
|
||||
from typing import List
|
||||
|
||||
from database import Marketplace
|
||||
from marketplaces import MarketplaceFactory, OzonMarketplace
|
||||
from queries.general import StockData
|
||||
from updaters.base import BaseMarketplaceUpdater
|
||||
from updaters.stocks_updater import StockUpdate
|
||||
|
||||
|
||||
class OzonUpdater(BaseMarketplaceUpdater):
|
||||
def __init__(self, marketplace: Marketplace):
|
||||
self.ozon_marketplace: OzonMarketplace = MarketplaceFactory.get_marketplace(marketplace)
|
||||
|
||||
async def update(self, updates: List[StockUpdate]):
|
||||
pass
|
||||
def get_update_for_marketplace(self, data: StockData) -> dict:
|
||||
return {
|
||||
'offer_id': str(data['article']),
|
||||
'stock': 0, # $data['full_stock'],
|
||||
'warehouse_id': self.marketplace.warehouse_id
|
||||
}
|
||||
|
||||
@@ -1,53 +1,47 @@
|
||||
import asyncio
|
||||
from collections import defaultdict
|
||||
from dataclasses import dataclass
|
||||
from enum import unique, IntEnum
|
||||
from typing import List, Union
|
||||
from typing import List
|
||||
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.dialects.postgresql import insert
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
import database
|
||||
from database import Marketplace, MarketplaceProduct, DailyStock
|
||||
|
||||
|
||||
@unique
|
||||
class StockUpdateType(IntEnum):
|
||||
SALE = 0
|
||||
SUPPLIER_UPDATE = 1
|
||||
WAREHOUSE_UPDATE = 2
|
||||
|
||||
@dataclass
|
||||
class StockUpdate:
|
||||
product_id: int
|
||||
type: StockUpdateType
|
||||
quantity: int
|
||||
from database import Marketplace, MarketplaceProduct, Warehouse, Company
|
||||
from schemas.general import StockUpdate
|
||||
from updaters.factory import UpdaterFactory
|
||||
|
||||
|
||||
class StocksUpdater:
|
||||
def __init__(self, session: AsyncSession):
|
||||
self.session = session
|
||||
|
||||
async def get_marketplace(self, marketplace_id: int):
|
||||
marketplace = await self.session.get(Marketplace, marketplace_id, options=[
|
||||
joinedload(Marketplace.warehouses).joinedload(Warehouse.suppliers),
|
||||
joinedload(Marketplace.warehouses).joinedload(Warehouse.company_warehouses),
|
||||
joinedload(Marketplace.company).joinedload(Company.warehouse)
|
||||
])
|
||||
return marketplace
|
||||
|
||||
async def update_marketplace(self, marketplace_id: int, updates: List[StockUpdate]):
|
||||
pass
|
||||
marketplace = await self.get_marketplace(marketplace_id)
|
||||
updater = UpdaterFactory.get_updater(self.session, marketplace)
|
||||
if not updater:
|
||||
return
|
||||
await updater.update(updates)
|
||||
|
||||
async def update(self, updates: list[StockUpdate]):
|
||||
updates_dict = defaultdict(list)
|
||||
stock_update_values = []
|
||||
for update in updates:
|
||||
# Working with sold today
|
||||
if update.type == StockUpdateType.SALE:
|
||||
stock_update_values.append({
|
||||
'product_id': update.product_id,
|
||||
'sold_today': update.quantity
|
||||
})
|
||||
# Working with marketplaces
|
||||
stmt = (
|
||||
select(
|
||||
MarketplaceProduct.marketplace_id.distinct()
|
||||
)
|
||||
.where(
|
||||
MarketplaceProduct.product_id == update.product_id
|
||||
MarketplaceProduct.product_id == update.product_id,
|
||||
MarketplaceProduct.marketplace_id.in_([9, 41])
|
||||
)
|
||||
)
|
||||
stmt_result = await self.session.execute(stmt)
|
||||
@@ -57,27 +51,9 @@ class StocksUpdater:
|
||||
for marketplace_id in marketplace_ids:
|
||||
updates_dict[marketplace_id].append(update)
|
||||
updates_list = list(updates_dict.items())
|
||||
updates_list = sorted(updates_list, key=lambda x: x[1])
|
||||
|
||||
# Updating DailyStock-s
|
||||
insert_stmt = (
|
||||
insert(
|
||||
DailyStock
|
||||
)
|
||||
.values(
|
||||
stock_update_values
|
||||
)
|
||||
)
|
||||
insert_stmt = (
|
||||
insert_stmt.on_conflict_do_update(
|
||||
index_elements=['product_id'],
|
||||
set_={
|
||||
'sold_today': DailyStock.sold_today + insert_stmt.excluded.sold_today
|
||||
}
|
||||
)
|
||||
)
|
||||
await self.session.execute(insert_stmt)
|
||||
await self.session.commit()
|
||||
updates_list = sorted(updates_list, key=lambda x: len(x[1]))
|
||||
|
||||
tasks = []
|
||||
for marketplace_id, marketplace_updates in updates_list:
|
||||
await self.update_marketplace(marketplace_id, marketplace_updates)
|
||||
tasks.append(self.update_marketplace(marketplace_id, marketplace_updates))
|
||||
await asyncio.gather(*tasks)
|
||||
|
||||
@@ -1 +1,11 @@
|
||||
from queries.general import StockData
|
||||
from updaters.base import BaseMarketplaceUpdater
|
||||
|
||||
|
||||
class WildberriesUpdater(BaseMarketplaceUpdater):
|
||||
|
||||
def get_update_for_marketplace(self, stock_data: StockData) -> dict:
|
||||
return {
|
||||
'sku': stock_data['marketplace_product'].third_additional_article,
|
||||
'amount': 0 # stock_data['full_stock']
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user