Fix fulfillment consumables pricing architecture

- Add pricePerUnit field to Supply model for seller pricing
- Fix updateSupplyPrice mutation to update pricePerUnit only
- Separate purchase price (price) from selling price (pricePerUnit)
- Fix GraphQL mutations to include organization field (CREATE/UPDATE_LOGISTICS)
- Update GraphQL types to make Supply.price required again
- Add comprehensive pricing rules to rules-complete.md sections 11.7.5 and 18.8
- Fix supplies-tab.tsx to show debug info and handle user loading

Architecture changes:
• Supply.price = purchase price from supplier (immutable)
• Supply.pricePerUnit = selling price to sellers (mutable by fulfillment)
• Warehouse shows purchase price only (readonly)
• Services shows/edits selling price only

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Veronika Smirnova
2025-08-07 14:33:40 +03:00
parent cd7dcd9333
commit 0304f69410
6 changed files with 371 additions and 54 deletions

View File

@ -718,7 +718,7 @@ export const resolvers = {
console.warn('🔥 SUPPLIES RESOLVER - NEW FORMAT:', {
organizationId: currentUser.organization.id,
suppliesCount: transformedSupplies.length,
supplies: transformedSupplies.map(s => ({
supplies: transformedSupplies.map((s) => ({
id: s.id,
name: s.name,
pricePerUnit: s.pricePerUnit,
@ -765,7 +765,7 @@ export const resolvers = {
// Расходники фулфилмента из склада (новая архитектура - синхронизация со склада)
myFulfillmentSupplies: async (_: unknown, __: unknown, context: Context) => {
console.warn('🔥🔥🔥 FULFILLMENT SUPPLIES RESOLVER CALLED (NEW ARCHITECTURE) 🔥🔥🔥')
if (!context.user) {
console.warn('❌ No user in context')
throw new GraphQLError('Требуется авторизация', {
@ -826,7 +826,7 @@ export const resolvers = {
})
// Преобразуем в формат для фронтенда
return supplies.map(supply => ({
return supplies.map((supply) => ({
...supply,
price: supply.price ? parseFloat(supply.price.toString()) : 0,
shippedQuantity: 0, // Добавляем для совместимости
@ -1387,7 +1387,6 @@ export const resolvers = {
// Мои товары и расходники (для поставщиков)
myProducts: async (_: unknown, __: unknown, context: Context) => {
if (!context.user) {
throw new GraphQLError('Требуется авторизация', {
extensions: { code: 'UNAUTHENTICATED' },
@ -1399,7 +1398,6 @@ export const resolvers = {
include: { organization: true },
})
if (!currentUser?.organization) {
throw new GraphQLError('У пользователя нет организации')
}
@ -3607,7 +3605,6 @@ export const resolvers = {
}
},
// Обновить цену расходника (новая архитектура - только цену можно редактировать)
updateSupplyPrice: async (
_: unknown,
@ -3655,7 +3652,7 @@ export const resolvers = {
const updatedSupply = await prisma.supply.update({
where: { id: args.id },
data: {
price: args.input.pricePerUnit, // Обновляем только цену
pricePerUnit: args.input.pricePerUnit, // Обновляем цену продажи, НЕ цену закупки
updatedAt: new Date(),
},
include: { organization: true },
@ -4050,7 +4047,7 @@ export const resolvers = {
return {
name: product.name,
description: product.description || `Заказано у ${partner.name}`,
price: product.price,
price: product.price, // Цена закупки у поставщика
quantity: item.quantity,
unit: 'шт',
category: productWithCategory?.category?.name || 'Расходники',
@ -5830,7 +5827,7 @@ export const resolvers = {
data: {
name: item.product.name,
description: item.product.description || `Поставка от ${existingOrder.partner.name}`,
price: item.price,
price: item.price, // Цена закупки у поставщика
quantity: item.quantity,
unit: 'шт',
category: item.product.category?.name || 'Расходники',
@ -6590,7 +6587,7 @@ export const resolvers = {
description: isSellerSupply
? `Расходники селлера ${updatedOrder.organization?.name || updatedOrder.organization?.fullName}`
: item.product.description || `Расходники от ${updatedOrder.partner.name}`,
price: item.price,
price: item.price, // Цена закупки у поставщика
quantity: item.quantity,
currentStock: item.quantity,
usedStock: 0,