Advertisement
Guest User

Untitled

a guest
Sep 18th, 2019
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 69.44 KB | None | 0 0
  1.  
  2. nom_price as (
  3.  
  4. -- Цены номенклатур по прайсу
  5. select
  6. it::integer
  7. , date_begin::date date_begin
  8. , coalesce(date_end::timestamp, 'infinity'::timestamp)::date date_end
  9. , (coalesce(pr_cost, 0.0))::numeric(32,2) price
  10. from unnest('{1972,1996,1997}'::bigint[], '{"2018-07-26","2018-11-06","2018-11-06"}'::varchar[], '{"2019-09-19","2019-09-19","2019-09-19"}'::varchar[], '{100.00,180.00,360.00}'::numeric[]::numeric[]) as t(it, date_begin, date_end, pr_cost)
  11.  
  12. ),
  13. pids as (
  14.  
  15. SELECT abs(1998::bigint) pid
  16. WHERE 1998::bigint is not null
  17. UNION ALL
  18. SELECT
  19. n."@Номенклатура" pid
  20. FROM pids p
  21. JOIN "Номенклатура" n ON n."Раздел" = p.pid
  22. WHERE n."Раздел@" is not null
  23. ),
  24. use_types as (
  25.  
  26.  
  27. select "@ТипНоменклатуры" tp from "ТипНоменклатуры" where "ВидУчета" = ANY('{0,1}'::bigint[])
  28.  
  29.  
  30. ),
  31. certs_types as (
  32. select "@ТипНоменклатуры" tp from "ТипНоменклатуры"
  33. where "Категория" = 8
  34. and "@ТипНоменклатуры" = any(array(table use_types))
  35. ),
  36. its as (
  37. with abs_params as (
  38. select abs(unnest('{1998}'::bigint[]))
  39. )
  40. select "@Номенклатура" it
  41. -- items
  42. from "Номенклатура"
  43. where "@Номенклатура" = any(array(table abs_params))
  44. and "Раздел@" is not true
  45. and "ТипНоменклатуры" = ANY( ARRAY( TABLE use_types ) )
  46.  
  47. union
  48. select "@Номенклатура" it
  49. -- items_in_foldes
  50. from "Номенклатура"
  51. where "Раздел" = ANY(ARRAY(
  52. with recursive folders_expand as (
  53. select "@Номенклатура" it
  54. from "Номенклатура"
  55. where "@Номенклатура" = any(array(table abs_params))
  56. and "Раздел@" is not null
  57. union
  58. select "@Номенклатура" it
  59. from folders_expand f
  60. join "Номенклатура" n on n."Раздел" = f.it
  61. where n."Раздел@" is not null
  62. )
  63. select it from folders_expand
  64. ))
  65. and ("Раздел" IS NOT NULL OR "Раздел@" IS NOT NULL) -- for index
  66. and "Раздел@" is not true
  67. and "ТипНоменклатуры" = ANY( ARRAY( TABLE use_types ) )
  68.  
  69. ),
  70. nom_price_date as (
  71.  
  72. -- Цены не партионных номенклатур
  73. -- подбор актуального прайса (выбор по конечной дате последнего прайса)
  74. select
  75. it
  76. , price
  77. from nom_price
  78. where (it, date_begin) in (
  79. select
  80. it
  81. , max(date_begin)
  82. from nom_price
  83. group by it
  84. )
  85.  
  86. ),
  87. pid_its as (
  88. select n."@Номенклатура" it
  89. from "Номенклатура" n
  90. where n."Раздел" = ANY(ARRAY(select pid from pids))
  91. and n."Раздел@" is not true
  92. and "ТипНоменклатуры" = ANY( ARRAY( TABLE use_types ) )
  93.  
  94. ),
  95. its_pid_its as (
  96.  
  97. select it from (
  98. select it
  99. from its
  100. order by it
  101. ) t
  102. join (
  103. select it
  104. from pid_its
  105. order by it
  106. ) t1 using(it)
  107.  
  108. ),
  109. its_certs as (
  110. select "@Номенклатура" it, p.pid
  111. -- идентификаторы гашений сертификатов, с заменеными разделами на разделы родителей
  112. from "Номенклатура"
  113. join (
  114. with recursive folders_expand2 as (
  115. select "@Номенклатура" it, "Раздел" pid
  116. from "Номенклатура"
  117. where "ТипНоменклатуры" = ANY( ARRAY( TABLE certs_types ) )
  118. and "@Номенклатура" = ANY(ARRAY(SELECT it FROM its_pid_its))
  119. and not(select count(1) = 1 from its)
  120. union
  121. select "@Номенклатура" it, "Раздел" pid
  122. from folders_expand2 f
  123. join "Номенклатура" n on n."Раздел" = f.it
  124. )
  125. select it, pid from folders_expand2
  126. ) p on "Раздел" = p.it
  127. where "Раздел@" is null
  128.  
  129. ),
  130. it_prep as (
  131. select "@Номенклатура" it
  132. from "Номенклатура" n
  133. where n."Раздел@" is not true
  134. and n."@Номенклатура" = ANY(ARRAY(SELECT it FROM its_pid_its))
  135.  
  136. union
  137. select "@Номенклатура" it
  138. from "Номенклатура" n
  139. where n."@Номенклатура" = ANY(ARRAY(SELECT it FROM its_certs))
  140.  
  141. ),
  142. itwh as (
  143. -- находим все складские карточки, которые надо исследовать
  144. with
  145. nom_type_cte as (
  146. -- типы номенклатур для исследования
  147. select
  148. "@ТипНоменклатуры"
  149. , "ВидУчета"
  150. , "ПодвидУчета"
  151. , case when t."ПодвидУчета" in (1,2,3,4,5) then 'day' else 'day'::varchar end as quantum
  152. , case when
  153.  
  154. COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date = "CostRecalcWorker.GetQuantBeginDate"(
  155.  
  156. "CostRecalcWorker.GetQuantByDate"(
  157. COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date
  158. , case when t."ПодвидУчета" in (1,2,3,4,5) then 'day' else 'day'::varchar end
  159. )
  160. , case when t."ПодвидУчета" in (1,2,3,4,5) then 'day' else 'day'::varchar end
  161. )
  162. then
  163. "CostRecalcWorker.GetQuantByDate"(
  164. COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date
  165. , case when t."ПодвидУчета" in (1,2,3,4,5) then 'day' else 'day'::varchar end
  166. )
  167. else
  168. "CostRecalcWorker.GetQuantByDate"(
  169. COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date - interval '1 msec'
  170. , case when t."ПодвидУчета" in (1,2,3,4,5) then 'day' else 'day'::varchar end
  171. )
  172. end as quant_date
  173. from "ТипНоменклатуры" t
  174. where "ВидУчета" IN (0, 1)
  175.  
  176. order by "@ТипНоменклатуры"
  177. )
  178. select
  179. wh."Номенклатура" it
  180. , wh."НоменклатураРаздел" pid
  181. , t."ВидУчета" tiv
  182. , wh."Склад" wh
  183. , wh."Остаток" qty
  184. , wh."СуммаСебест" sumit
  185. , wh."СуммаСебестБезНДС" sumxt
  186. , t.quantum
  187. , t.quant_date
  188. from "СкладскаяКартотека" wh
  189. left join nom_type_cte t on
  190. t."@ТипНоменклатуры" = wh."ТипНоменклатуры"
  191.  
  192. where true
  193. and wh."Номенклатура" = ANY(ARRAY(table it_prep))
  194.  
  195. and wh."ТипНоменклатуры" is not null
  196. and wh."ТипНоменклатуры" = any(array(select "@ТипНоменклатуры" from nom_type_cte order by "@ТипНоменклатуры"))
  197. ),
  198. itwh_wca as (
  199. -- Обогащаем данные из СкладскаяКартотека данными по актуальности рассчета
  200. select distinct on (it, wh)
  201. itwh.*
  202. , case
  203. when cq.id is not null then null
  204. when cc.dt is not null then cc.dt
  205. else 'infinity'::timestamp
  206. end::timestamp wca
  207. , cq.it is not null as in_queue
  208. from
  209. itwh itwh
  210. left join cost_queue cq on (cq.it, cq.wh) = (itwh.it, itwh.wh)
  211. left join cost_card cc on (cc.it, cc.wh) = (itwh.it, itwh.wh) and cq.id is null
  212. where
  213. cq.it is not null or cc.it is not null --Карточки по которым были движения
  214.  
  215. ),
  216. itwhf as (
  217. select
  218. w.it
  219. , w.pid
  220. , w.tiv
  221. , w.wh
  222. , wca
  223. , qty
  224. , sumit
  225. , sumxt
  226. , quant_date
  227. , quantum
  228. , in_queue
  229.  
  230. from
  231. itwh_wca w
  232. where true
  233. ),
  234. inv_nomdoc as (
  235.  
  236. -- для каждой складской карточки находим
  237. -- * ближайшую "сверху" от интервала инвентаризацию
  238. select
  239. itwhf.*
  240. -- inv - массив с информацией по инвентаризации (ДатаВремя, Количество, СуммаСебест, СуммаСебестБезНДС, АктИнвентаризации.ТипПроведения, Ид)
  241. , (
  242. coalesce((
  243. select ARRAY[
  244. CASE
  245. WHEN tp = 1 THEN date_trunc('day',dt)
  246. WHEN tp = 2 THEN date_trunc('day',dt) + interval '1 day' - interval '1 msec'
  247. ELSE dt
  248. END,
  249. not_crctd.qty,
  250. not_crctd.sumit,
  251. not_crctd.sumxt,
  252. not_crctd.tp,
  253. not_crctd.nd,
  254. true
  255. ]::text[]
  256. from (
  257. select
  258. "ДатаВремя" dt
  259. , CASE WHEN tiv = 0 THEN coalesce("Количество",0) ELSE 0 END::numeric(32,6) qty
  260. , coalesce("СуммаСебест", 0) sumit
  261. , coalesce("СуммаСебестБезНДС", 0) sumxt
  262. , coalesce(
  263. (select "ТипПроведения" from "АктИнвентаризации" where "@Документ" = dcit."СкладскойДокумент" limit 1)
  264. , 0) tp
  265. , "@НоменклатураДокумента" nd
  266. from
  267. "НоменклатураДокумента" dcit
  268. where
  269. ("Номенклатура", "Склад", "Тип", "Закрыто") = (itwhf.it, itwhf.wh, 2, TRUE) AND
  270.  
  271. "ДатаВремя" <= COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec'
  272.  
  273. and Флаги[4] is true
  274. order by
  275. "ДатаВремя" DESC
  276. limit 1
  277. ) as not_crctd
  278. ), Array['-infinity', 0, 0, 0, 0, 0, true]::text[])
  279. ) invit
  280. from
  281. itwhf itwhf
  282. where wca is null
  283.  
  284. ),
  285. wc_all_calc as (
  286.  
  287. select
  288. itwhf.*
  289. , coalesce((
  290. select
  291. ARRAY[
  292. dt::text
  293. , qty::text
  294. , sumit::text
  295. , sumxt::text
  296. , 0
  297. , 0
  298. , actual::text
  299. ]::text[]
  300. from cost_rest cr
  301. where (cr.it, cr.wh) = (itwhf.it, itwhf.wh) and
  302.  
  303. dt <= COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec'
  304.  
  305. order by dt desc
  306. limit 1
  307. ),
  308. Array['-infinity', 0, 0, 0, 0, 0, true]::text[]
  309. ) inv
  310. from
  311. itwhf
  312. itwhf
  313. where wca is not null
  314.  
  315. ),
  316. inv as (
  317.  
  318. select
  319. itwhf.*
  320. , coalesce(
  321. coalesce((
  322. select
  323. ARRAY[
  324. dt::text
  325. , qty::text
  326. , sumit::text
  327. , sumxt::text
  328. , 0
  329. , 0
  330. , actual::text
  331. ]::text[]
  332. from cost_rest cr2
  333. where (cr2.it, cr2.wh) = (itwhf.it, itwhf.wh)
  334. and actual is not null
  335. and dt <
  336. "CostRecalcWorker.GetQuantBeginDate"(
  337. "CostRecalcWorker.GetQuantByDate"(
  338. coalesce((
  339. select
  340. min(dt) dt
  341. from cost_rest cr
  342. where true
  343. and actual is null
  344.  
  345. and dt <= COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec'
  346.  
  347. and dt > COALESCE (invit[1]::timestamp, '-infinity'::timestamp)::date
  348. and (cr.it, cr.wh) = (itwhf.it, itwhf.wh)
  349. ),
  350.  
  351. COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec'
  352.  
  353. )
  354. , quantum)
  355. , quantum)
  356.  
  357. and dt > COALESCE (invit[1]::timestamp, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec'
  358.  
  359. order by dt desc
  360. limit 1
  361. ), invit),
  362. Array['-infinity', 0, 0, 0, 0, 0, true]::text[]
  363. ) inv
  364. from
  365. inv_nomdoc
  366. itwhf
  367.  
  368. ),
  369. inv_res as (
  370.  
  371. select
  372. it
  373. , pid
  374. , tiv
  375. , wh
  376. , wca
  377. , qty
  378. , sumit
  379. , sumxt
  380. , case when inv[1] = '-infinity' then invit else inv end as inv
  381. , quant_date
  382. , quantum
  383. , in_queue
  384.  
  385. from inv
  386. union all
  387. select
  388. it
  389. , pid
  390. , tiv
  391. , wh
  392. , wca
  393. , qty
  394. , sumit
  395. , sumxt
  396. , case when inv[1]::timestamp is null then Array['-infinity', 0, 0, 0, 0, 0, true]::text[] else inv end as inv
  397. , quant_date
  398. , quantum
  399. , in_queue
  400.  
  401. from wc_all_calc
  402.  
  403. ),
  404. extr_prt as (
  405. with
  406. _prtextr_ as (
  407. select
  408. parts.prt
  409. , case
  410. when parts.prt is not null and parts.prt_nd is null then -3 -- missing
  411. when parts.prt is not null and parts.actual is false then -1 -- prt and error
  412. --для актов инвентаризации партия ссылается на саму операцию
  413. when parts.prt is null and parts.prt_type = 2 then null -- OK
  414. when parts.prt is null and parts.actual is true then -4 -- avg
  415. when parts.prt is null and parts.actual is false then -1 -- error
  416. end rstbc_code
  417. , parts.dt
  418. , parts.it
  419. , parts.wh
  420. , parts.rstbqty
  421. , parts.rstbsumit
  422. , parts.rstbsumxt
  423. , inv.quant_date
  424. , "CostRecalcWorker.GetQuantByDate"(COALESCE (inv.inv[1]::timestamp, '-infinity'::timestamp), inv.quantum)::bigint quant_begin
  425. , inv[7]::boolean inv_code
  426. , false is_nd
  427. , inv[1]::timestamp as wca -- дата актуальности складской карточки
  428. , in_queue
  429. from inv_res inv
  430. join lateral (
  431. select coalesce("CostRecalcWorker.GetQuantByDate"(COALESCE (inv[1]::timestamp, '-infinity'::timestamp), quantum), 0) inv_quant
  432. ) inv_q on true
  433. join lateral (
  434. with agg_prt as (
  435. --агрегируем по prt, если партия списалась в 0, то зануляем метрики
  436. select
  437. prt
  438. , it
  439. , wh
  440. , bool_and(case when cr.id is NULL then cr.actual else true end) actual
  441. , sum(case when id is null then qty else 0 end)::double precision rstbqty
  442. , sum(case when id is null then cr.sumit else 0 end)::numeric(32,2) rstbsumit
  443. , sum(case when id is null then cr.sumxt else 0 end)::numeric(32,2) rstbsumxt
  444. from cost_result cr
  445. where (cr.it, cr.wh, cr.quant) = (inv.it, inv.wh, inv_q.inv_quant)
  446. and case when
  447. cr.manual is null
  448. and cr.actual is not null -- Условие для исключения списаний по точности учета, в остаток они не должны включаться
  449. then true
  450. else false
  451. end
  452. group by prt, it, wh
  453. )
  454. select
  455. prt
  456. , nd."@НоменклатураДокумента" prt_nd
  457. , nd."Тип" prt_type
  458. , nd."ДатаВремя" dt
  459. , it
  460. , wh
  461. , actual
  462. , case when inv.tiv <> 1 then rstbqty else 0 end::double precision rstbqty
  463. , rstbsumit
  464. , rstbsumxt
  465. from agg_prt
  466. left join "НоменклатураДокумента" nd on nd."@НоменклатураДокумента" = prt
  467. where TRUE
  468.  
  469. and case
  470. when prt is NULL and actual is TRUE then FALSE /* исключаем нулевой остаток "успешно" */
  471. when actual is TRUE AND (rstbsumit, rstbsumxt, rstbqty) = (0, 0, 0)
  472.  
  473. then FALSE /* выключаем если НЕ нужны 0 партии */
  474.  
  475. else TRUE
  476. end
  477. ) parts on true
  478. order by parts.prt
  479. ),
  480. _cost_nd_prt_ as (
  481. select
  482. raw_prt.prt
  483. , -2::int as rstbc_code -- wait - документы на расчете, подкраска синим
  484. , raw_prt.dt
  485. , raw_prt.it
  486. , raw_prt.wh
  487. , raw_prt.rstbqty
  488. , raw_prt.rstbsumit
  489. , raw_prt.rstbsumxt
  490. , raw_prt.quant_date
  491. , "CostRecalcWorker.GetQuantByDate"(COALESCE(raw_prt.inv_dt, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec', raw_prt.quantum)::bigint as quant_begin
  492. , raw_prt.inv_code
  493. , true as is_nd
  494. , raw_prt.inv_dt as wca -- дата актуальности складской карточки
  495. , in_queue
  496. from (
  497. select
  498. nd.prt
  499. , nd.it
  500. , nd.wh
  501. , nd.dt
  502. , sum(rstbqty) rstbqty
  503. , sum(rstbsumit) rstbsumit
  504. , sum(rstbsumxt) rstbsumxt
  505. , bool_and(inv_code) inv_code
  506. , min(inv_dt) inv_dt
  507. , min(quantum) quantum
  508. , min(quant_date) quant_date
  509. , min(wca) wca
  510. , bool_or(in_queue) in_queue
  511. from (
  512. select
  513. case
  514. when "Тип" = 0 and "Количество" > 0 or "Тип" = 1 and "Количество" < 0 then "@НоменклатураДокумента"
  515. when cr.manual is true then cr.prt
  516. else 0
  517. end prt
  518. , case
  519. when cr.prt is not null and nd."@НоменклатураДокумента" is null then -3 -- missing
  520. --для актов инвентаризации партия ссылается на саму операцию
  521. when cr.prt is null and nd."Тип" = 2 then null -- OK
  522. when cr.id is null then -2 -- wait
  523. when cr.prt is null and cr.actual is true then -4 -- avg
  524. when cr.prt is null then -1 -- error
  525. end rstbc_code
  526. , "Номенклатура" it
  527. , "Склад" wh
  528. , case when inv.tiv <> 1 then (coalesce( cr.qty * cr.op, "Количество" * case when "Тип" = 1 then -1 else 1 end)) else 0 end rstbqty
  529. , coalesce( cr.sumit * cr.op, "СуммаСебест" * case when "Тип" = 1 then -1 else 1 end) rstbsumit
  530. , coalesce( cr.sumxt * cr.op, "СуммаСебестБезНДС" * case when "Тип" = 1 then -1 else 1 end) rstbsumxt
  531. , inv.inv[7]::boolean inv_code
  532. , inv.inv[1]::timestamp inv_dt
  533. , inv.quantum
  534. , inv.quant_date
  535. , inv.wca
  536. , nd."ДатаВремя" dt
  537. , in_queue
  538. from "НоменклатураДокумента" nd
  539. join inv_res inv on (inv.it, inv.wh) = (nd."Номенклатура", nd."Склад")
  540. left join cost_result cr
  541. on (cr.it, cr.wh) = (nd."Номенклатура", nd."Склад")
  542. and cr.prt is not null
  543. and cr.id = "@НоменклатураДокумента"
  544. and cr.manual = true and cr.manual is not null --<< for index cost_result-id-manual
  545. and cr.op = -1
  546. where -- В прогнозе подставляются расходы, поэтому нет необходимости отбирать на этом этапе
  547. nd."Закрыто"
  548. and nd."Тип" = ANY (ARRAY[0, 1])
  549. and (
  550. -- приходы
  551. nd."Тип" is not distinct from 0
  552. or
  553. -- возвраты от покупателей
  554. nd."Тип" is not distinct from 1
  555. and nd."Количество" < 0
  556. and nd."Флаги"[11] is true
  557. and not exists(
  558. select "Основание"
  559. from "СвязьНаименований" ln
  560. where
  561. ln."Следствие" = nd."@НоменклатураДокумента"
  562. and ln."Тип" in (9, 10, 11, 12)
  563. limit 1
  564. )
  565. )
  566. -- только поступления, продукты выпуска и приходы, образующие партии.
  567. and (nd."Раздел" is null or nd."Флаги"[17] is true) is true
  568. and "ДатаВремя" > COALESCE (inv[1]::timestamp, '-infinity'::timestamp)
  569.  
  570. and "ДатаВремя" <= COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec'
  571.  
  572. ) nd
  573. group by nd.it, nd.wh, nd.prt, nd.dt
  574. ) raw_prt
  575. )
  576. -- разворов массива партий в рекорд
  577. select
  578. s.prt pid
  579. , s.it
  580. , s.wh
  581. , s.rstbqty
  582. , s.rstbsumit
  583. , s.rstbsumxt
  584. , case
  585. when is_nd then -2 -- Синий
  586. else
  587. case
  588. when s.prt <> 0 then rstbc_code -- Если партия подобрана, получаем подсветку из cost_result
  589. else -1 -- ошибка (красный)
  590. end
  591. end as rstbc_code
  592. , s.prt
  593. , s.wca
  594. , null::text[] inv
  595. , in_queue
  596. , null::bigint quant_date
  597. , null::text quantum
  598. , null::bigint quant_begin
  599.  
  600. from (
  601. select *
  602. from _prtextr_
  603. union
  604. select *
  605. from _cost_nd_prt_
  606. where true
  607. ) s
  608.  
  609. ),
  610. rcpexp as (
  611.  
  612. -- вычисляем обороты "до" и "внутри" искомого периода
  613. SELECT
  614. inv.*
  615. , case when wca is not null then (
  616. case when wca < coalesce('2019-09-18'::date, 'infinity'::timestamp)::date + INTERVAL '1 day' - INTERVAL '1 msec'
  617. then "CostRecalcWorker.GetQuantByDate"(COALESCE(wca::timestamp, '-infinity'::timestamp)::date, inv.quantum)
  618. else
  619. coalesce(q.quant, 0)
  620. end
  621. )
  622. else (
  623. case when inv is null or inv[1]::timestamp = '-infinity' then 0
  624. else "CostRecalcWorker.GetQuantByDate"(coalesce(inv[1]::timestamp::timestamp, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec', inv.quantum) end
  625. ) end as quant_begin
  626. , (
  627. SELECT
  628. ARRAY[
  629. -- rcpqty
  630. coalesce(sum(CASE WHEN "Тип" = 0 AND tiv = 0 THEN "Количество" END::numeric(32,6)), 0)
  631. -- rcpsumit
  632. , coalesce(sum(CASE WHEN "Тип" = 0 THEN "СуммаСебест" END), 0)
  633. -- rcpsumxt
  634. , coalesce(sum(CASE WHEN "Тип" = 0 THEN "СуммаСебестБезНДС" END), 0)
  635. -- rcpmdate
  636. , 0
  637. -- expqty
  638. , coalesce(sum(CASE WHEN "Тип" = 1 AND tiv = 0 THEN "Количество" END::numeric(32,6)), 0)
  639. -- expsumit
  640. , coalesce(sum(CASE WHEN "Тип" = 1 THEN "СуммаСебест" END), 0)
  641. -- expsumxt
  642. , coalesce(sum(CASE WHEN "Тип" = 1 THEN "СуммаСебестБезНДС" END), 0)
  643. -- expmdate
  644. , coalesce(min(actual_code), 1)
  645. ]::text[]
  646. FROM (
  647. select
  648. case
  649. when "Тип" not in (0, 1) then 0::double precision
  650. when "ДатаВремя" = inv[1]::timestamp and inv[5]::int <> 1 then 0::double precision
  651. when "ДатаВремя" = inv[1]::timestamp and inv[5]::int = 1 and "Раздел" is not distinct from inv[6]::int then 0::double precision
  652. else "Количество"
  653. end "Количество"
  654. , case
  655. when "Тип" not in (0, 1) then 0::numeric(32, 2)
  656. when "ДатаВремя" = inv[1]::timestamp and inv[5]::int <> 1 then 0::numeric(32, 2)
  657. when "ДатаВремя" = inv[1]::timestamp and inv[5]::int = 1 and "Раздел" is not distinct from inv[6]::int then 0::numeric(32, 2)
  658. else "СуммаСебест"
  659. end "СуммаСебест"
  660. , case
  661. when "Тип" not in (0, 1) then 0::numeric(32, 2)
  662. when "ДатаВремя" = inv[1]::timestamp and inv[5]::int <> 1 then 0::numeric(32, 2)
  663. when "ДатаВремя" = inv[1]::timestamp and inv[5]::int = 1 and "Раздел" is not distinct from inv[6]::int then 0::numeric(32, 2)
  664. else "СуммаСебестБезНДС"
  665. end "СуммаСебестБезНДС"
  666. , "Тип"
  667. , "ДатаВремя"
  668. , 0 actual_code
  669. , "@НоменклатураДокумента"
  670. from
  671. "НоменклатураДокумента" dcit
  672. WHERE
  673. ("Номенклатура", "Склад", "Закрыто") = (it, wh, TRUE) AND
  674. ("Тип" = ANY (ARRAY[0, 1])) AND
  675. "ДатаВремя" >= inv[1]::timestamp AND
  676.  
  677. "ДатаВремя" <= COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec'
  678.  
  679. ) dcitrec
  680. ) rcpexpb
  681. FROM
  682. inv_res inv
  683. LEFT JOIN LATERAL (
  684. select "CostRecalcWorker.GetQuantByDate"(COALESCE(rest.dt, '-infinity'::timestamp)::date, inv.quantum) quant
  685. from cost_rest rest
  686. where (rest.it, rest.wh) = (inv.it, inv.wh)
  687. and rest.dt <
  688.  
  689. COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec'
  690.  
  691. order by dt desc
  692. limit 1
  693. ) q on (wca is not null and wca >= coalesce('2019-09-18'::date, 'infinity'::timestamp)::date + INTERVAL '1 day' - INTERVAL '1 msec')
  694.  
  695. ),
  696. itwhext as (
  697.  
  698. -- "разворачиваем" остатки и обороты в нормальный вид
  699. SELECT
  700. it
  701. , wh
  702. , rcpexp.pid
  703.  
  704. , (case when tiv <> 1 then (
  705. inv[2]::numeric(32,6)
  706. + rcpexpb[1]::numeric(32,6)
  707. - rcpexpb[5]::numeric(32,6)
  708. ) else 0 end )::double precision rstbqty
  709. , (
  710. --rstbsumit
  711. inv[3]::numeric(32,2)
  712. + rcpexpb[2]::numeric(32,2)
  713. - rcpexpb[6]::numeric(32,2)
  714. ) rstbsumit
  715. , (
  716. -- rstbsumxt
  717. inv[4]::numeric(32,2)
  718. + rcpexpb[3]::numeric(32,2)
  719. - rcpexpb[7]::numeric(32,2)
  720. ) rstbsumxt
  721. -- следующие строки добавляют подкраску в отчете
  722. , case when wca is not null then (
  723. (select
  724. (case actual when true then null when false then -1 else -2 end)
  725. from cost_rest cr
  726. where (cr.it, cr.wh) = (rcpexp.it, rcpexp.wh)
  727. and cr.quant <= rcpexp.quant_date
  728. and cr.quant >= coalesce(quant_begin, 0)
  729. order by cr.quant desc, dt desc
  730. limit 1
  731. )
  732. )
  733. else (
  734. least((case when coalesce(inv[7]::boolean, true) then null else -1 end),
  735. (
  736. select
  737. min(case actual when true then null when false then -1 else -2 end) nact
  738. from cost_rest cr2
  739. where quant <= rcpexp.quant_date
  740. and quant >= coalesce(quant_begin, 0)
  741. and (cr2.it, cr2.wh) = (rcpexp.it, rcpexp.wh)
  742. )
  743. )) end as rstbc_code
  744. , inv[1]::timestamp wca
  745. , inv
  746. , in_queue
  747. , quant_date
  748. , quantum
  749. , quant_begin
  750. FROM
  751. rcpexp
  752.  
  753. ),
  754. itwhnz as (
  755. -- фильтруем полностью нулевые записи перед агрегацией
  756. SELECT
  757. itwhext.*
  758. FROM
  759. extr_prt
  760. itwhext
  761. WHERE true
  762.  
  763. and (rstbqty, rstbsumit, rstbsumxt) IS DISTINCT FROM (0, 0, 0)
  764.  
  765. or rstbc_code is distinct from null
  766.  
  767. ),
  768. itaggwh as (
  769.  
  770. -- группировка до складской карточки
  771. SELECT distinct
  772.  
  773. coalesce(it, 0) it
  774.  
  775. , wh
  776. , pid
  777.  
  778. , case when rstbqty <> 0 then 0 else
  779. coalesce((select "СуммаСебест" / "Количество"
  780. from "НоменклатураДокумента"
  781. where ("Номенклатура", "Склад", "Закрыто") = (it, wh, True)
  782. and "Тип" IN (0, 1)
  783. and "ДатаВремя" < COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec'
  784. and "Количество" <> 0
  785. order by "ДатаВремя" desc
  786. limit 1), 0)
  787. end "Себест"
  788. , case when rstbqty <> 0 then 0 else
  789. coalesce((select "СуммаСебестБезНДС" / "Количество"
  790. from "НоменклатураДокумента"
  791. where ("Номенклатура", "Склад", "Закрыто") = (it, wh, True)
  792. and "Тип" IN (0, 1)
  793. and "ДатаВремя" < COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec'
  794. and "Количество" <> 0
  795. order by "ДатаВремя" desc
  796. limit 1), 0)
  797. end "СебестБезНДС"
  798.  
  799. , prt
  800.  
  801. , (sum(rstbqty::numeric(32,6)) over w)::double precision rstbqty
  802. , sum(rstbsumit) over w rstbsumit
  803. , sum(rstbsumxt) over w rstbsumxt
  804. , min(rstbc_code) over w rstbc_code
  805.  
  806. , max(wca) over w wca
  807.  
  808. , inv
  809. , in_queue
  810. , quant_date
  811. , quantum
  812. , quant_begin
  813. FROM
  814. itwhnz
  815. window w as (partition by
  816.  
  817. it, wh, pid
  818.  
  819. )
  820.  
  821. ),
  822. pre_itagg_filter as (
  823.  
  824. -- применяем фильтрацию по отрицательным карточкам
  825. SELECT itaggwh.*
  826. FROM itaggwh
  827. WHERE true
  828. and (
  829.  
  830. ( (itaggwh.rstbsumit, itaggwh.rstbsumxt, itaggwh.rstbqty) IS DISTINCT FROM (0,0,0) or rstbc_code is distinct from null )
  831.  
  832. )
  833.  
  834.  
  835. ),
  836. itagg_filter as (
  837. -- применяем прайс к складским карточкам
  838. SELECT itaggwh.*
  839. , n."Раздел"
  840. , n."Раздел@"
  841. , n."НомНомер"
  842. , "Флаги"[6] as "ЖНВЛП"
  843. , t."ПодвидУчета"
  844. , t."Категория" as "ТипНоменклатуры.Категория"
  845. , case when n."Раздел@" is not TRUE then n."КодЕдиницаИзмерения" else null::text end as "КодЕдиницаИзмерения"
  846. , case when n."Раздел@" is not TRUE then ((ite."ЕИУ"[1])::json->'base'->>'abbr') else null::text end as "ЕдиницаИзмеренияНазвание"
  847. , case when n."Раздел@" is not TRUE then 0 else -4 end as "АгрегированныеМетрики"
  848.  
  849. FROM pre_itagg_filter itaggwh
  850. left join "Номенклатура" n on n."@Номенклатура" = itaggwh.it
  851. left join "НоменклатураРасш" ite on ite."@Номенклатура" = itaggwh.it
  852.  
  853. left join "ТипНоменклатуры" t on t."@ТипНоменклатуры" = n."ТипНоменклатуры"
  854.  
  855. ),
  856. all_orgs as (
  857.  
  858. select distinct "НашаОрганизация"
  859. from "Склад"
  860. where "@Лицо" = any(array(
  861. select distinct wh
  862. from itagg_filter
  863. order by wh
  864. ))
  865.  
  866. ),
  867. rst_prt_hand as (
  868. -- вычисляем количества по ручным закреплениям партий
  869. select
  870. -- идентификатор партии
  871. pt.*
  872. , coalesce(
  873. (
  874. select sum(cr.qty)
  875. from
  876. cost_result cr
  877. where
  878. cr.prt = pt.pid
  879. and (cr.op = -1 and cr.manual) is True
  880. and (
  881. cr.ord is null
  882. and (
  883. select
  884.  
  885. nd."ДатаВремя" <= COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec'
  886.  
  887. and nd."Флаги"[1] is distinct from true -- 'Удален'
  888. and nd."Закрыто"
  889. from "НоменклатураДокумента" nd
  890. where "@НоменклатураДокумента" = cr.id
  891. limit 1
  892. ) is true
  893. )
  894. )
  895. , 0
  896. )::double precision qty_hand
  897. from itagg_filter pt
  898. ),
  899. expense_w_code as (
  900.  
  901. with itwh_code as (
  902. -- Отберем все расходы с указанным кодом партии и без ручного установления партии
  903. select wr.*
  904. , array(
  905. select array[exp_c."КодПартии"::text, exp_c."Количество"::text]::text
  906. from (
  907. select lj."КодПартии", nd."Количество"
  908. from "НоменклатураДокумента" nd
  909. join lateral (
  910. select ndr."КодПартии"
  911. from "НоменклатураДокументаРасш" ndr
  912. where
  913. ndr."@НоменклатураДокумента" = nd."@НоменклатураДокумента"
  914. and ndr."КодПартии" is not null
  915. ) lj on true
  916. where
  917. -- проведенные наименований по СК на интервале от последних расчитанных остатков до указанной даты
  918. (wr.it, wr.wh) = (nd."Номенклатура", nd."Склад")
  919. and nd."ДатаВремя" > coalesce(wca, '-infinity'::timestamp)::timestamp -- Партии от даты актуальности
  920.  
  921. and nd."ДатаВремя" <= COALESCE ('2019-09-18'::date, '-infinity'::timestamp)::date + interval '1 day' - interval '1 msec'
  922.  
  923. and nd."Закрыто"
  924. and "Тип" = ANY (ARRAY[0, 1, 2])
  925. and case when nd."Тип" = 1 and nd."Количество" > 0 then true else false end
  926. and not exists(
  927. select 1
  928. from cost_result cr
  929. where
  930. cr.id = nd."@НоменклатураДокумента"
  931. and cr.manual is true
  932. limit 1
  933. )
  934. ) exp_c
  935. )::text[] out_w_code
  936. from
  937. (
  938. select distinct wr.it, wr.wh, wr.wca
  939. from itagg_filter wr
  940. where in_queue
  941. ) wr
  942.  
  943. ),
  944. -- TODO Не используется
  945. exp_code AS (
  946. -- Отберем все расходы с указанным кодом партии и без ручного установления партии
  947. select distinct wr.*
  948. , itwh.out_w_code
  949. from itagg_filter wr
  950. left join itwh_code itwh on (wr.it, wr.wh) = (itwh.it, itwh.wh)
  951. ),
  952. un_exp_code as (
  953. -- Разворот всех расходов по кодам патрий
  954. select
  955. distinct prt_code[1]::text id_code
  956. , prt_code[2]::double precision qty
  957. from (
  958. select unnest(out_w_code)::text[] prt_code
  959. from itwh_code
  960. ) t
  961. ),
  962. group_un_exp_code as (
  963. -- группировка суммарных расходов по кодам партий
  964. select
  965. id_code
  966. , sum(qty) qty
  967. from un_exp_code
  968. group by id_code
  969. ),
  970. prt_qty as (
  971. -- Получение партий с указанием их кода и временеи, для определения приоритета для списания
  972. select
  973. t.*
  974. , ndr."КодПартии"
  975. , nd."ДатаВремя"
  976. from (
  977. -- сводим "отфильтрованные" остатки по партиям с ручными партиями,
  978. -- в промежутке между актуальностью остатка и временем построения отчета
  979. select
  980. it
  981. , wh
  982. , prt
  983. , sum(qty) qty
  984. , sum(sumit) sumit
  985. , sum(sumxt) sumxt
  986. -- Если с партии было списание, тогда партия находится в очереди на расчет
  987. , min(least(rstbc_code, case when abs(rstbqty - qty) > 0 then -2 else null end)) rstbc_code
  988. from (
  989. select
  990. it
  991. , wh
  992. , pid prt
  993. , rstbc_code
  994. , rstbqty
  995. -- остаток - "ручные" закрепления
  996. , coalesce(rstbqty - qty_hand, 0)::double precision qty
  997. , case
  998. when abs(rstbqty) > 1e-10 then coalesce(rstbsumit - ((rstbsumit/rstbqty)*qty_hand), 0)
  999. else 0
  1000. end::numeric(32,2) as sumit
  1001. , case
  1002. when abs(rstbqty) > 1e-10 then coalesce(rstbsumxt - ((rstbsumxt/rstbqty)*qty_hand), 0)
  1003. else 0
  1004. end::numeric(32,2) as sumxt
  1005. from rst_prt_hand rph
  1006. ) q
  1007. group by prt, it, wh
  1008. ) t
  1009. left join "НоменклатураДокумента" nd on nd."@НоменклатураДокумента" = t.prt
  1010. left join "НоменклатураДокументаРасш" ndr on ndr."@НоменклатураДокумента" = nd."@НоменклатураДокумента"
  1011.  
  1012. where qty > 0
  1013.  
  1014. ),
  1015. prt_qty_agg as (
  1016. -- Агрегирование остатков по кодам партий, для упорядоченного списания
  1017. select
  1018. prt_qty.*
  1019. , coalesce(sum(qty) filter(where qty > 0) over w, 0) as total_sum
  1020. from prt_qty
  1021. window w as (partition by "КодПартии" order by "ДатаВремя", prt)
  1022. ),
  1023. prt_qty_agg_w_exp as (
  1024. -- списание с партий расходов по кодам партий
  1025. select
  1026. it
  1027. , wh
  1028. , prt
  1029. , least(
  1030. rstbc_code,
  1031. case
  1032. when abs(case when new_qty >= qty then qty else new_qty end - qty) > 0 then -2
  1033. else null
  1034. end
  1035. )::int rstbc_code
  1036. , qty
  1037. , sumit
  1038. , sumxt
  1039. --новое количество = (кол-во - списание по коду партии) или кол-во без списания)
  1040. , case when new_qty >= qty then
  1041. qty -- списание не произошло
  1042. else
  1043. case when qty < 0 then
  1044. qty -- Если по партии был отрицательный остаток, то ее не списываем
  1045. else
  1046. case when new_qty > 0 then
  1047. new_qty -- Частично списали по коду партии
  1048. else 0 -- списали по партии в 0
  1049. end
  1050. end
  1051. end as new_qty
  1052. from (
  1053. select
  1054. pqa.it
  1055. , pqa.wh
  1056. , pqa.prt
  1057. , pqa.rstbc_code
  1058. , pqa.qty
  1059. , pqa.sumit
  1060. , pqa.sumxt
  1061. , total_sum - case when pqa.qty > 0 then coalesce(guec.qty, 0) else 0 end as new_qty
  1062. from
  1063. prt_qty_agg pqa
  1064. left join group_un_exp_code guec on pqa."КодПартии" = guec.id_code
  1065. ) t
  1066. )
  1067. -- оставляем только партии с положительным остатком и рассчитываем пропорционально себестоимость
  1068. select
  1069. it
  1070. , wh
  1071. , prt
  1072. , rstbc_code
  1073. , new_qty::numeric(32,6)::double precision as qty
  1074. , case
  1075. when abs(qty) > 1e-10 then coalesce(((sumit/qty)*new_qty), 0)
  1076. else 0
  1077. end::numeric(32,2) as sumit
  1078. , case
  1079. when abs(qty) > 1e-10 then coalesce(((sumxt/qty)*new_qty), 0)
  1080. else 0
  1081. end::numeric(32,2) as sumxt
  1082. from prt_qty_agg_w_exp
  1083. -- pid = 0 - Партия не подобрана
  1084. where true
  1085.  
  1086. and new_qty > 0
  1087.  
  1088.  
  1089. ),
  1090. main_orgs as (
  1091.  
  1092. WITH RECURSIVE T1 AS(
  1093. SELECT "@Лицо",
  1094. "Раздел",
  1095. "Раздел@" "Папка",
  1096. 1 as "УровеньВложенности",
  1097. array[ "@Лицо" ]::int[] "Массив"
  1098. FROM "Контрагент"
  1099. WHERE "@Лицо" = any(array(table all_orgs))
  1100. UNION -- удаляем дубликаты, без ALL
  1101. SELECT "Контрагент"."@Лицо",
  1102. "Контрагент"."Раздел",
  1103. "Контрагент"."Раздел@" "Папка",
  1104. T1."УровеньВложенности" + 1 as "УровеньВложенности",
  1105. T1."Массив" || array[ "Контрагент"."@Лицо" ]::int[]
  1106. FROM T1 JOIN
  1107. "Контрагент" ON T1."Раздел" = "Контрагент"."@Лицо" AND
  1108. "Контрагент"."@Лицо" NOT IN ( SELECT( unnest( T1."Массив" ) ) )
  1109. )
  1110. select distinct main, sub
  1111. from (
  1112. select "@Лицо" main, "Массив"[1] sub, "УровеньВложенности", max("УровеньВложенности") over w as "УровеньВложенностиМакс"
  1113. from T1
  1114. where
  1115. ("Папка" IS NULL OR "Папка" = FALSE)
  1116. and ("Раздел" is null or "Раздел" <> any(array(select "@Лицо" from T1)))
  1117. window w as (partition by "Массив"[1])
  1118. ) q
  1119. where "УровеньВложенности" = "УровеньВложенностиМакс"
  1120.  
  1121. ),
  1122. not_prts as (
  1123.  
  1124. -- формирование метрик "Партия не подобрана"
  1125. select
  1126. wh
  1127. , it
  1128. , prt
  1129. , rstbc_code_itwh as rstbc_code
  1130. , qty
  1131. , sumit
  1132. , sumxt
  1133. from(
  1134. select
  1135. itwh.wh
  1136. , itwh.it
  1137. , 0 as prt
  1138. , min(itwh.rstbc_code) as rstbc_code_itwh
  1139. , min(prt.rstbc_code) as rstbc_code_prt
  1140. , sum(itwh.rstbqty - coalesce(prt.qty, 0)) qty
  1141. , sum(itwh.rstbsumit - coalesce(prt.sumit, 0)) sumit
  1142. , sum(itwh.rstbsumxt - coalesce(prt.sumxt, 0)) sumxt
  1143. from itwhext itwh
  1144. left join (
  1145. select
  1146. it
  1147. , wh
  1148. , min(coalesce(rstbc_code, 0)) as rstbc_code
  1149. , sum(qty) as qty
  1150. , sum(sumit) as sumit
  1151. , sum(sumxt) as sumxt
  1152. from expense_w_code
  1153.  
  1154.  
  1155. where TRUE
  1156.  
  1157. -- чтобы исключить записи входящие в диалог остатков по специальным отрицательным ключам
  1158. -- Если документ сформировал партию, но просчитан с ошибкой или находится на расчете, выводим как документ
  1159. -- подкрашиваем в зависимости от состояния документа и не агрегируем в партия не подобрана
  1160. and prt is distinct from null -- wait or error or prt is not null
  1161.  
  1162. -- Если есть фильтр по партии, то у нас не будет данных с неподобранной партией
  1163.  
  1164. group by it, wh
  1165. ) prt on (prt.it, prt.wh) = (itwh.it, itwh.wh)
  1166. group by itwh.wh, itwh.it
  1167. ) not_prt
  1168. where true
  1169.  
  1170. and (qty <> 0 or sumit <> 0.0 or sumxt <> 0.0
  1171. -- Если в периоде нет проблемных партий
  1172. -- но по складской карточке имеется документы с ошибкой (вскрытие с ошибкой)
  1173. -- тогда необходимо вывести "Партия не подобрана" с нулевыми метриками
  1174. or rstbc_code_itwh = -1 and rstbc_code_prt > -1)
  1175.  
  1176.  
  1177. ),
  1178. rst_prt as (
  1179. -- получаем список партий с ручными списаниями и списаниями по коду партий
  1180. select
  1181. wh
  1182. , it
  1183. , prt -- идентификатор партии (@НоменклатураДокумента)
  1184. , qty rstbqty -- количественный остаток
  1185. , sumit rstbsumit -- СуммаСебест
  1186. , sumxt rstbsumxt -- СуммаСебестБезНДС
  1187. , rstbc_code
  1188. , sumit СуммаЦен
  1189. , sumxt СуммаЦенБезНДС
  1190. , True as usecst
  1191. from expense_w_code
  1192.  
  1193. where TRUE
  1194.  
  1195. -- чтобы исключить записи входящие в диалог остатков по специальным отрицательным ключам
  1196. -- Если документ сформировал партию, но просчитан с ошибкой или находится на расчете, выводим как документ
  1197. -- подкрашиваем в зависимости от состояния документа и не агрегируем в партия не подобрана
  1198. and prt is distinct from null -- wait or error or prt is not null
  1199.  
  1200. -- формирование метрик "Партия не подобрана"
  1201.  
  1202. union
  1203. select
  1204. wh
  1205. , it
  1206. , prt
  1207. , qty rstbqty -- количественный остаток
  1208. , sumit rstbsumit -- СуммаСебест
  1209. , sumxt rstbsumxt -- СуммаСебестБезНДС
  1210. , rstbc_code
  1211. , sumit СуммаЦен
  1212. , sumxt СуммаЦенБезНДС
  1213. , True as usecst
  1214. from not_prts
  1215.  
  1216. ),
  1217. page_data_doc_parts as (
  1218.  
  1219. -- ветка с партиями
  1220. SELECT
  1221. itf.it
  1222.  
  1223. , null::int pid
  1224.  
  1225. , w."Раздел" wh
  1226. , mo.main as o
  1227. , rstbsumit "СуммаСебест"
  1228. , rstbsumxt "СуммаСебестБезНДС"
  1229. , rstbqty "Количество"
  1230. , rstbc_code
  1231. , -4 "АгрегированныеМетрики"
  1232. , coalesce(nd."СкладскойДокумент", 0) dp
  1233. , (case when tn."Признаки"[7] is TRUE then COALESCE(nd."Цена", 0)
  1234. else COALESCE(pr.price, 0)
  1235. end::numeric(32,2)) * rstbqty "СуммаЦен"
  1236. , case when n."Раздел@" is true then true else null end iss
  1237. , case when n."Раздел@" is not TRUE then n."КодЕдиницаИзмерения" else null::text end as "КодЕдиницаИзмерения"
  1238. , case when n."Раздел@" is not TRUE then ((ite."ЕИУ"[1])::json->'base'->>'abbr') else null::text end as "ЕдиницаИзмеренияНазвание"
  1239. , nd."Раздел"
  1240. , n."НомНомер"
  1241. , nd."Флаги"[6] as "ЖНВЛП"
  1242. , ((ndr."Параметры")::hstore -> 'Series')::text as "Series"
  1243. , ((ndr."Параметры")::hstore -> 'ManufacturerPrice')::text as "ManufacturerPrice"
  1244. , tn."ПодвидУчета"
  1245. , case when n."Раздел@" is not true then n."НомНомер" else null::text end "Номенклатура.НомНомер"
  1246. , tn."Категория" "ТипНоменклатуры.Категория"
  1247. , ne."Article" as "NomenclatureExt.Article"
  1248. , case when (ndr."КодПартии" is null or position(' ' in ndr."КодПартии") > 0)
  1249. then 1 -- опт
  1250. when ndr."КодПартии" is not distinct from ''::varchar
  1251. then 3 -- вскрытие
  1252. when ndr."КодПартии" is not null
  1253. then 2 -- торг.зал
  1254. else NULL::integer
  1255. end::smallint "ЕГАИСРегистр"
  1256. , case (tn."Параметры"::json #>> '{suitability,precision}')::int
  1257. when 1 then ((ndr."Параметры")::hstore -> 'ExpirationDate')::text
  1258. else (regexp_split_to_array(((ndr."Параметры")::hstore -> 'ExpirationDate')::text, '\s+'))[1]
  1259. end as "СрокГодности"
  1260. , CASE
  1261. WHEN usecst AND abs(rstbqty) > power(10, -12)
  1262. THEN rstbsumit / rstbqty
  1263. ELSE
  1264.  
  1265. 0
  1266.  
  1267. END::numeric(32,6) "Себест"
  1268. , CASE
  1269. WHEN usecst AND abs(rstbqty) > power(10, -12)
  1270. THEN rstbsumxt / rstbqty
  1271. ELSE
  1272.  
  1273. 0
  1274.  
  1275. END::numeric(32,6) "СебестБезНДС"
  1276.  
  1277. FROM
  1278. rst_prt itf
  1279. LEFT JOIN "Склад" w ON itf.wh = w."@Лицо"
  1280. LEFT JOIN "Склад" w1 ON w1."@Лицо" = w."Раздел"
  1281. JOIN main_orgs mo ON mo.sub = w."НашаОрганизация"
  1282. LEFT JOIN "НоменклатураДокумента" nd on nd."@НоменклатураДокумента" = itf.prt
  1283. left join "НоменклатураДокументаРасш" ndr on ndr."@НоменклатураДокумента" = nd."@НоменклатураДокумента"
  1284. left join "Номенклатура" n on n."@Номенклатура" = itf.it
  1285. left join "НоменклатураРасш" ite on ite."@Номенклатура" = itf.it
  1286. left join nom_price_date pr on itf.it = pr.it
  1287. left join "ТипНоменклатуры" tn on tn."@ТипНоменклатуры" = n."ТипНоменклатуры"
  1288. left join "NomenclatureExt" ne ON ne."@Номенклатура" = itf.it
  1289.  
  1290.  
  1291. ),
  1292. ready_data as (
  1293.  
  1294. select
  1295. it
  1296. , pid
  1297. , wh
  1298. , o
  1299.  
  1300. , dp
  1301. , "ЖНВЛП"
  1302. , "Series"
  1303. , "ManufacturerPrice"
  1304. , "ЕГАИСРегистр"
  1305. , "СрокГодности"
  1306.  
  1307. , "СуммаСебест"
  1308. , "СуммаСебестБезНДС"
  1309. , "Количество"
  1310. , "СуммаЦен"
  1311. , "NomenclatureExt.Article"
  1312. , it "Номенклатура.@Номенклатура"
  1313. , "Номенклатура.НомНомер"
  1314. , "КодЕдиницаИзмерения"
  1315. , "ЕдиницаИзмеренияНазвание"
  1316. , "ПодвидУчета"
  1317. , "ТипНоменклатуры.Категория"
  1318. , "АгрегированныеМетрики"
  1319. , coalesce(case when rstbc_code < -2 then -1 -- для остатков на дату подкраски меньше -2 равны -1
  1320. else rstbc_code
  1321. end, 0) "Индикация"
  1322. from
  1323. page_data_doc_parts
  1324.  
  1325.  
  1326. ),
  1327. mv_group as (
  1328.  
  1329. with recursive mv as (
  1330. -- фильтруем полностью нулевые записи перед агрегацией
  1331. SELECT
  1332. it
  1333. , wh
  1334. , o
  1335.  
  1336. , dp
  1337. , "ЖНВЛП"
  1338. , "Series"
  1339. , "ManufacturerPrice"
  1340. , "ЕГАИСРегистр"
  1341. , "СрокГодности"
  1342.  
  1343. , pid
  1344. , "СуммаСебест"
  1345. , "СуммаСебестБезНДС"
  1346. , "Количество"
  1347. , "СуммаЦен"
  1348. , "NomenclatureExt.Article"
  1349. , it "Номенклатура.@Номенклатура"
  1350. , "Номенклатура.НомНомер"
  1351. , "АгрегированныеМетрики"
  1352. , "Индикация"
  1353. , "КодЕдиницаИзмерения"
  1354. , "ЕдиницаИзмеренияНазвание"
  1355. , "ПодвидУчета"
  1356. , "ТипНоменклатуры.Категория"
  1357. FROM
  1358. ready_data itwhext
  1359. ),
  1360. itagg_hierarchy as (
  1361. SELECT distinct it, pid, it as itt, array[pid] as pid_array, "Раздел@"
  1362. FROM mv
  1363. left join "Номенклатура" it
  1364. on it."@Номенклатура" = mv.pid
  1365. where it."Раздел@" is not false
  1366. union
  1367. select distinct agg.it, it."Раздел", it."@Номенклатура", pid_array || it."Раздел" , it."Раздел@"
  1368. from itagg_hierarchy agg
  1369. join "Номенклатура" it
  1370. on it."@Номенклатура" = agg.pid
  1371. where agg.pid is distinct from agg.itt
  1372. and agg."Раздел@" is not false
  1373. ),
  1374. nom_tree as(
  1375. select
  1376. pid_new
  1377. , coalesce(pid_new, it) as it_order
  1378. , ih.it
  1379. , DENSE_RANK() over w - 1 as deep
  1380. , len
  1381. , '@it-' || (lag(pid_new) over w)::text as "Раздел"
  1382. , case when pid_new is not null then true else null end::bool as "Раздел@"
  1383. from (
  1384. select pid_array[len] as pid_new
  1385. , it
  1386. , case when pid_array[len] is null then 0 else len end len
  1387. from (
  1388. select
  1389. it
  1390. , pid_array
  1391. , coalesce(array_length(pid_array, 1), 0) as len
  1392. from itagg_hierarchy
  1393. ) hs
  1394.  
  1395. -- если искомая номенклатура раздел
  1396. where true
  1397.  
  1398. and 1998::bigint = any(array(table pids))
  1399.  
  1400. -- тогда отбираем всё что ниже по иерархии
  1401. and pid_array[len] = any(array(table pids))
  1402. and pid_array[len] <> 1998::bigint
  1403. or pid_array[len] is null
  1404.  
  1405. ) ih
  1406. window w as (partition by ih.it order by len desc)
  1407. ),
  1408. itaggit as (
  1409. select distinct --on (coalesce(pid_new, ih.it))
  1410. coalesce(pid_new, ih.it) as it
  1411. , wh
  1412. , o
  1413.  
  1414. , dp
  1415. , bool_or("ЖНВЛП") over w "ЖНВЛП"
  1416. , max("Series") over w "Series"
  1417. , max("ManufacturerPrice") over w "ManufacturerPrice"
  1418. , max("ЕГАИСРегистр") over w "ЕГАИСРегистр"
  1419. , max("СрокГодности") over w "СрокГодности"
  1420.  
  1421. , deep
  1422. , ih."Раздел"
  1423. , ih."Раздел@"
  1424. , sum("СуммаСебест") over w "СуммаСебест"
  1425. , sum("СуммаСебестБезНДС") over w "СуммаСебестБезНДС"
  1426. , sum("Количество") over w "Количество"
  1427. , sum("СуммаЦен") over w "СуммаЦен"
  1428. , max("NomenclatureExt.Article") over w "NomenclatureExt.Article"
  1429. , max("Номенклатура.НомНомер") over w "Номенклатура.НомНомер"
  1430. , max("ЕдиницаИзмеренияНазвание") over w "ЕдиницаИзмеренияНазвание"
  1431. , max("ПодвидУчета") over w "ПодвидУчета"
  1432. , max("ТипНоменклатуры.Категория") over w "ТипНоменклатуры.Категория"
  1433. , min("АгрегированныеМетрики") over w "АгрегированныеМетрики"
  1434. , min("Индикация") over w "Индикация"
  1435. from nom_tree ih
  1436. left join mv on mv.it = ih.it
  1437. window w as (partition by coalesce(pid_new, ih.it), wh, o
  1438.  
  1439. , dp
  1440.  
  1441. )
  1442. ),
  1443. tree_nom as (
  1444. select
  1445. "@Номенклатура" it
  1446. , "Раздел" pid
  1447. , "Раздел@"
  1448. , "Наименование"
  1449. , "НомНомер"
  1450. , "КодЕдиницаИзмерения"
  1451. from "Номенклатура"
  1452. where "@Номенклатура" = any(array(select it_order from nom_tree))
  1453. ),
  1454. search_sort as (
  1455. with recursive rec_order AS (
  1456. SELECT
  1457. n.it,
  1458. ARRAY[ROW_NUMBER() OVER(
  1459. ORDER BY
  1460. case when n."Раздел@" is TRUE then 0 else 1 end,
  1461. n."Наименование"
  1462. )] AS order_path
  1463. FROM
  1464. tree_nom AS n
  1465. --left join itwp mv on n.it = mv.it
  1466. WHERE
  1467. n.pid is not distinct from 1998::bigint
  1468. UNION ALL
  1469. SELECT
  1470. n.it,
  1471. r.order_path || ROW_NUMBER() OVER(
  1472. PARTITION BY r.it
  1473. ORDER BY
  1474. n."Раздел@" NULLS LAST,
  1475. n."Наименование"
  1476. ) AS order_path
  1477. FROM
  1478. tree_nom AS n
  1479. --LEFT JOIN itwp mv ON n.it = mv.it
  1480. INNER JOIN rec_order AS r
  1481. ON n.pid = r.it
  1482. )
  1483. SELECT
  1484. it
  1485. , order_path
  1486. , array_length(order_path, 1) - 1 as "Глубина"
  1487. FROM
  1488. tree_nom AS n
  1489. INNER JOIN rec_order AS r USING(it)
  1490. where it is distinct from 1998::bigint
  1491. ORDER BY r.order_path
  1492. )
  1493.  
  1494. select ROW_NUMBER() OVER (ORDER BY
  1495. order_path
  1496. , itg."Раздел@" DESC NULLS LAST
  1497. , itg."Раздел"
  1498. , "Наименование"
  1499. ) number_rec
  1500. , itg.it
  1501. , itg.wh
  1502. , itg.o
  1503.  
  1504. , dp
  1505. , "ЖНВЛП"
  1506. , "Series"
  1507. , "ManufacturerPrice"
  1508. , "ЕГАИСРегистр"
  1509. , "СрокГодности"
  1510.  
  1511. , itg.deep
  1512. , itg."Раздел"
  1513. , itg."Раздел@" as "РазделНоменклатура"
  1514. , "СуммаСебест"
  1515. , "СуммаСебестБезНДС"
  1516. , "Количество"
  1517. , "СуммаЦен"
  1518. , "NomenclatureExt.Article"
  1519. , itg.it "Номенклатура.@Номенклатура"
  1520. , "Номенклатура.НомНомер"
  1521. , "КодЕдиницаИзмерения"
  1522. , "ЕдиницаИзмеренияНазвание"
  1523. , "ПодвидУчета"
  1524. , "ТипНоменклатуры.Категория"
  1525. , "АгрегированныеМетрики"
  1526. , "Индикация"
  1527. from itaggit itg
  1528. join "Номенклатура" it on it."@Номенклатура" = itg.it
  1529. left join search_sort ss on ss.it = itg.it
  1530.  
  1531. ),
  1532. get_hierarchy as (
  1533. with
  1534. dp_dimension as (
  1535. select hstore(
  1536. array_agg(keys."@Документ"::text),
  1537. array_agg(hstore(
  1538. array['Склад.Название'::text,
  1539. 'ТултипДетализации'::text,
  1540. 'ТипДокумента.@ТипДокумента'::text,
  1541. 'Документ.Время'::text,
  1542. 'Документ.Номер'::text,
  1543. 'НашаОрганизация.@Лицо'::text,
  1544. 'Документ.Дата'::text,
  1545. 'ДокументРасширение.Сумма'::text,
  1546. 'ТипДокумента.ТипДокумента'::text,
  1547. 'ТипДокумента.НазваниеКраткое'::text,
  1548. 'ИдРегламента'::text,
  1549. 'Лицо1.@Лицо'::text,
  1550. 'РП.Сотрудник.НазваниеКраткое'::text,
  1551. 'НашаОрганизация.Название'::text,
  1552. 'ТипДокумента'::text,
  1553. 'Розница'::text,
  1554. 'Лицо1.Название'::text,
  1555. 'Лицо1'::text,
  1556. 'Склад.Название2'::text,
  1557. 'Регламент.Ид'::text,
  1558. 'НазваниеДетализации'::text],
  1559. array[wh."Название"::text,
  1560. (Л1."Название"::text || ' ' || keys."Номер"::text || ' ' || keys."Лицо3"::text || ' ' || ЛС."Название"::text || ' ' || wh."Название"::text)::text,
  1561. ТД."@ТипДокумента"::text,
  1562. keys."Время"::text,
  1563. keys."Номер"::text,
  1564. keys."Лицо3"::text,
  1565. keys."Дата"::text,
  1566. dr."Сумма"::text,
  1567. ТД."ТипДокумента"::text,
  1568. ТД."НазваниеКраткое"::text,
  1569. keys."ИдРегламента"::text,
  1570. Л1."@Лицо"::text,
  1571. ЛС."Название"::text,
  1572. Лицо3."Название"::text,
  1573. keys."ТипДокумента"::text,
  1574. case when keys."Лицо1" is NULL then TRUE else FALSE end::text,
  1575. Л1."Название"::text,
  1576. keys."Лицо1"::text,
  1577. (case when ТД."ТипДокумента" = any(array['ВнутрПрм','АктВыпуска']) then (
  1578. coalesce(
  1579. (
  1580. SELECT
  1581. wrh."Название"
  1582. FROM "Склад" as wrh
  1583. WHERE
  1584. wrh."@Лицо" = (
  1585. select "Лицо2"
  1586. from "Документ"
  1587. where "@Документ" = keys."@Документ"
  1588. )
  1589. ),(
  1590. SELECT wrh."Название"
  1591. FROM "Склад" as wrh
  1592. WHERE wrh."@Лицо" = (
  1593. select dn2."СкладДополнительный"
  1594. from "СкладскойДокументРасширение" as dn2
  1595. where dn2."@Документ" = keys."@Документ"
  1596. )
  1597. )
  1598. )
  1599. ) else null::text end)
  1600. ::text,
  1601. keys."ИдРегламента"::text,
  1602. Л1."Название"::text]
  1603. )::text)
  1604. ) as hs
  1605. from "Документ" keys
  1606.  
  1607. left join "Лицо" Л1 ON keys."Лицо1" = Л1."@Лицо"
  1608. left join "ДокументРасширение" dr ON keys."@Документ" = dr."@Документ"
  1609. left join "ТипДокумента" ТД ON keys."ТипДокумента" = ТД."@ТипДокумента"
  1610. left join "Лицо" ЛС ON keys."Сотрудник" = ЛС."@Лицо"
  1611. left join "СкладскойДокумент" wd ON wd."@Документ" = keys."@Документ"
  1612. left join "Лицо" Лицо3 ON keys."Лицо3" = Лицо3."@Лицо"
  1613. left join "Склад" wh ON wh."@Лицо" = wd."Склад"
  1614. where keys."@Документ"=any(array(select dp from mv_group order by dp))
  1615.  
  1616. )
  1617.  
  1618. select
  1619. null::text as "DBId"
  1620. , count(1) as "КоличествоСтрок"
  1621. , null::int "Документ.@Документ"
  1622. , null::text "Документ.Контрагент"
  1623. , null::text "Склад.Название"
  1624. , null::text "Документ.Время"
  1625. , null::int "НашаОрганизация.@Лицо"
  1626. , null::text "Документ.Дата"
  1627. , null::NUMERIC(32,2) "ДокументРасширение.Сумма"
  1628. , null::text "ТипДокумента.ТипДокумента"
  1629. , null::text "ИдРегламента"
  1630. , null::text "РП.Сотрудник.НазваниеКраткое"
  1631. , null::text "ТипДокумента"
  1632. , null::boolean "Розница"
  1633. , null::text "Лицо1.Название"
  1634. , null::int "Лицо1"
  1635. , null::text "Склад.Название2"
  1636. , null::uuid "Регламент.Ид"
  1637. , null::int "ТипДокумента.@ТипДокумента"
  1638. , null::text "Документ.Номер"
  1639. , null::text "ТипДокумента.НазваниеКраткое"
  1640. , null::int "Лицо1.@Лицо"
  1641. , null::text "НашаОрганизация.Название"
  1642. , null::text "КодЕдиницаИзмерения"
  1643. , null::text "Номенклатура.НомНомер"
  1644. , null::text "ЕдиницаИзмеренияНазвание"
  1645. , null::text as "НазваниеДетализации"
  1646. , null::text as "Раздел"
  1647. , True as "Раздел@"
  1648. , True as "ДетализацияРаздел@"
  1649. , bool_and("РазделНоменклатура") as "РазделНоменклатура"
  1650. , -4 as "АгрегированныеМетрики"
  1651. , 'Итоги'::text as "ТипЗаписи"
  1652. , sum("СуммаЦен") "СуммаЦен"
  1653. , sum("СуммаСебестБезНДС") "СуммаСебестБезНДС"
  1654. , sum("Количество") "Количество"
  1655. , sum("СуммаСебест") "СуммаСебест"
  1656. , case when sum("Количество") <> 0
  1657. then sum("СуммаЦен") / sum("Количество")
  1658. when sum("Количество") = 0.0
  1659. then sum("СуммаЦен")
  1660. ELSE 0
  1661. END "Цена"
  1662. , case when sum("Количество") <> 0 then sum(СуммаСебестБезНДС) / sum(Количество)
  1663. else sum(СуммаСебестБезНДС) end "СебестБезНДС"
  1664. , case when array_length(array_agg("СрокГодности"), 1) = 1
  1665. then max("СрокГодности") else Null
  1666. end "СрокГодности"
  1667. , case when sum("Количество") <> 0 then sum(СуммаСебест) / sum(Количество)
  1668. else sum(СуммаСебест) end "Себест"
  1669. , min("Индикация") as "Индикация"
  1670. , max("ПодвидУчета") as "ПодвидУчета"
  1671. , max("ТипНоменклатуры.Категория") as "ТипНоменклатуры.Категория"
  1672. , max("NomenclatureExt.Article") as "NomenclatureExt.Article"
  1673. , max("ЕГАИСРегистр") as "ЕГАИСРегистр"
  1674. , max("Series") as "Series"
  1675. , max("ManufacturerPrice") as "ManufacturerPrice"
  1676. , bool_or("ЖНВЛП") as "ЖНВЛП"
  1677. from (select * from mv_group) mv
  1678. where True
  1679. and "РазделНоменклатура" is null
  1680. union all
  1681. select
  1682. ('dp-' || dp::text )::text as "DBId"
  1683. , count(1) as "КоличествоСтрок"
  1684. , dp as "Документ.@Документ"
  1685. , min((dp_dimension.hs->dp::text)::hstore->'Документ.Контрагент') as "Документ.Контрагент"
  1686. , max((dp_dimension.hs->dp::text)::hstore->'Склад.Название')::text as "Склад.Название"
  1687. , max((dp_dimension.hs->dp::text)::hstore->'Документ.Время')::text as "Документ.Время"
  1688. , max((dp_dimension.hs->dp::text)::hstore->'НашаОрганизация.@Лицо')::int as "НашаОрганизация.@Лицо"
  1689. , max((dp_dimension.hs->dp::text)::hstore->'Документ.Дата')::text as "Документ.Дата"
  1690. , max((dp_dimension.hs->dp::text)::hstore->'ДокументРасширение.Сумма')::NUMERIC(32,2) as "ДокументРасширение.Сумма"
  1691. , max((dp_dimension.hs->dp::text)::hstore->'ТипДокумента.ТипДокумента')::text as "ТипДокумента.ТипДокумента"
  1692. , max((dp_dimension.hs->dp::text)::hstore->'ИдРегламента')::text as "ИдРегламента"
  1693. , max((dp_dimension.hs->dp::text)::hstore->'РП.Сотрудник.НазваниеКраткое')::text as "РП.Сотрудник.НазваниеКраткое"
  1694. , max((dp_dimension.hs->dp::text)::hstore->'ТипДокумента')::text as "ТипДокумента"
  1695. , max((dp_dimension.hs->dp::text)::hstore->'Розница')::boolean as "Розница"
  1696. , max((dp_dimension.hs->dp::text)::hstore->'Лицо1.Название')::text as "Лицо1.Название"
  1697. , max((dp_dimension.hs->dp::text)::hstore->'Лицо1')::int as "Лицо1"
  1698. , max((dp_dimension.hs->dp::text)::hstore->'Склад.Название2')::text as "Склад.Название2"
  1699. , max((dp_dimension.hs->dp::text)::hstore->'Регламент.Ид')::uuid as "Регламент.Ид"
  1700. , max((dp_dimension.hs->dp::text)::hstore->'ТипДокумента.@ТипДокумента')::int as "ТипДокумента.@ТипДокумента"
  1701. , max((dp_dimension.hs->dp::text)::hstore->'Документ.Номер')::text as "Документ.Номер"
  1702. , max((dp_dimension.hs->dp::text)::hstore->'ТипДокумента.НазваниеКраткое')::text as "ТипДокумента.НазваниеКраткое"
  1703. , max((dp_dimension.hs->dp::text)::hstore->'Лицо1.@Лицо')::int as "Лицо1.@Лицо"
  1704. , max((dp_dimension.hs->dp::text)::hstore->'НашаОрганизация.Название')::text as "НашаОрганизация.Название"
  1705. , null::text "КодЕдиницаИзмерения"
  1706. , null::text "Номенклатура.НомНомер"
  1707. , null::text "ЕдиницаИзмеренияНазвание"
  1708. , max(coalesce((dp_dimension.hs->dp::text)::hstore->'НазваниеДетализации', 'None')) as "НазваниеДетализации"
  1709. , null::text as "Раздел"
  1710. , case when dp = 0 then null else True end as "Раздел@"
  1711. , case when dp = 0 then null else True end as "ДетализацияРаздел@"
  1712. , bool_and("РазделНоменклатура") as "РазделНоменклатура"
  1713. , -4 as "АгрегированныеМетрики"
  1714. , 'ДокументПартия' as "ТипЗаписи"
  1715. , sum("СуммаЦен") "СуммаЦен"
  1716. , sum("СуммаСебестБезНДС") "СуммаСебестБезНДС"
  1717. , sum("Количество") "Количество"
  1718. , sum("СуммаСебест") "СуммаСебест"
  1719. , case when sum("Количество") <> 0
  1720. then sum("СуммаЦен") / sum("Количество")
  1721. when sum("Количество") = 0.0
  1722. then sum("СуммаЦен")
  1723. ELSE 0
  1724. END "Цена"
  1725. , case when sum("Количество") <> 0 then sum(СуммаСебестБезНДС) / sum(Количество)
  1726. else sum(СуммаСебестБезНДС) end "СебестБезНДС"
  1727. , case when array_length(array_agg("СрокГодности"), 1) = 1
  1728. then max("СрокГодности") else Null
  1729. end "СрокГодности"
  1730. , case when sum("Количество") <> 0 then sum(СуммаСебест) / sum(Количество)
  1731. else sum(СуммаСебест) end "Себест"
  1732. , min("Индикация") as "Индикация"
  1733. , max("ПодвидУчета") as "ПодвидУчета"
  1734. , max("ТипНоменклатуры.Категория") as "ТипНоменклатуры.Категория"
  1735. , max("NomenclatureExt.Article") as "NomenclatureExt.Article"
  1736. , max("ЕГАИСРегистр") as "ЕГАИСРегистр"
  1737. , max("Series") as "Series"
  1738. , max("ManufacturerPrice") as "ManufacturerPrice"
  1739. , bool_or("ЖНВЛП") as "ЖНВЛП"
  1740. from dp_dimension, (select * from mv_group order by dp) mv
  1741. where True
  1742. and "РазделНоменклатура" is null
  1743. group by
  1744. dp
  1745.  
  1746. ),
  1747. result_metrics as (
  1748.  
  1749. SELECT * FROM get_hierarchy
  1750.  
  1751. ),
  1752. order_hierarchy as (
  1753. with recursive rec_order AS (
  1754. SELECT
  1755. n."DBId"
  1756. , ARRAY[
  1757. ROW_NUMBER() OVER(
  1758. ORDER BY
  1759. case
  1760. when n."РазделНоменклатура" is TRUE then -1
  1761. when n."DBId" like '%dp-0%' then -2
  1762. else
  1763. case
  1764. when n."Раздел@" is TRUE then 0
  1765. else 1
  1766. end
  1767. end,
  1768. n."Документ.Дата" desc, n."Документ.Время" desc, n."Документ.@Документ"
  1769. )
  1770. ] AS order_path
  1771. , array[n."DBId", n."НазваниеДетализации", n."Раздел"::text, n."Раздел@"::text, NULL::text] prep_path
  1772. FROM
  1773. result_metrics
  1774. as n
  1775. WHERE
  1776. n."Раздел" is null
  1777. UNION ALL
  1778. SELECT
  1779. n."DBId"
  1780. , r.order_path || ROW_NUMBER() OVER(
  1781. PARTITION BY "Раздел"
  1782. ORDER BY
  1783. case
  1784. when n."РазделНоменклатура" is TRUE then -1
  1785. when n."DBId" like '%dp-0%' then -2
  1786. else
  1787. case
  1788. when n."Раздел@" is TRUE then 0
  1789. else 1
  1790. end
  1791. end,
  1792. n."Документ.Дата" desc, n."Документ.Время" desc, n."Документ.@Документ"
  1793. ) AS order_path
  1794. , prep_path || array[n."DBId", n."НазваниеДетализации", n."Раздел"::text, n."Раздел@"::text, NULL::text] prep_path
  1795. FROM
  1796. result_metrics
  1797. AS n
  1798. INNER JOIN rec_order AS r ON n."Раздел" = r."DBId"
  1799. )
  1800. select
  1801. n.*
  1802. , ROW_NUMBER() OVER (ORDER BY
  1803. order_path
  1804. , "Раздел@" DESC NULLS LAST,
  1805. n."Документ.Дата" desc, n."Документ.Время" desc, n."Документ.@Документ"
  1806. ) number_rec
  1807. , "Глубина"
  1808. , prep_path
  1809. from
  1810. result_metrics
  1811. n
  1812. left join (
  1813. select
  1814. n."DBId"
  1815. , order_path
  1816. , coalesce(array_length(order_path, 1) - 1, 0) as "Глубина"
  1817. , prep_path
  1818. from
  1819. result_metrics
  1820. AS n
  1821. join rec_order AS r using("DBId")
  1822. where
  1823. n."DBId" is distinct from null
  1824. ORDER BY
  1825. r.order_path
  1826. ) ss using("DBId")
  1827. order by order_path nulls first
  1828. ),
  1829. report_hierarchy as (
  1830.  
  1831. select *
  1832. from
  1833. order_hierarchy
  1834.  
  1835. ),
  1836. query as (
  1837.  
  1838. SELECT * FROM report_hierarchy
  1839.  
  1840. limit 10000::bigint offset 0::bigint
  1841.  
  1842. )
  1843. select * from query;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement