Регистрация

"сьезжают" остатки на карточках

пользователям системы "NS2000"
Модератор
Сообщения: 407
Зарегистрирован: Чт июл 12, 2001 4:00 am

"сьезжают" остатки на карточках

Сообщение van » Ср авг 10, 2005 4:19 pm

это происходит периодически, но нерегулярно.
вследствие чего причину искать чрезвычайно трудно.
как оказалось, для многих компаний, работающих в этой системе, эта проблема не нова. и по наши данным никто ее так и не решил.
у всех работает механизм (предложенный никосом) ежесуточного пересчета документов по карточкам, который назвать решением язык не поворачивается.
предлагаю обьединить усилия в поиске причины.
давайте для начала систематизируем наблюдения по этому поводу.

Старожил
Сообщения: 85
Зарегистрирован: Чт ноя 28, 2002 12:04 pm

Сообщение AG » Чт авг 11, 2005 11:37 am

Обрисую нашу ситуацию.
Проблема такая есть: примерно раз в неделю приходится разбираться с какой-нибудь отдельной карточкой с минусовыми остатками. Наверное половина причин - это либо руки пользователя ( например документ без даты ) , либо наши технологические цепочки. половина - это неопознаные причины. Пересчитывать каждые сутки карточки у нас задача нереальная , да и ненужная, обходимся пересчетом по данной карточке.
/****************************************************/
Как мы дошли до жизни такой .
У нас 2 базы, между которыми бегают новости. Данный модуль от Никос-софта по моим сведениям серьезно переделан, убрано большое количество ошибок, которые влияли на остатки. Возможно дело в этом модуле.
/*****************************************************/
Что замечено мною:

обнаружилась следующая засада . во время сторнирования документа
перемещения ( меняет кол-во на исходящем складе , не меняет на
складе-приемнике ) кривились остатки по причине следующей ошибки:

внутренняя procedure count-inv-rem в процедуре s-iarem.p:

меняются свойства строчки документа (gdsbody.property =
gd-type.property) от вида документа . if документ явлется
документом перемещения и строчка идет на приемник и
СТРОКА ДОКУМЕНТА НЕ СТОРНИРОВАНА то меняем свойства
строчки (gdsbody.property = gd-type.prn-form-code.)
в итоге получали следующее - строка влияла и на исходящий
склад и на склад приемник . отсюда проблемы с остатками
при переводе документа из вида в вид через сторнирование
сие исправлено с помощью флага action-flag .


Код: Выделить всё
procedure count-inv-rem :
   ...............
/** change by ag 12/07/02
    if gd-type.cli-card = yes and gdsbody.incom <> gd-type.incom
      AND GDSBODY.STORNO = NO then
        gdsbody.property  = gd-type.prn-form-code.
     */   
    if gd-type.cli-card = yes and gdsbody.incom <> gd-type.incom
      AND ( GDSBODY.STORNO = NO OR action-flag = 4 ) then
        gdsbody.property  = gd-type.prn-form-code.
   .................
end procedure.
[/quote]

Модератор
Сообщения: 407
Зарегистрирован: Чт июл 12, 2001 4:00 am

Сообщение van » Чт авг 11, 2005 11:52 am

на "новости" тоже грешили, но недавно пообщались с одной компанией, у которой "новости" вообще не задействованы, но тем не менее остатки кривятся. попробую их пригласить к этому разговору

Старожил
Сообщения: 85
Зарегистрирован: Чт ноя 28, 2002 12:04 pm

Сообщение AG » Чт авг 11, 2005 11:57 am

на "новости" тоже грешили, но недавно пообщались с одной компанией, у которой "новости" вообще не задействованы, но тем не менее остатки кривятся. попробую их пригласить к этому разговору

было бы конечно очень полезно. А насколько часто у вас такое происходит ?

Модератор
Сообщения: 407
Зарегистрирован: Чт июл 12, 2001 4:00 am

Сообщение van » Чт авг 11, 2005 12:26 pm

ответ будет наверное смешным, но пока точнее не скажешь.
часто настолько, чтобы этого не замечать, и в то же время редко настолько, чтобы быстро найти причину ;)
ежесуточный пересчет все попытки поиска нивелирует, а обойтись без него тоже нельзя.. впрочем, недавно подумали, что вроде ушла проблема и сделали пересчет еженедельным, но все-равно вылез баг.
сейчас будем пристальнее наблюдать. блин, муторно это искать больше потому, что непонятно как искать. программисты сами цепочки изменения документов прогоняли, криминала не нашли. а вот когда юзеры наваливаются своей массой, вот тогда это и вылазит.. да и то не всегда.. такое впечатление, что баг провоцируется как раз совместным доступом к карточкам

Модератор
Сообщения: 407
Зарегистрирован: Чт июл 12, 2001 4:00 am

Сообщение van » Сб авг 13, 2005 8:24 am

van писал(а):с одной компанией, у которой "новости" вообще не задействованы, но тем не менее остатки кривятся. попробую их пригласить к этому разговору


у них все ключевые люди в отпусках. и у нас тоже.
так что, придется продолжить только в сентябре

Старожил
Сообщения: 85
Зарегистрирован: Чт ноя 28, 2002 12:04 pm

Сообщение AG » Пн авг 15, 2005 6:13 pm

остатки плывут также от документов без даты. это конечно все знают, но часто забывают :)

Старожил
Сообщения: 29
Зарегистрирован: Чт июл 22, 2004 3:58 pm
Откуда: г. Пермь

Re: "сьезжают" остатки на карточках

Сообщение rda » Ср авг 17, 2005 1:20 pm

van писал(а):предлагаю обьединить усилия в поиске причины.
давайте для начала систематизируем наблюдения по этому поводу.

У нас это также давняя проблема. Нашел один из багов в модуле новости (файл invchk.i, вызываемый из all-fls2.aai -> in-wareh.p), влияющий на остатки в карточках.

/* Проверяем не второй ли это сторнированный документ */
find base.invoice where
base.invoice.invoice-net = inbase.invoice.invoice-net
and base.invoice.invoice-num = inbase.invoice.invoice-num
use-index invoice-net-num no-lock no-error.

dbl_storn = no.
if available base.invoice then do:
if inbase.invoice.storno and base.invoice.storno then
dbl_storn = yes.
else do:
/* RDA 06.11.03 добавлена проверка следующей ситуации:
если по новостям пришел НЕархивный документ, а в базе уже
существует архивный документ с датой изменения ПОЗЖЕ, чем в новостях,
то делаем признак again_flag = yes (не пересчитываем остатки по документу)
*/

if inbase.invoice.storno = no and base.invoice.storno = yes and
((base.invoice.whenmod > inbase.invoice.whenmod) or
(base.invoice.whenmod = inbase.invoice.whenmod and
base.invoice.timemod > inbase.invoice.timemod)) then
again_flag = true.
end.

end.

Кстати, говоря о некорректных остатках на складских карточках, то же самое можно и сказать про бухгалтерские карточки. У нас также иногда "съезжают" остатки по ним. Боремся только пересчетами.

Старожил
Сообщения: 85
Зарегистрирован: Чт ноя 28, 2002 12:04 pm

Сообщение AG » Ср авг 17, 2005 2:12 pm

У нас это также давняя проблема. Нашел один из багов в модуле новости (файл invchk.i, вызываемый из all-fls2.aai -> in-wareh.p), влияющий на остатки в карточках.

У нас это исправлено тем же способом. Вот еще кусок из новостей: процедура in-wareh.p
Код: Выделить всё
/* 12/04/2001 A.D.Romanov пересчет остатков после приема новостей.
  ЗА*О ловить ошибки в news'ах.
*/ 
{ defsel work-file-invoice NEW }
  { all-fls2.aai "in-work.i" }
RUN n-inrem.p .

, Где n-inrem.p

Код: Выделить всё

/* ROMAN K.  Пересчет остатков по документам, пришедшим по Новостям
   CREATED: 01.04.01 21:09
   CHANGED: 01.04.01 21:09
*/

/*{ checkrem.def new }*/
{ global.i }
{ sy-sign.i }

define shared variable qbf_rec as recid no-undo.

{ defsel work-file-invoice }  /* ссылки на пришедшие документы */
/* { defsel wf-goods NEW } */
/* ссылки на карточки по пришедшим локументам (без повторений) */
DEFINE TEMP-TABLE wf-goods NO-UNDO
    FIELD t-goods-net LIKE base.goods.goods-net
    FIELD t-goods-num LIKE base.goods.goods-num
    FIELD t-inv-date  AS DATE
  /*ссылка на invoice. Если 2 документа с одной датой - считаем по первому*/
    FIELD t-inv-recid AS RECID
  INDEX i-netnum IS PRIMARY UNIQUE
    t-goods-net
    t-goods-num
    .

define new shared variable data-error  as integer no-undo.
define new shared variable exist-error as integer no-undo.
define new shared variable rem-error   as integer no-undo.
/*define variable st-code                as integer no-undo.*/
define new shared variable end-check   as logical no-undo init no.
define variable action-type-num        as int init 2 no-undo. /* Пересчет */

define variable action as character INIT "Пересчет" no-undo.
define variable num-form               as char no-undo.
define variable c-i as integer INITIAL 0 no-undo. /* invoice count */
define variable c-g as integer INITIAL 0 no-undo. /* gdsbody(goods) count */

/* define buffer goods-buf for base.goods. */
define buffer gdb-buf for base.gdsbody.
define new shared stream err-stream.
define variable ok as log init no no-undo.

FORM
  "                 ### " action NO-LABEL " ### " SKIP
  "                 Документ:" base.invoice.usr-inv-num FORMAT "x(12)" NO-LABEL
                               ":" base.invoice.gd-type-code FORMAT "999" NO-LABEL
                               " от " base.invoice.inv-date NO-LABEL SKIP
  "                    Фирма:" base.goods.firm-code NO-LABEL SKIP
  "                 Владелец:" base.goods.cli-type NO-LABEL ":" base.goods.st-code NO-LABEL SKIP
  "    Всего карточек(строк):" c-g NO-LABEL SKIP
  "          Название товара:" base.goods.gds-name FORMAT "x(30)" NO-LABEL SKIP
  "                   Партия:" base.goods.usr-gds-num NO-LABEL SKIP
  "                 ===== Ошибки =====     " SKIP
  " Остаток за неверную дату: "  data-error  NO-LABEL      SKIP
  "              Нет остатка: "  exist-error NO-LABEL      SKIP
  "     Неправильный остаток: "  rem-error NO-LABEL

WITH FRAME a2 ROW 6 CENTERED OVERLAY SIDE-LABEL
     TITLE "[Остатки на карточках в Складе (C) Nikos-Soft 2001]".

/************************************************************************/

OUTPUT STREAM err-stream TO "n-inrem.log" APPEND.

PUT STREAM err-stream
  SKIP
  action " карточек по документам, пришедшим по Новостям. Начало "
  TODAY FORMAT "99/99/9999" " " STRING(TIME,"HH:MM:SS") SKIP
  "Пользователь НОВОСТИ"
  SKIP.

FIND FIRST work-file-invoice NO-LOCK NO-ERROR.
IF NOT AVAIL work-file-invoice THEN DO:
  PUT STREAM err-stream
    SKIP
    "Нет документов, для пересчета. Конец "
    TODAY FORMAT "99/99/9999" " " STRING(TIME,"HH:MM:SS") SKIP
    .
  OUTPUT STREAM err-stream CLOSE.
  OK = YES.
  RETURN.
END.

/* собираем ссылки на карточки, чтобы не пересчитывать одну карточку неск-ко раз */
{ delwf wf-goods }
FOR EACH work-file-invoice NO-LOCK,
  FIRST base.invoice FIELDS(inv-date)
    WHERE RECID(base.invoice) = work-file-invoice.sel-rid NO-LOCK,
  EACH base.gdsbody FIELDS(goods-net goods-num) OF base.invoice WHERE
       base.gdsbody.incom = base.invoice.incom AND
       base.gdsbody.line-type = "т"
NO-LOCK:
  /* храним дату самый старого док-та, чтобы правильно установить начальную дату пересчета */
  FIND FIRST wf-goods WHERE
    wf-goods.t-goods-net = base.gdsbody.goods-net
    AND wf-goods.t-goods-num = base.gdsbody.goods-num
  NO-ERROR.
  IF NOT AVAIL wf-goods THEN DO:
    CREATE wf-goods.
    ASSIGN
      wf-goods.t-goods-net  = base.gdsbody.goods-net
      wf-goods.t-goods-num  = base.gdsbody.goods-num
      wf-goods.t-inv-date   = base.invoice.inv-date
      wf-goods.t-inv-recid  = work-file-invoice.sel-rid
      .
  END.
  ELSE IF base.invoice.inv-date < wf-goods.t-inv-date THEN
    ASSIGN
      wf-goods.t-inv-date  = base.invoice.inv-date
      wf-goods.t-inv-recid = work-file-invoice.sel-rid
      .
END.

cycle:
DO /*transaction on error undo, return error*/ :
  FOR EACH work-file-invoice NO-LOCK:
    c-i = c-i + 1.
    FIND base.invoice WHERE RECID(base.invoice) = work-file-invoice.sel-rid NO-LOCK NO-ERROR.
    IF NOT AVAIL base.invoice THEN DO:
      PUT STREAM err-stream
        "NA invoice : RECID " work-file-invoice.sel-rid SKIP.
      NEXT.
    END.

    { s-iarem.chk
      &lock = YES
      &inv-buf = base.invoice
      &is-news = YES1
    }

    FOR EACH gdb-buf FIELDS() OF base.invoice NO-LOCK,
      FIRST wf-goods WHERE wf-goods.t-goods-net = base.gdb-buf.goods-net
        AND wf-goods.t-goods-num = base.gdb-buf.goods-num
        AND wf-goods.t-inv-date = base.invoice.inv-date
        AND wf-goods.t-inv-recid = work-file-invoice.sel-rid
    NO-LOCK:
        FIND FIRST base.goods WHERE
          base.goods.goods-net      = wf-goods.t-goods-net
          AND base.goods.goods-num  = wf-goods.t-goods-num
        NO-LOCK NO-ERROR.
        IF NOT AVAILABLE goods THEN
          NEXT.
        c-g = c-g + 1.
        PAUSE 0.
        DISPLAY
          action
          base.invoice.usr-inv-num base.invoice.gd-type-code
          base.invoice.inv-date
          goods.firm-code
          goods.cli-type goods.st-code
          c-i
          c-g
          goods.gds-name
          goods.usr-gds-num
          data-error
          exist-error
          rem-error
        WITH FRAME a2.
        &SCOPED-DEFINE Start-Date base.invoice.inv-date
        /* - НЕ РАБОТАЕТ с стандартным инклудом - берем модифицированный */
        { recalgd_.i goods gdsbody YES }

    END. /* FOR gdb-buf */

    { s-iarem.chk
      &lock = NO
      &inv-buf = base.invoice
      &is-news = YES1
    }

  END.
END.

/* IF rem-error > 0 OR exist-error > 0 OR data-error > 0 THEN */
/*   PAUSE MESSAGE "Нажмите любую клавишу".                   */
/* HIDE FRAME a2 NO-PAUSE.                                    */

HIDE FRAME a2 NO-PAUSE.
IF end-check = YES THEN
  PUT STREAM err-stream
    " Работа прервана " SKIP.

PUT STREAM err-stream
  " Окончание работы "
  TODAY FORMAT "99/99/9999"
  " "
  STRING(TIME,"hh:mm:ss")
  SKIP
  " Обработано " c-i " документов, "  c-g  " карточек." SKIP
  " Итого -  Ошибки  "   SKIP
  " Остаток за неверную дату: "  data-error   SKIP
  "              Нет остатка: "  exist-error  SKIP
  "     Неправильный остаток: "  rem-error    SKIP.

OUTPUT STREAM err-stream CLOSE.




s-iarem.chk служит для блокировки пересчета, пока др. пользователь не закончит пересчет.

Старожил
Сообщения: 85
Зарегистрирован: Чт ноя 28, 2002 12:04 pm

Сообщение AG » Ср авг 17, 2005 2:13 pm

Кстати, говоря о некорректных остатках на складских карточках, то же самое можно и сказать про бухгалтерские карточки. У нас также иногда "съезжают" остатки по ним. Боремся только пересчетами.

И новости здесь похоже не при чем. Точно такая же ситуация.

Старожил
Сообщения: 29
Зарегистрирован: Чт июл 22, 2004 3:58 pm
Откуда: г. Пермь

Сообщение rda » Ср авг 17, 2005 2:37 pm

Т.е. это попытка решить проблему путем постоянного пересчета карточек по документу.
Но это же замедляет процесс встраивания новостей - получается пересчет идет дважды - сначала стандартным образом, потом еще процедурой n-inrem.p

Старожил
Сообщения: 85
Зарегистрирован: Чт ноя 28, 2002 12:04 pm

Сообщение AG » Ср авг 17, 2005 2:53 pm

Т.е. это попытка решить проблему путем постоянного пересчета карточек по документу.
Но это же замедляет процесс встраивания новостей - получается пересчет идет дважды - сначала стандартным образом, потом еще процедурой n-inrem.p

Да, именно так и получается. По времени прохождение новостей получается 2-5 минут ( при средней нагрузке 30-60 invoice ). Юзеры все равно могут конечно успевать войти в клинч с новостями, решаем эту проблему автоматическим отслеживанием и в случае зависания идет месседж юзеру, чтобы вышел из документа. Схема несколько плоха, но работает

Новичок
Сообщения: 9
Зарегистрирован: Пн авг 30, 2004 4:39 pm
Откуда: Питер

Сообщение Alexander » Пт сен 09, 2005 3:19 pm

Неужели никому так и не удалось побороть эту беду полностью?
Скажите хотя бы что это реально, код можно и не выкладывать, будем сами копать глубже.

Модератор
Сообщения: 407
Зарегистрирован: Чт июл 12, 2001 4:00 am

Сообщение van » Пн сен 19, 2005 9:54 am

imho:
для того, чтобы эта тема сдвинулась с мертвой точки, надо чтобы в этом топике начали общаться ВСЕ специалисты, сведующие в предмете.
этого увы пока нет :(
хоть приз обьявляй.. только призового фонда нет :(

попутно еще imho. чтобы понять где происходит сбой списания остатков при сохранении документа, придется еще и разобраться во всех тех дебрях проверок условий, которые логистически навешиваются в настройках за годы эксплуатации.
это бы изначально документировать и поддерживать описание актуальным, но мы например так и не сподобились.
кто-нибудь из пользователей NS документирует настройки и в каким способом?

Старожил
Сообщения: 172
Зарегистрирован: Чт июн 29, 2006 10:16 am
Откуда: Питер

А у нас - вот так

Сообщение Яр » Чт июн 29, 2006 10:55 am

При приеме новостей карточки (и складские, и бухгалтерские) вообще не пересчитываются. Вместо этого они летят в очередь на пересчет (кажется, route-news используется с каким-то левым номером сети). На серваке висит sekf-service клиент который очередь просматривает и по одной карте за транзакцию пересчитывает. Заодно такой подход решает проблему клинча юзеров с новостями.
Теоретически, разницы между теорией и практикой нет.

След.

Вернуться в NS2000

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1