krona-front/dist/assets/InventoryModule-VpTxuRuh.js

1 line
No EOL
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import{f as e,h as t,i as n,r,s as i,t as a}from"./useToast-CS8pZhce.js";import{T as o,b as s,lt as c,r as l,t as u}from"./index-CrJKtV0u.js";import{t as d}from"./useOrders-TRZWcao8.js";import{t as f}from"./currency-DdDs82F5.js";import{t as p}from"./useInventory-C7Fo8GE1.js";var m=t(e(),1),h=i(),g=()=>{let{showToast:e}=a(),{warehouses:t,stockItems:i,movements:g,receipts:_,adjustStock:v,createAndReceiveGoods:y}=p(),{products:b}=d(),[x,S]=(0,m.useState)(`balances`),[C,w]=(0,m.useState)(``),[T,E]=(0,m.useState)(`all`),[D,O]=(0,m.useState)(!1),[k,A]=(0,m.useState)(!1),[j,M]=(0,m.useState)(``),[N,P]=(0,m.useState)(`wh_main`),[F,I]=(0,m.useState)(``),[L,R]=(0,m.useState)(50),[z,B]=(0,m.useState)(12e4),[V,H]=(0,m.useState)(null),[U,W]=(0,m.useState)(`-1`),[G,K]=(0,m.useState)(`Порча / Срок годности`),q=(0,m.useMemo)(()=>i.filter(e=>{let t=T===`all`||e.warehouseId===T,n=!C||e.productName.toLowerCase().includes(C.toLowerCase())||e.sku.toLowerCase().includes(C.toLowerCase());return t&&n}),[i,T,C]),J=(0,m.useMemo)(()=>[...g].sort((e,t)=>t.timestamp>e.timestamp?1:-1),[g]),Y=async t=>{t.preventDefault();let n=b.find(e=>e.id===F)||b[0];if(!n){e(`Выберите товар`,`error`);return}try{let t=`REC-${Date.now().toString().slice(-6)}`,r=[{productId:n.id,sku:n.sku,name:n.name,quantity:L,costPrice:{minor:z,currency:`RUB`}}];await y(N,t,j||`ООО «Поставщик Продукт»`,r),e(`Поступление по накладной №${t} проведено! Остатки увеличены.`,`success`),O(!1),M(``)}catch(t){e(`Ошибка: ${t instanceof Error?t.message:String(t)}`,`error`)}},X=async t=>{if(t.preventDefault(),V)try{let t=Number(U);await v(V.warehouseId,V.productId,t,G),e(t<0?`Списание со склада проведено.`:`Корректировка остатка проведена.`,`success`),A(!1),H(null)}catch(t){e(`Ошибка: ${t instanceof Error?t.message:String(t)}`,`error`)}},Z=e=>{switch(e){case`receipt`:return(0,h.jsx)(r,{variant:`green`,size:`sm`,children:`Поступление (+)`});case`shipment`:return(0,h.jsx)(r,{variant:`blue`,size:`sm`,children:`Отгрузка (-)`});case`transfer`:return(0,h.jsx)(r,{variant:`gold`,size:`sm`,children:`Резерв / Трансфер`});case`loss`:return(0,h.jsx)(r,{variant:`danger`,size:`sm`,children:`Списание (-)`});default:return(0,h.jsx)(r,{variant:`gray`,size:`sm`,children:`Коррекция`})}};return(0,h.jsxs)(`div`,{className:`space-y-4 animate-fade-in`,children:[(0,h.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-3 bg-krona-surface p-3.5 rounded-xl border border-krona-border shadow-krona-soft`,children:[(0,h.jsxs)(`div`,{children:[(0,h.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,h.jsx)(`h1`,{className:`text-sm font-bold text-krona-primary`,children:`Складской учет, остатки и движение партий`}),(0,h.jsx)(u,{level:`pilot1`,size:`sm`})]}),(0,h.jsx)(`p`,{className:`text-xs text-krona-secondary mt-0.5`,children:`Точный баланс: Физический остаток, Резервы заказов, Доступное количество и Складской журнал`})]}),(0,h.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,h.jsxs)(n,{variant:`primary`,size:`sm`,onClick:()=>O(!0),children:[(0,h.jsx)(o,{className:`w-3.5 h-3.5 mr-1`}),` Приходная накладная`]})})]}),(0,h.jsxs)(`div`,{className:`flex flex-col sm:flex-row sm:items-center justify-between gap-3`,children:[(0,h.jsxs)(`div`,{className:`flex items-center gap-1.5 overflow-x-auto text-xs`,children:[(0,h.jsxs)(`button`,{onClick:()=>S(`balances`),className:`px-3 py-1.5 rounded-lg font-medium transition-colors ${x===`balances`?`bg-krona-green text-white shadow-sm`:`bg-krona-surface text-krona-secondary hover:text-krona-primary border border-krona-border`}`,children:[`Остатки на складах (`,i.length,`)`]}),(0,h.jsxs)(`button`,{onClick:()=>S(`movements`),className:`px-3 py-1.5 rounded-lg font-medium transition-colors ${x===`movements`?`bg-krona-green text-white shadow-sm`:`bg-krona-surface text-krona-secondary hover:text-krona-primary border border-krona-border`}`,children:[`Журнал движений (`,g.length,`)`]}),(0,h.jsxs)(`button`,{onClick:()=>S(`receipts`),className:`px-3 py-1.5 rounded-lg font-medium transition-colors ${x===`receipts`?`bg-krona-green text-white shadow-sm`:`bg-krona-surface text-krona-secondary hover:text-krona-primary border border-krona-border`}`,children:[`Поступления (`,_.length,`)`]})]}),(0,h.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,h.jsxs)(`select`,{value:T,onChange:e=>E(e.target.value),className:`px-2.5 py-1.5 text-xs bg-krona-surface border border-krona-border rounded-lg text-krona-primary focus:outline-none focus:border-krona-green`,children:[(0,h.jsx)(`option`,{value:`all`,children:`Все склады`}),t.map(e=>(0,h.jsx)(`option`,{value:e.id,children:e.name},e.id))]}),(0,h.jsxs)(`div`,{className:`relative w-60`,children:[(0,h.jsx)(s,{className:`w-3.5 h-3.5 absolute left-2.5 top-2.5 text-krona-secondary`}),(0,h.jsx)(`input`,{type:`text`,value:C,onChange:e=>w(e.target.value),placeholder:`Поиск по артикулу или товару...`,className:`w-full pl-8 pr-3 py-1.5 text-xs bg-krona-surface border border-krona-border rounded-lg text-krona-primary focus:outline-none focus:border-krona-green`})]})]})]}),x===`balances`&&(0,h.jsx)(`div`,{className:`bg-krona-surface border border-krona-border rounded-xl shadow-krona-soft overflow-hidden`,children:(0,h.jsxs)(`table`,{className:`w-full text-xs text-left`,children:[(0,h.jsx)(`thead`,{className:`bg-krona-workspace text-krona-secondary border-b border-krona-border`,children:(0,h.jsxs)(`tr`,{children:[(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Артикул (SKU)`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Наименование товара`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Склад`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold text-center`,children:`Физический остаток (On Hand)`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold text-center`,children:`В резерве (Reserved)`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold text-center`,children:`Доступно к заказу (Available)`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Мин. порог`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold text-right`,children:`Действие`})]})}),(0,h.jsxs)(`tbody`,{className:`divide-y divide-krona-border`,children:[q.map(e=>{let t=e.minThreshold!==void 0&&e.available<=e.minThreshold;return(0,h.jsxs)(`tr`,{className:`hover:bg-krona-workspace/50 transition-colors`,children:[(0,h.jsx)(`td`,{className:`p-3 font-mono font-semibold text-krona-secondary`,children:e.sku}),(0,h.jsx)(`td`,{className:`p-3 font-medium text-krona-primary`,children:e.productName}),(0,h.jsx)(`td`,{className:`p-3 text-krona-secondary`,children:e.warehouseName}),(0,h.jsxs)(`td`,{className:`p-3 font-bold text-krona-primary text-center`,children:[e.onHand,` `,e.unit]}),(0,h.jsx)(`td`,{className:`p-3 font-semibold text-amber-600 dark:text-amber-400 text-center`,children:e.reserved>0?`${e.reserved} ${e.unit}`:`0`}),(0,h.jsx)(`td`,{className:`p-3 text-center`,children:(0,h.jsxs)(`span`,{className:`font-bold px-2 py-0.5 rounded ${e.available>0?`bg-emerald-500/10 text-emerald-600 dark:text-emerald-400`:`bg-rose-500/10 text-rose-600 dark:text-rose-400`}`,children:[e.available,` `,e.unit]})}),(0,h.jsx)(`td`,{className:`p-3`,children:e.minThreshold===void 0?`—`:(0,h.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,h.jsxs)(`span`,{children:[e.minThreshold,` `,e.unit]}),t&&(0,h.jsx)(r,{variant:`warning`,size:`sm`,children:`Мало`})]})}),(0,h.jsx)(`td`,{className:`p-3 text-right`,children:(0,h.jsx)(n,{variant:`secondary`,size:`sm`,onClick:()=>{H(e),W(`-1`),A(!0)},children:`Коррекция / Списание`})})]},e.id)}),q.length===0&&(0,h.jsx)(`tr`,{children:(0,h.jsx)(`td`,{colSpan:8,className:`p-8 text-center text-krona-secondary text-xs italic`,children:`Остатки не найдены`})})]})]})}),x===`movements`&&(0,h.jsx)(`div`,{className:`bg-krona-surface border border-krona-border rounded-xl shadow-krona-soft overflow-hidden`,children:(0,h.jsxs)(`table`,{className:`w-full text-xs text-left`,children:[(0,h.jsx)(`thead`,{className:`bg-krona-workspace text-krona-secondary border-b border-krona-border`,children:(0,h.jsxs)(`tr`,{children:[(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Дата / Время`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Тип движения`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Артикул`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Товар`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Количество`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Основание / Примечание`})]})}),(0,h.jsxs)(`tbody`,{className:`divide-y divide-krona-border`,children:[J.map(e=>(0,h.jsxs)(`tr`,{className:`hover:bg-krona-workspace/50 transition-colors`,children:[(0,h.jsx)(`td`,{className:`p-3 font-mono text-krona-secondary`,children:c(e.timestamp)}),(0,h.jsx)(`td`,{className:`p-3`,children:Z(e.type)}),(0,h.jsx)(`td`,{className:`p-3 font-mono text-krona-secondary`,children:e.sku}),(0,h.jsx)(`td`,{className:`p-3 font-medium text-krona-primary`,children:e.productName}),(0,h.jsxs)(`td`,{className:`p-3 font-bold text-krona-primary`,children:[e.type===`receipt`?`+${e.quantity}`:e.type===`shipment`||e.type===`loss`?`-${e.quantity}`:`${e.quantity}`,` шт.`]}),(0,h.jsx)(`td`,{className:`p-3 text-krona-secondary`,children:e.notes||`—`})]},e.id)),J.length===0&&(0,h.jsx)(`tr`,{children:(0,h.jsx)(`td`,{colSpan:6,className:`p-8 text-center text-krona-secondary text-xs italic`,children:`Записи в складском журнале отсутствуют`})})]})]})}),x===`receipts`&&(0,h.jsx)(`div`,{className:`bg-krona-surface border border-krona-border rounded-xl shadow-krona-soft overflow-hidden`,children:(0,h.jsxs)(`table`,{className:`w-full text-xs text-left`,children:[(0,h.jsx)(`thead`,{className:`bg-krona-workspace text-krona-secondary border-b border-krona-border`,children:(0,h.jsxs)(`tr`,{children:[(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Номер накладной`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Поставщик`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Дата поступления`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Позиций`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold`,children:`Сумма поставки`}),(0,h.jsx)(`th`,{className:`p-3 font-semibold text-center`,children:`Статус`})]})}),(0,h.jsxs)(`tbody`,{className:`divide-y divide-krona-border`,children:[_.map(e=>(0,h.jsxs)(`tr`,{className:`hover:bg-krona-workspace/50 transition-colors`,children:[(0,h.jsx)(`td`,{className:`p-3 font-mono font-bold text-krona-primary`,children:e.receiptNumber}),(0,h.jsx)(`td`,{className:`p-3 font-medium text-krona-primary`,children:e.supplierName||`Поставщик`}),(0,h.jsx)(`td`,{className:`p-3 font-mono text-krona-secondary`,children:e.receivedAt?c(e.receivedAt):`—`}),(0,h.jsxs)(`td`,{className:`p-3 text-krona-secondary`,children:[e.items.length,` поз.`]}),(0,h.jsx)(`td`,{className:`p-3 font-bold text-krona-green`,children:f(e.totalCost.minor)}),(0,h.jsx)(`td`,{className:`p-3 text-center`,children:(0,h.jsx)(r,{variant:`green`,size:`sm`,children:`Оприходовано`})})]},e.id)),_.length===0&&(0,h.jsx)(`tr`,{children:(0,h.jsx)(`td`,{colSpan:6,className:`p-8 text-center text-krona-secondary text-xs italic`,children:`Приходные накладные отсутствуют`})})]})]})}),(0,h.jsx)(l,{isOpen:D,onClose:()=>O(!1),title:`Оформление приходной накладной (Поступление товаров)`,size:`md`,children:(0,h.jsxs)(`form`,{onSubmit:Y,className:`space-y-4 text-xs`,children:[(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`label`,{className:`block font-semibold text-krona-primary mb-1`,children:`Поставщик:`}),(0,h.jsx)(`input`,{type:`text`,required:!0,value:j,onChange:e=>M(e.target.value),placeholder:`Например: ООО «Кофе Импорт Трейд»`,className:`w-full px-3 py-1.5 bg-krona-workspace border border-krona-border rounded-lg text-krona-primary`})]}),(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`label`,{className:`block font-semibold text-krona-primary mb-1`,children:`Склад приемки:`}),(0,h.jsx)(`select`,{value:N,onChange:e=>P(e.target.value),className:`w-full px-3 py-1.5 bg-krona-workspace border border-krona-border rounded-lg text-krona-primary`,children:t.map(e=>(0,h.jsx)(`option`,{value:e.id,children:e.name},e.id))})]}),(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`label`,{className:`block font-semibold text-krona-primary mb-1`,children:`Товар:`}),(0,h.jsx)(`select`,{value:F,onChange:e=>I(e.target.value),className:`w-full px-3 py-1.5 bg-krona-workspace border border-krona-border rounded-lg text-krona-primary`,children:b.map(e=>(0,h.jsxs)(`option`,{value:e.id,children:[e.name,` (`,e.sku,`)`]},e.id))})]}),(0,h.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`label`,{className:`block font-semibold text-krona-primary mb-1`,children:`Количество (шт.):`}),(0,h.jsx)(`input`,{type:`number`,min:1,value:L,onChange:e=>R(Number(e.target.value)||1),className:`w-full px-3 py-1.5 bg-krona-workspace border border-krona-border rounded-lg text-krona-primary`})]}),(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`label`,{className:`block font-semibold text-krona-primary mb-1`,children:`Закупочная цена (коп.):`}),(0,h.jsx)(`input`,{type:`number`,min:1,value:z,onChange:e=>B(Number(e.target.value)||0),className:`w-full px-3 py-1.5 bg-krona-workspace border border-krona-border rounded-lg text-krona-primary`})]})]}),(0,h.jsxs)(`div`,{className:`p-3 bg-emerald-500/10 border border-emerald-500/30 rounded-lg text-emerald-800 dark:text-emerald-300`,children:[`После подтверждения накладной физический и доступный остаток на складе увеличится на`,` `,(0,h.jsxs)(`strong`,{children:[L,` шт.`]}),`, а запись появится в Журнале складских движений.`]}),(0,h.jsxs)(`div`,{className:`flex justify-end gap-2 pt-2 border-t border-krona-border`,children:[(0,h.jsx)(n,{variant:`secondary`,size:`sm`,type:`button`,onClick:()=>O(!1),children:`Отмена`}),(0,h.jsxs)(n,{variant:`primary`,size:`sm`,type:`submit`,children:[(0,h.jsx)(o,{className:`w-3.5 h-3.5 mr-1`}),` Оприходовать на склад`]})]})]})}),(0,h.jsx)(l,{isOpen:k,onClose:()=>A(!1),title:V?`Коррекция остатка: ${V.productName}`:``,size:`md`,children:V&&(0,h.jsxs)(`form`,{onSubmit:X,className:`space-y-4 text-xs`,children:[(0,h.jsxs)(`div`,{className:`p-3 bg-krona-workspace rounded-lg border border-krona-border space-y-1`,children:[(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`span`,{className:`text-krona-secondary`,children:`Склад:`}),` `,(0,h.jsx)(`strong`,{children:V.warehouseName})]}),(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`span`,{className:`text-krona-secondary`,children:`Текущий физический остаток:`}),` `,(0,h.jsxs)(`strong`,{children:[V.onHand,` `,V.unit]})]})]}),(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`label`,{className:`block font-semibold text-krona-primary mb-1`,children:`Изменение количества (+ для прихода, - для списания):`}),(0,h.jsx)(`input`,{type:`number`,value:U,onChange:e=>W(e.target.value),className:`w-full px-3 py-1.5 bg-krona-workspace border border-krona-border rounded-lg text-krona-primary font-bold`})]}),(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`label`,{className:`block font-semibold text-krona-primary mb-1`,children:`Причина корректировки:`}),(0,h.jsx)(`input`,{type:`text`,required:!0,value:G,onChange:e=>K(e.target.value),className:`w-full px-3 py-1.5 bg-krona-workspace border border-krona-border rounded-lg text-krona-primary`})]}),(0,h.jsxs)(`div`,{className:`flex justify-end gap-2 pt-2 border-t border-krona-border`,children:[(0,h.jsx)(n,{variant:`secondary`,size:`sm`,type:`button`,onClick:()=>A(!1),children:`Отмена`}),(0,h.jsx)(n,{variant:`primary`,size:`sm`,type:`submit`,children:`Сохранить изменение`})]})]})})]})};export{g as InventoryModule};