/* Server version: WI-V6.3.7.18553 Firebird 2.1 
   SQLDialect: 3. ODS: 11.1. Forced writes: On. Sweep inteval: 20000.
   Page size: 8192. Cache pages: 9500 (76000 Kb). Read-only: False. */

SET SQL DIALECT 3;

ALTER TABLE STOCK DROP CONSTRAINT FK_STOCK_VAT_GROUP;

/* Alter Procedure (Before Drop)... */
SET TERM ^ ;

ALTER PROCEDURE EAI_EVO_TRANSFER$INT(ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_EAI_MAP INTEGER,
EXTERNAL_IFC VARCHAR(100),
ID_EAI_MAP_ALLINCLUSIVE INTEGER = null)
 RETURNS(ID_MAP_TAG INTEGER,
STOCK_QTY NUMERIC(15,4),
STOCK_VALUE NUMERIC(15,4),
SINGLE_PRICE NUMERIC(15,4),
GROUP_NAME VARCHAR(50),
SMETKA_LINE_IDS BLOB SUB_TYPE 1)
 AS
 BEGIN SUSPEND; END
^

ALTER PROCEDURE EAI_FRONT_SUB(ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_EAI_MAP INTEGER,
EXTERNAL_IFC VARCHAR(100),
ID_EAI_MAP_ALLINCLUSIVE INTEGER = null)
 RETURNS(ID_MAP_TAG INTEGER,
SUM_VALUE NUMERIC(15,4),
ID_STOCK_GROUP INTEGER,
SMETKA_LINE_IDS BLOB SUB_TYPE 1)
 AS
 BEGIN SUSPEND; END
^

ALTER PROCEDURE FISCALIZE_DISCOUNTS$FISC(ID_DOC_HEAD INTEGER)
 RETURNS(DISCOUNTS_SUM NUMERIC(15,4))
 AS
 BEGIN SUSPEND; END
^


/* Drop Procedure... */
ALTER PROCEDURE EAI_EVO_TRANSFER$P2E(ID_END_WORK INTEGER,
HOTEL VARCHAR(50),
ID_SMETKA_HEAD INTEGER,
ID_EAI_MAP INTEGER,
EXTERNAL_IFC VARCHAR(100),
GUEST_BOARD VARCHAR(30) = null)
 RETURNS(TAG_VALUE VARCHAR(30),
TAG_NAME VARCHAR(50),
DESCRIPTION VARCHAR(50),
TRANSFER_QTY NUMERIC(15,4),
TRANSFER_AMOUNT NUMERIC(15,4),
ALL_INCLUSIVE_PAYMENT_TYPE INTEGER,
UNIQUE_SALES_NUMBER VARCHAR(30))
 AS
 BEGIN SUSPEND; END
^

SET TERM ; ^

DROP PROCEDURE EAI_EVO_TRANSFER$INT;

SET TERM ^ ;

ALTER PROCEDURE EAI_FRONT(ID_END_WORK INTEGER,
HOTEL VARCHAR(50),
ID_SMETKA_HEAD INTEGER,
ID_EAI_MAP INTEGER,
EXTERNAL_IFC VARCHAR(100),
GUEST_BOARD VARCHAR(30) = null)
 RETURNS(TAG_VALUE VARCHAR(30),
TAG_NAME VARCHAR(50),
SUM_VALUE NUMERIC(15,4),
ALL_INCLUSIVE_PAYMENT_TYPE INTEGER,
UNIQUE_SALES_NUMBER VARCHAR(30))
 AS
 BEGIN SUSPEND; END
^

SET TERM ; ^

DROP PROCEDURE EAI_FRONT_SUB;

DROP PROCEDURE FISCALIZE_DISCOUNTS$FISC;


ALTER TABLE ARCHIVE_LINE ADD VAT_CODE NAME_10;

ALTER TABLE MENU_LINE ADD ID_VAT_GROUP ID_REF;

ALTER TABLE SMETKA_LINE ADD VAT_CODE NAME_10;

UPDATE RDB$RELATION_FIELDS SET RDB$FIELD_SOURCE='ID_REF' WHERE RDB$FIELD_NAME='ID_VAT_GROUP' AND RDB$RELATION_NAME='STOCK';

/* Alter Field (Null / Not Null)... */
UPDATE RDB$RELATION_FIELDS SET RDB$NULL_FLAG = NULL WHERE RDB$FIELD_NAME='ID_VAT_GROUP' AND RDB$RELATION_NAME='STOCK';


/* Create Procedure... */
SET TERM ^ ;

CREATE PROCEDURE EAI_EVO_BILL_TRANSFER$INT(ID_SMETKA_HEAD INTEGER,
ID_EAI_MAP INTEGER,
HOTEL VARCHAR(50),
GUEST_BOARD VARCHAR(30) = null)
 RETURNS(ID_MAP_TAG INTEGER,
STOCK_QTY NUMERIC(15,4),
STOCK_VALUE NUMERIC(15,4),
SINGLE_PRICE NUMERIC(15,4),
GROUP_NAME VARCHAR(50),
SMETKA_LINE_IDS BLOB SUB_TYPE 1,
ALL_INCLUSIVE_PAYMENT_TYPE INTEGER)
 AS
 BEGIN SUSPEND; END
^

CREATE PROCEDURE EAI_EVO_EW_TRANSFER$INT(ID_END_WORK INTEGER,
ID_EAI_MAP INTEGER,
EXTERNAL_IFC VARCHAR(100))
 RETURNS(ID_MAP_TAG INTEGER,
STOCK_QTY NUMERIC(15,4),
STOCK_VALUE NUMERIC(15,4),
GROUP_NAME VARCHAR(50))
 AS
 BEGIN SUSPEND; END
^

CREATE PROCEDURE EAI_FRONT_BILL_TRANSFER$INT(ID_SMETKA_HEAD INTEGER,
ID_EAI_MAP INTEGER,
HOTEL VARCHAR(50),
GUEST_BOARD VARCHAR(30) = null)
 RETURNS(ID_MAP_TAG INTEGER,
SUM_VALUE NUMERIC(15,4),
ID_STOCK_GROUP INTEGER,
SMETKA_LINE_IDS BLOB SUB_TYPE 1,
ALL_INCLUSIVE_PAYMENT_TYPE INTEGER)
 AS
 BEGIN SUSPEND; END
^

CREATE PROCEDURE EAI_FRONT_EW_TRANSFER$INT(ID_END_WORK INTEGER,
ID_EAI_MAP INTEGER,
EXTERNAL_IFC VARCHAR(100))
 RETURNS(ID_MAP_TAG INTEGER,
SUM_VALUE NUMERIC(15,4),
ID_STOCK_GROUP INTEGER)
 AS
 BEGIN SUSPEND; END
^


SET TERM ; ^

DROP VIEW SALE_DETAIL;

/* Create view: SALE_DETAIL */
CREATE VIEW SALE_DETAIL(
UNIQUE_SALES_NUMBER,
ID_BILL,
ID_OBJECT,
OBJECT_NAME,
SMETKA_DATE,
POS_CODE,
STOCK_NAME,
QTY,
SALE_PRICE,
DISCOUNT_SUM,
TAX_PERCENT,
TOTAL_WOT_TAX,
TOTAL_SUM,
USER_NAME,
ID_CLIENT_POS,
HOTEL_ROOM,
INCLUDED_IN_BOARD,
HOTEL_TRANSFER)
 AS 
select h.UNIQUE_SALES_NUMBER,
       h.ID_SMETKA_HEAD,
       o.ID_OBJECT,
       o.OBJECT_NAME,
       h.SMETKA_DATE,
       s.POS_CODE,
       s.STOCK_NAME,
       l.QTY,
       l.SALE_PRICE,
       l.DISCOUNT_SUM,
       l.TAX_PERCENT,
       l.NETO_WOT_TAX,
       l.NETO_SUM,
       t.USER_CREATED,
       t.ID_CLIENT_POS,
       cast(sf.ROOM_NAME || ' | ' || sf.GUEST_NAME as varchar(140)) as hotel_room,
       iif(h.ID_SMETKA_FRONT is not null and tll.ID_SMETKA_LINE is null, 1, 0) as INCLUDED_IN_BOARD,
       tl.TAG_NAME || '|' || tl.TAG_VALUE as hotel_transfer
from   SMETKA_HEAD h
       join SMETKA_LINE l on l.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD and l.STATUS > 0
       join STOCK s on s.ID_STOCK = l.ID_STOCK
       join SMETKA_TRANS t on t.ID_SMETKA_TRANS = l.ID_SMETKA_TRANS
       join RIGHT_USER u on u.USER_NAME = t.USER_CREATED
       join NOM_OBJECT o on o.ID_OBJECT = h.ID_OBJECT
       left outer join SMETKA_FRONT sf on sf.ID_SMETKA_FRONT = h.ID_SMETKA_FRONT
       left outer join EAI_P2F_TRANSFER_LOG_LINES tll on tll.ID_SMETKA_LINE = l.ID_SMETKA_LINE and sf.ID_SMETKA_FRONT is not null
       left outer join EAI_P2F_TRANSFER_LOG tl on tl.ID_EAI_P2F_TRANSFER_LOG = tll.ID_EAI_P2F_TRANSFER_LOG
union all
select h.UNIQUE_SALES_NUMBER,
       h.ID_SMETKA_HEAD,
       o.ID_OBJECT,
       o.OBJECT_NAME,
       h.SMETKA_DATE,
       s.POS_CODE,
       s.STOCK_NAME,
       l.QTY,
       l.SALE_PRICE,
       l.DISCOUNT_SUM,
       l.TAX_PERCENT,
       l.NETO_WOT_TAX,
       l.NETO_SUM,
       t.USER_CREATED,
       t.ID_CLIENT_POS,
       cast(sf.ROOM_NAME || ' | ' || sf.GUEST_NAME as varchar(140)) as hotel_room,
       iif(h.ID_SMETKA_FRONT is not null and tll.ID_SMETKA_LINE is null, 1, 0) as INCLUDED_IN_BOARD,
       tl.TAG_NAME || '|' || tl.TAG_VALUE as hotel_transfer
from   ARCHIVE_HEAD h
       join ARCHIVE_LINE l on l.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD and l.STATUS > 0
       join STOCK s on s.ID_STOCK = l.ID_STOCK
       join ARCHIVE_TRANS t on t.ID_SMETKA_TRANS = l.ID_SMETKA_TRANS
       join RIGHT_USER u on u.USER_NAME = t.USER_CREATED
       join NOM_OBJECT o on o.ID_OBJECT = h.ID_OBJECT
       left outer join ARCHIVE_FRONT sf on sf.ID_SMETKA_FRONT = h.ID_SMETKA_FRONT
       left outer join EAI_P2F_TRANSFER_LOG_LINES tll on tll.ID_SMETKA_LINE = l.ID_SMETKA_LINE and sf.ID_SMETKA_FRONT is not null
       left outer join EAI_P2F_TRANSFER_LOG tl on tl.ID_EAI_P2F_TRANSFER_LOG = tll.ID_EAI_P2F_TRANSFER_LOG
;

DROP VIEW SALE_DETAIL_OPEN_VOID;

/* Create view: SALE_DETAIL_OPEN_VOID */
CREATE VIEW SALE_DETAIL_OPEN_VOID(
UNIQUE_SALES_NUMBER,
ID_BILL,
ID_OBJECT,
OBJECT_NAME,
SMETKA_DATE,
POS_CODE,
STOCK_NAME,
QTY,
SALE_PRICE,
DISCOUNT_SUM,
TAX_PERCENT,
TAX_SUM,
TOTAL_SUM,
START_DATE,
START_TIME,
VOID_DATE,
VOID_TIME,
USER_NAME,
USER_CODE,
ID_CLIENT_POS)
 AS 
select h.UNIQUE_SALES_NUMBER,
       h.ID_SMETKA_HEAD,
       o.ID_OBJECT,
       o.OBJECT_NAME,
       h.SMETKA_DATE,
       s.POS_CODE,
       s.STOCK_NAME,
       void_l.QTY_VOID,
       l.SALE_PRICE,
       l.DISCOUNT_SUM,
       l.TAX_PERCENT,
       cast(roundto(void_l.VOID_SUM * cast(void_l.TAX_PERCENT as double precision)/(100 + void_l.TAX_PERCENT), 0.01)  as numeric(15,4)),
       --cast(iif(coalesce(l.NETO_WOT_TAX, 0) = 0, null, void_l.VOID_SUM - l.NETO_WOT_TAX) as numeric(15,4)),
       void_l.VOID_SUM,
       cast(t.START_DATE as date),
       cast(t.START_TIME as time),
       cast(m.DATETIME as date),
       cast(m.DATETIME as time),
       vu.USER_NAME,
       vu.CODE,
       t.ID_CLIENT_POS
from   SMETKA_HEAD h
       join SMETKA_LINE void_l on void_l.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD and void_l.STATUS < 0
       join SMETKA_LINE l on l.ID_SMETKA_LINE = void_l.ID_VOIDED_LINE
       join STOCK s on s.ID_STOCK = l.ID_STOCK
       join SMETKA_TRANS t on t.ID_SMETKA_TRANS = l.ID_SMETKA_TRANS
       join RIGHT_USER u on u.USER_NAME = t.USER_CREATED
       join SMETKA_MANAGE m on m.ID_SMETKA_MANAGE = void_l.ID_LINE_VOID
       join NOM_OBJECT o on o.ID_OBJECT = h.ID_OBJECT
       left outer join RIGHT_OVERRULE ro on ro.ID_RIGHT_OVERRULE = m.ID_REASON_OVERRULE
       left outer join RIGHT_USER vu on vu.USER_NAME = coalesce(ro.USER_MASTER, m.USER_NAME)
where  h.STATUS <> -3
union all
select h.UNIQUE_SALES_NUMBER,
       h.ID_SMETKA_HEAD,
       o.ID_OBJECT,
       o.OBJECT_NAME,
       h.SMETKA_DATE,
       s.POS_CODE,
       s.STOCK_NAME,
       void_l.QTY_VOID,
       l.SALE_PRICE,
       l.DISCOUNT_SUM,
       l.TAX_PERCENT,
       cast(roundto(void_l.VOID_SUM * cast(void_l.TAX_PERCENT as double precision)/(100 + void_l.TAX_PERCENT), 0.01)  as numeric(15,4)),
       void_l.VOID_SUM,
       cast(t.START_DATE as date),
       cast(t.START_TIME as time),
       cast(m.DATETIME as date),
       cast(m.DATETIME as time),
       vu.USER_NAME,
       vu.CODE,
       t.ID_CLIENT_POS
from   ARCHIVE_HEAD h
       join ARCHIVE_LINE void_l on void_l.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD and void_l.STATUS < 0
       join ARCHIVE_LINE l on l.ID_SMETKA_LINE = void_l.ID_VOIDED_LINE
       join STOCK s on s.ID_STOCK = l.ID_STOCK
       join ARCHIVE_TRANS t on t.ID_SMETKA_TRANS = l.ID_SMETKA_TRANS
       join RIGHT_USER u on u.USER_NAME = t.USER_CREATED
       join ARCHIVE_MANAGE m on m.ID_SMETKA_MANAGE = void_l.ID_LINE_VOID
       join NOM_OBJECT o on o.ID_OBJECT = h.ID_OBJECT
       left outer join RIGHT_OVERRULE ro on ro.ID_RIGHT_OVERRULE = m.ID_REASON_OVERRULE
       left outer join RIGHT_USER vu on vu.USER_NAME = coalesce(ro.USER_MASTER, m.USER_NAME)
where  h.STATUS <> -3
;

DROP VIEW SALE_DETAIL_VOID;

/* Create view: SALE_DETAIL_VOID */
CREATE VIEW SALE_DETAIL_VOID(
UNIQUE_SALES_NUMBER,
ID_BILL,
ID_OBJECT,
OBJECT_NAME,
SMETKA_DATE,
POS_CODE,
STOCK_NAME,
QTY,
SALE_PRICE,
DISCOUNT_SUM,
TAX_PERCENT,
TAX_SUM,
TOTAL_SUM,
END_DATE,
END_TIME,
VOID_DATE,
VOID_TIME,
FISCAL_DEVICE_NUMBER,
USER_NAME,
USER_CODE,
ID_CLIENT_POS,
HOTEL_ROOM,
INCLUDED_IN_BOARD,
HOTEL_TRANSFER)
 AS 
select h.UNIQUE_SALES_NUMBER,
       h.ID_SMETKA_HEAD,
       o.ID_OBJECT,
       o.OBJECT_NAME,
       h.SMETKA_DATE,
       s.POS_CODE,
       s.STOCK_NAME,
       void_l.QTY_VOID,
       l.SALE_PRICE,
       l.DISCOUNT_SUM,
       l.TAX_PERCENT,
       cast(iif(coalesce(l.NETO_WOT_TAX, 0) = 0, null, void_l.VOID_SUM - l.NETO_WOT_TAX) as numeric(15,4)),
       void_l.VOID_SUM,
       cast(t.TRANS_END as date),
       cast(t.TRANS_END as time),
       cast(m.DATETIME as date),
       cast(m.DATETIME as time),
       fd.STORNO_FISCAL_DEVICE_ID,
       vu.USER_NAME,
       vu.CODE,
       t.ID_CLIENT_POS,
       cast(sf.ROOM_NAME || ' | ' || sf.GUEST_NAME as varchar(140)) as hotel_room,
       iif(h.ID_SMETKA_FRONT is not null and tll.ID_SMETKA_LINE is null, 1, 0) as INCLUDED_IN_BOARD,
       tl.TAG_NAME || '|' || tl.TAG_VALUE as hotel_transfer
from   SMETKA_HEAD h
       join SMETKA_LINE void_l on void_l.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD and void_l.STATUS < 0
       join SMETKA_LINE l on l.ID_SMETKA_LINE = void_l.ID_VOIDED_LINE
       join STOCK s on s.ID_STOCK = l.ID_STOCK
       join SMETKA_TRANS t on t.ID_SMETKA_TRANS = l.ID_SMETKA_TRANS
       join RIGHT_USER u on u.USER_NAME = t.USER_CREATED
       join SMETKA_MANAGE m on m.ID_SMETKA_MANAGE = void_l.ID_LINE_VOID
       join NOM_OBJECT o on o.ID_OBJECT = h.ID_OBJECT
       left outer join SMETKA_FRONT sf on sf.ID_SMETKA_FRONT = h.ID_SMETKA_FRONT
       left outer join EAI_P2F_TRANSFER_LOG_LINES tll on tll.ID_SMETKA_LINE = l.ID_SMETKA_LINE and sf.ID_SMETKA_FRONT is not null
       left outer join EAI_P2F_TRANSFER_LOG tl on tl.ID_EAI_P2F_TRANSFER_LOG = tll.ID_EAI_P2F_TRANSFER_LOG
       left outer join SMETKA_FISCAL_DATA fd on fd.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD
       left outer join RIGHT_OVERRULE ro on ro.ID_RIGHT_OVERRULE = m.ID_REASON_OVERRULE
       left outer join RIGHT_USER vu on vu.USER_NAME = coalesce(ro.USER_MASTER, m.USER_NAME)
where  h.STATUS = -3
union all
select h.UNIQUE_SALES_NUMBER,
       h.ID_SMETKA_HEAD,
       o.ID_OBJECT,
       o.OBJECT_NAME,
       h.SMETKA_DATE,
       s.POS_CODE,
       s.STOCK_NAME,
       void_l.QTY_VOID,
       l.SALE_PRICE,
       l.DISCOUNT_SUM,
       l.TAX_PERCENT,
       cast(iif(coalesce(l.NETO_WOT_TAX, 0) = 0, null, void_l.VOID_SUM - l.NETO_WOT_TAX) as numeric(15,4)),
       void_l.VOID_SUM,
       cast(t.TRANS_END as date),
       cast(t.TRANS_END as time),
       cast(m.DATETIME as date),
       cast(m.DATETIME as time),
       fd.STORNO_FISCAL_DEVICE_ID,
       vu.USER_NAME,
       vu.CODE,
       t.ID_CLIENT_POS,
       cast(sf.ROOM_NAME || ' | ' || sf.GUEST_NAME as varchar(140)) as hotel_room,
       iif(h.ID_SMETKA_FRONT is not null and tll.ID_SMETKA_LINE is null, 1, 0) as INCLUDED_IN_BOARD,
       tl.TAG_NAME || '|' || tl.TAG_VALUE as hotel_transfer
from   ARCHIVE_HEAD h
       join ARCHIVE_LINE void_l on void_l.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD and void_l.STATUS < 0
       join ARCHIVE_LINE l on l.ID_SMETKA_LINE = void_l.ID_VOIDED_LINE
       join STOCK s on s.ID_STOCK = l.ID_STOCK
       join ARCHIVE_TRANS t on t.ID_SMETKA_TRANS = l.ID_SMETKA_TRANS
       join RIGHT_USER u on u.USER_NAME = t.USER_CREATED
       join ARCHIVE_MANAGE m on m.ID_SMETKA_MANAGE = void_l.ID_LINE_VOID
       join NOM_OBJECT o on o.ID_OBJECT = h.ID_OBJECT
       left outer join ARCHIVE_FRONT sf on sf.ID_SMETKA_FRONT = h.ID_SMETKA_FRONT
       left outer join EAI_P2F_TRANSFER_LOG_LINES tll on tll.ID_SMETKA_LINE = l.ID_SMETKA_LINE and sf.ID_SMETKA_FRONT is not null
       left outer join EAI_P2F_TRANSFER_LOG tl on tl.ID_EAI_P2F_TRANSFER_LOG = tll.ID_EAI_P2F_TRANSFER_LOG
       left outer join SMETKA_FISCAL_DATA fd on fd.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD
       left outer join RIGHT_OVERRULE ro on ro.ID_RIGHT_OVERRULE = m.ID_REASON_OVERRULE
       left outer join RIGHT_USER vu on vu.USER_NAME = coalesce(ro.USER_MASTER, m.USER_NAME)
where  h.STATUS = -3
;

/* Alter View (Drop, Create)... */
/* Drop altered view: BILL_NETO */
SET TERM ^ ;

ALTER PROCEDURE BILL_TAXES_CALC(ID_SMETKA_HEAD INTEGER)
 AS
 BEGIN EXIT; END
^

ALTER PROCEDURE BILL_TAXES_EVAL(ID_SMETKA_HEAD INTEGER,
ROUND_TO NUMERIC(15,4))
 AS
 BEGIN EXIT; END
^

ALTER PROCEDURE FISCALIZE_PREPARE_LINES$INT(ID_DOC_HEAD INTEGER)
 RETURNS(FISC_PRICE NUMERIC(15,4),
FISC_QTY NUMERIC(15,4),
FISC_TEXT VARCHAR(30),
FISC_GRP VARCHAR(10))
 AS
 BEGIN SUSPEND; END
^

ALTER PROCEDURE SUMMARY_DAY(ID_END_WORK INTEGER,
ID_OBJECT INTEGER,
DATE_FISCAL DATE)
 RETURNS(ERR_CODE INTEGER)
 AS
 BEGIN SUSPEND; END
^

ALTER PROCEDURE SUMMARY_STOCK(ID_END_WORK INTEGER,
ID_OBJECT INTEGER,
DATE_FISCAL DATE)
 RETURNS(ERR_CODE INTEGER)
 AS
 BEGIN SUSPEND; END
^

SET TERM ; ^

DROP VIEW BILL_NETO;

/* Create altered view: BILL_NETO */
/* Create view: BILL_NETO */
CREATE VIEW BILL_NETO(
ID_SMETKA_LINE,
ID_SMETKA_HEAD,
ID_SMETKA_TRANS,
ID_LINE_DISCOUNT,
ID_INVENT,
ID_STOCK,
ID_END_WORK,
STATUS,
BRUTO_SUM,
DISCOUNT_SUM,
NETO_SUM,
SURCHARGE_SUM,
ID_TAX_GROUP,
TAX_PERCENT,
VAT_CODE,
NETO_WOT_TAX,
VOID_SUM,
QTY,
SALE_PRICE)
 AS 
select SL.ID_SMETKA_LINE,
       SL.ID_SMETKA_HEAD,
       SL.ID_SMETKA_TRANS,
       SL.ID_LINE_DISCOUNT,
       SL.ID_INVENT,
       SL.ID_STOCK,
       SL.ID_END_WORK,
       SL.STATUS,
       SL.LINE_SUM,
       SL.DISCOUNT_SUM + coalesce((
         select sum(SM.DISCOUNT_SUM)
         from   SMETKA_MODIFFIER SM
         where  SL.ID_MOD_SESSION = SM.ID_MOD_SESSION), 0) as discount_sum,
       SL.NETO_SUM + coalesce((
         select sum(SM1.NETO_SUM)
         from   SMETKA_MODIFFIER SM1
         where  SL.ID_MOD_SESSION = SM1.ID_MOD_SESSION), 0) as neto_sum,
       SL.SURCHARGE_SUM + coalesce((
         select sum(SM2.SURCHARGE_SUM)
         from   SMETKA_MODIFFIER SM2
         where  SL.ID_MOD_SESSION = SM2.ID_MOD_SESSION), 0) as surcharge_sum,
       SL.ID_VAT,
       sl.TAX_PERCENT,
       sl.VAT_CODE,
       SL.NETO_WOT_TAX,
       SL.VOID_SUM,
       SL.QTY,
       SL.SALE_PRICE
from   SMETKA_LINE SL
;

/* Drop altered view: SECURE_OBJECT */
SET TERM ^ ;

ALTER PROCEDURE NOM_MODIFY_OBJECT_SUPPRESS(ID_CLIENT_POS INTEGER,
ID_OBJECT INTEGER,
OPERATION VARCHAR(20))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

ALTER PROCEDURE SYSTEM_LOGON_OVERRULE(ID_CLIENT_POS INTEGER,
USER_PASSWORD VARCHAR(50),
CLIENT_KIND VARCHAR(10))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
USER_NAME VARCHAR(30))
 AS
 BEGIN SUSPEND; END
^

ALTER PROCEDURE SYSTEM_LOGON_USER(ID_CLIENT_POS INTEGER,
USER_PASSWORD VARCHAR(50),
CLIENT_KIND VARCHAR(10),
ID_MULTI_PROFILE INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
ID_LANG_USER INTEGER,
ID_LOGON INTEGER,
USER_NAME VARCHAR(30),
ID_EW_NEXT INTEGER,
FISCAL_SESSION_ID INTEGER)
 AS
 BEGIN SUSPEND; END
^

SET TERM ; ^

DROP VIEW SECURE_OBJECT;

/* Create altered view: SECURE_OBJECT */
/* Create view: SECURE_OBJECT */
CREATE VIEW SECURE_OBJECT(
ID_OBJECT,
OBJECT_NAME,
TABLES,
SITES,
IS_USE,
ID_EW_NEXT,
USER_NAME)
 AS 
select distinct
    O.ID_OBJECT,
    O.OBJECT_NAME,
    O.TABLES,
    O.SITES,
    O.IS_USE,
    O.ID_EW_NEXT,
    RUG.USER_NAME
from NOM_OBJECT O
     join RIGHT_SECURE_LEVEL RSL on RSL.ID_SECURE_LEVEL = O.ID_SECURE_LEVEL
     join RIGHT_GROUP_LINE RGL on RGL.RIGHT_CODE = RSL.SECURE_RIGHT_CODE
     join RIGHT_USER_GROUP RUG on RUG.ID_RIGHT_GROUP = RGL.ID_RIGHT_GROUP
where
  RSL.REQUIRED_LEVEL = RGL.GRANTED_VALUE
union
select distinct
    O.ID_OBJECT,
    O.OBJECT_NAME,
    O.TABLES,
    O.SITES,
    O.IS_USE,
    O.ID_EW_NEXT,
    '_AUDITOR_'
from NOM_OBJECT O
where current_role = 'AUDITOR_ROLE'
union
select distinct
    O.ID_OBJECT,
    O.OBJECT_NAME,
    O.TABLES,
    O.SITES,
    O.IS_USE,
    O.ID_EW_NEXT,
    'SYSDBA'
from NOM_OBJECT O
;

/* Create Foreign Key... */
RECONNECT;

ALTER TABLE MENU_LINE ADD CONSTRAINT FK_MENU_LINE_VAT_GROUP FOREIGN KEY (ID_VAT_GROUP) REFERENCES NOM_VAT_GROUP (ID_VAT);

/*  Empty FISCALIZE_PREPARE$FISC for FISCALIZE_PREPARE_LINES$INT(param list change)  */
SET TERM ^ ;

ALTER PROCEDURE FISCALIZE_PREPARE$FISC(ID_DOC_HEAD INTEGER)
 RETURNS(UNIQUE_SALES_NUMBER VARCHAR(30),
FISCALIZATION_DETAILS VARCHAR(255),
VOID_REASON VARCHAR(30),
IS_VOID /* TYPE OF TLOGICAL */ SMALLINT,
DOC_DESCRIPTION /* TYPE OF NAME_100 */ VARCHAR(100))
 AS
 BEGIN SUSPEND; END
^

/*  Empty IMPORT_MENU_LINE$ENT for MENU_MODIFY_LINE(param list change)  */
ALTER PROCEDURE IMPORT_MENU_LINE$ENT(ID_MENU_HEAD INTEGER,
INVENT_NAME VARCHAR(30),
STOCK_NAME VARCHAR(50),
MENU_STOCK_NAME VARCHAR(50),
MENU_GROUP_NAME VARCHAR(50),
MENU_GROUP_LINK_NAME VARCHAR(50),
TAG INTEGER)
 RETURNS(ID_MENU_LINE INTEGER,
ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

/*  Empty MENU_MODIFY_MULTILINE for MENU_MODIFY_LINE(param list change)  */
ALTER PROCEDURE MENU_MODIFY_MULTILINE(ID_MENU_HEAD INTEGER,
ID_INVENT INTEGER,
ID_MENU_GROUP INTEGER,
MENU_GROUP_LINK INTEGER,
TAG INTEGER,
STOCK_LIST VARCHAR(4000),
OPERATION VARCHAR(10))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

/*  Empty IMPORT_STOCK$ENT for STOCK_MODIFY(param list change)  */
ALTER PROCEDURE IMPORT_STOCK$ENT(STOCK_NAME VARCHAR(30),
STOCK_NAME_SEARCH VARCHAR(30),
COST_PRICE NUMERIC(15,4),
STOCK_GROUP_NAME VARCHAR(30),
IS_USE SMALLINT,
POS_CODE VARCHAR(30),
NOTE VARCHAR(100),
VAT_GROUP_NAME VARCHAR(10),
IS_SERVICE SMALLINT,
IS_FREE_VOID SMALLINT,
IS_FREE_PRICE SMALLINT,
IS_MODIFIER SMALLINT,
TRADE_CODE VARCHAR(30),
UUID VARCHAR(40))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

/*  Empty BILL_POST_PRINT for SYSTEM_GET_PRINTERS(param list change)  */
ALTER PROCEDURE BILL_POST_PRINT(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
CLOSE_TYPE VARCHAR(10),
VIP_LINES INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
REPORT_NAME VARCHAR(50),
ID_PRINTER INTEGER,
REPORT_DATA VARCHAR(500))
 AS
 BEGIN SUSPEND; END
^

/*  Empty ENDWORK_PRINT for SYSTEM_GET_PRINTERS(param list change)  */
ALTER PROCEDURE ENDWORK_PRINT(ID_CLIENT_POS INTEGER,
END_WORK_KIND VARCHAR(30),
EW_USER_LIST_QUOTED VARCHAR(3000),
SERVER_OPTION VARCHAR(20),
GLOBAL_OPTION VARCHAR(20),
ID_EW_REPORT INTEGER,
ID_CURRENT_EW INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
REPORT_NAME VARCHAR(50),
REPORT_NAME_PREFIX VARCHAR(50),
ID_PRINTER INTEGER,
REPORT_DATA VARCHAR(500))
 AS
 BEGIN SUSPEND; END
^

/*  Empty MANAGE_PRINT_COPY for SYSTEM_GET_PRINTERS(param list change)  */
ALTER PROCEDURE MANAGE_PRINT_COPY(ID_CLIENT_POS INTEGER,
ID_DATA INTEGER,
DATA_TYPE VARCHAR(10))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
REPORT_NAME VARCHAR(50),
ID_PRINTER INTEGER,
REPORT_DATA VARCHAR(500))
 AS
 BEGIN SUSPEND; END
^

/* Alter empty procedure FISCALIZE_PREPARE_LINES$INT with new param-list */
ALTER PROCEDURE FISCALIZE_PREPARE_LINES$INT(ID_DOC_HEAD INTEGER)
 RETURNS(FISC_PRICE NUMERIC(15,4),
FISC_QTY NUMERIC(15,4),
FISC_TEXT VARCHAR(30),
FISC_GRP VARCHAR(10),
FISC_DISCOUNT_VALUE NUMERIC(15,4),
FISC_DISCOUNT_TEXT VARCHAR(50))
 AS
 BEGIN SUSPEND; END
^

/* Alter empty procedure MENU_MODIFY_LINE with new param-list */
ALTER PROCEDURE MENU_MODIFY_LINE(ID_MENU_LINE INTEGER,
ID_MENU_HEAD INTEGER,
ID_INVENT INTEGER,
STOCK_NAME VARCHAR(50),
ID_STOCK INTEGER,
ID_MENU_GROUP INTEGER,
MENU_GROUP_LINK INTEGER,
TAG INTEGER,
ID_VAT_GROUP INTEGER,
OPERATION VARCHAR(10))
 RETURNS(NEW_ID_MENU_LINE INTEGER,
ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

/* Alter empty procedure STOCK_MODIFY with new param-list */
ALTER PROCEDURE STOCK_MODIFY(ID_STOCK INTEGER,
STOCK_NAME VARCHAR(30),
STOCK_NAME_SEARCH VARCHAR(30),
COST_PRICE NUMERIC(15,4),
ID_STOCK_GROUP INTEGER,
IS_USE SMALLINT,
POS_CODE VARCHAR(30),
NOTE VARCHAR(100),
IS_SERVICE SMALLINT,
IS_FREE_VOID SMALLINT,
IS_FREE_PRICE SMALLINT,
IS_MODIFIER SMALLINT,
TRADE_CODE VARCHAR(30),
OPERATION VARCHAR(20))
 RETURNS(NEW_ID_STOCK INTEGER,
NEW_POS_CODE VARCHAR(30),
ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

/* Alter empty procedure SYSTEM_GET_PRINTERS with new param-list */
ALTER PROCEDURE SYSTEM_GET_PRINTERS(ID_CLIENT_POS INTEGER,
ID_INVENT INTEGER,
REPORT_CATEGORY VARCHAR(50),
IS_COPY INTEGER,
REPORT_DATA_SUB VARCHAR(500))
 RETURNS(REPORT_NAME VARCHAR(50),
ID_PRINTER VARCHAR(30),
REPORT_DATA VARCHAR(500))
 AS
 BEGIN SUSPEND; END
^

/* Alter Procedure... */
/* empty dependent procedure body */
/* Clear: BILL_POST_ADD for: BILL_POST_ADD */
ALTER PROCEDURE BILL_POST_ADD(ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_MENU_PRICE_LIST INTEGER,
ID_PRICE_LIST_OVERRULE INTEGER,
ID_STOCK INTEGER,
ID_INVENT INTEGER,
ID_VAT INTEGER,
QTY NUMERIC(15,4),
SALE_PRICE NUMERIC(15,4),
LINE_SUM NUMERIC(15,4),
ID_LINE_DISCOUNT INTEGER,
ID_LINE_VOID INTEGER,
EDIT_KIND VARCHAR(10),
ID_MASTER_LINE INTEGER,
LINE_TEXT VARCHAR(2000),
MOD_CNT INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_MOD_SESSION INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* empty dependent procedure body */
/* Clear: BILL_POST_ADD$PDA for: BILL_POST_ADD */
ALTER PROCEDURE BILL_POST_ADD$PDA(ID_CLIENT_POS INTEGER,
ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
TOTAL_SUM NUMERIC(15,4))
 AS
 BEGIN SUSPEND; END
^

/* empty dependent procedure body */
/* Clear: MANAGE_VOID_BILL for: BILL_POST_ADD */
ALTER PROCEDURE MANAGE_VOID_BILL(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_VOID_REASON INTEGER,
ID_VOID_OVERRULE INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
CLOSE_TYPE VARCHAR(10),
VIP_LINES INTEGER,
NEW_ID_SMETKA_TRANS INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* Alter (BILL_POST_ADD) */
ALTER PROCEDURE BILL_POST_ADD(ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_MENU_PRICE_LIST INTEGER,
ID_PRICE_LIST_OVERRULE INTEGER,
ID_STOCK INTEGER,
ID_INVENT INTEGER,
ID_VAT INTEGER,
QTY NUMERIC(15,4),
SALE_PRICE NUMERIC(15,4),
LINE_SUM NUMERIC(15,4),
ID_LINE_DISCOUNT INTEGER,
ID_LINE_VOID INTEGER,
EDIT_KIND VARCHAR(10),
ID_MASTER_LINE INTEGER,
LINE_TEXT VARCHAR(2000),
MOD_CNT INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_MOD_SESSION INTEGER)
 AS
declare variable cost_price numeric(15, 4);
  declare variable status integer;
  declare variable vqty numeric(15, 4);
  declare variable vsl_dbkey char(8);
  declare variable qty_post numeric(15, 4);
  declare variable qty_void numeric(15, 4);
  declare variable id_voided_discount integer;
  declare variable discount_sum numeric(15, 4);
  declare variable void_sum numeric(15, 4);
  declare variable post_status integer;
  declare variable is_service integer;
  declare variable is_use integer;
  declare variable new_line_text integer;
  declare variable tax_percent numeric(15,4);
  declare variable unique_sales_number varchar(30);
  declare variable stock_name varchar(30);
  declare variable object_name varchar(30);
  declare variable smetka_date date;
  declare variable smetka_num integer;
  declare variable fiscal_device_id varchar(10);
  declare variable new_id_line_void integer;
  declare variable id_client_pos integer;
  declare variable id_void_reason integer;
  declare variable id_transfer_source_line integer;
  declare variable vat_code varchar(10);
begin
  execute procedure FISCAL_DEVICE_STATUS_CHECK(null)
  returning_values :fiscal_device_id;

  err_code = 0;
  err_text = '';
  void_sum = 0;
  new_line_text = 0;
  id_transfer_source_line = null;

  select S.COST_PRICE, S.IS_SERVICE, s.IS_USE, s.STOCK_NAME
  from   STOCK S
  where  S.ID_STOCK = :id_stock
  into   :cost_price, :is_service, :is_use, :stock_name;
  if (:is_use = 0 and coalesce(:EDIT_KIND, '') = '') then begin
    ERR_CODE = -311;
    ERR_TEXT = :stock_name;
    exit;
  end
  if (:is_service = 1) then post_status = -3;
  else post_status = 1;

  select tg.TAXES_VALUE, tg.VAT_CODE
  from   TAX_GROUP TG
  where  TG.ID_TAX_GROUP = :ID_VAT
  into   :tax_percent, :vat_code;

  if (:edit_kind in ('EDIT_VOID', 'EDIT_MOVE', '')) then begin
    if (:id_line_discount is not null) then begin
      select SD.DISCOUNT_SUM
      from   SMETKA_DISCOUNT SD
      where  SD.ID_SMETKA_DISCOUNT = :id_line_discount
      into   :discount_sum;
    end else discount_sum = 0;

    if (:edit_kind in ('EDIT_VOID', 'EDIT_MOVE')) then begin
      select SL.RDB$DB_KEY, SL.ID_LINE_DISCOUNT, SL.QTY, SL.QTY_POST, SL.QTY_VOID,
             SL.ID_MOD_SESSION, s.STOCK_NAME, h.UNIQUE_SALES_NUMBER, o.OBJECT_NAME,
             h.SMETKA_DATE, h.SMETKA_NUM
      from   SMETKA_LINE SL
             join STOCK s on s.ID_STOCK = sl.ID_STOCK
             join SMETKA_HEAD h on h.ID_SMETKA_HEAD = sl.ID_SMETKA_HEAD
             join NOM_OBJECT o on o.ID_OBJECT = h.ID_OBJECT
      where  SL.ID_SMETKA_LINE = :id_master_line
      into   :vsl_dbkey, :id_voided_discount, :vqty, :qty_post, :qty_void,
             :new_id_mod_session, :stock_name, :unique_sales_number, :object_name,
             :smetka_date, :smetka_num;

      if (:vqty < :qty) then begin
        err_code = -1;
        err_text = 'QTY_FOR_VOID='||:qty||', QTY_NALICH='||:vqty||'ID_SMETKA_LINE'||:ID_MASTER_LINE;
        exit;
      end else if (:qty = 0) then status = -10;
      else status = 1;
      if (:edit_kind = 'EDIT_VOID') then begin
        qty_void = (:qty_void + (:vqty - :qty));
        qty_post = :qty_post;

        update SMETKA_LINE SL
        set    SL.ID_LINE_DISCOUNT = :id_line_discount,
               SL.DISCOUNT_SUM = :discount_sum,
               SL.LINE_SUM     = :line_sum,
               SL.STATUS       = :status,
               SL.QTY_VOID     = :qty_void,
               SL.QTY_POST     = :qty_post,
               SL.QTY          = :qty,
               SL.NETO_SUM     = :line_sum
        where  SL.RDB$DB_KEY = :vsl_dbkey;
    
        if (:id_voided_discount is not null) then begin
          delete from SMETKA_DISCOUNT SD
          where SD.ID_SMETKA_DISCOUNT = :id_voided_discount;
        end
  
        execute procedure SYSTEM_LOG_ADD('BILL', :ID_SMETKA_HEAD, 'BILL_LINE_VOID',
                f_character(29) || :stock_name || f_character(28) || :smetka_num || f_character(28) || :object_name || f_character(28)
                || :smetka_date || f_character(28) || float_to_str(:qty_void, 'F;0.0') || f_character(28)
                || float_to_str(:sale_price, 'F;0.00') || f_character(28) || :unique_sales_number);

      end else if (:edit_kind = 'EDIT_MOVE') then begin
        execute procedure BILL_POST_ADD(:ID_END_WORK, :ID_SMETKA_HEAD, :ID_SMETKA_TRANS,
                :ID_MENU_PRICE_LIST, :ID_PRICE_LIST_OVERRULE, :ID_STOCK, :ID_INVENT, :ID_VAT,
                :QTY, :SALE_PRICE, :qty * :SALE_PRICE, :ID_LINE_DISCOUNT, null, 'EDIT_VOID',
                :ID_MASTER_LINE, :LINE_TEXT, 0)
        returning_values (:ERR_CODE, :ERR_TEXT, :NEW_ID_MOD_SESSION);
        if (:ERR_CODE <> 0) then exit;

        id_client_pos = RDB$GET_CONTEXT('USER_SESSION', 'ID_CLIENT_POS');

        execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'TRANSFER_VOID')
        returning_values (:id_void_reason);

        execute procedure BILL_POST_ADD_VOID (RDB$GET_CONTEXT('USER_SESSION', 'ID_CLIENT_POS'),
                :ID_SMETKA_HEAD, :id_void_reason, :ID_PRICE_LIST_OVERRULE)
        returning_values (:ERR_CODE, :ERR_TEXT, :new_id_line_void);
        if (:ERR_CODE <> 0) then exit;

        qty = :vqty - :qty;
        execute procedure BILL_POST_ADD(:ID_END_WORK, :ID_SMETKA_HEAD, :ID_SMETKA_TRANS,
                :ID_MENU_PRICE_LIST, :ID_PRICE_LIST_OVERRULE, :ID_STOCK, :ID_INVENT, :ID_VAT,
                :qty, :SALE_PRICE, :qty*:SALE_PRICE, :ID_LINE_DISCOUNT, :new_id_line_void, 'OLD',
                :ID_MASTER_LINE, '<void>'||:LINE_TEXT, 0)
        returning_values (:ERR_CODE, :ERR_TEXT, :NEW_ID_MOD_SESSION);
        if (:ERR_CODE <> 0) then exit;
      end

      exit;
    end
    if (:id_master_line is not null) then begin
      /* SPLITTING IS GOING ON  */
      select SL.ID_MOD_SESSION, sl.ID_TRANSFER_SOURCE_LINE
      from   SMETKA_LINE SL
      where  SL.ID_SMETKA_LINE = :id_master_line
      into   :new_id_mod_session, :id_transfer_source_line;

      id_transfer_source_line = coalesce(:id_transfer_source_line, :ID_MASTER_LINE);
      id_master_line = null;
    end else begin
      new_line_text = 1;
      new_id_mod_session = gen_id(gen_mod_session_id, 1);
      if (:mod_cnt = 0) then new_id_mod_session = -1*:new_id_mod_session;
    end
    qty_void = 0;
    qty_post = :qty;
    status = 1;
  end else begin
    /* PREPARING DATA FOR VOID LINES */
    qty_void = :qty;
    qty_post = 0;
    id_line_discount = null;
    discount_sum = 0;
    if (:edit_kind = 'CURRENT') then begin
      new_id_mod_session = gen_id(gen_mod_session_id, 1);
      status = -20;
      id_master_line = gen_id(gen_smetka_line_id, 1);
      insert into SMETKA_LINE (ID_SMETKA_LINE, ID_SMETKA_TRANS, ID_SMETKA_HEAD, ID_STOCK, ID_INVENT,
        QTY, QTY_POST, QTY_VOID, COST_PRICE, SALE_PRICE, LINE_SUM, VOID_SUM, ID_MENU_PRICE_LIST,
        ID_VOIDED_LINE, ID_LINE_VOID, ID_LINE_DISCOUNT, POST_STATUS, STATUS, ID_VAT, DISCOUNT_SUM,
        ID_PRICE_LIST_OVERRULE, ID_END_WORK, ID_MOD_SESSION, NETO_SUM, TAX_PERCENT, VAT_CODE,
        ID_TRANSFER_SOURCE_LINE)
      values (:id_master_line, :id_smetka_trans, :id_smetka_head, :id_stock, :id_invent,
        0, :qty, :qty, :cost_price, :sale_price, 0, 0, :id_menu_price_list,
        null, null, null, :post_status, :status, :id_vat, 0,
        :id_price_list_overrule, :id_end_work, :new_id_mod_session, 0, :tax_percent, :vat_code,
        :id_transfer_source_line);

      new_line_text = 1;
    end else if (:edit_kind = 'OLD') then begin
      select SL.ID_MOD_SESSION
      from   SMETKA_LINE SL
      where  SL.ID_SMETKA_LINE = :id_master_line
      into   :new_id_mod_session;
      status = -10;
    end
    qty = 0; /* VOIDING LINES ARE WITH 0 VALID QTY */
    void_sum = :line_sum;
    line_sum = 0;
  end

  if (:new_line_text = 1) then begin
    insert into SMETKA_LINE_TEXT(ID_MOD_SESSION, ID_END_WORK, LINE_TEXT)
    values (:new_id_mod_session, :id_end_work, :line_text);
  end


  insert into SMETKA_LINE (ID_SMETKA_TRANS, ID_SMETKA_HEAD, ID_STOCK, ID_INVENT,
    QTY, QTY_POST, QTY_VOID, COST_PRICE, SALE_PRICE, LINE_SUM, VOID_SUM,
    ID_MENU_PRICE_LIST,
    ID_VOIDED_LINE, ID_LINE_VOID, ID_LINE_DISCOUNT, POST_STATUS, STATUS, ID_VAT,
    DISCOUNT_SUM, ID_PRICE_LIST_OVERRULE, ID_END_WORK,
    ID_MOD_SESSION, NETO_SUM, TAX_PERCENT, VAT_CODE, ID_TRANSFER_SOURCE_LINE)
  values (:id_smetka_trans, :id_smetka_head, :id_stock, :id_invent,
    :qty, :qty_post, :qty_void, :cost_price, :sale_price, :line_sum, :void_sum,
    :id_menu_price_list,
    :id_master_line, :id_line_void, :id_line_discount, :post_status, :status, :id_vat,
    :discount_sum, :id_price_list_overrule, :id_end_work,
    :new_id_mod_session, :line_sum, :tax_percent, :vat_code, :id_transfer_source_line);

END
^

/* empty dependent procedure body */
/* Clear: BILL_POST_FINALIZE$PDA for: BILL_POST_ADD$PDA */
ALTER PROCEDURE BILL_POST_FINALIZE$PDA(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
TABLE_NO INTEGER,
ID_MANUAL_MENU INTEGER,
ID_END_WORK INTEGER,
CUSTOMER_CNT INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

/* Alter (BILL_POST_ADD$PDA) */
ALTER PROCEDURE BILL_POST_ADD$PDA(ID_CLIENT_POS INTEGER,
ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
TOTAL_SUM NUMERIC(15,4))
 AS
declare variable post_price numeric(15,4);
  declare variable stock_name varchar(50);
  declare variable pbp_dbkey char(8);
  declare variable base_dbkey char(8);
  declare variable int_mod_cnt integer;
  declare variable int_base_price numeric (15,4);
  declare variable int_line_text varchar(2000);

  declare variable id_menu_price_list integer;
  declare variable id_stock integer;
  declare variable post_qty numeric(15,4);
  declare variable base_tot_price numeric(15,4);
  declare variable mod_price numeric(15,4);

  declare variable id_invent integer;
  declare variable is_modifier integer;
  declare variable id_vat integer;
  declare variable line_sum numeric(15,4);
  declare variable line_text varchar(2000);
  declare variable mod_cnt integer;
  declare variable new_id_mod_session integer;
begin
  err_code = 0;
  err_text = '';

  base_dbkey = null;
  for
    select PBP.RDB$DB_KEY, PBP.POST_PRICE, S.IS_MODIFIER, F_FIRSTUPPERCASE(S.STOCK_NAME)
    from   PDA_BILL_POST PBP
           join STOCK S on S.ID_STOCK = PBP.ID_STOCK
    where  PBP.ID_SESSION = current_connection
    order by PBP.ID_PDA_POST
    into   :pbp_dbkey, :post_price, :is_modifier, :stock_name
  do begin
    if (:is_modifier = 1) then begin
      update PDA_BILL_POST PBPU
      set    PBPU.INT_BASE_PRICE = :post_price,
             PBPU.INT_MOD_CNT = 0,
             PBPU.INT_LINE_TEXT = ''
      where  PBPU.RDB$DB_KEY = :pbp_dbkey;
      int_base_price = :int_base_price + :post_price;
      int_mod_cnt = :int_mod_cnt + 1;
      int_line_text = :int_line_text || F_CRLF() || '    -' || :stock_name;
    end else if (:base_dbkey is not null) then begin
      update PDA_BILL_POST PBPU
      set    PBPU.INT_BASE_PRICE = :int_base_price,
             PBPU.INT_MOD_CNT = :int_mod_cnt,
             PBPU.INT_LINE_TEXT = :int_line_text
      where  PBPU.RDB$DB_KEY = :base_dbkey;
      base_dbkey = null;
    end
    if (:base_dbkey is null) then begin
      base_dbkey = :pbp_dbkey;
      int_base_price = :post_price;
      int_mod_cnt = 0;
      int_line_text = :stock_name;
    end
  end
  if (:base_dbkey is not null) then begin
    update PDA_BILL_POST PBPU
    set    PBPU.INT_BASE_PRICE = :int_base_price,
           PBPU.INT_MOD_CNT = :int_mod_cnt,
           PBPU.INT_LINE_TEXT = :int_line_text
    where  PBPU.RDB$DB_KEY = :base_dbkey;
  end
  new_id_mod_session = null;
  total_sum = 0;
  for
    select PBP.ID_MENU_PRICE_LIST, PBP.ID_STOCK, PBP.POST_QTY, PBP.INT_BASE_PRICE, PBP.POST_PRICE,
           PBP.INT_MOD_CNT, PBP.INT_LINE_TEXT, S.IS_MODIFIER
    from   PDA_BILL_POST PBP
           join STOCK S on S.ID_STOCK = PBP.ID_STOCK
    where  PBP.ID_SESSION = current_connection
    order by PBP.ID_PDA_POST
    into   :id_menu_price_list, :id_stock, :post_qty, :base_tot_price, :mod_price,
           :mod_cnt, :line_text, :is_modifier
  do begin
    select ML.ID_INVENT, ml.ID_VAT_GROUP
    from   MENU_PRICE_LIST MPL
           join MENU_LINE ML on ML.ID_MENU_HEAD = MPL.ID_MENU_HEAD
    where  MPL.ID_MENU_PRICE_LIST = :id_menu_price_list
           and ML.ID_STOCK = :id_stock
    into   :id_invent, :id_vat;

    if (:is_modifier = 0) then begin
      line_sum = roundto(:post_qty * :base_tot_price, 0.01);
      execute procedure BILL_POST_ADD(:id_end_work, :id_smetka_head, :id_smetka_trans, :id_menu_price_list,
              null, :id_stock, :id_invent, :id_vat, :post_qty, :base_tot_price, :line_sum, null, null, '',
              null, :line_text, :mod_cnt)
      returning_values  :err_code, :err_text, :new_id_mod_session;
      if (:err_code < 0) then exit;
    end else begin
      line_sum = 0;

      insert into SMETKA_MODIFFIER (ID_END_WORK, ID_MOD_SESSION, ID_STOCK, SALE_PRICE, NETO_SUM, SURCHARGE_SUM, DISCOUNT_SUM)
      values (:id_end_work, :new_id_mod_session, :id_stock, :mod_price, null, 0, 0);
    end
    total_sum = :total_sum + :line_sum;
  end

  delete from PDA_BILL_POST PBP where PBP.ID_SESSION = current_connection;
end
^

/* Alter (BILL_POST_FINALIZE$PDA) */
ALTER PROCEDURE BILL_POST_FINALIZE$PDA(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
TABLE_NO INTEGER,
ID_MANUAL_MENU INTEGER,
ID_END_WORK INTEGER,
CUSTOMER_CNT INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable new_lines_sum numeric(15,4);
  declare variable new_id_smetka_trans integer;
  declare variable id_smetka_discount integer;
  declare variable id_contragent_ integer;
  declare variable card_code_ varchar(50);

  declare variable id_surcharge_ integer;
  declare variable surcharge_value numeric(15,4);
  declare variable is_percent_surcharge integer;
  declare variable cnt_lines integer;
  declare variable cnt_voids integer;
  declare variable total_sum numeric(15,4);
  declare variable discount_sum numeric(15,4);
  declare variable surcharge_sum numeric(15,4);
  declare variable grand_total_sum numeric(15,4);
  declare variable vip_lines integer;

  declare variable id_discount integer;
  declare variable is_percent_discount integer;
  declare variable discount_base numeric(15,4);
  declare variable discount_value numeric(15,4);

  declare variable open_type varchar(20);
  declare variable close_type varchar(20);
  declare variable discount_status integer;
  declare variable id_discount_overrrule integer;
  declare variable smetka_num varchar(20);
  declare variable no_use varchar(100);
begin
  err_code = 0;
  err_text = '';
  if (:id_smetka_head > 0) then open_type = 'OPEN';
  else open_type = 'CREATE';

  execute procedure BILL_OPEN(:id_client_pos, :id_smetka_head, :table_no, :customer_cnt, 'OPEN', :id_end_work)
  returning_values  :err_code, :err_text, :id_smetka_head, :new_id_smetka_trans,
                    :no_use, :no_use, :no_use, :id_contragent_,
                    :no_use, :id_smetka_discount, :id_surcharge_, :no_use,
                    :surcharge_value, :is_percent_surcharge, :id_discount, :is_percent_discount,
                    :no_use, :discount_status, :discount_value, :no_use,
                    :no_use, :no_use, :card_code_;
  if (:err_code < 0) then exit;

  execute procedure BILL_POST_ADD$PDA(:id_client_pos, :id_end_work, :id_smetka_head, :new_id_smetka_trans)
  returning_values  :err_code, :err_text, :new_lines_sum;
  if (:err_code < 0) then exit;

  select sum(iif(SL.STATUS < 0, 0, SL.LINE_SUM)),
         sum(iif((SL.STATUS < 0) or (SL.ID_LINE_DISCOUNT is not null), 0, SL.LINE_SUM)),
         count(SL.ID_SMETKA_LINE),
         count(iif(SL.STATUS < 0, SL.ID_SMETKA_LINE, null))
  from   SMETKA_LINE SL
  where  SL.ID_SMETKA_HEAD = :id_smetka_head
  into   :total_sum, :discount_base, :cnt_lines, :cnt_voids;

  if (:id_discount is not null) then begin
    if (:is_percent_discount = 1) then begin
      discount_sum = roundto((:discount_value/100.00) * :discount_base, 0.01);
    end else discount_sum = :discount_value;
    if (:id_smetka_discount is not null) then begin
      select SD.ID_RIGHT_OVERRULE
      from   SMETKA_DISCOUNT SD
      where  SD.ID_SMETKA_DISCOUNT = :id_smetka_discount
      into   :id_discount_overrrule;
    end else id_discount_overrrule = null;
    execute procedure BILL_POST_ADD_DISC(:id_end_work, :id_smetka_head, :id_discount, :discount_status,
            :discount_base, :discount_value, :discount_sum, :id_discount_overrrule)
    returning_values  :err_code, :err_text, :id_smetka_discount;
    if (:err_code < 0) then exit;
  end else discount_sum = 0;

  if (:id_surcharge_ is not null) then begin
    if (:is_percent_surcharge = 1) then begin
      surcharge_sum = roundto((:surcharge_value/100.00) * (:total_sum - :discount_sum), 0.01);
    end else surcharge_sum = :surcharge_value;
  end else surcharge_sum = 0;

  grand_total_sum = :total_sum - :discount_sum + :surcharge_sum;
  if (:open_type = 'CREATE' and :cnt_lines = 0) then close_type = 'CANCEL';
  else close_type = 'ORDER';
  execute procedure BILL_POST_FINALIZE(:id_client_pos, :id_end_work, :id_smetka_head, :new_id_smetka_trans,
          :id_smetka_discount, :id_contragent_, null, :open_type,
          :close_type, :id_manual_menu, :id_surcharge_, :surcharge_value, :cnt_lines,
          :cnt_voids, :total_sum, :discount_sum, :surcharge_sum, :grand_total_sum,
          :customer_cnt, :card_code_)
  returning_values  :err_code, :err_text, :vip_lines;
  if (:err_code < 0) then exit;

  execute procedure BILL_POST_FINALIZE_NUM(:id_client_pos, :id_smetka_head, :new_id_smetka_trans, :close_type, null)
  returning_values  :err_code, :err_text, :smetka_num;
  if (:err_code < 0) then exit;

  execute procedure BILL_POST_PRINT$PDA(:id_client_pos, :id_smetka_head, :new_id_smetka_trans, :close_type, :vip_lines)
  returning_values  :err_code, :err_text;
end
^

/* Alter (BILL_POST_GETLINES) */
ALTER PROCEDURE BILL_POST_GETLINES(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER)
 RETURNS(ID_SMETKA_LINE INTEGER,
ID_STOCK INTEGER,
ID_INVENT INTEGER,
ID_MENU_PRICE_LIST INTEGER,
STOCK_NAME VARCHAR(2000),
ID_VAT INTEGER,
VAT_GROUP VARCHAR(10),
VAT_VALUE NUMERIC(15,4),
QTY NUMERIC(15,4),
SALE_PRICE NUMERIC(15,4),
ID_DISCOUNT INTEGER,
DISCOUNT_NAME VARCHAR(50),
DISCOUNT_VALUE NUMERIC(15,4),
IS_PERCENT INTEGER,
IS_VOID INTEGER,
ID_MASTER_LINE INTEGER)
 AS
declare variable qty_post numeric(15, 4);
  declare variable qty_void numeric(15, 4);
begin
  for
    select SL.ID_SMETKA_LINE, SL.ID_MENU_PRICE_LIST, SL.QTY_POST, SL.QTY_VOID,
           SL.SALE_PRICE, SD.ID_DISCOUNT, D.DISCOUNT_NAME, SD.DISCOUNT_VALUE,
           D.IS_PERCENT, SL.ID_VOIDED_LINE, SL.ID_VAT, SL.VAT_CODE, sl.TAX_PERCENT,
           SLT.LINE_TEXT, SL.ID_INVENT, SL.ID_STOCK
    from   SMETKA_LINE SL
           join SMETKA_LINE_TEXT SLT on SLT.ID_MOD_SESSION = SL.ID_MOD_SESSION
           left outer join SMETKA_DISCOUNT SD on SD.ID_SMETKA_DISCOUNT = SL.ID_LINE_DISCOUNT
           left outer join NOM_DISCOUNT D on D.ID_DISCOUNT = SD.ID_DISCOUNT
    where  SL.ID_SMETKA_HEAD = :id_smetka_head
           and SL.STATUS > -20
    order by SL.ID_SMETKA_LINE asc
    into   :id_smetka_line, :id_menu_price_list, :qty_post, :qty_void,
           :sale_price, :id_discount, :discount_name, :discount_value,
           :is_percent, :id_master_line, :id_vat, :vat_group, :vat_value,
           :stock_name, :id_invent, :id_stock
  do begin
    if (:id_master_line is not null) then begin
      is_void = 1;
      qty = :qty_void;
    end else begin
      is_void = 0;
      qty = :qty_post;
    end
    suspend;
  end
END
^

/* Alter (BILL_POST_GETMENU) */
ALTER PROCEDURE BILL_POST_GETMENU(ID_MENU_PRICE_LIST INTEGER)
 RETURNS(ID_STOCK INTEGER,
ID_INVENT INTEGER,
ID_MENU_GROUP INTEGER,
POS_CODE VARCHAR(30),
STOCK_NAME VARCHAR(50),
POST_TEXT VARCHAR(50),
IS_FREE_VOID INTEGER,
IS_FREE_PRICE INTEGER,
IS_MODIFIER INTEGER,
MENU_GROUP_LINK INTEGER,
SALE_PRICE NUMERIC(15,4),
ID_VAT INTEGER,
VAT_GROUP VARCHAR(10),
VAT_VALUE NUMERIC(15,4),
IS_STOCKOUT INTEGER,
AVAILABLE_QTY NUMERIC(15,4))
 AS
declare variable id_menu_head integer;
  declare variable price_list_type varchar(30);
  declare variable profit_percent numeric(15, 4);
  declare variable round_dec numeric(15, 4);
  declare variable cost_price numeric(15, 4);
  declare variable base_price numeric(15, 4);
  declare variable base_price_list integer;
  declare variable id_menu_line integer;
begin
  id_invent = null;
  id_stock = null;
  sale_price = null;
  vat_group = null;
  vat_value = null;

  select MPL.PRICE_LIST_TYPE, MPL.ROUND_DEC, MPL.ID_MENU_HEAD
  from   MENU_PRICE_LIST MPL
  where  MPL.ID_MENU_PRICE_LIST = :id_menu_price_list
  into   :price_list_type, :round_dec, :id_menu_head;

  for
    select MG.ID_MENU_GROUP, f_firstuppercase(MG.MENU_GROUP_NAME)
    from   MENU_GROUP MG
    where  exists(
             select ML.ID_MENU_GROUP
             from   MENU_LINE ML
             where  ML.ID_MENU_HEAD = :id_menu_head
                    and MG.ID_MENU_GROUP = ML.ID_MENU_GROUP
           )
    order by MG.SORT_NUM, MG.MENU_GROUP_NAME
    into   :id_menu_group, :stock_name
  do suspend;

  if (:price_list_type = 'BASE_PERCENT') then
    select MPL.ID_MENU_PRICE_LIST
    from   MENU_PRICE_LIST MPL
    where  MPL.ID_MENU_HEAD = :id_menu_head
           and MPL.IS_BASE = 1
    into   :base_price_list;

  for
    select ML.ID_INVENT, ML.ID_STOCK, ML.STOCK_NAME, ML.ID_MENU_GROUP,
           MLP.SALE_PRICE, MLP.PROFIT_PERCENT, ML.ID_MENU_LINE, S.POS_CODE,
           S.IS_FREE_VOID, S.IS_FREE_PRICE, TG.VAT_CODE, TG.TAXES_VALUE, TG.ID_TAX_GROUP,
           S.COST_PRICE, f_firstuppercase(S.STOCK_NAME),
           S.IS_MODIFIER, ML.MENU_GROUP_LINK, case when 0 = coalesce(SS.qty_available, -1) then 1 else 0 end,
           SS.qty_available
    from   MENU_LINE ML
           join MENU_GROUP MG on MG.ID_MENU_GROUP = ML.ID_MENU_GROUP
           join MENU_LINE_PRICE MLP on MLP.ID_MENU_LINE = ML.ID_MENU_LINE
           join MENU_HEAD MH on MH.ID_MENU_HEAD = ML.ID_MENU_HEAD
           join STOCK S on S.ID_STOCK = ML.ID_STOCK and S.IS_USE = 1
           left join TAX_GROUP TG on TG.ID_TAX_GROUP = ML.ID_VAT_GROUP
           left outer join SMETKA_STOCKOUT SS on SS.ID_STOCK = ML.ID_STOCK
                           and SS.ID_OBJECT = MH.ID_OBJECT
    where  MLP.ID_MENU_PRICE_LIST = :id_menu_price_list
    order by MG.SORT_NUM, MG.MENU_GROUP_NAME, ML.STOCK_NAME asc
    into   :id_invent, :id_stock, :stock_name, :id_menu_group,
           :sale_price, :profit_percent, :id_menu_line, :pos_code,
           :is_free_void, :is_free_price, :vat_group, :vat_value, :id_vat,
           :cost_price, :post_text,
           :is_modifier, :menu_group_link, :is_stockout, :available_qty
  do begin
    if (:price_list_type = 'PRICE') then begin
      if (:sale_price is not null) then begin
        sale_price = RoundTo(:sale_price, :round_dec);
        suspend;
      end
    end else if (:price_list_type = 'COST_PERCENT') then begin
      if ((:cost_price is not null) and  (:profit_percent is not null)) then begin
        sale_price = RoundTo(:cost_price + :cost_price*(:profit_percent/100), :round_dec);
        suspend;
      end
    end else if (:price_list_type = 'BASE_PERCENT') then begin
      select MLP.SALE_PRICE
      from   MENU_LINE_PRICE MLP
      where  MLP.ID_MENU_PRICE_LIST = :base_price_list
             and MLP.ID_MENU_LINE = :id_menu_line
      into   :base_price;
      if ((:base_price is not null) and  (:profit_percent is not null)) then begin
        sale_price = RoundTo(:base_price + :base_price*(:profit_percent/100), :round_dec);
        suspend;
      end
    end
  end
end
^

/* empty dependent procedure body */
/* Clear: BILL_POST_PRINT$PDA for: BILL_POST_PRINT */
ALTER PROCEDURE BILL_POST_PRINT$PDA(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
CLOSE_TYPE VARCHAR(10),
VIP_LINES INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

ALTER PROCEDURE SYSTEM_GET_PRINTERS(ID_CLIENT_POS INTEGER,
ID_INVENT INTEGER,
REPORT_CATEGORY VARCHAR(50),
IS_COPY INTEGER,
REPORT_DATA_SUB VARCHAR(500))
 RETURNS(REPORT_NAME VARCHAR(50),
ID_PRINTER VARCHAR(30),
REPORT_DATA VARCHAR(500))
 AS
declare variable id_setting_profile integer;
  declare variable id_profile_printer integer;
begin

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CLIENT_PROFILE')
  returning_values  :id_setting_profile;

  for
    select SPP.REPORT_NAME, SPP.ID_PRINTER, SPP.ID_PROFILE_PRINTER
    from   SETTING_PROFILE_PRINTER SPP
           join NOM_PRINTER P on P.ID_PRINTER = SPP.ID_PRINTER
    where  SPP.ID_SETTING_PROFILE = :id_setting_profile
           and SPP.REPORT_CATEGORY = :report_category
           and SPP.IS_COPY = :is_copy
           and SPP.IS_ACTIVE = 1
           and P.IS_ACTIVE = 1
    order by SPP.ID_PROFILE_PRINTER asc
    into   :report_name, :id_printer, :id_profile_printer
  do begin
    report_data = :report_data_sub||f_CRLF()||'ID_PRN_PRO='||:id_profile_printer;
    if (:id_printer = 1) then begin  /* ACCORDING TO THE INVENT */
      for
        select IP.ID_PRINTER
        from   INVENT_PRINTER IP
               join NOM_PRINTER P on P.ID_PRINTER = IP.ID_PRINTER
        where  IP.ID_INVENT = :id_invent
               and IP.IS_COPY = :is_copy
               and P.IS_ACTIVE = 1
        into   :id_printer
      do begin
        report_data = :report_data||f_CRLF()||'ID_PRINTER='||:id_printer;
        suspend;
      end
    end else begin
      report_data = :report_data||f_CRLF()||'ID_PRINTER='||:id_printer;
      suspend;
    end
  end
end
^

/* Alter (BILL_POST_PRINT) */
ALTER PROCEDURE BILL_POST_PRINT(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
CLOSE_TYPE VARCHAR(10),
VIP_LINES INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
REPORT_NAME VARCHAR(50),
ID_PRINTER INTEGER,
REPORT_DATA VARCHAR(500))
 AS
declare variable report_main varchar(200);
  declare variable report_data_sub varchar(500);
  declare variable id_smetka_bon integer;
  declare variable status integer;
  declare variable report_category varchar(50);
  declare variable id_invent integer;
  declare variable duplicate_total integer;
  declare variable print_unique_ids integer;
  declare variable id_print varchar(30);
  declare variable duplicatereport integer;
  declare variable fisc_status integer;
begin
  err_code = 0;
  err_text = '';
  if (:close_type = 'CANCEL') then exit;
  if ((:VIP_lines = 0) and (:close_type = 'ORDER')) then exit;
  duplicateReport = 0;
  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'PRINT_UNIQUE_IDS')
  returning_values  :print_unique_ids;
  if (:print_unique_ids = 1) then id_print = :id_smetka_trans;
  else id_print = '';

  if (:close_type in ('TOTAL_VOID', 'REOPEN', 'FISCAL')) then begin
    if (:close_type = 'FISCAL') then report_category = 'FISCAL_BON';
    else report_category = 'PAY_VOID';
    if ((:print_unique_ids = 1) and (:id_smetka_trans = -1)) then begin
      /* THIS SITUATION MAY OCCUR ONLY IN REFISCALIZE */
      id_smetka_trans = null;
      select max(SP.ID_SMETKA_TRANS)
      from   SMETKA_PAYMENT SP
      where  SP.ID_SMETKA_HEAD = :id_smetka_head
      into   :id_smetka_trans;
      if (:id_smetka_trans is null) then id_smetka_trans = gen_id(gen_smetka_trans_id, 1);
      id_print = :id_smetka_trans;
    end
    report_data_sub = 'ID_SMETKA='||:id_smetka_head||f_CRLF()||'ID_ORDER='||:id_smetka_trans||f_CRLF()||'ID_PRINT='||:id_print||f_CRLF()||'PREFF=NONE';
    for
      select SGP.REPORT_NAME, SGP.ID_PRINTER, SGP.REPORT_DATA
      from   SYSTEM_GET_PRINTERS(:id_client_pos, null, :report_category, 0, :report_data_sub) SGP
      into   :report_name, :id_printer, :report_data
    do suspend;

    if (:close_type in ('REOPEN', 'FISCAL')) then exit;
  end

  report_main = 'ID_SMETKA='||:id_smetka_head||f_CRLF()||'ID_ORDER='||:id_smetka_trans||f_CRLF()||'ID_PRINT='||:id_print;

  for
    select SBI.ID_SMETKA_INVENT, SBI.STATUS, SBI.ID_INVENT
    from   SMETKA_BON_INVENT SBI
    where  SBI.ID_SMETKA_HEAD = :id_smetka_head
           and SBI.ID_SMETKA_TRANS = :id_smetka_trans
    into   :id_smetka_bon, :status, :id_invent
  do begin
    if (:status = 1) then report_category = 'BON_INVENT';
    else report_category = 'BON_VOID';
    report_data_sub = 'ID_BON='||:id_smetka_bon||f_CRLF()||'PREFF=NONE';
    for
      select SGP.REPORT_NAME, SGP.ID_PRINTER, SGP.REPORT_DATA
      from   SYSTEM_GET_PRINTERS(:id_client_pos, :id_invent, :report_category, 0, :report_data_sub) SGP
      into   :report_name, :id_printer, :report_data
    do suspend;
  end

  if (:close_type = 'ORDER') then begin
    report_category = 'ORDER';
    report_data = :report_main||f_CRLF()||'PREFF=NONE'||f_CRLF()||'ID_CLIENT_POS='||coalesce(:ID_CLIENT_POS, '');
  end else begin
    if (:close_type = 'SUBTOTAL') then begin
      report_category = 'SUBTOTAL';
      report_data = :report_main||f_CRLF()||'PREFF=SUBTOTAL';
    end else begin
      report_data = :report_main||f_CRLF()||'PREFF=NONE';
      if (:close_type in ('TOTAL_VOID', 'OPEN_VOID')) then report_category = 'TOTAL_VOID';
      else report_category = 'TOTAL';
    end
  end

  if (:report_category = 'TOTAL') then begin
    /*execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'DUPLICATE_TOTAL')
    returning_values  :duplicate_total;*/
    duplicate_total = 0; -- N18 requirements

    select max(PT.EXTRA_TOTAL), max(SP.FISC_STATUS)
    from   SMETKA_PAYMENT SP
           join NOM_PAYMENT_TYPE PT on pt.ID_PAYMENT_TYPE = SP.ID_PAYMENT_TYPE
    where  SP.ID_SMETKA_HEAD = :id_smetka_head
           and SP.STATUS = 1
           and SP.ID_PAYMENT_VOID is null
    into   :duplicateReport, :fisc_status;

    if ((:duplicate_total = 0) and (:fisc_status >= 1)) then exit;
  end

  report_data_sub = :report_data;
  for
    select SGP.REPORT_NAME, SGP.ID_PRINTER, SGP.REPORT_DATA
    from   SYSTEM_GET_PRINTERS(:id_client_pos, :id_invent, :report_category, 0, :report_data_sub) SGP
    into   :report_name, :id_printer, :report_data
  do begin
    suspend;
    if (:duplicateReport = 1) then suspend;
  end
end
^

/* Alter (BILL_POST_PRINT$PDA) */
ALTER PROCEDURE BILL_POST_PRINT$PDA(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
CLOSE_TYPE VARCHAR(10),
VIP_LINES INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable report_name varchar(50);
  declare variable id_printer integer;
  declare variable report_data varchar(500);
  declare variable new_id_print_queue integer;
  declare variable printing_queued integer;
  declare variable id_end_work integer;
  declare variable locale_id varchar(10);
begin
  err_code = 0;
  err_text = '';

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_EW')
  returning_values  :id_end_work;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'LOCALE_ID')
  returning_values  :locale_id;

  printing_queued = 0;
  for
    select BPP.ERR_CODE, BPP.ERR_TEXT, BPP.REPORT_NAME, BPP.ID_PRINTER, BPP.REPORT_DATA
    from   BILL_POST_PRINT(:id_client_pos, :id_smetka_head, :id_smetka_trans, :close_type, :vip_lines) BPP
    into   :err_code, :err_text, :report_name, :id_printer, :report_data
  do begin
    if (:err_code < 0) then exit;
    new_id_print_queue = gen_id(GEN_SMETKA_PRINT_QUEUE_ID, 1);
    insert into SMETKA_PRINT_QUEUE (ID_PRINT_QUEUE, ID_CLIENT_POS, ID_SMETKA_HEAD, ID_SMETKA_TRANS,
           CLOSE_TYPE, VIP_LINES, REPORT_NAME, ID_PRINTER, REPORT_DATA, STATUS, ID_END_WORK, LANG)
           -- VIP_LINES may be gone
    values (:new_id_print_queue, :id_client_pos, :id_smetka_head, :id_smetka_trans,
           :close_type, :vip_lines, :report_name, :id_printer, :report_data, '', :id_end_work, :locale_id);
    printing_queued = 1;
  end
  if (:printing_queued = 1) then post_event 'printing_queued';
end
^

/* empty dependent procedure body */
/* Clear: BILL_POST_FINALIZE_NUM for: BILL_TAXES_CALC */
ALTER PROCEDURE BILL_POST_FINALIZE_NUM(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
CLOSE_TYPE VARCHAR(10),
ID_PROGRAM_LEVEL INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
SMETKA_NUM INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* Alter (BILL_TAXES_CALC) */
ALTER PROCEDURE BILL_TAXES_CALC(ID_SMETKA_HEAD INTEGER)
 AS
declare variable round_to numeric(15,4);
declare variable sl_neto_sum numeric(15,4);
declare variable id_tax_group integer;
declare variable id_smetka_line integer;
declare variable taxable_value numeric(15,4);
declare variable tax_percent numeric(15,4);
begin
  execute procedure SYSTEM_GET_VALUE(null, 'ROUND_TO')
  returning_values  :round_to;

  for
    select sl.ID_SMETKA_LINE, sl.ID_TAX_GROUP,
           sl.NETO_SUM
    from   BILL_NETO SL
    where  sl.ID_SMETKA_HEAD = :ID_SMETKA_HEAD
    into   :id_smetka_line, :id_tax_group, :sl_neto_sum
  do begin
    select TV.TAXABLE_VALUE, tv.TAX_PERCENT
    from   TAX_VALUE_DEDUCT (:sl_neto_sum, :round_to, :id_tax_group, 0) TV
    into   :taxable_value, :tax_percent;

    update SMETKA_LINE SL
    set    sl.NETO_WOT_TAX = :taxable_value,
           sl.TAX_PERCENT = :tax_percent
    where  sl.ID_SMETKA_LINE = :id_smetka_line;
  end

  execute procedure BILL_TAXES_EVAL (:ID_SMETKA_HEAD, :round_to);
end
^

/* Alter (BILL_TAXES_EVAL) */
ALTER PROCEDURE BILL_TAXES_EVAL(ID_SMETKA_HEAD INTEGER,
ROUND_TO NUMERIC(15,4))
 AS
declare variable id_sale_tax integer;
declare variable value_wot_tax numeric(15,4);
declare variable tax_value numeric(15,4);
declare variable eval_wot_tax numeric(15,4);
declare variable taxable_value numeric(15,4);
declare variable total_value numeric(15,4);
declare variable tax_percent numeric(15,4);
declare variable wot_tax_diff numeric(15,4);
declare variable wot_vat numeric(15,4);
declare variable tax_name varchar(50);
declare variable dl_dbkey char(8);
declare variable compensation_idx integer;
declare variable taxes_cnt integer;
declare variable id_sale_taxation integer;
declare variable id_end_work integer;
begin
  delete from SMETKA_TAX ST where st.ID_SMETKA_HEAD = :ID_SMETKA_HEAD;
  ----------------
  taxes_cnt = 0;
  for
    select  STV.ID_END_WORK,
            STV.ID_TAX_GROUP,
            STV.TOTAL_VALUE,
            STV.WOT_TAX,
            TVD.VALUE_WOT_TAX
    from   (select h.ID_END_WORK,
                   l.ID_TAX_GROUP as id_tax_group,
                   sum(l.NETO_SUM) as total_value,
                   sum(l.NETO_WOT_TAX) as wot_tax
            from   SMETKA_HEAD H
                   join BILL_NETO L on l.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD
            where  L.ID_SMETKA_HEAD = :ID_SMETKA_HEAD
            group by h.ID_END_WORK, l.ID_TAX_GROUP) STV
            left outer join TAX_VALUE_DEDUCT (STV.TOTAL_VALUE, :round_to, STV.ID_TAX_GROUP) TVD on 1=1
    into    :id_end_work, :id_sale_taxation, :total_value, :value_wot_tax, :eval_wot_tax
  do begin
    wot_tax_diff = :eval_wot_tax     -- wanted wot_tax value
                   - :value_wot_tax; -- current vot_tax value
    -- diffs must be added to doc lines
    -- line wot_vat is smaller than target wot_vat
    compensation_idx = case when :wot_tax_diff > 0 then 1
                            when :wot_tax_diff < 0 then -1
                            else 0 end;

    if (roundto(:wot_tax_diff, :ROUND_TO) <> 0) then begin
      for
        select l.RDB$DB_KEY,
               l.NETO_WOT_TAX
        from   SMETKA_LINE L
               left outer join TAX_VALUE_DEDUCT (l.NETO_SUM, :round_to, l.ID_VAT, 0) TV on 1=1
        where  L.ID_SMETKA_HEAD = :ID_SMETKA_HEAD
               and l.ID_VAT = :id_sale_taxation
        order by (tv.tax_diff_value * :compensation_idx) desc,  -- biggest wot_tax difss first
               l.NETO_SUM desc
        into   :dl_dbkey, :wot_vat
      do begin
        if (roundto(:wot_tax_diff, :round_to) <> 0) then begin
          WOT_VAT = :wot_vat + :round_to * :compensation_idx;
          value_wot_tax = :value_wot_tax + :round_to * :compensation_idx;
          wot_tax_diff = :wot_tax_diff - :round_to * :compensation_idx;
        end else begin
          compensation_idx = 0;
        end

        if (:compensation_idx <> 0) then begin
          update SMETKA_LINE l
          set    l.NETO_WOT_TAX = :wot_vat
          where  L.RDB$DB_KEY = :dl_dbkey;
        end else begin
          break;
        end

      end
    end
    /* insert final, evaluated tax values */
    for
      select td.ID_TAX, td.TAXABLE_VALUE, td.TAX_PERCENT,
             td.TAX_VALUE, st.TAX_NAME
      from   TAX_VALUE_DEDUCT (:total_value, :round_to, :id_sale_taxation, 1) td
             left outer join NOM_TAXES sT on st.ID_TAX = td.ID_TAX
      into   :id_sale_tax, :taxable_value, :tax_percent,
             :tax_value, :tax_name
    do begin
      update SMETKA_TAX DT
      set    dt.TAX_VALUE = dt.TAX_VALUE + :tax_value,
             dt.TAXABLE_VALUE = dt.TAXABLE_VALUE + :taxable_value
      where  DT.ID_SMETKA_HEAD = :ID_SMETKA_HEAD
             and dt.ID_TAX = :id_sale_tax;

      if (row_count = 0) then begin
        insert into SMETKA_TAX (ID_SMETKA_HEAD, ID_TAX, TAX_NAME, TAX_VALUE, TAX_PERCENT, TAXABLE_VALUE, ID_END_WORK)
        values (:ID_SMETKA_HEAD, :id_sale_tax, :tax_name, :tax_value, :tax_percent, :taxable_value, :id_end_work);
        taxes_cnt = :taxes_cnt + 1;
      end
    end 
  end

  --if (:vat_restriction = 1 and :taxes_cnt > 1) then exception DOCUMENT_EXCEPTION '-367';
end
^

/* Alter (EAI_EVO_TRANSFER$P2E) */
ALTER PROCEDURE EAI_EVO_TRANSFER$P2E(ID_END_WORK INTEGER,
HOTEL VARCHAR(50),
ID_SMETKA_HEAD INTEGER,
ID_EAI_MAP INTEGER,
EXTERNAL_IFC VARCHAR(100),
GUEST_BOARD VARCHAR(30) = null)
 RETURNS(TAG_VALUE VARCHAR(30),
TAG_NAME VARCHAR(50),
DESCRIPTION VARCHAR(50),
TRANSFER_QTY NUMERIC(15,4),
TRANSFER_AMOUNT NUMERIC(15,4),
ALL_INCLUSIVE_PAYMENT_TYPE INTEGER,
UNIQUE_SALES_NUMBER VARCHAR(30))
 AS
declare variable id_map_tag integer;
  declare variable has_payable smallint;
  declare variable group_name varchar(30);
  declare variable smetka_line_ids varchar(5000);
  declare variable id_log integer;
  declare variable id_ai_payment_type integer;
begin
  TAG_VALUE = null;
  TAG_NAME = null;
  DESCRIPTION = null;
  TRANSFER_QTY = null;
  TRANSFER_AMOUNT = null;
  ALL_INCLUSIVE_PAYMENT_TYPE = null;

  if (coalesce(:ID_SMETKA_HEAD, -1) > 0) then begin
    -- BILL transfer
    select sh.UNIQUE_SALES_NUMBER
    from   SMETKA_HEAD SH
    where  SH.ID_SMETKA_HEAD = :id_smetka_head
    into   :UNIQUE_SALES_NUMBER;
  
    if (:UNIQUE_SALES_NUMBER is null) then begin
      -- preliminary UNIQUE_SALES_NUMBER sets
      execute procedure BILL_UNQ_SALES_NUMBER_SET(:ID_SMETKA_HEAD, null)
      returning_values (:UNIQUE_SALES_NUMBER);
    end

    has_payable = 0;
    for
      select IFS.ID_MAP_TAG, IFS.GROUP_NAME, ifs.ALL_INCLUSIVE_PAYMENT_TYPE,
             sum(IFS.STOCK_QTY), sum(IFS.STOCK_VALUE), list(ifs.smetka_line_ids)
      from   EAI_EVO_BILL_TRANSFER$INT(:ID_SMETKA_HEAD, :ID_EAI_MAP, :HOTEL, :GUEST_BOARD) IFS
      group by 1, 2, 3, IFS.SINGLE_PRICE
      into   :id_map_tag, :group_name, :id_ai_payment_type,
             :transfer_qty, :transfer_amount, :smetka_line_ids
    do begin
      if (:id_ai_payment_type is not null) then begin
        ALL_INCLUSIVE_PAYMENT_TYPE = :id_ai_payment_type;
      end else begin
        select MT.TAG_NAME, MT.TAG_VALUE
        from   EAI_MAP_TAG MT
        where  MT.ID_MAP_TAG = :id_map_tag
        into   :tag_name, :tag_value;
    
        insert into EAI_P2F_TRANSFER_LOG (ID_SMETKA_HEAD, ID_SMETKA_PAYMENT, ID_END_WORK, EXTERNAL_IFC,
               TAG_NAME, TAG_VALUE, GROUP_NAME, TRANSFER_QTY, TRANSFER_AMOUNT)
        values (:ID_SMETKA_HEAD, null, null, :EXTERNAL_IFC,
               :TAG_NAME, :TAG_VALUE, :group_name, :transfer_qty, :transfer_amount)
        returning ID_EAI_P2F_TRANSFER_LOG into :id_log;
    
        insert into EAI_P2F_TRANSFER_LOG_LINES(ID_EAI_P2F_TRANSFER_LOG, ID_SMETKA_LINE)
        select :id_log, p.ITEM
        from   SYSTEM_STRING_PARSER(:smetka_line_ids, ',') p;
        has_payable = 1;
      end
    end

    if (:has_payable = 1) then begin
      for
        select tl.TAG_NAME, tl.TAG_VALUE, tl.GROUP_NAME, tl.TRANSFER_QTY, tl.TRANSFER_AMOUNT
        from   EAI_P2F_TRANSFER_LOG tl
        where  tl.EXTERNAL_IFC is not distinct from :EXTERNAL_IFC
               and tl.ID_SMETKA_HEAD = :ID_SMETKA_HEAD and tl.ID_SMETKA_PAYMENT is null
        into   :TAG_NAME, :TAG_VALUE, :DESCRIPTION, :TRANSFER_QTY, :TRANSFER_AMOUNT
      do begin
        suspend;
      end
    end else begin
      TAG_VALUE = null;
      TAG_NAME = null;
      DESCRIPTION = null;
      TRANSFER_QTY = null;
      TRANSFER_AMOUNT = null;
      suspend;
    end

  end else begin
    -- EW transfer
    for
      select IFS.ID_MAP_TAG, IFS.GROUP_NAME, sum(IFS.STOCK_QTY), sum(IFS.STOCK_VALUE)
      from   EAI_EVO_EW_TRANSFER$INT(:id_end_work, :id_eai_map, :external_ifc) IFS
      group by 1, 2
      into   :id_map_tag, :group_name, :transfer_qty, :transfer_amount
    do begin
      select MT.TAG_NAME, MT.TAG_VALUE
      from   EAI_MAP_TAG MT
      where  MT.ID_MAP_TAG = :id_map_tag
      into   :tag_name, :tag_value;
  
      insert into EAI_P2F_TRANSFER_LOG (ID_SMETKA_HEAD, ID_SMETKA_PAYMENT, ID_END_WORK, EXTERNAL_IFC,
             TAG_NAME, TAG_VALUE, GROUP_NAME, TRANSFER_QTY, TRANSFER_AMOUNT)
      values (null, null, :ID_END_WORK, :EXTERNAL_IFC,
             :TAG_NAME, :TAG_VALUE, :group_name, :transfer_qty, :transfer_amount);
    end

    for
      select tl.TAG_NAME, tl.TAG_VALUE, null, sum(tl.TRANSFER_QTY), sum(tl.TRANSFER_AMOUNT)
      from   EAI_P2F_TRANSFER_LOG tl
      where  tl.EXTERNAL_IFC is not distinct from :EXTERNAL_IFC
             and tl.ID_END_WORK = :ID_END_WORK
      group by 1, 2
      into   :TAG_NAME, :TAG_VALUE, :DESCRIPTION, :TRANSFER_QTY, :TRANSFER_AMOUNT
    do begin
      suspend;
    end
  end
end
^

/* Alter (EAI_FRONT) */
ALTER PROCEDURE EAI_FRONT(ID_END_WORK INTEGER,
HOTEL VARCHAR(50),
ID_SMETKA_HEAD INTEGER,
ID_EAI_MAP INTEGER,
EXTERNAL_IFC VARCHAR(100),
GUEST_BOARD VARCHAR(30) = null)
 RETURNS(TAG_VALUE VARCHAR(30),
TAG_NAME VARCHAR(50),
SUM_VALUE NUMERIC(15,4),
ALL_INCLUSIVE_PAYMENT_TYPE INTEGER,
UNIQUE_SALES_NUMBER VARCHAR(30))
 AS
declare variable id_map_tag integer;
  declare variable id_stock_group integer;
  declare variable has_payable smallint;
  declare variable transfer_value numeric(15,4);
  declare variable group_name varchar(30);
  declare variable smetka_line_ids varchar(5000);
  declare variable id_log integer;
  declare variable id_ai_payment_type integer;
begin
  TAG_VALUE = NULL;
  TAG_NAME = NULL;
  SUM_VALUE = NULL;
  ALL_INCLUSIVE_PAYMENT_TYPE = NULL;

  if (coalesce(:ID_SMETKA_HEAD, -1) > 0) then begin
    -- BILL transfer
    select sh.UNIQUE_SALES_NUMBER
    from   SMETKA_HEAD SH
    where  SH.ID_SMETKA_HEAD = :id_smetka_head
    into   :UNIQUE_SALES_NUMBER;
  
    if (:UNIQUE_SALES_NUMBER is null) then begin
      -- preliminary UNIQUE_SALES_NUMBER sets
      execute procedure BILL_UNQ_SALES_NUMBER_SET(:ID_SMETKA_HEAD, null)
      returning_values (:UNIQUE_SALES_NUMBER);
    end

    has_payable = 0;
    for
      select IFS.ID_MAP_TAG, IFS.ID_STOCK_GROUP, ifs.ALL_INCLUSIVE_PAYMENT_TYPE,
             sum(IFS.SUM_VALUE), list(ifs.smetka_line_ids)
      from   EAI_FRONT_BILL_TRANSFER$INT(:ID_SMETKA_HEAD, :ID_EAI_MAP, :HOTEL, :GUEST_BOARD) IFS
      group by 1, 2, 3
      into   :id_map_tag, :id_stock_group, :id_ai_payment_type,
             :transfer_value, :smetka_line_ids
    do begin
      if (:id_ai_payment_type is not null) then begin
        ALL_INCLUSIVE_PAYMENT_TYPE = :id_ai_payment_type;
      end else begin
        select MT.TAG_NAME, MT.TAG_VALUE
        from   EAI_MAP_TAG MT
        where  MT.ID_MAP_TAG = :id_map_tag
        into   :tag_name, :tag_value;
    
        select sg.STOCK_GROUP
        from   STOCK_GROUP SG
        where  sg.ID_STOCK_GROUP = :id_stock_group
        into   :group_name;
    
        insert into EAI_P2F_TRANSFER_LOG (ID_SMETKA_HEAD, ID_SMETKA_PAYMENT, ID_END_WORK, EXTERNAL_IFC,
               TAG_NAME, TAG_VALUE, GROUP_NAME, TRANSFER_AMOUNT)
        values (:ID_SMETKA_HEAD, null, null, :EXTERNAL_IFC,
               :TAG_NAME, :TAG_VALUE, :group_name, :transfer_value)
        returning ID_EAI_P2F_TRANSFER_LOG into :id_log;
    
        insert into EAI_P2F_TRANSFER_LOG_LINES(ID_EAI_P2F_TRANSFER_LOG, ID_SMETKA_LINE)
        select :id_log, p.ITEM
        from   SYSTEM_STRING_PARSER(:smetka_line_ids, ',') p;
    
        has_payable = 1;
      end
    end

    if (:has_payable = 1) then begin
      for
        select tl.TAG_NAME, tl.TAG_VALUE, sum(tl.TRANSFER_AMOUNT)
        from   EAI_P2F_TRANSFER_LOG tl
        where  tl.EXTERNAL_IFC is not distinct from :EXTERNAL_IFC
               and tl.ID_SMETKA_HEAD = :ID_SMETKA_HEAD and tl.ID_SMETKA_PAYMENT is null
        group by 1, 2
        into   :TAG_NAME, :TAG_VALUE, :SUM_VALUE
      do suspend;

    end else begin
      TAG_VALUE = NULL;
      TAG_NAME = NULL;
      SUM_VALUE = NULL;
      suspend;
    end

  end else begin
    for
      select IFS.ID_MAP_TAG, IFS.ID_STOCK_GROUP, sum(IFS.SUM_VALUE)
      from   EAI_FRONT_EW_TRANSFER$INT(:ID_END_WORK, :ID_EAI_MAP, :EXTERNAL_IFC) IFS
      group by 1, 2
      into   :id_map_tag, :id_stock_group, :transfer_value
    do begin
      select MT.TAG_NAME, MT.TAG_VALUE
      from   EAI_MAP_TAG MT
      where  MT.ID_MAP_TAG = :id_map_tag
      into   :tag_name, :tag_value;
  
      select sg.STOCK_GROUP
      from   STOCK_GROUP SG
      where  sg.ID_STOCK_GROUP = :id_stock_group
      into   :group_name;
  
      insert into EAI_P2F_TRANSFER_LOG (ID_SMETKA_HEAD, ID_SMETKA_PAYMENT, ID_END_WORK, EXTERNAL_IFC,
             TAG_NAME, TAG_VALUE, GROUP_NAME, TRANSFER_AMOUNT)
      values (null, null, :ID_END_WORK, :EXTERNAL_IFC,
             :TAG_NAME, :TAG_VALUE, :group_name, :transfer_value);
    end

    for
      select tl.TAG_NAME, tl.TAG_VALUE, sum(tl.TRANSFER_AMOUNT)
      from   EAI_P2F_TRANSFER_LOG tl
      where  tl.EXTERNAL_IFC is not distinct from :EXTERNAL_IFC
             and tl.ID_END_WORK = :ID_END_WORK
      group by 1, 2
      into   :TAG_NAME, :TAG_VALUE, :SUM_VALUE
    do suspend;

  end
end
^

/* Alter (ENDWORK_PRINT) */
ALTER PROCEDURE ENDWORK_PRINT(ID_CLIENT_POS INTEGER,
END_WORK_KIND VARCHAR(30),
EW_USER_LIST_QUOTED VARCHAR(3000),
SERVER_OPTION VARCHAR(20),
GLOBAL_OPTION VARCHAR(20),
ID_EW_REPORT INTEGER,
ID_CURRENT_EW INTEGER)
 RETURNS(REPORT_NAME VARCHAR(50),
REPORT_NAME_PREFIX VARCHAR(50),
ID_PRINTER INTEGER,
REPORT_DATA VARCHAR(500))
 AS
declare variable ew_user_name varchar(30);
  declare variable report_data_sub varchar(500);
  declare variable where_clause varchar(300);
  declare variable id_current_day_ew integer;
  declare variable report_data_tmp varchar(500);
begin
  report_name_prefix = '';
  if (:global_option not in ('REAL', 'MIDDLE', 'FINALIZE')) then
    exception WRONG_VALUE 'global_option = '||:global_option;

  if (:end_work_kind not in ('DAY', 'SERVER', 'SERVER_ALL', 'OBJECT')) then
    exception WRONG_VALUE 'end_work_kind = '||:end_work_kind;

  if ((:end_work_kind in ('SERVER', 'SERVER_ALL')) and (:server_option not in ('PER_SERVER', 'ALTOGETHER'))) then
    exception WRONG_VALUE  'server_option = '||:server_option;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_EW')
  returning_values  :id_current_day_ew;

  /* GLOBAL PARAMS FOR ALL NAR-REPORTS */
  report_data_tmp = 'ID_DAY_EW='||:id_current_day_ew||f_CRLF()||'ID_CURRENT_EW='||:id_current_ew||f_CRLF()||'ID_EW_REPORT='||:id_ew_report;

  if (:global_option <> 'FINALIZE') then begin
    if (:end_work_kind <> 'DAY') then
      report_data_tmp = :report_data_tmp||f_CRLF()||'GLOBAL_OPTION='||:global_option||f_CRLF()||'EW_KIND='||:end_work_kind;

    if (:end_work_kind = 'OBJECT') then begin
      ew_user_name = '';
      report_data = :report_data_tmp||f_CRLF()||'USER_LIST='||:ew_user_name;
  
      where_clause = 'and SH.END_WORK_OBJECT is null';
      report_data = :report_data||f_CRLF()||'WHERE_CLAUSE='||:where_clause;
      report_data_sub = :report_data;
      for
        select SGP.REPORT_NAME, SGP.ID_PRINTER, SGP.REPORT_DATA
        from   SYSTEM_GET_PRINTERS(:id_client_pos, null, 'EW_OBJECT', 0, :report_data_sub) SGP
        into   :report_name, :id_printer, :report_data
      do suspend;

      if (:ID_PRINTER is null) then exception MISSING_VALUE '-30';

    end else if (:end_work_kind in ('SERVER', 'SERVER_ALL')) then begin
      if (:server_option = 'ALTOGETHER') then begin
        report_data = :report_data_tmp||f_CRLF()||'USER_LIST='||:ew_user_list_quoted;

        where_clause = 'and SH.END_WORK_USER is null and SH.USER_OWNER in ('||:ew_user_list_quoted||')';
        report_data = :report_data||f_CRLF()||'WHERE_CLAUSE='||:where_clause;
        report_data_sub = :report_data;
        for
          select SGP.REPORT_NAME, SGP.ID_PRINTER, SGP.REPORT_DATA
          from   SYSTEM_GET_PRINTERS(:id_client_pos, null, 'EW_SERVER', 0, :report_data_sub) SGP
          into   :report_name, :id_printer, :report_data
        do suspend;

        if (:ID_PRINTER is null) then exception MISSING_VALUE '-30';

      end else begin
        /* PER SERVER */
        for
          select SSP.ITEM
          from   SYSTEM_STRING_PARSER(:ew_user_list_quoted, ',') SSP
          into   :ew_user_name
        do begin
          report_data = :report_data_tmp||f_CRLF()||'USER_LIST='||:ew_user_name;
                      
          where_clause = 'and SH.END_WORK_USER is null and SH.USER_OWNER in ('||:ew_user_name||')';
          report_data = :report_data||f_CRLF()||'WHERE_CLAUSE='||:where_clause;
          report_data_sub = :report_data;
          report_name_prefix = :ew_user_name;
          for
            select SGP.REPORT_NAME, SGP.ID_PRINTER, SGP.REPORT_DATA
            from   SYSTEM_GET_PRINTERS(:id_client_pos, null, 'EW_SERVER', 0, :report_data_sub) SGP
            into   :report_name, :id_printer, :report_data
          do suspend;

          if (:ID_PRINTER is null) then exception MISSING_VALUE '-30';

          report_name_prefix = '';
        end
      end
    end else if (:end_work_kind = 'DAY') then begin
      report_data_sub = :report_data_tmp;
      for
        select SGP.REPORT_NAME, SGP.ID_PRINTER, SGP.REPORT_DATA
        from   SYSTEM_GET_PRINTERS(:id_client_pos, null, 'EW_DAY', 0, :report_data_sub) SGP
        into   :report_name, :id_printer, :report_data
      do suspend;

      if (:ID_PRINTER is null) then exception MISSING_VALUE '-30';
    end
  end else begin
    /* global_option = 'FINALIZE' */
    report_data_sub = :report_data_tmp;
    for
      select SGP.REPORT_NAME, SGP.ID_PRINTER, SGP.REPORT_DATA
      from   SYSTEM_GET_PRINTERS(:id_client_pos, null, 'EW_CONFIRM', 0, :report_data_sub) SGP
      into   :report_name, :id_printer, :report_data
    do suspend;

    if (:ID_PRINTER is null) then exception MISSING_VALUE '-30';
  end
end
^

/* empty dependent procedure body */
/* Clear: ENDWORK_PROCESS for: ENDWORK_SUB_ARCHIVE */
ALTER PROCEDURE ENDWORK_PROCESS(ID_CLIENT_POS INTEGER,
END_WORK_KIND VARCHAR(30),
NEXT_DATE DATE,
EW_USER_LIST VARCHAR(3000),
ID_CURRENT_EW INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
UPD_NEXT_DATE DATE,
UPD_NEXT_ID_EW INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* empty dependent procedure body */
/* Clear: ENDWORK_REGENERATE for: ENDWORK_SUB_ARCHIVE */
ALTER PROCEDURE ENDWORK_REGENERATE(ID_DAY_EW INTEGER,
OPTIONS VARCHAR(255))
 RETURNS(ERR_CODE INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* Alter (ENDWORK_SUB_ARCHIVE) */
ALTER PROCEDURE ENDWORK_SUB_ARCHIVE(ID_END_WORK INTEGER)
 RETURNS(ERR_CODE INTEGER)
 AS
declare variable id_smetka_payment integer;
  declare variable sp_dbkey char(8);
begin 
  err_code = 0;
  /* 1 */
  insert into ARCHIVE_HEAD (ID_SMETKA_HEAD, ID_END_WORK, SMETKA_DATE, TABLE_NO,
    SMETKA_NUM, ID_OBJECT, ID_CONTRAGENT, ID_CONTRAGENT_OVERRULE, TOTAL_SUM,
    DISCOUNT_SUM, SURCHARGE_SUM, GRAND_TOTAL_SUM, CUSTOMER_CNT, USER_OWNER,
    START_DATE, START_TIME, STOP_DATETIME, ID_MANUAL_PRICE_LIST, ID_SURCHARGE,
    SURCHARGE_VALUE, ID_SMETKA_DISCOUNT, STATUS, END_WORK_USER,
    END_WORK_OBJECT, CARD_CODE, UNIQUE_SALES_NUMBER, ID_CLIENT_POS, ID_SMETKA_FRONT)
  select SH.ID_SMETKA_HEAD, SH.ID_END_WORK, SH.SMETKA_DATE, SH.TABLE_NO,
    SH.SMETKA_NUM, SH.ID_OBJECT, SH.ID_CONTRAGENT, SH.ID_CONTRAGENT_OVERRULE, SH.TOTAL_SUM,
    SH.DISCOUNT_SUM, SH.SURCHARGE_SUM, SH.GRAND_TOTAL_SUM, SH.CUSTOMER_CNT, SH.USER_OWNER,
    SH.START_DATE, SH.START_TIME, SH.STOP_DATETIME, SH.ID_MANUAL_PRICE_LIST, SH.ID_SURCHARGE,
    SH.SURCHARGE_VALUE, SH.ID_SMETKA_DISCOUNT, SH.STATUS, SH.END_WORK_USER,
    SH.END_WORK_OBJECT, SH.CARD_CODE, sh.UNIQUE_SALES_NUMBER, sh.ID_CLIENT_POS, sh.ID_SMETKA_FRONT
  from SMETKA_HEAD SH
  where  SH.ID_END_WORK = :id_end_work;

  /* 2 */
  insert into ARCHIVE_TRANS(ID_SMETKA_TRANS, ID_END_WORK, USER_CREATED, START_DATE,
         START_TIME, TRANS_END, CNT_VOIDS, CNT_LINES, ID_CLIENT_POS)
  select ST.ID_SMETKA_TRANS, ST.ID_END_WORK, ST.USER_CREATED, ST.START_DATE,
         ST.START_TIME, ST.TRANS_END, ST.CNT_VOIDS, ST.CNT_LINES, st.ID_CLIENT_POS
  from   SMETKA_TRANS ST
  where  ST.ID_END_WORK = :id_end_work;

  /* 3 */
  insert into ARCHIVE_BON_INVENT(ID_SMETKA_INVENT, ID_END_WORK, ID_SMETKA_HEAD,
         ID_SMETKA_TRANS, ID_INVENT, BON_DATE, BON_NUM,
         ID_VOIDED_BON, STATUS)
  select SBI.ID_SMETKA_INVENT, SBI.ID_END_WORK, SBI.ID_SMETKA_HEAD,
         SBI.ID_SMETKA_TRANS, SBI.ID_INVENT, SBI.BON_DATE, SBI.BON_NUM,
         SBI.ID_VOIDED_BON, SBI.STATUS
  from   SMETKA_BON_INVENT SBI
  where  SBI.ID_END_WORK = :id_end_work;

  /* 4 */
  insert into ARCHIVE_DISCOUNT(ID_SMETKA_DISCOUNT, ID_SMETKA_HEAD, ID_END_WORK,
         ID_DISCOUNT, DISCOUNT_BASE, DISCOUNT_VALUE, DISCOUNT_SUM,
         ID_RIGHT_OVERRULE, STATUS, IS_SURCHARGE)
  select SD.ID_SMETKA_DISCOUNT, SD.ID_SMETKA_HEAD, SD.ID_END_WORK,
         SD.ID_DISCOUNT, SD.DISCOUNT_BASE, SD.DISCOUNT_VALUE, SD.DISCOUNT_SUM,
         SD.ID_RIGHT_OVERRULE, SD.STATUS, SD.IS_SURCHARGE
  from   SMETKA_DISCOUNT SD
  where  SD.ID_END_WORK = :id_end_work;

  /* 5 */
  insert into ARCHIVE_MANAGE(ID_SMETKA_MANAGE, ID_SMETKA_HEAD, ID_END_WORK, MANAGE_TYPE,
         ID_REASON, ID_REASON_OVERRULE, USER_NAME, DATETIME, MANAGE_DATA)
  select SM.ID_SMETKA_MANAGE, SM.ID_SMETKA_HEAD, SM.ID_END_WORK, SM.MANAGE_TYPE,
         SM.ID_REASON, SM.ID_REASON_OVERRULE, SM.USER_NAME, SM.DATETIME, SM.MANAGE_DATA
  from   SMETKA_MANAGE SM
  where  SM.ID_END_WORK = :id_end_work;

  /* 6 */
  insert into ARCHIVE_LINE (ID_SMETKA_LINE, ID_SMETKA_TRANS, ID_SMETKA_HEAD,
    ID_END_WORK, ID_STOCK, ID_INVENT, ID_VAT, QTY_POST, QTY_VOID, QTY, COST_PRICE,
    SALE_PRICE, LINE_SUM, VOID_SUM, DISCOUNT_SUM, ID_MENU_PRICE_LIST,
    ID_PRICE_LIST_OVERRULE, ID_VOIDED_LINE, ID_LINE_VOID, ID_LINE_DISCOUNT,
    POST_STATUS, STATUS, ID_SMETKA_BON, ID_MOD_SESSION, NETO_SUM, SURCHARGE_SUM,
    NETO_WOT_TAX, TAX_PERCENT, VAT_CODE, ID_TRANSFER_SOURCE_LINE)
  select SL.ID_SMETKA_LINE, SL.ID_SMETKA_TRANS, SL.ID_SMETKA_HEAD,
    SL.ID_END_WORK, SL.ID_STOCK, SL.ID_INVENT, SL.ID_VAT, SL.QTY_POST, SL.QTY_VOID, SL.QTY, SL.COST_PRICE,
    SL.SALE_PRICE, SL.LINE_SUM, SL.VOID_SUM, SL.DISCOUNT_SUM, SL.ID_MENU_PRICE_LIST,
    SL.ID_PRICE_LIST_OVERRULE, SL.ID_VOIDED_LINE, SL.ID_LINE_VOID, SL.ID_LINE_DISCOUNT,
    SL.POST_STATUS, SL.STATUS, SL.ID_SMETKA_BON, SL.ID_MOD_SESSION, SL.NETO_SUM, SL.SURCHARGE_SUM,
    SL.NETO_WOT_TAX, SL.TAX_PERCENT, sl.VAT_CODE, sl.ID_TRANSFER_SOURCE_LINE
  from SMETKA_LINE SL
  where  SL.ID_END_WORK = :id_end_work;

  insert into ARCHIVE_LINE_TEXT (ID_MOD_SESSION, ID_END_WORK, LINE_TEXT)
  select SLT.ID_MOD_SESSION, SLT.ID_END_WORK, SLT.LINE_TEXT
  from   SMETKA_LINE_TEXT SLT
  where  SLT.ID_END_WORK = :id_end_work;

  insert into ARCHIVE_MODIFFIER (ID_SMETKA_MODIFFIER, ID_END_WORK, ID_MOD_SESSION,
    ID_STOCK, SALE_PRICE, NETO_SUM, SURCHARGE_SUM, DISCOUNT_SUM)
  select SM.ID_SMETKA_MODIFFIER, SM.ID_END_WORK, SM.ID_MOD_SESSION,
    SM.ID_STOCK, SM.SALE_PRICE, SM.NETO_SUM, SM.SURCHARGE_SUM, SM.DISCOUNT_SUM
  from  SMETKA_MODIFFIER SM
  where SM.ID_END_WORK = :id_end_work;

  /* 7 */
  for
    select SP.ID_SMETKA_PAYMENT, SP.rdb$db_key
    from   SMETKA_PAYMENT SP
    where  SP.ID_END_WORK = :id_end_work
    into   :id_smetka_payment, :sp_dbkey
  do begin
    insert into ARCHIVE_PAYMENT (ID_SMETKA_PAYMENT, ID_SMETKA_HEAD, ID_END_WORK,
           ID_SMETKA_TRANS, ID_PAYMENT_TYPE, ID_PAYMENT_OVERRULE, ID_PAYMENT_VOID,
           PAYMENT_VALUE, CHANGE_VALUE, STATUS, FISC_STATUS, ID_SMETKA_FRONT)
    select SP.ID_SMETKA_PAYMENT, SP.ID_SMETKA_HEAD, SP.ID_END_WORK,
           SP.ID_SMETKA_TRANS, SP.ID_PAYMENT_TYPE, SP.ID_PAYMENT_OVERRULE, SP.ID_PAYMENT_VOID,
           SP.PAYMENT_VALUE, SP.CHANGE_VALUE, SP.STATUS, SP.FISC_STATUS, SP.ID_SMETKA_FRONT
    from   SMETKA_PAYMENT SP
    where  SP.rdb$db_key = :sp_dbkey;
  
    insert into ARCHIVE_PAYMENT_EXTERNAL(ID_SMETKA_PAYMENT, EXTERNAL_DATA, VOID_ERR_CODE, EXTERNAL_TEXT)
    select SPE.ID_SMETKA_PAYMENT, SPE.EXTERNAL_DATA, SPE.VOID_ERR_CODE, SPE.EXTERNAL_TEXT
    from   SMETKA_PAYMENT_EXTERNAL SPE
    where  SPE.ID_SMETKA_PAYMENT = :id_smetka_payment;
  end
  /* 8 */
  insert into ARCHIVE_FOOTER(ID_SMETKA_FOOTER, ID_END_WORK, ID_SMETKA_HEAD,
         TEXT_KIND, TEXT_LINE)
  select SF.ID_SMETKA_FOOTER, SF.ID_END_WORK, SF.ID_SMETKA_HEAD,
         SF.TEXT_KIND, SF.TEXT_LINE
  from   SMETKA_FOOTER SF
  where  SF.ID_END_WORK = :id_end_work;

  /* 9 */
  insert into ARCHIVE_FRONT (ID_SMETKA_FRONT, ID_END_WORK, ID_ACCOUNT,
         GUEST_NAME, ROOM_NAME, HOTEL_NAME, SMETKA_DATE, GUEST_BOARD, TRANSFER_AMOUNT)
  select SF.ID_SMETKA_FRONT, SF.ID_END_WORK, SF.ID_ACCOUNT,
         SF.GUEST_NAME, SF.ROOM_NAME, SF.HOTEL_NAME, SF.SMETKA_DATE,
         SF.GUEST_BOARD, SF.TRANSFER_AMOUNT
  from   SMETKA_FRONT SF
  where  SF.ID_END_WORK = :id_end_work;

  /* 10 */
  insert into ARCHIVE_PRINT_QUEUE (ID_PRINT_QUEUE, ID_CLIENT_POS, ID_SMETKA_HEAD, ID_SMETKA_TRANS,
         CLOSE_TYPE, VIP_LINES, REPORT_NAME, ID_PRINTER, REPORT_DATA, STATUS,
         ID_END_WORK, LANG, PRINT_TRY_COUNT, PRINT_ERRORS, DT_CREATED)
  select SPQ.ID_PRINT_QUEUE, SPQ.ID_CLIENT_POS, SPQ.ID_SMETKA_HEAD, SPQ.ID_SMETKA_TRANS,
         SPQ.CLOSE_TYPE, SPQ.VIP_LINES, SPQ.REPORT_NAME, SPQ.ID_PRINTER, SPQ.REPORT_DATA, SPQ.STATUS,
         SPQ.ID_END_WORK, SPQ.LANG, SPQ.PRINT_TRY_COUNT, SPQ.PRINT_ERRORS, SPQ.DT_CREATED
  from   SMETKA_PRINT_QUEUE SPQ
  where  SPQ.ID_END_WORK = :id_end_work;
  /* 11 */
  insert into ARCHIVE_TAX (ID_SMETKA_HEAD, ID_TAX, TAX_NAME, TAX_PERCENT, TAX_VALUE, TAXABLE_VALUE, ID_END_WORK)
  select ID_SMETKA_HEAD, ID_TAX, TAX_NAME, TAX_PERCENT, TAX_VALUE, TAXABLE_VALUE, ID_END_WORK
  from   SMETKA_TAX st
  where  st.ID_END_WORK = :ID_END_WORK;
end
^

/* Alter (ENDWORK_UNDO) */
ALTER PROCEDURE ENDWORK_UNDO(ID_END_WORK INTEGER,
UNDO_TYPE VARCHAR(20))
 AS
declare variable id_object integer;
  declare variable prev_date date;
  declare variable id_end_work_m integer;
begin
  if (:undo_type not in ('REVERT', 'DELETE')) then begin
    exception WRONG_VALUE;
  end

  if (:undo_type = 'REVERT') then begin
    select EW.ID_OBJECT, EW.PREV_DATE
    from   SYSTEM_END_WORK EW
    where  EW.id_end_work = :id_end_work
    into   :id_object, :prev_date;
  
    /* 1 */
    insert into SMETKA_HEAD (ID_SMETKA_HEAD, ID_END_WORK, SMETKA_DATE, TABLE_NO,
      SMETKA_NUM, ID_OBJECT, ID_CONTRAGENT, ID_CONTRAGENT_OVERRULE, TOTAL_SUM,
      DISCOUNT_SUM, SURCHARGE_SUM, GRAND_TOTAL_SUM, CUSTOMER_CNT, USER_OWNER,
      START_DATE, START_TIME, STOP_DATETIME, ID_MANUAL_PRICE_LIST, ID_SURCHARGE,
      SURCHARGE_VALUE, ID_SMETKA_DISCOUNT, STATUS, END_WORK_USER,
      END_WORK_OBJECT, CARD_CODE, UNIQUE_SALES_NUMBER, ID_CLIENT_POS, ID_SMETKA_FRONT)
    select SH.ID_SMETKA_HEAD, SH.ID_END_WORK, SH.SMETKA_DATE, SH.TABLE_NO,
      SH.SMETKA_NUM, SH.ID_OBJECT, SH.ID_CONTRAGENT, SH.ID_CONTRAGENT_OVERRULE, SH.TOTAL_SUM,
      SH.DISCOUNT_SUM, SH.SURCHARGE_SUM, SH.GRAND_TOTAL_SUM, SH.CUSTOMER_CNT, SH.USER_OWNER,
      SH.START_DATE, SH.START_TIME, SH.STOP_DATETIME, SH.ID_MANUAL_PRICE_LIST, SH.ID_SURCHARGE,
      SH.SURCHARGE_VALUE, SH.ID_SMETKA_DISCOUNT, SH.STATUS, SH.END_WORK_USER,
      SH.END_WORK_OBJECT, sh.CARD_CODE, sh.UNIQUE_SALES_NUMBER, sh.ID_CLIENT_POS, sh.ID_SMETKA_FRONT
    from ARCHIVE_HEAD SH
    where  SH.ID_END_WORK = :id_end_work;
  
    /* 2 */
    insert into SMETKA_TRANS(ID_SMETKA_TRANS, ID_END_WORK, USER_CREATED, START_DATE,
         START_TIME, TRANS_END, CNT_VOIDS, CNT_LINES, ID_CLIENT_POS)
    select ST.ID_SMETKA_TRANS, ST.ID_END_WORK, ST.USER_CREATED, ST.START_DATE,
         ST.START_TIME, ST.TRANS_END, ST.CNT_VOIDS, ST.CNT_LINES, st.ID_CLIENT_POS
    from ARCHIVE_TRANS ST
    where ST.ID_END_WORK = :id_end_work;
  
    /* 3 */
    insert into SMETKA_BON_INVENT (ID_SMETKA_INVENT, ID_END_WORK, ID_SMETKA_HEAD, ID_SMETKA_TRANS,
           ID_INVENT, BON_DATE, BON_NUM, ID_VOIDED_BON, STATUS)
    select ID_SMETKA_INVENT, ID_END_WORK, ID_SMETKA_HEAD, ID_SMETKA_TRANS,
           ID_INVENT, BON_DATE, BON_NUM, ID_VOIDED_BON, STATUS
    from   ARCHIVE_BON_INVENT SBI
    where  SBI.ID_END_WORK = :id_end_work;
  
    /* 4 */
    insert into SMETKA_DISCOUNT(ID_SMETKA_DISCOUNT, ID_SMETKA_HEAD, ID_END_WORK,
         ID_DISCOUNT, DISCOUNT_BASE, DISCOUNT_VALUE, DISCOUNT_SUM,
         ID_RIGHT_OVERRULE, STATUS, IS_SURCHARGE)
    select ID_SMETKA_DISCOUNT, ID_SMETKA_HEAD, ID_END_WORK,
         ID_DISCOUNT, DISCOUNT_BASE, DISCOUNT_VALUE, DISCOUNT_SUM,
         ID_RIGHT_OVERRULE, STATUS, IS_SURCHARGE
    from ARCHIVE_DISCOUNT SD
    where  SD.ID_END_WORK = :id_end_work;
  
    /* 5 */
    insert into SMETKA_MANAGE(ID_SMETKA_MANAGE, ID_SMETKA_HEAD, ID_END_WORK, MANAGE_TYPE,
         ID_REASON, ID_REASON_OVERRULE, USER_NAME, DATETIME, MANAGE_DATA)
    select ID_SMETKA_MANAGE, ID_SMETKA_HEAD, ID_END_WORK, MANAGE_TYPE,
         ID_REASON, ID_REASON_OVERRULE, USER_NAME, DATETIME, MANAGE_DATA
    from ARCHIVE_MANAGE SM
    where  SM.ID_END_WORK = :id_end_work;
  
    /* 6 */
    insert into SMETKA_LINE(ID_SMETKA_LINE, ID_SMETKA_TRANS, ID_SMETKA_HEAD,
        ID_END_WORK, ID_STOCK, ID_INVENT, ID_VAT, QTY_POST, QTY_VOID, QTY, COST_PRICE,
        SALE_PRICE, LINE_SUM, VOID_SUM, DISCOUNT_SUM, ID_MENU_PRICE_LIST,
        ID_PRICE_LIST_OVERRULE, ID_VOIDED_LINE, ID_LINE_VOID, ID_LINE_DISCOUNT,
        POST_STATUS, STATUS, ID_SMETKA_BON, ID_MOD_SESSION, NETO_SUM, SURCHARGE_SUM,
        NETO_WOT_TAX, TAX_PERCENT, VAT_CODE, ID_TRANSFER_SOURCE_LINE)
    select ID_SMETKA_LINE, ID_SMETKA_TRANS, ID_SMETKA_HEAD,
        ID_END_WORK, ID_STOCK, ID_INVENT, ID_VAT, QTY_POST, QTY_VOID, QTY, COST_PRICE,
        SALE_PRICE, LINE_SUM, VOID_SUM, DISCOUNT_SUM, ID_MENU_PRICE_LIST,
        ID_PRICE_LIST_OVERRULE, ID_VOIDED_LINE, ID_LINE_VOID, ID_LINE_DISCOUNT,
        POST_STATUS, STATUS, ID_SMETKA_BON, ID_MOD_SESSION, NETO_SUM, SURCHARGE_SUM,
        NETO_WOT_TAX, TAX_PERCENT, VAT_CODE, ID_TRANSFER_SOURCE_LINE
    from ARCHIVE_LINE SL
    where  SL.ID_END_WORK = :id_end_work;
  
    insert into SMETKA_LINE_TEXT(ID_MOD_SESSION, ID_END_WORK, LINE_TEXT)
    select ID_MOD_SESSION, ID_END_WORK, LINE_TEXT
    from   ARCHIVE_LINE_TEXT SL
    where  SL.ID_END_WORK = :id_end_work;

    insert into SMETKA_MODIFFIER(ID_SMETKA_MODIFFIER, ID_END_WORK, ID_MOD_SESSION,
        ID_STOCK, SALE_PRICE, NETO_SUM, SURCHARGE_SUM, DISCOUNT_SUM)
    select ID_SMETKA_MODIFFIER, ID_END_WORK, ID_MOD_SESSION,
        ID_STOCK, SALE_PRICE, NETO_SUM, SURCHARGE_SUM, DISCOUNT_SUM
    from ARCHIVE_MODIFFIER SM
    where  SM.ID_END_WORK = :id_end_work;

    /* 7 */
    insert into SMETKA_FRONT (ID_SMETKA_FRONT, ID_END_WORK, ID_ACCOUNT,
      GUEST_NAME, ROOM_NAME, HOTEL_NAME, SMETKA_DATE, GUEST_BOARD, TRANSFER_AMOUNT)
    select SF.ID_SMETKA_FRONT, SF.ID_END_WORK, SF.ID_ACCOUNT,
      SF.GUEST_NAME, SF.ROOM_NAME, SF.HOTEL_NAME, SF.SMETKA_DATE, SF.GUEST_BOARD, SF.TRANSFER_AMOUNT
    from   ARCHIVE_FRONT SF
    where  SF.ID_END_WORK = :id_end_work;

    /* 8 */
    insert into SMETKA_PAYMENT (ID_SMETKA_PAYMENT, ID_SMETKA_HEAD, ID_END_WORK,
      ID_SMETKA_TRANS, ID_PAYMENT_TYPE, ID_PAYMENT_OVERRULE, ID_PAYMENT_VOID,
      PAYMENT_VALUE, CHANGE_VALUE, STATUS, FISC_STATUS, ID_SMETKA_FRONT)
    select SP.ID_SMETKA_PAYMENT, SP.ID_SMETKA_HEAD, SP.ID_END_WORK,
      SP.ID_SMETKA_TRANS, SP.ID_PAYMENT_TYPE, SP.ID_PAYMENT_OVERRULE, SP.ID_PAYMENT_VOID,
      SP.PAYMENT_VALUE, SP.CHANGE_VALUE, SP.STATUS, SP.FISC_STATUS, SP.ID_SMETKA_FRONT
    from ARCHIVE_PAYMENT SP
    where  SP.ID_END_WORK = :id_end_work;

    /* 9 */
    insert into SMETKA_PAYMENT_EXTERNAL(ID_SMETKA_PAYMENT, EXTERNAL_DATA, VOID_ERR_CODE,
           EXTERNAL_TEXT, EXTERNAL_IFC, INTERNAL_DATA)
    select SPE.ID_SMETKA_PAYMENT, SPE.EXTERNAL_DATA, SPE.VOID_ERR_CODE,
           SPE.EXTERNAL_TEXT, SPE.EXTERNAL_IFC, spe.INTERNAL_DATA
    from   ARCHIVE_PAYMENT_EXTERNAL SPE
           join ARCHIVE_PAYMENT SP on SP.ID_SMETKA_PAYMENT = SPE.ID_SMETKA_PAYMENT
    where  SP.ID_END_WORK = :id_end_work;

    /* 10 */
    insert into SMETKA_FOOTER(ID_SMETKA_FOOTER, ID_END_WORK, ID_SMETKA_HEAD, TEXT_KIND, TEXT_LINE)
    select ID_SMETKA_FOOTER, ID_END_WORK, ID_SMETKA_HEAD, TEXT_KIND, TEXT_LINE
    from   ARCHIVE_FOOTER SF
    where  SF.ID_END_WORK = :id_end_work;

    /* 11 */
    insert into SMETKA_TAX (ID_SMETKA_HEAD, ID_TAX, TAX_NAME, TAX_PERCENT, TAX_VALUE, TAXABLE_VALUE, ID_END_WORK)
    select ID_SMETKA_HEAD, ID_TAX, TAX_NAME, TAX_PERCENT, TAX_VALUE, TAXABLE_VALUE, ID_END_WORK
    from   ARCHIVE_TAX t
    where  t.ID_END_WORK = :id_end_work;

    update NOM_OBJECT O
    set    O.SYSTEM_DATE = :prev_date,
           O.ID_EW_NEXT  = :id_end_work
    where  O.ID_OBJECT   = :id_object;
  end

  delete from ARCHIVE_BON_INVENT
  where id_end_work = :id_end_work;

  delete from ARCHIVE_DISCOUNT
  where id_end_work = :id_end_work;

  delete from ARCHIVE_FOOTER
  where id_end_work = :id_end_work;

  delete from ARCHIVE_FRONT
  where id_end_work = :id_end_work;

  delete from ARCHIVE_HEAD
  where id_end_work = :id_end_work;

  delete from ARCHIVE_LINE
  where id_end_work = :id_end_work;

  delete from SMETKA_LINE_TEXT
  where id_end_work = :id_end_work;

  delete from SMETKA_MODIFFIER
  where id_end_work = :id_end_work;

  delete from ARCHIVE_MANAGE
  where id_end_work = :id_end_work;

  delete from ARCHIVE_PAYMENT
  where id_end_work = :id_end_work;
/* TRQBVA REFERENTALA DA SVYRSHI TOVA
  delete from ARCHIVE_PAYMENT_EXTERNAL
  where id_end_work = :id_end_work;
*/
  delete from ARCHIVE_TRANS
  where id_end_work = :id_end_work;

  delete from ARCHIVE_TAX
  where  ID_END_WORK = :id_end_work;

  delete from SUM_DAY
  where id_end_work = :id_end_work;

  delete from SUM_STOCK
  where id_end_work = :id_end_work;

  delete from SUM_DISCOUNT
  where id_end_work = :id_end_work;

  delete from SUM_VOID
  where id_end_work = :id_end_work;

  delete from EAI_P2F_TRANSFER_LOG tl
  where  tl.ID_END_WORK = :id_end_work;

  for
    select  EW.ID_END_WORK
    from    SYSTEM_END_WORK EW
    where   EW.ID_DAY_MASTER = :id_end_work
            and ((:undo_type = 'DELETE') or (EW.EW_KIND=2 /* DAY */))
    into    :id_end_work_m
  do begin
    delete from EAI_EFFECT_SALE S
    where  S.END_WORK_DAY = :id_end_work_m;

    delete from SYSTEM_END_WORK
    where id_end_work = :id_end_work_m;
  end
end
^

/* Alter (FISCALIZE_LINE$FISC) */
ALTER PROCEDURE FISCALIZE_LINE$FISC(ID_DOC_HEAD INTEGER)
 RETURNS(FISC_PRICE NUMERIC(15,4),
FISC_QTY NUMERIC(15,4),
FISC_TEXT VARCHAR(100),
FISC_GRP VARCHAR(10),
FISC_DISCOUNT_VALUE NUMERIC(15,4),
FISC_DISCOUNT_TEXT VARCHAR(50),
TRANSACTION_VALUE NUMERIC(15,4))
 AS
declare variable fld_sep varchar(10);
  declare variable line_sep varchar(10);
  declare variable line varchar(255);
  declare variable end_pos integer;
  declare variable lines_data blob sub_type 1 segment size 100;
  declare variable i integer;
  declare variable status integer;
  declare variable fiscal_device_id varchar(10);
  declare variable storno_fiscal_device_id varchar(10);
begin
  select f.SMETKA_LINES, h.status, f.FISCAL_DEVICE_ID, f.STORNO_FISCAL_DEVICE_ID
  from   SMETKA_FISCAL_DATA f              
         join SMETKA_HEAD h on h.ID_SMETKA_HEAD = f.ID_SMETKA_HEAD
  where  f.ID_SMETKA_HEAD = :ID_DOC_HEAD
  into   :lines_data, :status, :fiscal_device_id, :storno_fiscal_device_id;
  -- Status && fiscal data compatibility check
  if (:status = 2 and :fiscal_device_id is not null) then
    exception FISCALIZE_EXCEPTION '-315';

  if (:status = -3 and :storno_fiscal_device_id is not null) then
    exception FISCALIZE_EXCEPTION '-314';

  i = 0;
  fld_sep = f_character(28);
  line_sep = f_character(29);
  while (trim(:lines_data) <> '') do begin
    end_pos = position(:line_sep, :lines_data);
    line = substring(:lines_data from 1 for end_pos);
    lines_data = substring(:lines_data from end_pos + 1);
    if (:line <> '') then begin
      FISC_PRICE = substring(:line from 1 for position(:fld_sep, :line)-1);
      line = substring(:line from position(:fld_sep, :line)+1);
      FISC_QTY = substring(:line from 1 for position(:fld_sep, :line)-1);
      line = substring(:line from position(:fld_sep, :line)+1);
      FISC_TEXT = substring(:line from 1 for position(:fld_sep, :line)-1);
      line = substring(:line from position(:fld_sep, :line)+1);
      FISC_GRP = substring(:line from 1 for position(:fld_sep, :line)-1);
      line = substring(:line from position(:fld_sep, :line)+1);
      FISC_DISCOUNT_VALUE = nullif(substring(:line from 1 for position(:fld_sep, :line)-1), '');
      line = substring(:line from position(:fld_sep, :line)+1);
      FISC_DISCOUNT_TEXT = nullif(substring(:line from 1 for position(:fld_sep, :line)-1), '');
      line = substring(:line from position(:fld_sep, :line)+1);
      TRANSACTION_VALUE = nullif(substring(:line from 1 for position(:line_sep, :line)-1), '');

      if (:status = -3 and :FISC_DISCOUNT_VALUE is not null) then begin
        -- storno bons - discounts must be included in price!!!
        for
          select sl.QTY, sl.SINGLE_PRICE
          from   AMOUNT_APPORTION_TO_PRICE$FISC(:FISC_PRICE * :FISC_QTY - :FISC_DISCOUNT_VALUE, :FISC_QTY, 0.01) sl
          where  sl.SINGLE_PRICE <> 0
          into   :FISC_QTY, :FISC_PRICE
        do begin
          FISC_DISCOUNT_TEXT = null;
          FISC_DISCOUNT_VALUE = null;
          suspend;
        end 
      end else begin
        suspend;
      end
    end
    i= :i + 1;
    if (:i = 4096) then exit; -- Too many cycles, recursion prevents.
  end
end
^

ALTER PROCEDURE FISCALIZE_PREPARE_LINES$INT(ID_DOC_HEAD INTEGER)
 RETURNS(FISC_PRICE NUMERIC(15,4),
FISC_QTY NUMERIC(15,4),
FISC_TEXT VARCHAR(30),
FISC_GRP VARCHAR(10),
FISC_DISCOUNT_VALUE NUMERIC(15,4),
FISC_DISCOUNT_TEXT VARCHAR(50))
 AS
declare variable fisc_status integer;
begin
  FISC_PRICE = null;
  FISC_TEXT = null;
  FISC_GRP = null;
  FISC_QTY = null;
  FISC_DISCOUNT_VALUE = null;
  FISC_DISCOUNT_TEXT = null;

  select max(SP.FISC_STATUS)
  from   SMETKA_PAYMENT SP
         join SMETKA_HEAD SH on SH.ID_SMETKA_HEAD = Sp.ID_SMETKA_HEAD
         join NOM_PAYMENT_TYPE PT on PT.ID_PAYMENT_TYPE = SP.ID_PAYMENT_TYPE
  where  SH.ID_SMETKA_HEAD = :id_doc_head
         and SP.ID_PAYMENT_VOID is null
         and SH.STATUS = 2
  into   :fisc_status;

 -- if (:fisc_status <> 1) then exit;

  for
    select sl.VAT_CODE,
           S.STOCK_NAME,
           sl.SALE_PRICE,
           d.DISCOUNT_NAME,
           sum(sl.QTY),
           sum(sl.DISCOUNT_SUM) as discount_amount
    from   SMETKA_HEAD SH
           join BILL_NETO SL on SL.ID_SMETKA_HEAD = SH.ID_SMETKA_HEAD
           left outer join STOCK S on S.ID_STOCK = SL.ID_STOCK
           left outer join SMETKA_DISCOUNT ld on ld.ID_SMETKA_DISCOUNT = sl.ID_LINE_DISCOUNT
           left outer join SMETKA_DISCOUNT hd on hd.ID_SMETKA_DISCOUNT = sh.ID_SMETKA_DISCOUNT
           left outer join NOM_DISCOUNT d on d.ID_DISCOUNT = coalesce(ld.ID_DISCOUNT, hd.ID_SMETKA_DISCOUNT)
    where  SL.ID_SMETKA_HEAD = :id_doc_head
           and SH.STATUS = 2
           and SL.STATUS > 0
    group by 1, 2, 3, 4

    union all

    select 'SRV', D.DISCOUNT_NAME, SH.SURCHARGE_SUM, null, 1, null
    from   SMETKA_HEAD SH
           join NOM_DISCOUNT D on D.ID_DISCOUNT = SH.ID_SURCHARGE
    where  SH.ID_SMETKA_HEAD = :id_doc_head

    into   :FISC_GRP, :FISC_TEXT, :FISC_PRICE, :FISC_DISCOUNT_TEXT, :FISC_QTY, :FISC_DISCOUNT_VALUE
  do begin
    if (:FISC_PRICE <> 0) then suspend;
  end
end
^

/* Alter (FISCALIZE_PREPARE$FISC) */
ALTER PROCEDURE FISCALIZE_PREPARE$FISC(ID_DOC_HEAD INTEGER)
 RETURNS(UNIQUE_SALES_NUMBER VARCHAR(30),
FISCALIZATION_DETAILS VARCHAR(255),
VOID_REASON VARCHAR(30),
IS_VOID TYPE OF TLOGICAL,
DOC_DESCRIPTION TYPE OF NAME_100)
 AS
declare variable fld_sep varchar(10);
  declare variable line_sep varchar(10);
  declare variable line varchar(255);
  declare variable lines_data blob sub_type 1 segment size 80;
  declare variable payments_data blob sub_type 1 segment size 80;
  declare variable bill_status integer;
  declare variable min_fisc_status integer;
  declare variable max_fisc_status integer;
begin
  fld_sep = f_character(28);
  line_sep = f_character(29);
  lines_data = '';
  FISCALIZATION_DETAILS = null;  -- Fiscalization API compatibility
  VOID_REASON = null;
  IS_VOID = 0;
  DOC_DESCRIPTION = null;

  select h.UNIQUE_SALES_NUMBER, h.STATUS
  from   SMETKA_HEAD h
  where  h.ID_SMETKA_HEAD = :ID_DOC_HEAD
  into   :UNIQUE_SALES_NUMBER, :bill_status;

  if (:bill_status = -4) then exit;  -- void open bill
  if (:bill_status <> 2) then exception FISCALIZE_EXCEPTION '-312';

  select max(SP.FISC_STATUS), min(sp.FISC_STATUS)
  from   SMETKA_PAYMENT SP
  where  SP.ID_SMETKA_HEAD = :id_doc_head
         and SP.ID_PAYMENT_VOID is null
  into   :max_fisc_status, :min_fisc_status;

  if (:min_fisc_status <> :max_fisc_status) then exception FISCALIZE_EXCEPTION '-307';
  else if (:max_fisc_status = 0) then exit;  -- Nothing to fiscalize
  else if (:max_fisc_status = 2) then exit;  -- Payments are marked as fiscalized already
  -- !!! Only fisc_status=1 allows to continue with data preparation !!!


  for
    select coalesce(l.FISC_PRICE, 0) || :fld_sep
           || coalesce(l.FISC_QTY, 0) || :fld_sep
           || coalesce(l.FISC_TEXT, '') || :fld_sep
           || coalesce(l.FISC_GRP, '') || :fld_sep
           || coalesce(l.FISC_DISCOUNT_VALUE, '') || :fld_sep
           || coalesce(l.FISC_DISCOUNT_TEXT, '') || :fld_sep
           || '0' || :line_sep  -- removed :TRANSACTION_VALUE
    from   FISCALIZE_PREPARE_LINES$INT (:ID_DOC_HEAD) l
    into   :line
  do begin
    lines_data = :lines_data || :line;
  end

  payments_data = '';
  for
    select coalesce(sum(SP.PAYMENT_VALUE), 0) || :fld_sep
           || coalesce(PT.PAYMENT_NAME, '') || :fld_sep
           || coalesce(PT.FISCAL_ID, '') || :line_sep
    from   SMETKA_PAYMENT SP
           join SMETKA_HEAD SH on SH.ID_SMETKA_HEAD = Sp.ID_SMETKA_HEAD
           join NOM_PAYMENT_TYPE PT on PT.ID_PAYMENT_TYPE = SP.ID_PAYMENT_TYPE
    where  SH.ID_SMETKA_HEAD = :id_doc_head
           and SP.ID_PAYMENT_VOID is null
           and SH.STATUS = 2
    group by PT.PAYMENT_NAME, PT.FISCAL_ID
    having sum(SP.PAYMENT_VALUE) > 0
    into   :line
  do begin
    payments_data = :payments_data || :line;
  end

  insert into SMETKA_FISCAL_DATA(ID_SMETKA_HEAD, UNIQUE_SALES_NUMBER, SMETKA_LINES, SMETKA_PAYMENTS)
  values (:ID_DOC_HEAD, :UNIQUE_SALES_NUMBER, :lines_data, :payments_data);
end
^

ALTER PROCEDURE MENU_MODIFY_LINE(ID_MENU_LINE INTEGER,
ID_MENU_HEAD INTEGER,
ID_INVENT INTEGER,
STOCK_NAME VARCHAR(50),
ID_STOCK INTEGER,
ID_MENU_GROUP INTEGER,
MENU_GROUP_LINK INTEGER,
TAG INTEGER,
ID_VAT_GROUP INTEGER,
OPERATION VARCHAR(10))
 RETURNS(NEW_ID_MENU_LINE INTEGER,
ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
begin
  err_code = 0;
  err_text = '';
  if (:operation not in('add', 'mod', 'del')) then begin
    err_code = -1;
    err_text = 'operation unknown !';
  end

  if (operation = 'add') then begin
    if (exists(
      select *
      from   MENU_LINE ML
             join STOCK S on S.ID_STOCK = ML.ID_STOCK
      where  ML.ID_MENU_HEAD = :id_menu_head
             and S.ID_STOCK = :id_stock
             and S.IS_MODIFIER = 0
      )
    ) then begin
      err_code = -54;
    end

    begin
      new_id_menu_line = gen_id(gen_menu_line_id,1);
      insert into MENU_LINE(ID_MENU_LINE, STOCK_NAME ,ID_MENU_HEAD,
        ID_INVENT, ID_STOCK, ID_MENU_GROUP, MENU_GROUP_LINK, TAG, ID_VAT_GROUP)
      values (:new_id_menu_line, :stock_name, :id_menu_head,
        :id_invent, :id_stock, :id_menu_group, :menu_group_link, :tag, :id_vat_group);

      when sqlcode -803 do begin
        ERR_CODE = -55;
        exit;
      end
    end

    insert into MENU_LINE_PRICE(ID_MENU_LINE, ID_MENU_PRICE_LIST, PROFIT_PERCENT, SALE_PRICE)
    select :new_id_menu_line, MPL.ID_MENU_PRICE_LIST, MPL.DEF_PROFIT_PERCENT, 0
    from   MENU_PRICE_LIST MPL
    where  MPL.ID_MENU_HEAD = :id_menu_head;
  end else if (operation = 'mod') then begin
    update MENU_LINE
    set    STOCK_NAME = :stock_name,
           ID_MENU_GROUP = :id_menu_group,
           ID_INVENT = :id_invent,
           MENU_GROUP_LINK = :menu_group_link,
           ID_VAT_GROUP = :id_vat_group
    where  ID_MENU_LINE = :id_menu_line;

    when sqlcode -803 do begin
      ERR_CODE = -55;
      exit;
    end
  end else if (operation = 'del') then begin
    delete from MENU_LINE
    where  ID_MENU_LINE = :id_menu_line;
  end

  when sqlcode -803 do exit;
end
^

/* Alter (IMPORT_MENU_LINE$ENT) */
ALTER PROCEDURE IMPORT_MENU_LINE$ENT(ID_MENU_HEAD INTEGER,
INVENT_NAME VARCHAR(30),
STOCK_NAME VARCHAR(50),
MENU_STOCK_NAME VARCHAR(50),
MENU_GROUP_NAME VARCHAR(50),
MENU_GROUP_LINK_NAME VARCHAR(50),
TAG INTEGER,
VAT_GROUP_NAME VARCHAR(50))
 RETURNS(ID_MENU_LINE INTEGER,
ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable id_invent integer;
  declare variable id_stock integer;
  declare variable id_menu_group integer;
  declare variable id_menu_group_link integer;
  declare variable id_vat_group integer;
begin
  execute procedure LOOKUP_INVENT$ENT(:INVENT_NAME)
  returning_values :ID_INVENT;

  execute procedure LOOKUP_STOCK$ENT(:STOCK_NAME)
  returning_values :ID_STOCK;

  execute procedure LOOKUP_MENU_GROUP$ENT(:MENU_GROUP_NAME)
  returning_values :ID_MENU_GROUP;

  execute procedure LOOKUP_MENU_GROUP$ENT(:MENU_GROUP_LINK_NAME)
  returning_values :ID_MENU_GROUP_LINK;

  execute procedure LOOKUP_VAT_GROUP$ENT(:VAT_GROUP_NAME)
  returning_values :ID_VAT_GROUP;

  execute procedure MENU_MODIFY_LINE(null, :ID_MENU_HEAD, :ID_INVENT, :MENU_STOCK_NAME,
    :ID_STOCK, :ID_MENU_GROUP, :ID_MENU_GROUP_LINK, :TAG, :id_vat_group, 'add')
  returning_values :ID_MENU_LINE, :ERR_CODE, :ERR_TEXT;

  delete from MENU_LINE_PRICE mlp
  where mlp.ID_MENU_LINE = :ID_MENU_LINE;
end
^

ALTER PROCEDURE STOCK_MODIFY(ID_STOCK INTEGER,
STOCK_NAME VARCHAR(30),
STOCK_NAME_SEARCH VARCHAR(30),
COST_PRICE NUMERIC(15,4),
ID_STOCK_GROUP INTEGER,
IS_USE SMALLINT,
POS_CODE VARCHAR(30),
NOTE VARCHAR(100),
IS_SERVICE SMALLINT,
IS_FREE_VOID SMALLINT,
IS_FREE_PRICE SMALLINT,
IS_MODIFIER SMALLINT,
TRADE_CODE VARCHAR(30),
OPERATION VARCHAR(20))
 RETURNS(NEW_ID_STOCK INTEGER,
NEW_POS_CODE VARCHAR(30),
ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable is_barcode integer;
  declare variable enterprise_mode varchar(255);
  declare variable s_dbkey char(8);
  declare variable old_is_service integer;
  declare variable old_is_modifier integer;
  declare variable service_status_can_be_changed integer;
  declare variable modifier_status_can_be_changed integer;
  declare variable max_pos_length integer;
  declare variable old_cost_price numeric(15,4);
begin
  err_code = 0;
  err_text = '';
  max_pos_length = 5;

  if (:operation not in('add', 'mod', 'del', 'gen_pos_code')) then begin
    err_code = -1;
    err_text = 'operation unknown !';
  end

  if (operation = 'gen_pos_code') then begin
    new_pos_code = null;
    select max(cast(S.POS_CODE as integer))+1
    from   STOCK S
    where  S.IS_BARCODE = 0
           and S.POS_CODE <> ''
    into   :new_pos_code;
    if (:new_pos_code is null) then new_pos_code = 1;
  end else if (operation = 'add') then begin
    if ((:id_stock is null) or (:id_stock <= 0)) then new_id_stock = gen_id(gen_stock_id, 1);
    else new_id_stock = :id_stock;

    if(char_length(:pos_code) <= :max_pos_length) then is_barcode = 0;
    else is_barcode = 1;
    insert into stock (ID_STOCK, STOCK_NAME, STOCK_NAME_SEARCH, COST_PRICE,
      ID_STOCK_GROUP, IS_USE, POS_CODE, NOTE, IS_SERVICE,
      IS_FREE_VOID, IS_FREE_PRICE, IS_BARCODE, TRADE_CODE, IS_MODIFIER)
    values (:new_id_stock, :stock_name, :stock_name_search, :cost_price,
      :id_stock_group, :is_use, :pos_code, :note, :is_service,
      :is_free_void, :is_free_price, :is_barcode, :trade_code, :is_modifier);

    execute procedure SYSTEM_LOG_ADD('STOCK', :NEW_ID_STOCK, 'STOCK_CREATE', f_character(29) || :STOCK_NAME || f_character(28) || :pos_code);

  end else if (operation = 'mod') then begin
    if(char_length(:pos_code) <= :max_pos_length) then is_barcode = 0;
    else is_barcode = 1;
    select S.rdb$db_key, S.IS_SERVICE, S.IS_MODIFIER, s.COST_PRICE
    from   STOCK S
    where  S.ID_STOCK = :id_stock
    into   :s_dbkey, :old_is_service, :old_is_modifier, :old_cost_price;

    if (:old_is_service <> :is_service) then begin
      /* CHECK IF THE STOCK IS SOLD */
      if (exists(
        select *
        from   SMETKA_LINE SL
        where  SL.ID_STOCK = :id_stock)
      ) then service_status_can_be_changed = 0;
      else if (exists(
        select *
        from   SUM_STOCK SS
        where  SS.ID_STOCK = :id_stock)
      ) then service_status_can_be_changed = 0;
      else service_status_can_be_changed = 1;

      if (:service_status_can_be_changed = 0) then begin
        err_code = -162;
        exit;
      end else begin
        update STOCK S
        set    S.IS_SERVICE = :is_service
        where  S.RDB$DB_KEY = :s_dbkey;
      end
    end

    if (:old_is_modifier <> :is_modifier) then begin
      /* CHECK IF THE STOCK IS SOLD OR PARTICIPATE IN MENU */
      if (exists(
        select *
        from   MENU_LINE ML
        where  ML.ID_STOCK = :id_stock)
      ) then modifier_status_can_be_changed = 0;
      else if (exists(
        select *
        from   SMETKA_LINE SL
        where  SL.ID_STOCK = :id_stock)
      ) then modifier_status_can_be_changed = 0;
      else if (exists(
        select *
        from   SUM_STOCK SS
        where  SS.ID_STOCK = :id_stock)
      ) then modifier_status_can_be_changed = 0;
      else modifier_status_can_be_changed = 1;
      if (:modifier_status_can_be_changed = 0) then begin
        err_code = -163;
        exit;
      end else begin
        update STOCK S
        set    S.IS_MODIFIER = :is_modifier
        where  S.RDB$DB_KEY = :s_dbkey;
      end
    end

    update STOCK S
    set    S.STOCK_NAME = :stock_name,
           S.STOCK_NAME_SEARCH = :stock_name_search,
           S.COST_PRICE = :cost_price,
           S.ID_STOCK_GROUP = :id_stock_group,
           S.IS_USE = :is_use,
           S.POS_CODE = :pos_code,
           S.NOTE = :note,
           S.IS_FREE_VOID = :is_free_void,
           S.IS_FREE_PRICE = :is_free_price,
           S.IS_BARCODE = :is_barcode,
           S.TRADE_CODE = :trade_code
    where  S.RDB$DB_KEY = :s_dbkey;

    if (:COST_PRICE is distinct from :old_cost_price) then
      execute procedure STOCK_INVALIDATE_PRICE_LIST (:ID_STOCK);

    execute procedure SYSTEM_LOG_ADD('STOCK', :ID_STOCK, 'STOCK_MODIFY', f_character(29) || :STOCK_NAME || f_character(28) || :pos_code);
  end else if (operation = 'del') then begin
    execute procedure SYSTEM_INFO_GET('ENTERPRISE_MODE')
    returning_values  :enterprise_mode;
    if (:enterprise_mode in ('CENTRAL', 'CENTRAL_V2')) then begin
      err_code = -3;
      err_text = 'IN ENTERPRISE MODE STOCKS ARE IMMUTABLE';
      exit;
    end
     
    delete
    from   stock
    where  id_stock = :id_stock
    returning stock_name, pos_code
    into      :STOCK_NAME, :POS_CODE;

    execute procedure SYSTEM_LOG_ADD('STOCK', :ID_STOCK, 'STOCK_DELETE', f_character(29) || :STOCK_NAME || f_character(28) || :pos_code);

    when sqlcode -530 do begin
      ERR_CODE = -309;
      exit;
    end
  end
end
^

/* Alter (IMPORT_STOCK$ENT) */
ALTER PROCEDURE IMPORT_STOCK$ENT(STOCK_NAME VARCHAR(30),
STOCK_NAME_SEARCH VARCHAR(30),
COST_PRICE NUMERIC(15,4),
STOCK_GROUP_NAME VARCHAR(30),
IS_USE SMALLINT,
POS_CODE VARCHAR(30),
NOTE VARCHAR(100),
IS_SERVICE SMALLINT,
IS_FREE_VOID SMALLINT,
IS_FREE_PRICE SMALLINT,
IS_MODIFIER SMALLINT,
TRADE_CODE VARCHAR(30),
UUID VARCHAR(40))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable id_stock integer;
declare variable new_id_stock integer;
declare variable id_stock_group integer;
declare variable operation varchar(3);
begin
  select s.ID_STOCK
    from STOCK s
    where s.UUID = :UUID
    into :ID_STOCK;

  if (ID_STOCK is null) then begin
    select s.ID_STOCK
      from STOCK s
      where s.STOCK_NAME = :STOCK_NAME
      into :ID_STOCK;
  end

  execute procedure LOOKUP_STOCK_GROUP$ENT(:STOCK_GROUP_NAME)
  returning_values :ID_STOCK_GROUP;
/*
  execute procedure LOOKUP_VAT_GROUP$ENT(:VAT_GROUP_NAME)
  returning_values :ID_VAT_GROUP;
*/
  OPERATION = 'mod';
  if (ID_STOCK is null) then begin
    OPERATION = 'add';
  end

  execute procedure STOCK_MODIFY(:ID_STOCK, :STOCK_NAME, :STOCK_NAME_SEARCH, :COST_PRICE, :ID_STOCK_GROUP,
    :IS_USE, :POS_CODE, :NOTE, :IS_SERVICE, :IS_FREE_VOID, :IS_FREE_PRICE, :IS_MODIFIER,
    :TRADE_CODE, :OPERATION)
  returning_values :NEW_ID_STOCK, :POS_CODE, ERR_CODE, ERR_TEXT;
  ID_STOCK = coalesce(:NEW_ID_STOCK, :ID_STOCK);

  update STOCK s
    set s.UUID = :UUID
    where s.ID_STOCK = :ID_STOCK;
end
^

/* Alter (MANAGE_PRINT_COPY) */
ALTER PROCEDURE MANAGE_PRINT_COPY(ID_CLIENT_POS INTEGER,
ID_DATA INTEGER,
DATA_TYPE VARCHAR(10))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
REPORT_NAME VARCHAR(50),
ID_PRINTER INTEGER,
REPORT_DATA VARCHAR(500))
 AS
declare variable id_invent integer;
  declare variable report_category varchar(50);
  declare variable report_data_sub varchar(500);
  declare variable id_smetka_head integer;
  declare variable smetka_status integer;
  declare variable bon_status integer;
  declare variable right_required varchar(50);
  declare variable preff varchar(50);
  declare variable print_unique_ids integer;
  declare variable id_smetka_trans integer;
  declare variable id_print varchar(30);
begin
  /*  Description:
  ||
  */
  if (:data_type not in ('BON', 'ORDER')) then begin
    err_code = -1;
    err_text = 'operation unknown !';
    suspend;
    exit;
  end

  if (:data_type = 'ORDER') then begin
    id_smetka_head = :id_data;
    select SH.STATUS
    from   SMETKA_HEAD SH
    where  SH.ID_SMETKA_HEAD = :id_smetka_head
    into   :smetka_status;
    if (:smetka_status is null) then begin
      err_code = -158;
      suspend;
      exit;
    end
    if (:smetka_status = 1) then begin
      err_code = -320;
      suspend;
      exit;
    end
    if (exists (select sp.ID_SMETKA_PAYMENT
                from   SMETKA_PAYMENT sp
                where  sp.ID_SMETKA_HEAD = :id_smetka_head
                       and sp.STATUS = 1
                       and sp.FISC_STATUS > 0)) then
    begin
      err_code = -319;
      suspend;
      exit;
    end
    right_required = 'COPY_BILL_TOTAL';
  end else begin
    right_required = 'COPY_BON';
  end

  execute procedure SYSTEM_CHECK_RIGHT(:id_client_pos, :right_required)
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then begin suspend; exit; end

  if (:data_type = 'BON') then begin
    select SBI.ID_INVENT, SBI.ID_SMETKA_HEAD, SBI.STATUS
    from   SMETKA_BON_INVENT SBI
    where  SBI.ID_SMETKA_INVENT = :id_data
    into   :id_invent, :id_smetka_head, :bon_status;

    report_category = iif(:bon_status = 1, 'BON_INVENT', 'BON_VOID');

    report_data = 'ID_BON='||:id_data||f_CRLF()||'PREFF=COPY';
    report_data_sub = :report_data;

    for
      select SGP.REPORT_NAME, SGP.ID_PRINTER, SGP.REPORT_DATA
      from   SYSTEM_GET_PRINTERS(:id_client_pos, :id_invent, :report_category, 0, :report_data_sub) SGP
      into   :report_name, :id_printer, :report_data
    do suspend;

  end else if (:data_type = 'ORDER') then begin
    select max(SP.ID_SMETKA_TRANS)
    from   SMETKA_PAYMENT SP
    where  SP.ID_SMETKA_HEAD = :id_smetka_head
    into   :id_smetka_trans;

    if (:id_smetka_trans is null) then id_smetka_trans = gen_id(gen_smetka_trans_id, 1);

    execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'PRINT_UNIQUE_IDS')
    returning_values  :print_unique_ids;
    if (:print_unique_ids = 1) then id_print = :id_smetka_trans;
    else id_print = '';

    if (:smetka_status > 0) then begin
      if (:smetka_status = 1) then begin
        report_category = 'SUBTOTAL';
        preff = 'PREFF=SUBTOTAL';
      end else begin
        report_category = 'TOTAL';
        preff = 'PREFF=COPY';
      end
    end else begin
      report_category = 'TOTAL_VOID';
      preff = 'PREFF=COPY';
    end
    report_data = 'ID_SMETKA='||:id_smetka_head||f_CRLF()||'ID_ORDER='||:id_smetka_trans||f_CRLF()||'ID_PRINT='||:id_print||f_CRLF()||:preff;
    report_data_sub = :report_data;
    for
      select SGP.REPORT_NAME, SGP.ID_PRINTER, SGP.REPORT_DATA
      from   SYSTEM_GET_PRINTERS(:id_client_pos, null, :report_category, 0, :report_data_sub) SGP
      into   :report_name, :id_printer, :report_data
    do suspend;
  end
end
^

/* Alter (MANAGE_VOID_BILL) */
ALTER PROCEDURE MANAGE_VOID_BILL(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_VOID_REASON INTEGER,
ID_VOID_OVERRULE INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
CLOSE_TYPE VARCHAR(10),
VIP_LINES INTEGER,
NEW_ID_SMETKA_TRANS INTEGER)
 AS
declare variable cnt_voids integer;
  declare variable id_smetka_void integer;
  declare variable active_user varchar(50);
  declare variable right_required varchar(20);
  declare variable smetka_status integer;
  declare variable id_smetka_line integer;
  declare variable id_menu_price_lis integer;
  declare variable id_invent integer;
  declare variable id_stock integer;
  declare variable id_vat integer;
  declare variable qty numeric(15, 4);
  declare variable sale_price numeric(15, 4);
  declare variable line_sum numeric(15, 4);
  declare variable id_contragent integer;
  declare variable id_current_ew integer;
  declare variable no_use integer;
  declare variable card_code varchar(50);
begin
  err_code = 0;
  err_text = '';
  select SH.STATUS, SH.ID_CONTRAGENT, SH.CARD_CODE
  from   SMETKA_HEAD SH
  where  SH.ID_SMETKA_HEAD = :id_smetka_head
  into   :smetka_status, :id_contragent, :card_code;

  if (:smetka_status is null) then err_code = -158;
  else if (:smetka_status not in (1, 2)) then err_code = -155;
  if (:err_code < 0) then exit;

  if (:smetka_status = 2) then begin
    right_required = 'BILL_VOID_TOTAL';
    close_type = 'TOTAL_VOID';
  end else if (:smetka_status = 1) then begin
    right_required = 'BILL_VOID_OPEN';
    close_type = 'OPEN_VOID';
  end

  execute procedure SYSTEM_CHECK_RIGHT(:id_client_pos, :right_required)
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;

  execute procedure MANAGE_COMMON(:id_client_pos, null, :id_smetka_head, :close_type,
    :id_void_reason, :id_void_overrule, '', 'LOG')
  returning_values  :err_code, :err_text, :id_smetka_void;
  if (:err_code < 0) then exit;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_USER')
  returning_values  :active_user;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_EW')
  returning_values  :id_current_ew;

  execute procedure BILL_TRANSACTION(null, :id_current_ew, :active_user, 0, 0, :id_client_pos, 'START')
  returning_values  :err_code, :err_text, :new_id_smetka_trans;
  if (:err_code < 0) then exit;

  /* 1. PAY_VOID  */
  if (:close_type = 'TOTAL_VOID') then begin
    update SMETKA_HEAD SH
    set    SH.STATUS = 1,
           SH.STOP_DATETIME = null
    where  SH.ID_SMETKA_HEAD = :id_smetka_head;

    execute procedure BILL_PAYMENT_VOID(:id_client_pos, :id_smetka_head, :new_id_smetka_trans,
      :id_void_reason, :id_void_overrule)
    returning_values  :err_code, :err_text;
    if (:err_code < 0) then exit;
  end

  /* 2. VOID_LINES */
  cnt_voids = 0;
  for
    select SL.ID_SMETKA_LINE, SL.ID_MENU_PRICE_LIST, SL.ID_INVENT, SL.ID_STOCK, SL.ID_VAT,
           SL.QTY, SL.SALE_PRICE, SL.LINE_SUM
    from   SMETKA_LINE SL
    where  SL.ID_SMETKA_HEAD = :id_smetka_head
           and SL.STATUS > 0
    into   :id_smetka_line, :id_menu_price_lis, :id_invent, :id_stock, :id_vat,
           :qty, :sale_price, :line_sum
  do begin
    execute procedure BILL_POST_ADD(:id_current_ew, :id_smetka_head, :new_id_smetka_trans, :id_menu_price_lis, null,
      :id_stock, id_invent, :id_vat, :qty, :sale_price, :line_sum, null, :id_smetka_void,
      'OLD', :id_smetka_line, null, null)
    returning_values  :err_code, :err_text, :no_use;
    if (:err_code < 0) then exit;

    execute procedure BILL_POST_ADD(:id_current_ew, :id_smetka_head, :new_id_smetka_trans, :id_menu_price_lis, null,
      :id_stock, id_invent, :id_vat, 0, :sale_price, 0, null, null,
      'EDIT_VOID', :id_smetka_line, null, null)
    returning_values  :err_code, :err_text, :no_use;
    if (:err_code < 0) then exit;
    cnt_voids = :cnt_voids + 1;
  end

  /* 3. BILL_FINALIZE */
  execute procedure BILL_POST_FINALIZE(:id_client_pos, :id_current_ew, :id_smetka_head, :new_id_smetka_trans, null,
   :id_contragent, null, 'OPEN', :close_type, null, null, 0, :cnt_voids, :cnt_voids, 0, 0, 0, 0, 0, :card_code)
  returning_values :err_code, err_text, :VIP_lines;
end
^

/* Alter (MENU_MODIFY_MULTILINE) */
ALTER PROCEDURE MENU_MODIFY_MULTILINE(ID_MENU_HEAD INTEGER,
ID_INVENT INTEGER,
ID_MENU_GROUP INTEGER,
MENU_GROUP_LINK INTEGER,
TAG INTEGER,
ID_VAT_GROUP INTEGER,
STOCK_LIST VARCHAR(4000),
OPERATION VARCHAR(10))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable new_id integer;
  declare variable stock_name varchar(50);
  declare variable id_stock integer;
  declare variable id_menu_line integer;
begin
  err_code = 0;
  err_text = '';
  if (:operation not in('add', 'del', 'mod;mg', 'mod;mgl', 'mod;inv', 'mod;osn', 'mod;vat')) then begin
    err_code = -1;
    err_text = 'operation unknown !';
  end

  if (:operation = 'add') then begin
    for
      select SSP.ITEM
      from   SYSTEM_STRING_PARSER(:stock_list, ',') SSP
      into   :id_stock
    do begin
      select S.STOCK_NAME
      from   STOCK S
      where  S.ID_STOCK = :id_stock
      into   :stock_name;
  
      execute procedure MENU_MODIFY_LINE(null, :id_menu_head, :id_invent, :stock_name, :id_stock,
                        :id_menu_group, :menu_group_link, :tag, :ID_VAT_GROUP, 'add')
      returning_values  :new_id, :err_code, :err_text;
      if (:err_code < 0) then exit;
    end
  end else if (:operation = 'del') then begin
    for
      select SSP.ITEM
      from   SYSTEM_STRING_PARSER(:stock_list, ',') SSP
      into   :id_menu_line
    do begin
      execute procedure MENU_MODIFY_LINE(:id_menu_line, null, null, null, null,
                        null, null, null, null, 'del')
      returning_values  :new_id, :err_code, :err_text;
      if (:err_code < 0) then exit;
    end
  end else if (:operation = 'mod;mgl') then begin
    for
      select SSP.ITEM
      from   SYSTEM_STRING_PARSER(:stock_list, ',') SSP
      into   :id_menu_line
    do begin
       update MENU_LINE ML
       set ML.MENU_GROUP_LINK = :menu_group_link,
           ML.TAG = :TAG
       where  ML.ID_MENU_LINE = :id_menu_line;
    end
  end else if (:operation = 'mod;mg') then begin
    for
      select SSP.ITEM
      from   SYSTEM_STRING_PARSER(:stock_list, ',') SSP
      into   :id_menu_line
    do begin
       update MENU_LINE ML
       set ML.ID_MENU_GROUP = :id_menu_group,
           ML.TAG = :TAG
       where  ML.ID_MENU_LINE = :id_menu_line;
    end
  end else if (:operation = 'mod;inv') then begin
    for
      select SSP.ITEM
      from   SYSTEM_STRING_PARSER(:stock_list, ',') SSP
      into   :id_menu_line
    do begin
       update MENU_LINE ML
       set ML.ID_INVENT = :ID_INVENT,
           ML.TAG = :TAG
       where  ML.ID_MENU_LINE = :id_menu_line;
    end
  end else if (:operation = 'mod;osn') then begin
    for
      select SSP.ITEM
      from   SYSTEM_STRING_PARSER(:stock_list, ',') SSP
      into   :id_menu_line
    do begin
       update MENU_LINE ML
       set ML.STOCK_NAME = (select S.STOCK_NAME from STOCK S where S.ID_STOCK = ML.ID_STOCK),
           ML.TAG = :TAG
       where  ML.ID_MENU_LINE = :id_menu_line;
    end
  end else if (:operation = 'mod;vat') then begin
    for
      select SSP.ITEM
      from   SYSTEM_STRING_PARSER(:stock_list, ',') SSP
      into   :id_menu_line
    do begin
       update MENU_LINE ML
       set ML.ID_VAT_GROUP = :ID_VAT_GROUP,
           ML.TAG = :TAG
       where  ML.ID_MENU_LINE = :id_menu_line;
    end
  end
end
^

/* empty dependent procedure body */
/* Clear: ENDWORK_IN_PROGRESS for: NOM_MODIFY_OBJECT_SUPPRESS */
ALTER PROCEDURE ENDWORK_IN_PROGRESS(ID_CLIENT_POS INTEGER,
ID_END_WORK INTEGER,
EW_USER INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
ID_END_WORK_REAL INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* empty dependent procedure body */
/* Clear: ENDWORK_SKIP_DAYS for: NOM_MODIFY_OBJECT_SUPPRESS */
ALTER PROCEDURE ENDWORK_SKIP_DAYS(ID_CLIENT_POS INTEGER,
ID_OBJECT INTEGER,
NEW_SYSTEM_DATE DATE)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

/* Alter (NOM_MODIFY_OBJECT_SUPPRESS) */
ALTER PROCEDURE NOM_MODIFY_OBJECT_SUPPRESS(ID_CLIENT_POS INTEGER,
ID_OBJECT INTEGER,
OPERATION VARCHAR(20))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable dbg varchar(2000);
  declare variable curr_user_name varchar(50);
  declare variable suppress_datetime timestamp;
begin
  /*  Description:
  ||
  */
  err_code = 0;
  err_text = '';
  if (:operation is null) then operation = 'null';
  if (:operation not in('rise', 'clear', 'check')) then begin
    err_code = -1;
    err_text = 'operation unknown for procedure NOM_MODIFY_OBJECT_SUPPRESS, value='||:operation;
  end
  if (:operation = 'check') then begin
    suppress_datetime = null;
    select OS.SUPPRESS_DATETIME
    from   NOM_OBJECT_SUPPRESS OS
    where  OS.ID_OBJECT = :id_object
    into   :suppress_datetime;
    if (:suppress_datetime is not null) then begin
      err_code = -164;
      err_text = '';
      exit;
    end
  end else begin
    execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_USER')
    returning_values  :curr_user_name;
    if (not exists(
      select *
      from   SECURE_OBJECT SO
      where  SO.USER_NAME = :curr_user_name
             and SO.ID_OBJECT = :id_object)
    ) then begin
      err_code = -11;
      exit;
    end
    if (:operation = 'rise') then begin
      delete from NOM_OBJECT_SUPPRESS where ID_OBJECT = :id_object;
      insert into NOM_OBJECT_SUPPRESS(ID_OBJECT) values (:id_object);
    end else if (:operation = 'clear') then begin
      delete from NOM_OBJECT_SUPPRESS where ID_OBJECT = :id_object;
    end
  end
end
^

/* Alter (RIGHTS_MODIFY_GROUPUSER) */
ALTER PROCEDURE RIGHTS_MODIFY_GROUPUSER(USER_NAME VARCHAR(30),
ID_RIGHT_GROUP INTEGER,
OPERATION VARCHAR(10))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(100))
 AS
declare variable action_text varchar(255);
begin
  err_code = 0;
  err_text = '';
  if (:operation not in ('add', 'del')) then begin
    err_code = -1;
    err_text = 'operation unknown !';
    exit;
  end

  if (:USER_NAME = 'SYSDBA') then
    exception FORBIDDEN_OPERATION 'Can not modify "System user" rights!';

  select g.GROUP_NAME
  from   RIGHT_GROUP g
  where  g.ID_RIGHT_GROUP = :ID_RIGHT_GROUP
  into   :action_text;

  action_text = f_character(29) || :USER_NAME || f_character(28) || :action_text;

  if (:operation = 'del') then begin
    delete
    from  RIGHT_USER_GROUP
    where USER_NAME = :user_name
          and ID_RIGHT_GROUP = :id_right_group;

    execute procedure SYSTEM_LOG_ADD('RIGHT_USER', :USER_NAME, 'RIGHT_USER_GROUP_REMOVE', :action_text);

  end else if (:operation = 'add') then begin
    insert into RIGHT_USER_GROUP (USER_NAME, ID_RIGHT_GROUP)
    values (:user_name, :id_right_group);

    execute procedure SYSTEM_LOG_ADD('RIGHT_USER', :USER_NAME, 'RIGHT_USER_GROUP_ADD', :action_text);
  end
end
^

/* empty dependent procedure body */
/* Clear: ENDWORK_SUB_SUMMARY for: SUMMARY_DAY */
ALTER PROCEDURE ENDWORK_SUB_SUMMARY(ID_END_WORK INTEGER,
ID_OBJECT INTEGER,
DATE_FISCAL DATE)
 RETURNS(ERR_CODE INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* Alter (SUMMARY_DAY) */
ALTER PROCEDURE SUMMARY_DAY(ID_END_WORK INTEGER,
ID_OBJECT INTEGER,
DATE_FISCAL DATE)
 RETURNS(ERR_CODE INTEGER)
 AS
declare variable id_stock integer;
  declare variable neto numeric(15, 4);
  declare variable clnts integer;
  declare variable trans integer;
  declare variable for_hour integer;
  declare variable sum_stock_key char(8);
  declare variable date_real date;
  declare variable day_clnt_cnt integer;
  declare variable day_service_sum numeric(15, 4);
  declare variable day_void_sum numeric(15, 4);
begin 
  err_code = 0;
  insert   into SUM_CONTRAGENT (ID_END_WORK, ID_OBJECT, DATE_FISCAL, DATE_REAL, ID_CONTRAGENT,
           BRUTO_SUM, DISCOUNT_SUM, SERVICE_SUM, NETO_SUM, BILLS_CNT, STOCK_CNT)
  select   :id_end_work, :id_object, :date_fiscal, SH.START_DATE, SH.ID_CONTRAGENT,
           sum(SL.BRUTO_SUM) as BRUTO_SUM,
           sum(SL.DISCOUNT_SUM) as DISC_SUM,
           sum(SL.SURCHARGE_SUM),
           sum(SL.NETO_SUM),
           count(distinct SH.ID_SMETKA_HEAD),
           count(distinct SL.ID_STOCK)
  from     BILL_NETO SL
           join SMETKA_HEAD SH on SH.ID_SMETKA_HEAD = SL.ID_SMETKA_HEAD
  where    SL.ID_END_WORK = :id_end_work
           and SL.STATUS > 0
           and SH.STATUS > 0
  group by SH.START_DATE, SH.ID_CONTRAGENT;

  insert   into SUM_CONTRAGENT_PAY (ID_END_WORK, ID_OBJECT, DATE_FISCAL, DATE_REAL, ID_CONTRAGENT,
           ID_PAYMENT_TYPE, PAY_SUM)
  select   :id_end_work, :id_object, :date_fiscal, SH.START_DATE, SH.ID_CONTRAGENT,
           SP.ID_PAYMENT_TYPE, sum(SP.PAYMENT_VALUE)
  from     SMETKA_HEAD SH
           join SMETKA_PAYMENT SP on SH.ID_SMETKA_HEAD = SP.ID_SMETKA_HEAD and SP.STATUS > 0
  where    SP.ID_END_WORK = :id_end_work
  group by SH.START_DATE, SH.ID_CONTRAGENT, SP.ID_PAYMENT_TYPE;

  insert   into SUM_DAY (ID_END_WORK, ID_OBJECT, DATE_FISCAL, DATE_REAL,
           DAY_TRANS_CNT,
           DAY_VOID_SUM, 
           DAY_DISC_SUM, DAY_NETO_SUM,
           DAY_BRUTO_SUM, DAY_SERVICE_SUM, DAY_CLNT_CNT, DAY_TOTALS_CNT)
  select   :id_end_work, :id_object, :date_fiscal, SH.START_DATE,
           count(*/*distinct SL.ID_SMETKA_TRANS*/) as TRANS_CNT,
           0 as VOID_SUM,
           sum(SL.DISCOUNT_SUM) as DISC_SUM, sum(SL.NETO_SUM) as NETO_SUM,
           sum(SL.BRUTO_SUM) as LINE_SUM, 0, 0, count(distinct SH.ID_SMETKA_HEAD)
  from     BILL_NETO SL
           join SMETKA_HEAD SH on SH.ID_SMETKA_HEAD = SL.ID_SMETKA_HEAD
  where    SL.ID_END_WORK = :id_end_work
           and SL.STATUS > 0
           and SH.STATUS > 0
  group by SH.START_DATE;

  for
    select  SD.RDB$DB_KEY, SD.DATE_REAL
    from    SUM_DAY SD
    where   SD.ID_END_WORK = :id_end_work
    into    :sum_stock_key, :date_real
  do begin
    select sum(SH.SURCHARGE_SUM), sum(SH.CUSTOMER_CNT)
--           count(distinct case when SH.ID_CONTRAGENT = 0 then -1*AH.ID_SMETKA_HEAD else AH.ID_CONTRAGENT end )
    from   SMETKA_HEAD SH
    where  SH.START_DATE = :date_real
           and SH.ID_END_WORK = :id_end_work
           and SH.STATUS > 0
    into   :day_service_sum, :day_clnt_cnt;

    select sum(SL.VOID_SUM) as VOID_SUM
    from   SMETKA_HEAD SH
           join SMETKA_LINE SL on SH.ID_SMETKA_HEAD = SL.ID_SMETKA_HEAD
    where  SH.START_DATE = :date_real
           and SH.ID_END_WORK = :id_end_work
           and SL.STATUS < 0
    into   :day_void_sum;

    update SUM_DAY SDU
    set    SDU.DAY_SERVICE_SUM = ntoz(:day_service_sum),
           SDU.DAY_CLNT_CNT = ntoz(:day_clnt_cnt),
           SDU.DAY_VOID_SUM = ntoz(:day_void_sum)
    where  SDU.rdb$db_key = :sum_stock_key;

    for
      select cast(formatdate(SH.START_TIME, 'D;hh') as integer),
             sum(SL.NETO_SUM+SL.SURCHARGE_SUM),

             count(distinct SL.ID_SMETKA_HEAD),
             count(distinct SL.ID_SMETKA_TRANS)
      from   BILL_NETO SL
             join SMETKA_HEAD SH on SH.ID_SMETKA_HEAD = SL.ID_SMETKA_HEAD
      where  SL.ID_END_WORK = :id_end_work
             and SL.STATUS > 0
             and SH.START_DATE = :date_real
      group by formatdate(SH.START_TIME, 'D;hh')
      into   :for_hour, :neto, :clnts, :trans
    do execute procedure SUMMARY_DAY_SUB(:sum_stock_key, :for_hour, :neto, :clnts, :trans);
  end
end
^

/* Alter (SUMMARY_STOCK) */
ALTER PROCEDURE SUMMARY_STOCK(ID_END_WORK INTEGER,
ID_OBJECT INTEGER,
DATE_FISCAL DATE)
 RETURNS(ERR_CODE INTEGER)
 AS
declare variable id_stock integer;
  declare variable neto numeric(15, 4);
  declare variable qty integer;
  declare variable trans integer;
  declare variable for_hour integer;
  declare variable sum_stock_key char(8);
  declare variable id_invent integer;
  declare variable date_real date;
begin 
  err_code = 0;
  insert   into SUM_STOCK (ID_END_WORK, ID_OBJECT, DATE_FISCAL, DATE_REAL, ID_STOCK, ID_INVENT,
           DAY_QTY, DAY_TRANS_CNT,
           DAY_VOID_SUM, 
           DAY_DISC_SUM, DAY_NETO_SUM,
           DAY_BRUTO_SUM,
           DAY_TOTALS_CNT, DAY_CLNT_CNT)
  select   :id_end_work, :id_object, :date_fiscal, SH.START_DATE, SL.ID_STOCK, SL.ID_INVENT,
           sum(SL.QTY) as QTY, count(*/*distinct SL.ID_SMETKA_TRANS*/) as TRANS_CNT,
           sum(SL.VOID_SUM) as VOID_SUM,
           sum(SL.DISCOUNT_SUM) as DISC_SUM, sum(SL.NETO_SUM) as NETO_SUM,
           sum(SL.BRUTO_SUM) as LINE_SUM,
           count(distinct SH.ID_SMETKA_HEAD),
           count(distinct case when SH.ID_CONTRAGENT = 0 then -1*SH.ID_SMETKA_HEAD else SH.ID_CONTRAGENT end )
  from     BILL_NETO SL
           join SMETKA_HEAD SH on SH.ID_SMETKA_HEAD = SL.ID_SMETKA_HEAD
  where    SL.ID_END_WORK = :id_end_work
           and SL.STATUS > 0
  group by SH.START_DATE, SL.ID_STOCK, SL.ID_INVENT;

  for
    select  SS.rdb$db_key, SS.DATE_REAL, SS.ID_STOCK, SS.ID_INVENT
    from    SUM_STOCK SS
    where   SS.ID_END_WORK = :id_end_work
    into    :sum_stock_key, :date_real, :id_stock, :id_invent
  do begin
    for
      select cast(formatdate(SH.START_TIME, 'D;hh') as integer),
             sum(SL.QTY), sum(SL.NETO_SUM), count(*/*distinct SL.ID_SMETKA_TRANS*/)
      from   BILL_NETO SL
             join SMETKA_HEAD SH on SH.ID_SMETKA_HEAD = SL.ID_SMETKA_HEAD
      where  SL.ID_END_WORK = :id_end_work
             and SL.STATUS > 0
             and SL.ID_STOCK = :id_stock
             and SH.START_DATE = :date_real
             and SL.ID_INVENT = :id_invent
      group by formatdate(SH.START_TIME, 'D;hh')
      into   :for_hour, :qty, :neto, :trans
    do execute procedure SUMMARY_STOCK_SUB(:sum_stock_key, :for_hour, :neto, :qty, :trans);
  end
end
^

/* empty dependent procedure body */
/* Clear: MANAGE_CHANGE_OWNER for: SYSTEM_CHECK_RIGHT */
ALTER PROCEDURE MANAGE_CHANGE_OWNER(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
NEW_OWNER VARCHAR(30))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

/* empty dependent procedure body */
/* Clear: MANAGE_MOVE_BILL for: SYSTEM_CHECK_RIGHT */
ALTER PROCEDURE MANAGE_MOVE_BILL(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
NEW_TABLE_NO INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

/* empty dependent procedure body */
/* Clear: RIGHTS_MODIFY_AUDIT_USER for: SYSTEM_CHECK_RIGHT */
ALTER PROCEDURE RIGHTS_MODIFY_AUDIT_USER(USER_PASSWORD VARCHAR(50),
SYSUSER_NAME VARCHAR(20),
SYSUSER_PASSWORD VARCHAR(20),
OPERATION VARCHAR(10))
 RETURNS(USER_NAME VARCHAR(30),
ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

/* Alter (SYSTEM_CHECK_RIGHT) */
ALTER PROCEDURE SYSTEM_CHECK_RIGHT(ID_CLIENT_POS INTEGER,
RIGHT_CODE VARCHAR(20))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable user_name varchar(30);
begin
  err_code = 0;
  err_text = '';

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_USER')
  returning_values  :user_name;

  if (:user_name = 'SYSDBA') then begin
    exit;
  end else if (:user_name = '_AUDITOR_' and current_role = 'AUDITOR_ROLE') then begin
    exit;
  end else if (exists(
    select *
    from  RIGHT_USER_GROUP R
          join RIGHT_GROUP_LINE RGL on R.ID_RIGHT_GROUP = RGL.ID_RIGHT_GROUP
    where R.USER_NAME = :user_name
          and RGL.RIGHT_CODE  = :right_code
    )) then exit;
  else begin
    err_code = -105;
    err_text = '@'||:right_code;
  end
end
^

/* Alter (SYSTEM_GET_RIGHTS) */
ALTER PROCEDURE SYSTEM_GET_RIGHTS(ID_CLIENT_POS INTEGER,
USER_NAME VARCHAR(30))
 RETURNS(RIGHT_ITEM VARCHAR(100),
RIGHT_KIND VARCHAR(10),
GRANTED_VALUE INTEGER)
 AS
declare variable client_kind varchar(10);
begin
  if ((:user_name is null) or (:user_name = '')) then exception RIGHTS_ERR_LOGON;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CLIENT_KIND')
  returning_values  :client_kind;

  right_kind = 'rights';
  for
    select RD.RIGHT_CODE, max(RGL.GRANTED_VALUE)
    from   RIGHT_DEFINE RD 
           join RIGHT_GROUP_LINE RGL on RGL.RIGHT_CODE = RD.RIGHT_CODE
           join RIGHT_USER_GROUP RUG on RUG.ID_RIGHT_GROUP = RGL.ID_RIGHT_GROUP
                and RUG.USER_NAME = :user_name
    where  RD.CLIENT_KIND = :client_kind
    group by RD.RIGHT_CODE
    union
    select RD.RIGHT_CODE, iif(RD.IS_VALUE_REQUIRED = 1 and rd.IS_PLURAL = 0, 5, 0)
    from   RIGHT_DEFINE RD 
    where  RD.CLIENT_KIND = :client_kind
           and ( (:USER_NAME = 'SYSDBA') or (:user_name = '_AUDITOR_' and current_role = 'AUDITOR_ROLE') )
    into   :right_item, :granted_value
  do suspend;

  right_kind = 'reports';
  granted_value = 0;
  for
    select distinct RGR.REPORT_NAME
    from   RIGHT_GROUP_REPORT RGR
           join RIGHT_USER_GROUP RUG on RUG.ID_RIGHT_GROUP = RGR.ID_RIGHT_GROUP
    where  RUG.USER_NAME = :user_name
    into   :right_item
  do suspend;
end
^

/* Alter (SYSTEM_LOGON_OVERRULE) */
ALTER PROCEDURE SYSTEM_LOGON_OVERRULE(ID_CLIENT_POS INTEGER,
USER_PASSWORD VARCHAR(50),
CLIENT_KIND VARCHAR(10))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
USER_NAME VARCHAR(30))
 AS
declare variable expires_on date;
  declare variable id_object integer;
begin
  /*  Description:
  ||
  */
  err_code = 0;
  err_text = '';

  select RU.EXPIRES_ON, RU.USER_NAME
  from   RIGHT_USER RU
  where  RU.USER_PASSWORD = :user_password
         and RU.IS_EXPIRED = 0
  into   :expires_on, :user_name;
  if (:user_name is null) then begin
    err_code = -7;
    exit;
  end

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_OBJECT')
  returning_values  :id_object;
  if (not exists(
    select * from SECURE_OBJECT SO
    where  SO.USER_NAME = :user_name
           and SO.ID_OBJECT = :id_object
  )) then begin
    err_code = -11;
    select O.OBJECT_NAME
    from   NOM_OBJECT O
    where  O.ID_OBJECT = :id_object
    into   :err_text;
    exit;
  end
END
^

/* Alter (SYSTEM_LOGON_USER) */
ALTER PROCEDURE SYSTEM_LOGON_USER(ID_CLIENT_POS INTEGER,
USER_PASSWORD VARCHAR(50),
CLIENT_KIND VARCHAR(10),
ID_MULTI_PROFILE INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
ID_LANG_USER INTEGER,
ID_LOGON INTEGER,
USER_NAME VARCHAR(30),
ID_EW_NEXT INTEGER,
FISCAL_SESSION_ID INTEGER)
 AS
declare variable machine_name varchar(30);
  declare variable new_object varchar(30);
  declare variable id_object integer;
  declare variable set_id_object integer;
  declare variable log_logon_enabled integer;
  declare variable id_price_list integer;
  declare variable id_setting_profile integer;
begin
  err_code = 0;
  err_text = '';
  if (current_user = 'SYSDBA') then begin
    err_code = -1;
    err_text = 'Unallowed system user - SYSDBA!'||f_crlf();
    err_text = :err_text||'To fix the problem go to POSitive Admin'||f_crlf()||'Global Settings->System';
    exit;
  end

  if (:client_kind = 'EFFECT_IFC') then exit;
  select RU.USER_NAME
  from   RIGHT_USER RU
  where  RU.USER_PASSWORD = :user_password
         and RU.IS_EXPIRED = 0
  into   :user_name;
  if (:user_name is null) then begin
    err_code = -7;
    exit;
  end
/*
 else if ((:expires_on is not null) and (:expires_on <= current_date)) then err_code = -8;
 GOES TO END WORK
 */
  if (:id_multi_profile = -1) then begin
    select SC.ID_OBJECT, SC.SET_ID_OBJECT
    from   SYSTEM_CLIENT SC
    where  SC.ID_CLIENT_POS = :id_client_pos
    into   :id_object, :set_id_object;
  
    if ((:id_object <> :set_id_object) and (:client_kind = 'POS')) then begin
      err_code = -12;
      select O.OBJECT_NAME
      from   NOM_OBJECT O
      where  O.ID_OBJECT = :id_object
      into   :err_text;
      select O.OBJECT_NAME
      from   NOM_OBJECT O
      where  O.ID_OBJECT = :set_id_object
      into   :new_object;
      err_text = err_text||'->'||:new_object;
      id_object = :set_id_object;
    end
  end else begin
    select SC.ID_SETTING_PROFILE
    from   SYSTEM_CLIENT SC
    where  SC.ID_CLIENT_POS = :id_client_pos
    into   :id_setting_profile;

    select SCM.ID_OBJECT, SCM.ID_PRICE_LIST
    from   SYSTEM_CLIENT_MULTIPROFILE SCM
    where  SCM.ID_MULTI_PROFILE = :id_multi_profile
    into   :id_object, :id_price_list;

    update SETTING_VALUE SV set SV.SETTING_VALUE = :id_price_list
    where  SV.ID_SETTING_PROFILE = :id_setting_profile
           and SV.ID_SETTING = (
             select first 1 S.ID_SETTING
             from   SETTING S
             where  S.SETTING_CODE = 'DEFAULT_PRICE_LIST'
           );
  end

  id_ew_next = null;
  select SO.ID_EW_NEXT
  from   SECURE_OBJECT SO
  where  SO.USER_NAME = :user_name
         and SO.ID_OBJECT = :id_object
  into   :id_ew_next;
  if ((:id_ew_next is null) and (client_kind = 'POS')) then begin
    err_code = -11;
    if (:err_text = '') then
      select O.OBJECT_NAME
      from   NOM_OBJECT O
      where  O.ID_OBJECT = :id_object
      into   :err_text;
    exit;
  end

  if ((:id_object is null) and (client_kind = 'POS')) then begin
    err_code = -10;
    err_text = ' id_client_pos='||coalesce(:id_client_pos, 'null');
    execute procedure SYS_DBG('all SYSTEM_LOGON_USER, err_code='||:err_code||:err_text);
    exit;
  end

  if (:client_kind = 'POS') then begin
    execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'LOG_USER_LOGON')
    returning_values  :log_logon_enabled;

    -- delete potential obsoleted locks
    delete from  SYSTEM_LOCK sl
    where  sl.ID_CLIENT_POS = :ID_CLIENT_POS
           and sl.USER_NAME = :USER_NAME;

  end else begin
    /* ADMIN IS LOGING ON */
    delete from SYSTEM_CLIENT_SECURE SOD
    where  SOD.ID_CLIENT_POS = :id_client_pos;
    insert into SYSTEM_CLIENT_SECURE(ID_CLIENT_POS, ID_OBJECT)
    select :id_client_pos, SO.ID_OBJECT
    from   SECURE_OBJECT SO
    where  SO.USER_NAME = :user_name;
    log_logon_enabled = 1;
  end

  if (:log_logon_enabled = 1) then begin
    select CP.MACHINE
    from   SYSTEM_CLIENT CP
    where  CP.ID_CLIENT_POS = :id_client_pos
    into   :machine_name;

    id_logon = gen_id(GEN_RIGHT_LOGON_LOG_ID, 1 );
    insert into RIGHT_LOGON_LOG(
      ID_LOGON, USER_NAME, LOGON, LOGOFF, IS_CLOSED, MACHINE_NAME, ID_CLIENT_POS
    ) values (
      :id_logon, :user_name, current_timestamp, null, 0, :machine_name, :id_client_pos);
  end

  FISCAL_SESSION_ID = current_connection;

  update SYSTEM_CLIENT SC
  set    SC.ACTIVE_USER = :user_name,
         SC.ID_OBJECT = :id_object,
         sc.FISCAL_SESSION_ID = :FISCAL_SESSION_ID,
         sc.FISCAL_DEVICE_ID = null,
         sc.FISCAL_DEVICE_ERROR = null
  where  SC.ID_CLIENT_POS = :id_client_pos;

  RDB$SET_CONTEXT('USER_SESSION', 'ID_CLIENT_POS', :id_client_pos);

  execute procedure SYSTEM_LOG_ADD('RIGHT_USER', :USER_NAME, 'USER_LOG_IN', f_character(29) || :USER_NAME || f_character(28) || :CLIENT_KIND);
end
^

/* Restore proc. body: BILL_POST_FINALIZE_NUM */
ALTER PROCEDURE BILL_POST_FINALIZE_NUM(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
CLOSE_TYPE VARCHAR(10),
ID_PROGRAM_LEVEL INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
SMETKA_NUM INTEGER)
 AS
declare variable id_object integer;
  declare variable bon_num integer;
  declare variable sbi_dbkey char(8);
  declare variable sh_dbkey char(8);
  declare variable id_invent integer;
  declare variable grand_total_sum numeric(15,4);
  declare variable id_contragent integer;
  declare variable id_pool integer;
  declare variable post_reason varchar(100);
  declare variable payment_value numeric (15,4);
  declare variable object_name varchar(50);
  declare variable id_smetka_trans_pay integer;
  declare variable payment_name varchar(30);
  declare variable signv integer;
  declare variable no_post integer;
  declare variable acc_shorttext varchar(30);
  declare variable object_text varchar(30);
begin
  /*  Description:
  ||  This procedure is called in special (artificial) transaction mode - REPETABLE ON LOCK.
  ||  This is the reason why CONTRAGENT TURNOVER is stored and eventualy sumarized here.
  */
  err_code = 0;
  err_text = '';

  select SH.rdb$db_key, SH.SMETKA_NUM, SH.GRAND_TOTAL_SUM, SH.ID_CONTRAGENT, SH.ID_OBJECT, O.OBJECT_NAME
  from   SMETKA_HEAD SH
         join NOM_OBJECT O on O.ID_OBJECT = SH.ID_OBJECT
  where  SH.ID_SMETKA_HEAD = :id_smetka_head
  into   :sh_dbkey, :smetka_num, :grand_total_sum, :id_contragent, :id_object, :object_name;

  if (:close_type not in ('TOTAL_VOID', 'OPEN_VOID')) then begin
    if (:smetka_num = 0) then begin
      execute procedure BILL_GET_NUM(:id_object, 'BILL')
      returning_values  :smetka_num;

      update SMETKA_HEAD SH
      set    SH.SMETKA_NUM = :smetka_num
      where  SH.rdb$db_key = :sh_dbkey;
    end
  end

  for
    select SBI.rdb$db_key, SBI.ID_INVENT
    from   SMETKA_BON_INVENT SBI
    where  SBI.ID_SMETKA_HEAD = :id_smetka_head
           and SBI.ID_SMETKA_TRANS = :id_smetka_trans
    into   :sbi_dbkey, :id_invent
  do begin
    execute procedure BILL_GET_NUM(:id_invent, 'BON')
    returning_values  :bon_num;
    update  SMETKA_BON_INVENT SBIu
    set     SBIu.BON_NUM = :bon_num
    where   SBIu.rdb$db_key = :sbi_dbkey;
  end

  if (:close_type = 'TOTAL') then begin
    /* CALCULATE AND EVALUATE TAXES, INCLUDED INTO STOCK PRICES */
    execute procedure BILL_TAXES_CALC (:ID_SMETKA_HEAD);

    if (:id_contragent > 0) then begin
      /* MANAGE CONTRAGENT POOLS */
      execute procedure SYSTEM_GET_TEXT(:id_client_pos, 'ACCOUNT_SHORT_NAME')
      returning_values  :acc_shorttext;
  
      execute procedure SYSTEM_GET_TEXT(:id_client_pos, 'OBJECT')
      returning_values  :object_text;
  
      for
        select PT.ID_POOL, PT.PAYMENT_NAME, PT.POOL_SIGN,
               SP.ID_SMETKA_TRANS, SP.PAYMENT_VALUE
        from   SMETKA_PAYMENT SP
               join NOM_PAYMENT_TYPE PT on PT.ID_PAYMENT_TYPE = SP.ID_PAYMENT_TYPE
        where  SP.STATUS > 0
               and SP.ID_SMETKA_HEAD = :id_smetka_head
        into   :id_pool, :payment_name, :signv,
               :id_smetka_trans_pay, :payment_value
      do begin
        no_post = 0;
        if (:id_pool is null) then no_post = 1;
        else if ((exists(select * from CL_PROGRAM P where P.ID_POOL = :id_pool)) and (:id_program_level is null)) then no_post = 1;
  
        if (:no_post = 0) then begin
          payment_value = :signv*:payment_value;
    
          post_reason = substring((:acc_shorttext||:smetka_num||' '||:payment_name||' '||:payment_value||' '||:object_text||' '||:object_name) from 1 for 100);
          execute procedure CL_POST_POOL_VALUE(:id_client_pos, :id_smetka_head, :id_contragent,
            :id_pool, :payment_value, 0, :post_reason, :id_smetka_trans_pay, 3)
          returning_values  :err_code, :err_text;
          if (:err_code < 0) then exit;
        end
      end
      post_reason = substring((:acc_shorttext||:smetka_num||' '||:close_type||' '||:grand_total_sum||' '||:object_text||' '||:object_name) from 1 for 100);
      execute procedure CL_POST_POOL_VALUE(:id_client_pos, :id_smetka_head, :id_contragent,
        1, :grand_total_sum, 0, :post_reason, :id_smetka_trans_pay, 3)
      returning_values  :err_code, :err_text;
    end
  end
end
^

/* Restore proc. body: EAI_EVO_BILL_TRANSFER$INT */
ALTER PROCEDURE EAI_EVO_BILL_TRANSFER$INT(ID_SMETKA_HEAD INTEGER,
ID_EAI_MAP INTEGER,
HOTEL VARCHAR(50),
GUEST_BOARD VARCHAR(30) = null)
 RETURNS(ID_MAP_TAG INTEGER,
STOCK_QTY NUMERIC(15,4),
STOCK_VALUE NUMERIC(15,4),
SINGLE_PRICE NUMERIC(15,4),
GROUP_NAME VARCHAR(50),
SMETKA_LINE_IDS BLOB SUB_TYPE 1,
ALL_INCLUSIVE_PAYMENT_TYPE INTEGER)
 AS
declare variable is_object integer;
  declare variable is_invent integer;
  declare variable is_stock_grp integer;
  declare variable id_object integer;
  declare variable id_invent integer;
  declare variable id_stock_group integer;
  declare variable id_eai_map_allinclusive integer;
  declare variable id_ai_payment_type integer;
  declare variable complex_id varchar(30);
begin
  select SH.ID_OBJECT
  from   SMETKA_HEAD SH
  where  SH.ID_SMETKA_HEAD = :id_smetka_head
  into   :id_object;

  select first 1 A.ID_PAYMENT_TYPE, A.ID_EAI_MAP_ALLINCLUSIVE
  from   EAI_MAP_ALLINCLUSIVE A
  where  A.HOTEL = :hotel
         and A.ID_OBJECT = :id_object
         and ((coalesce(a.COMPATIBLE_GUEST_BOARD, '') = '')
              or (a.COMPATIBLE_GUEST_BOARD = coalesce(:GUEST_BOARD, '')))
  order by nullif(a.COMPATIBLE_GUEST_BOARD, '') asc nulls last
  into   :id_ai_payment_type, :id_eai_map_allinclusive;

  select EM.IS_OBJECT, EM.IS_INVENT, EM.IS_STOCK_GRP
  from   EAI_MAP EM
  where  EM.ID_MAP = :id_eai_map
  into   :is_object, :is_invent, :is_stock_grp;

  for
    select BN.ID_INVENT, s.ID_STOCK_GROUP, s.STOCK_NAME,
           cast((BN.NETO_SUM + BN.SURCHARGE_SUM)/bn.QTY as numeric(15,4)),
           iif(:id_eai_map_allinclusive is not null and aip.ID_STOCK_GROUP is null, :id_ai_payment_type, null),
           sum(BN.QTY), sum(BN.NETO_SUM + BN.SURCHARGE_SUM), list(bn.ID_SMETKA_LINE)
    from   BILL_NETO BN
           join STOCK S on S.ID_STOCK = BN.ID_STOCK
           left outer join EAI_MAP_ALL_INCLUSIVE_PAYABLE aip on aip.ID_EAI_MAP_ALL_INCLUSIVE = :ID_EAI_MAP_ALLINCLUSIVE
                                                                and aip.ID_STOCK_GROUP = s.ID_STOCK_GROUP
    where  BN.ID_SMETKA_HEAD = :id_smetka_head
           and BN.STATUS > 0
    group by 1, 2, 3, 4, 5

    into   :id_invent, :id_stock_group, :GROUP_NAME,
           :SINGLE_PRICE, :ALL_INCLUSIVE_PAYMENT_TYPE, :STOCK_QTY, :STOCK_VALUE, :SMETKA_LINE_IDS
  do begin
    if (:is_object = 1) then complex_id = :id_object;
    else complex_id = 'null';
    if (:is_invent = 1) then complex_id = :complex_id||'_'||:id_invent;
    else complex_id = :complex_id||'_null';
    if (:is_stock_grp = 1) then complex_id = :complex_id||'_'||:id_stock_group;
    else complex_id = :complex_id||'_null';
    id_map_tag = null;
    select MD.ID_MAP_TAG
    from   EAI_MAP_DATA MD
    where  MD.COMPLEX_ID = :complex_id
           and MD.ID_MAP = :id_eai_map
    into   :id_map_tag;
    if (:id_map_tag is null) then
      select MD.ID_MAP_TAG
      from   EAI_MAP_DATA MD
      where  MD.COMPLEX_ID = 'null_null_null'
             and MD.ID_MAP = :id_eai_map
      into   :id_map_tag;
    suspend;
  end
end
^

/* Restore proc. body: EAI_EVO_EW_TRANSFER$INT */
ALTER PROCEDURE EAI_EVO_EW_TRANSFER$INT(ID_END_WORK INTEGER,
ID_EAI_MAP INTEGER,
EXTERNAL_IFC VARCHAR(100))
 RETURNS(ID_MAP_TAG INTEGER,
STOCK_QTY NUMERIC(15,4),
STOCK_VALUE NUMERIC(15,4),
GROUP_NAME VARCHAR(50))
 AS
declare variable is_object integer;
  declare variable is_invent integer;
  declare variable is_stock_grp integer;
  declare variable id_object integer;
  declare variable id_invent integer;
  declare variable id_stock_group integer;
  declare variable complex_id varchar(30);
begin

  select EM.IS_OBJECT, EM.IS_INVENT, EM.IS_STOCK_GRP
  from   EAI_MAP EM
  where  EM.ID_MAP = :id_eai_map
  into   :is_object, :is_invent, :is_stock_grp;

  for
    select SH.ID_OBJECT, BN.ID_INVENT, sg.ID_STOCK_GROUP, sg.STOCK_GROUP,
           null, sum(BN.NETO_SUM + BN.SURCHARGE_SUM)
    from   SMETKA_HEAD SH
           join BILL_NETO BN on BN.ID_SMETKA_HEAD = SH.ID_SMETKA_HEAD
           join STOCK S on S.ID_STOCK = BN.ID_STOCK
           join STOCK_GROUP SG on SG.ID_STOCK_GROUP = S.ID_STOCK_GROUP
    where  SH.ID_END_WORK = :id_end_work
           and BN.STATUS > 0
           and SH.STATUS = 2
           and not exists(
             select sp.ID_SMETKA_PAYMENT
             from   SMETKA_PAYMENT SP
                    join SMETKA_PAYMENT_EXTERNAL SPE on SPE.ID_SMETKA_PAYMENT = SP.ID_SMETKA_PAYMENT
             where  SP.ID_SMETKA_HEAD = SH.ID_SMETKA_HEAD
                    and SP.STATUS > 0
                    and SPE.EXTERNAL_IFC = :external_ifc)
           and not exists(select sp.ID_SMETKA_PAYMENT
                          from   SMETKA_PAYMENT SP
                                 join EAI_P2F_SUPPRESS_TP STP on STP.ID_PAYMENT_TYPE = SP.ID_PAYMENT_TYPE
                          where  SP.ID_SMETKA_HEAD = SH.ID_SMETKA_HEAD
                                 and SP.STATUS > 0)
    group by 1, 2, 3, 4
    into   :id_object, :id_invent, :id_stock_group, :GROUP_NAME,
           :STOCK_QTY, :STOCK_VALUE
  do begin
    if (:is_object = 1) then complex_id = :id_object;
    else complex_id = 'null';
    if (:is_invent = 1) then complex_id = :complex_id||'_'||:id_invent;
    else complex_id = :complex_id||'_null';
    if (:is_stock_grp = 1) then complex_id = :complex_id||'_'||:id_stock_group;
    else complex_id = :complex_id||'_null';
    id_map_tag = null;
    select MD.ID_MAP_TAG
    from   EAI_MAP_DATA MD
    where  MD.COMPLEX_ID = :complex_id
           and MD.ID_MAP = :id_eai_map
    into   :id_map_tag;
    if (:id_map_tag is null) then
      select MD.ID_MAP_TAG
      from   EAI_MAP_DATA MD
      where  MD.COMPLEX_ID = 'null_null_null'
             and MD.ID_MAP = :id_eai_map
      into   :id_map_tag;
    suspend;
  end
end
^

/* Restore proc. body: EAI_FRONT_BILL_TRANSFER$INT */
ALTER PROCEDURE EAI_FRONT_BILL_TRANSFER$INT(ID_SMETKA_HEAD INTEGER,
ID_EAI_MAP INTEGER,
HOTEL VARCHAR(50),
GUEST_BOARD VARCHAR(30) = null)
 RETURNS(ID_MAP_TAG INTEGER,
SUM_VALUE NUMERIC(15,4),
ID_STOCK_GROUP INTEGER,
SMETKA_LINE_IDS BLOB SUB_TYPE 1,
ALL_INCLUSIVE_PAYMENT_TYPE INTEGER)
 AS
declare variable is_object integer;
  declare variable is_invent integer;
  declare variable is_stock_grp integer;
  declare variable id_object integer;
  declare variable id_invent integer;
  declare variable id_eai_map_allinclusive integer;
  declare variable id_ai_payment_type integer;
  declare variable complex_id varchar(30);
begin
  select SH.ID_OBJECT
  from   SMETKA_HEAD SH
  where  SH.ID_SMETKA_HEAD = :id_smetka_head
  into   :id_object;

  select first 1 A.ID_PAYMENT_TYPE, A.ID_EAI_MAP_ALLINCLUSIVE
  from   EAI_MAP_ALLINCLUSIVE A
  where  A.HOTEL = :hotel
         and A.ID_OBJECT = :id_object
         and ((coalesce(a.COMPATIBLE_GUEST_BOARD, '') = '')
              or (a.COMPATIBLE_GUEST_BOARD = coalesce(:GUEST_BOARD, '')))
  order by nullif(a.COMPATIBLE_GUEST_BOARD, '') asc nulls last
  into   :id_ai_payment_type, :id_eai_map_allinclusive;

  select EM.IS_OBJECT, EM.IS_INVENT, EM.IS_STOCK_GRP
  from   EAI_MAP EM
  where  EM.ID_MAP = :id_eai_map
  into   :is_object, :is_invent, :is_stock_grp;

  for
    select BN.ID_INVENT, S.ID_STOCK_GROUP,
           iif(:id_eai_map_allinclusive is not null and aip.ID_STOCK_GROUP is null, :id_ai_payment_type, null),
           sum(BN.NETO_SUM + BN.SURCHARGE_SUM), list(bn.ID_SMETKA_LINE)
    from   BILL_NETO BN
           join STOCK S on S.ID_STOCK = BN.ID_STOCK
           left outer join EAI_MAP_ALL_INCLUSIVE_PAYABLE aip on aip.ID_EAI_MAP_ALL_INCLUSIVE = :ID_EAI_MAP_ALLINCLUSIVE
                                                                and aip.ID_STOCK_GROUP = s.ID_STOCK_GROUP
    where  BN.ID_SMETKA_HEAD = :id_smetka_head
           and BN.STATUS > 0
    group by BN.ID_INVENT, S.ID_STOCK_GROUP, 3
    into   :id_invent, :id_stock_group, :ALL_INCLUSIVE_PAYMENT_TYPE,
           :sum_value, :smetka_line_ids
  do begin
    if (:is_object = 1) then complex_id = :id_object;
    else complex_id = 'null';
    if (:is_invent = 1) then complex_id = :complex_id||'_'||:id_invent;
    else complex_id = :complex_id||'_null';
    if (:is_stock_grp = 1) then complex_id = :complex_id||'_'||:id_stock_group;
    else complex_id = :complex_id||'_null';
    id_map_tag = null;
    select MD.ID_MAP_TAG
    from   EAI_MAP_DATA MD
    where  MD.COMPLEX_ID = :complex_id
           and MD.ID_MAP = :id_eai_map
    into   :id_map_tag;
    if (:id_map_tag is null) then
      select MD.ID_MAP_TAG
      from   EAI_MAP_DATA MD
      where  MD.COMPLEX_ID = 'null_null_null'
             and MD.ID_MAP = :id_eai_map
      into   :id_map_tag;
    suspend;
  end
end
^

/* Restore proc. body: EAI_FRONT_EW_TRANSFER$INT */
ALTER PROCEDURE EAI_FRONT_EW_TRANSFER$INT(ID_END_WORK INTEGER,
ID_EAI_MAP INTEGER,
EXTERNAL_IFC VARCHAR(100))
 RETURNS(ID_MAP_TAG INTEGER,
SUM_VALUE NUMERIC(15,4),
ID_STOCK_GROUP INTEGER)
 AS
declare variable is_object integer;
  declare variable is_invent integer;
  declare variable is_stock_grp integer;
  declare variable id_object integer;
  declare variable id_invent integer;
  declare variable complex_id varchar(30);
begin

  select EM.IS_OBJECT, EM.IS_INVENT, EM.IS_STOCK_GRP
  from   EAI_MAP EM
  where  EM.ID_MAP = :id_eai_map
  into   :is_object, :is_invent, :is_stock_grp;

  for
    select SH.ID_OBJECT, BN.ID_INVENT, S.ID_STOCK_GROUP, sum(BN.NETO_SUM + BN.SURCHARGE_SUM)
    from   SMETKA_HEAD SH
           join BILL_NETO BN on BN.ID_SMETKA_HEAD = SH.ID_SMETKA_HEAD
           join STOCK S on S.ID_STOCK = BN.ID_STOCK
    where  SH.ID_END_WORK = :id_end_work
           and BN.STATUS > 0
           and SH.STATUS = 2
           and not exists(
             select sp.ID_SMETKA_PAYMENT
             from   SMETKA_PAYMENT SP
                    join SMETKA_PAYMENT_EXTERNAL SPE on SPE.ID_SMETKA_PAYMENT = SP.ID_SMETKA_PAYMENT
             where  SP.ID_SMETKA_HEAD = SH.ID_SMETKA_HEAD
                    and SP.STATUS > 0
                    and SPE.EXTERNAL_IFC = :external_ifc)
           and not exists(select sp.ID_SMETKA_PAYMENT
                          from   SMETKA_PAYMENT SP
                                 join EAI_P2F_SUPPRESS_TP STP on STP.ID_PAYMENT_TYPE = SP.ID_PAYMENT_TYPE
                          where  SP.ID_SMETKA_HEAD = SH.ID_SMETKA_HEAD
                                 and SP.STATUS > 0)
    group by SH.ID_OBJECT, BN.ID_INVENT, S.ID_STOCK_GROUP
    into   :id_object, :id_invent, :id_stock_group, :sum_value
  do begin
    if (:is_object = 1) then complex_id = :id_object;
    else complex_id = 'null';
    if (:is_invent = 1) then complex_id = :complex_id||'_'||:id_invent;
    else complex_id = :complex_id||'_null';
    if (:is_stock_grp = 1) then complex_id = :complex_id||'_'||:id_stock_group;
    else complex_id = :complex_id||'_null';
    id_map_tag = null;
    select MD.ID_MAP_TAG
    from   EAI_MAP_DATA MD
    where  MD.COMPLEX_ID = :complex_id
           and MD.ID_MAP = :id_eai_map
    into   :id_map_tag;
    if (:id_map_tag is null) then
      select MD.ID_MAP_TAG
      from   EAI_MAP_DATA MD
      where  MD.COMPLEX_ID = 'null_null_null'
             and MD.ID_MAP = :id_eai_map
      into   :id_map_tag;
    suspend;
  end
end
^

/* Restore proc. body: ENDWORK_IN_PROGRESS */
ALTER PROCEDURE ENDWORK_IN_PROGRESS(ID_CLIENT_POS INTEGER,
ID_END_WORK INTEGER,
EW_USER INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
ID_END_WORK_REAL INTEGER)
 AS
declare variable dbg varchar(2000);
  declare variable current_id_object integer;
begin
  /*  Description:
  ||  CLIENTS MUST BE LOGOUT AUTOMATICALLY WHEN SOMEONE STARTS END_WORK !!
  ||  TILL NOW THIS IS NOT 100% SURE, SO THIS IS THE PLACE TO CHECK
  ||  IF THE GUI IS WORKING WITH THE LAST END_WORK.
  ||
  ||  Because of pending END_WORK between POS and FRONT we must add another
  ||  check here - if the object is not suppressed for work.
  ||  Suppression is done automatically on the POS END WORK.
  */
  err_code = 0;
  err_text = '';
  if (:ew_user is not null) then begin
    err_code = -152;
    exit;
  end

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_OBJECT')
  returning_values  :current_id_object;

  execute procedure NOM_MODIFY_OBJECT_SUPPRESS(:id_client_pos, :current_id_object, 'check')
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_EW')
  returning_values  :id_end_work_real;
  if (:id_end_work <> :id_end_work_real) then begin
    err_code = -159;
  end
end
^

/* Restore proc. body: ENDWORK_PROCESS */
ALTER PROCEDURE ENDWORK_PROCESS(ID_CLIENT_POS INTEGER,
END_WORK_KIND VARCHAR(30),
NEXT_DATE DATE,
EW_USER_LIST VARCHAR(3000),
ID_CURRENT_EW INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
UPD_NEXT_DATE DATE,
UPD_NEXT_ID_EW INTEGER)
 AS
declare variable id_object integer;
  declare variable id_sales integer;
  declare variable user_name varchar(30);
  declare variable prev_date date;
  declare variable replication integer;
  declare variable id_current_day_ew integer;
  declare variable ew_user_name varchar(30);
  declare variable no_use integer;
  declare variable suppress_object integer;
begin
  err_code = 0;
  err_text = ''; replication = 0; /* MUST BE A SETTING */
  upd_next_id_ew = null;
  /* Description
  ||
  */
  if (:end_work_kind = 'SERVER_ALL') then end_work_kind = 'SERVER';
  if (:end_work_kind not in ('DAY', 'SERVER', 'OBJECT')) then begin
    err_code = -1;
    err_text = 'end_work_kind = '||:end_work_kind;
    exit;
  end
  /*  user expiration*/

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_USER')
  returning_values  :user_name;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_EW')
  returning_values  :id_current_day_ew;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_OBJECT')
  returning_values  :id_object;

  select  O.SYSTEM_DATE
  from   NOM_OBJECT O
  where  O.ID_OBJECT = :id_object
  into   :prev_date;

  RDB$SET_CONTEXT('USER_TRANSACTION', 'ENDWORK_PROCESS', :id_current_day_ew);

  if (:end_work_kind = 'DAY') then begin
    execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'SUPPRESS_OBJECT')
    returning_values  :suppress_object;
    if (:suppress_object = 1) then begin
      execute procedure NOM_MODIFY_OBJECT_SUPPRESS(:id_client_pos, :id_object, 'rise')
      returning_values  :err_code, :err_text;
      if (:err_code < 0) then exit;
    end
    insert into SYSTEM_END_WORK(ID_END_WORK, ID_OBJECT, PREV_DATE, NEXT_DATE,
      EW_USER, EW_KIND, ID_DAY_MASTER)
    values (:id_current_ew, :id_object, :prev_date, :next_date,
      :user_name, 2, :id_current_ew);

    update SYSTEM_END_WORK SEW
    set    SEW.ID_DAY_MASTER = :id_current_ew
    where  SEW.ID_OBJECT = :id_object
           and SEW.ID_DAY_MASTER is null;

    update SYSTEM_NOMERATOR N
    set    N.NUM_NEXT = 1
    where  N.NUM_CLASS = 'BILL'
           and N.NUM_OBJECT = :id_object;

    /* archive */
    execute procedure ENDWORK_SUB_ARCHIVE(:id_current_day_ew)
    returning_values  :err_code;
    if (:err_code < 0) then exit;

    if (:replication = 0) then begin
      /* summarize  */
      execute procedure ENDWORK_SUB_SUMMARY(:id_current_day_ew, :id_object, :prev_date)
      returning_values  :err_code;
      if (:err_code < 0) then exit;

      execute procedure ENDWORK_SUB_CLEAR(:id_current_day_ew)
      returning_values  :err_code;
      if (:err_code < 0) then exit;
    end
    upd_next_date = :next_date;
    execute procedure ENDWORK_GETID(:id_object, 'JUST_GEN', '')
    returning_values  :err_code, :err_text, :upd_next_id_ew, :no_use;
  end else if (:end_work_kind = 'OBJECT') then begin
    /* INTERFASE_TRADE */
    execute procedure EAI_EFFECT(:id_current_day_ew, :id_current_ew, :id_object, :prev_date)
    returning_values  :err_code, :id_sales;

    insert into SALES_HEAD (
      ID_SALES, ID_OBJECT, ID_END_WORK, SALE_DATE, IS_ACTIVE, IS_VALID, NOTE, SALE_NUM)
    select
      SH.ID_SALE_HEAD, SH.ID_OBJECT, SH.END_WORK_DAY, SH.SALE_DATE, SH.IS_ACTIVE, 1, SH.NOTE, SH.ID_SALE_HEAD
    from   EAI_EFFECT_SALE SH
    where  SH.ID_SALE_HEAD = :id_sales;
    
    insert into SALES_LINE (
      ID_SALE_LINE, ID_SALES, ID_STOCK, ID_INVENT, SALE_QTY, SALE_PRICE,
      BASE_PRICE, IS_DDS, DDS_STAVKA, DDS_GROUP, POS_CODE, IS_FISCAL, ID_MENU,
      ID_SMETKA, ID_TYPE_PAYMENT)
    select
      SL.ID_SALE_LINE, SL.ID_SALE_HEAD, SL.ID_POST_ITEM, SL.ID_INVENT_DELIVERY, SL.SALE_QTY, 0,
      0, 1, SL.VAT_VALUE, SL.VAT_NAME, SL.POS_CODE, 1, -1,
      -1, null
    from   EAI_EFFECT_LINE SL
    where  SL.ID_SALE_HEAD = :id_sales;

    update SMETKA_HEAD SH
    set    SH.END_WORK_OBJECT = :id_current_ew
    where  SH.ID_END_WORK = :id_current_day_ew
           and SH.END_WORK_OBJECT is null;

    insert into SYSTEM_END_WORK(ID_END_WORK, ID_OBJECT, PREV_DATE, NEXT_DATE,
      EW_USER, EW_KIND, ID_DAY_MASTER)
    values (:id_current_ew, :id_object, :prev_date, null,
      :user_name, 1, null);
  end else if (:end_work_kind = 'SERVER') then begin
    for
      select SSP.ITEM
      from   SYSTEM_STRING_PARSER(:ew_user_list, ',') SSP
      into   :ew_user_name
    do begin
      update SMETKA_HEAD SH
      set    SH.END_WORK_USER = :id_current_ew
      where  SH.ID_END_WORK = :id_current_day_ew
             and SH.END_WORK_USER is null
             and SH.USER_OWNER = :ew_user_name;
    end

    insert into SYSTEM_END_WORK(ID_END_WORK, ID_OBJECT, PREV_DATE, NEXT_DATE,
      EW_USER, EW_KIND, ID_DAY_MASTER)
    values (:id_current_ew, :id_object, :prev_date, null,
      :user_name, 0, null);
  end

  RDB$SET_CONTEXT('USER_TRANSACTION', 'ENDWORK_PROCESS', null);
end
^

/* Restore proc. body: ENDWORK_REGENERATE */
ALTER PROCEDURE ENDWORK_REGENERATE(ID_DAY_EW INTEGER,
OPTIONS VARCHAR(255))
 RETURNS(ERR_CODE INTEGER)
 AS
declare variable dbg varchar(2000);
  declare variable id_object integer;
  declare variable fiscal_date date;
  declare variable id_invent_ew integer;
  declare variable no_use varchar(20);
begin
  /*  Description:
  ||
  */
  select EW.ID_OBJECT, EW.PREV_DATE
  from   SYSTEM_END_WORK EW
  where  EW.ID_END_WORK = :id_day_ew
  into   :id_object, :fiscal_date;

  execute procedure ENDWORK_UNDO(:id_day_ew, 'REVERT');
  
  execute procedure ENDWORK_SUB_ARCHIVE(:id_day_ew)
  returning_values  :err_code;
  
  execute procedure ENDWORK_SUB_SUMMARY(:id_day_ew, :id_object, :fiscal_date)
  returning_values  :err_code;

  if (:options = 'with_effect_export') then begin
    for
      select EW.ID_END_WORK
      from   SYSTEM_END_WORK EW
      where  EW.ID_DAY_MASTER = :id_day_ew
             and EW.EW_KIND = 1
      into   :id_invent_ew
    do begin
      delete from EAI_EFFECT_SALE S
      where  S.END_WORK_DAY = :id_invent_ew;
      update SMETKA_HEAD SH
      set    SH.END_WORK_OBJECT = null
      where  SH.END_WORK_OBJECT = :id_invent_ew;
      execute procedure EAI_EFFECT(:id_day_ew, :id_invent_ew, :id_object, :fiscal_date)
      returning_values  :err_code, :no_use;
    end
  end
  execute procedure ENDWORK_SUB_CLEAR(:id_day_ew)
  returning_values  :err_code;
end
^

/* Restore proc. body: ENDWORK_SKIP_DAYS */
ALTER PROCEDURE ENDWORK_SKIP_DAYS(ID_CLIENT_POS INTEGER,
ID_OBJECT INTEGER,
NEW_SYSTEM_DATE DATE)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable dbg varchar(2000);
  declare variable id_current_ew integer;
  declare variable next_id_ew integer;
  declare variable prev_date date;
  declare variable no_use varchar(200);
  declare variable curr_user_name varchar(50);
begin
  execute procedure SYSTEM_CHECK_RIGHT(:id_client_pos, 'EW_DAY')
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_USER')
  returning_values  :curr_user_name;

  select O.ID_EW_NEXT, O.SYSTEM_DATE
  from   NOM_OBJECT O
  where  O.ID_OBJECT = :id_object
  into   :id_current_ew, :prev_date;

  if (:prev_date >= :new_system_date) then begin
    err_code = -165;
    err_text = 'new = '||:new_system_date||' old = '||:prev_date;
    exit;
  end
  if (exists(
     select * from SMETKA_HEAD SH
     where  SH.ID_END_WORK = :id_current_ew)
  ) then begin
    err_code = -200;
    err_text = 'Standart Day end work must be done first!';
    exit;
  end

  execute procedure NOM_MODIFY_OBJECT_SUPPRESS(:id_client_pos, :id_object, 'rise')
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;

  insert into SYSTEM_END_WORK(ID_END_WORK, ID_OBJECT, PREV_DATE, NEXT_DATE,
    EW_USER, EW_KIND, ID_DAY_MASTER)
  values (:id_current_ew, :id_object, :prev_date, :new_system_date,
    :curr_user_name, 2, :id_current_ew);

  update SYSTEM_END_WORK SEW
  set    SEW.ID_DAY_MASTER = :id_current_ew
  where  SEW.ID_OBJECT = :id_object
         and SEW.ID_DAY_MASTER is null;

  execute procedure ENDWORK_GETID(:id_object, 'JUST_GEN', '')
  returning_values  :err_code, :err_text, :next_id_ew, :no_use;
  if (:err_code < 0) then exit;

  update NOM_OBJECT O
  set    O.SYSTEM_DATE = :new_system_date,
         O.ID_EW_NEXT = :next_id_ew
  where  O.ID_OBJECT = :id_object;

  execute procedure NOM_MODIFY_OBJECT_SUPPRESS(:id_client_pos, :id_object, 'clear')
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;
end
^

/* Restore proc. body: ENDWORK_SUB_SUMMARY */
ALTER PROCEDURE ENDWORK_SUB_SUMMARY(ID_END_WORK INTEGER,
ID_OBJECT INTEGER,
DATE_FISCAL DATE)
 RETURNS(ERR_CODE INTEGER)
 AS
begin
  err_code = 0;
  /* SUM_STOCK */
  execute procedure SUMMARY_STOCK(:id_end_work, :id_object, :date_fiscal)
  returning_values  :err_code;

  /* SUM_DAY */
  execute procedure SUMMARY_DAY(:id_end_work, :id_object, :date_fiscal)
  returning_values  :err_code;

  /* SUM_DISCOUNT */
  insert   into SUM_DISCOUNT (ID_END_WORK, ID_OBJECT, DATE_FISCAL, DATE_REAL,
           ID_DISCOUNT, DISCOUNT_BASE, DISCOUNT_SUM, DISCOUNT_CNT, IS_SURCHARGE)
  select   :id_end_work, :id_object, :date_fiscal, SH.START_DATE,
           SD.ID_DISCOUNT, sum(SD.DISCOUNT_BASE), sum(SD.DISCOUNT_SUM), count(*), 0
  from     SMETKA_HEAD SH
           join SMETKA_DISCOUNT SD on SD.ID_SMETKA_HEAD = SH.ID_SMETKA_HEAD
  where    SH.ID_END_WORK = :id_end_work
           and SH.STATUS > 0
  group by SH.START_DATE, SD.ID_DISCOUNT;

  /* SUM_VOID */
  insert   into SUM_VOID (ID_END_WORK, ID_OBJECT, DATE_FISCAL, DATE_REAL,
           ID_VOID_REASON, VOID_SUM, VOID_CNT, VOID_QTY)
  select   :id_end_work, :id_object, :date_fiscal, SH.START_DATE,
           SM.ID_REASON, sum(SL.VOID_SUM), count(*), sum(SL.QTY_VOID)
  from     SMETKA_MANAGE SM
           join SMETKA_HEAD SH on SH.ID_SMETKA_HEAD = SM.ID_SMETKA_HEAD
           join SMETKA_LINE SL on SL.ID_LINE_VOID = SM.ID_SMETKA_MANAGE
  where    SM.ID_END_WORK = :id_end_work
/*           and SM.MANAGE_TYPE = 'LINE_VOID' MISSING 'OPEN_VOID', etc.*/
  group by SH.START_DATE, SM.ID_REASON;

  /* SUM_PAY */
  insert   into SUM_PAY (ID_END_WORK, ID_OBJECT, DATE_FISCAL, DATE_REAL,
           ID_PAYMENT_TYPE, PAY_CNT, PAY_SUM, FISC_STATUS)
  select   :id_end_work, :id_object, :date_fiscal, SH.START_DATE,
           SP.ID_PAYMENT_TYPE, count(*), sum(SP.PAYMENT_VALUE), SP.FISC_STATUS+(SP.STATUS-1)
  from     SMETKA_HEAD SH
           join SMETKA_PAYMENT SP on SP.ID_SMETKA_HEAD = SH.ID_SMETKA_HEAD
  where    SH.ID_END_WORK = :id_end_work
  group by SH.START_DATE, SP.ID_PAYMENT_TYPE, SP.FISC_STATUS, SP.STATUS;
/*
FISC_STATUS       0   1   2
SUM_FISC_STATUS  -3  -2  -1
*/
end
^

/* Restore proc. body: MANAGE_CHANGE_OWNER */
ALTER PROCEDURE MANAGE_CHANGE_OWNER(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
NEW_OWNER VARCHAR(30))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable id_smetka_manage integer;
  declare variable smetka_status integer;
  declare variable id_object integer;
begin
  select SH.STATUS, SH.ID_OBJECT
  from   SMETKA_HEAD SH
  where  SH.ID_SMETKA_HEAD = :id_smetka_head
  into   :smetka_status, :id_object;
  if (:smetka_status is null) then err_code = -158;
  else if (:smetka_status <> 1) then err_code = -153;
  if (:err_code < 0) then exit;

  execute procedure SYSTEM_CHECK_RIGHT(:id_client_pos, 'BILL_CHANGE_OWNER')
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;

  execute procedure MANAGE_COMMON(:id_client_pos, null,
    :id_smetka_head, 'CHANGE_OWNER', null, null, '', 'START')
  returning_values  :err_code, :err_text, :id_smetka_manage;
  if (:err_code < 0) then exit;

  execute procedure BILL_LOCK (-:ID_SMETKA_HEAD, :ID_CLIENT_POS, :id_object, :NEW_OWNER);

  update SMETKA_HEAD SH
  set    SH.USER_OWNER = :new_owner
  where  SH.ID_SMETKA_HEAD = :id_smetka_head;

  execute procedure MANAGE_COMMON(null, null, :id_smetka_head, null,
    null, null, null, 'STOP')
  returning_values  :err_code, :err_text, :id_smetka_manage;
  if (:err_code < 0) then exit;

  execute procedure BILL_LOCK (-:ID_SMETKA_HEAD, :ID_CLIENT_POS, null, null);
END
^

/* Restore proc. body: MANAGE_MOVE_BILL */
ALTER PROCEDURE MANAGE_MOVE_BILL(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
NEW_TABLE_NO INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable id_smetka_manage integer;
  declare variable sh_dbkey char(8);
  declare variable status integer;
  declare variable smetka_status integer;
  declare variable dbg varchar(2000);
begin
  /*  Description:
  ||  PREHVYRLIANE SMETKATA NA DRUGA MASA
  */
  err_code = 0;
  err_text = '';
  select SH.STATUS
  from   SMETKA_HEAD SH
  where  SH.ID_SMETKA_HEAD = :id_smetka_head
  into   :smetka_status;
  if (:smetka_status is null) then err_code = -158;
  else if (:smetka_status <> 1) then err_code = -153;
  if (:err_code < 0) then exit;

  execute procedure SYSTEM_CHECK_RIGHT(:id_client_pos, 'BILL_CHANGE_TABLE')
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;

  execute procedure MANAGE_COMMON(:id_client_pos, null, :id_smetka_head, 'MOVE_BILL',
    null, null, '', 'START')
  returning_values  :err_code, :err_text, :id_smetka_manage;
  if (:err_code < 0) then exit;

  select SH.RDB$DB_KEY, SH.STATUS
  from   SMETKA_HEAD SH
  where  SH.ID_SMETKA_HEAD = :id_smetka_head
  into   :sh_dbkey, :status;
  if (:status <> 1) then err_code = -153;

  update SMETKA_HEAD SH
  set    SH.TABLE_NO = :new_table_no
  where  SH.RDB$DB_KEY = :sh_dbkey;

  execute procedure MANAGE_COMMON(null, null, :id_smetka_head, null,
    null, null, null, 'STOP')
  returning_values  :err_code, :err_text, :id_smetka_manage;
END
^

/* Restore proc. body: RIGHTS_MODIFY_AUDIT_USER */
ALTER PROCEDURE RIGHTS_MODIFY_AUDIT_USER(USER_PASSWORD VARCHAR(50),
SYSUSER_NAME VARCHAR(20),
SYSUSER_PASSWORD VARCHAR(20),
OPERATION VARCHAR(10))
 RETURNS(USER_NAME VARCHAR(30),
ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable is_expired smallint;
  declare variable lang_code varchar(10);
  declare variable user_operation varchar(10);
  declare variable user_name_long varchar(50);
  declare variable id_client_pos integer;
begin
  id_client_pos = RDB$GET_CONTEXT('USER_SESSION', 'ID_CLIENT_POS');

  execute procedure SYSTEM_CHECK_RIGHT(:id_client_pos, 'RIGHTS_AUDIT_MANAGE')
  returning_values (:ERR_CODE, :ERR_TEXT);
  if (:ERR_CODE <> 0) then exit;

  USER_NAME = '_AUDITOR_';
  user_name_long = 'Clock audit system user';
  lang_code = 'bg';
  is_expired = iif(:OPERATION = 'activate', 0, 1);

  if (:OPERATION = 'activate' and not exists (select * from RIGHT_USER u where u.USER_NAME = :USER_NAME)) then
    user_operation = 'add';
  else
    user_operation = 'mod';

  execute procedure RIGHTS_MODIFY_USER(:user_name, :user_name_long, :USER_PASSWORD,
          null, :lang_code, :SYSUSER_NAME, :SYSUSER_PASSWORD, 1, null, :is_expired, null, :user_operation)
  returning_values (:ERR_CODE, :ERR_TEXT);

  if (:user_operation = 'add' and coalesce(:ERR_CODE, 0) = 0) then begin
    update RIGHT_USER ru
    set    ru.DB_ROLE = 'AUDITOR_ROLE'
    where  ru.USER_NAME = :USER_NAME;
  end
end
^

/* Creating trigger... */
CREATE TRIGGER RIGHT_USER_BD0 FOR RIGHT_USER
ACTIVE BEFORE DELETE POSITION 0 
AS
begin
  if (old.user_name = 'SYSDBA') then exception FORBIDDEN_OPERATION 'Can not delete "System user"!';
end
^


/* Alter Procedure... */
/* Alter (BILL_POST_FINALIZE_NUM) */
ALTER PROCEDURE BILL_POST_FINALIZE_NUM(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
CLOSE_TYPE VARCHAR(10),
ID_PROGRAM_LEVEL INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
SMETKA_NUM INTEGER)
 AS
declare variable id_object integer;
  declare variable bon_num integer;
  declare variable sbi_dbkey char(8);
  declare variable sh_dbkey char(8);
  declare variable id_invent integer;
  declare variable grand_total_sum numeric(15,4);
  declare variable id_contragent integer;
  declare variable id_pool integer;
  declare variable post_reason varchar(100);
  declare variable payment_value numeric (15,4);
  declare variable object_name varchar(50);
  declare variable id_smetka_trans_pay integer;
  declare variable payment_name varchar(30);
  declare variable signv integer;
  declare variable no_post integer;
  declare variable acc_shorttext varchar(30);
  declare variable object_text varchar(30);
begin
  /*  Description:
  ||  This procedure is called in special (artificial) transaction mode - REPETABLE ON LOCK.
  ||  This is the reason why CONTRAGENT TURNOVER is stored and eventualy sumarized here.
  */
  err_code = 0;
  err_text = '';

  select SH.rdb$db_key, SH.SMETKA_NUM, SH.GRAND_TOTAL_SUM, SH.ID_CONTRAGENT, SH.ID_OBJECT, O.OBJECT_NAME
  from   SMETKA_HEAD SH
         join NOM_OBJECT O on O.ID_OBJECT = SH.ID_OBJECT
  where  SH.ID_SMETKA_HEAD = :id_smetka_head
  into   :sh_dbkey, :smetka_num, :grand_total_sum, :id_contragent, :id_object, :object_name;

  if (:close_type not in ('TOTAL_VOID', 'OPEN_VOID')) then begin
    if (:smetka_num = 0) then begin
      execute procedure BILL_GET_NUM(:id_object, 'BILL')
      returning_values  :smetka_num;

      update SMETKA_HEAD SH
      set    SH.SMETKA_NUM = :smetka_num
      where  SH.rdb$db_key = :sh_dbkey;
    end
  end

  for
    select SBI.rdb$db_key, SBI.ID_INVENT
    from   SMETKA_BON_INVENT SBI
    where  SBI.ID_SMETKA_HEAD = :id_smetka_head
           and SBI.ID_SMETKA_TRANS = :id_smetka_trans
    into   :sbi_dbkey, :id_invent
  do begin
    execute procedure BILL_GET_NUM(:id_invent, 'BON')
    returning_values  :bon_num;
    update  SMETKA_BON_INVENT SBIu
    set     SBIu.BON_NUM = :bon_num
    where   SBIu.rdb$db_key = :sbi_dbkey;
  end

  if (:close_type = 'TOTAL') then begin
    /* CALCULATE AND EVALUATE TAXES, INCLUDED INTO STOCK PRICES */
    execute procedure BILL_TAXES_CALC (:ID_SMETKA_HEAD);

    if (:id_contragent > 0) then begin
      /* MANAGE CONTRAGENT POOLS */
      execute procedure SYSTEM_GET_TEXT(:id_client_pos, 'ACCOUNT_SHORT_NAME')
      returning_values  :acc_shorttext;
  
      execute procedure SYSTEM_GET_TEXT(:id_client_pos, 'OBJECT')
      returning_values  :object_text;
  
      for
        select PT.ID_POOL, PT.PAYMENT_NAME, PT.POOL_SIGN,
               SP.ID_SMETKA_TRANS, SP.PAYMENT_VALUE
        from   SMETKA_PAYMENT SP
               join NOM_PAYMENT_TYPE PT on PT.ID_PAYMENT_TYPE = SP.ID_PAYMENT_TYPE
        where  SP.STATUS > 0
               and SP.ID_SMETKA_HEAD = :id_smetka_head
        into   :id_pool, :payment_name, :signv,
               :id_smetka_trans_pay, :payment_value
      do begin
        no_post = 0;
        if (:id_pool is null) then no_post = 1;
        else if ((exists(select * from CL_PROGRAM P where P.ID_POOL = :id_pool)) and (:id_program_level is null)) then no_post = 1;
  
        if (:no_post = 0) then begin
          payment_value = :signv*:payment_value;
    
          post_reason = substring((:acc_shorttext||:smetka_num||' '||:payment_name||' '||:payment_value||' '||:object_text||' '||:object_name) from 1 for 100);
          execute procedure CL_POST_POOL_VALUE(:id_client_pos, :id_smetka_head, :id_contragent,
            :id_pool, :payment_value, 0, :post_reason, :id_smetka_trans_pay, 3)
          returning_values  :err_code, :err_text;
          if (:err_code < 0) then exit;
        end
      end
      post_reason = substring((:acc_shorttext||:smetka_num||' '||:close_type||' '||:grand_total_sum||' '||:object_text||' '||:object_name) from 1 for 100);
      execute procedure CL_POST_POOL_VALUE(:id_client_pos, :id_smetka_head, :id_contragent,
        1, :grand_total_sum, 0, :post_reason, :id_smetka_trans_pay, 3)
      returning_values  :err_code, :err_text;
    end
  end
end
^

/* empty dependent procedure body */
/* Clear: BILL_OPEN for: ENDWORK_IN_PROGRESS */
ALTER PROCEDURE BILL_OPEN(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
TABLE_NO INTEGER,
CUSTOMER_CNT INTEGER,
OPEN_TYPE VARCHAR(10),
ID_END_WORK INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_SMETKA_HEAD INTEGER,
NEW_ID_SMETKA_TRANS INTEGER,
DEFAULT_PRICE_LIST INTEGER,
MANUAL_PRICE_LIST INTEGER,
SMETKA_NUM INTEGER,
ID_CONTRAGENT INTEGER,
CONTRAGENT_NAME VARCHAR(50),
ID_SMETKA_DISCOUNT INTEGER,
ID_SURCHARGE INTEGER,
SURCHARGE_NAME VARCHAR(50),
SURCHARGE_VALUE NUMERIC(15,4),
IS_PERCENT_SURCHARGE INTEGER,
ID_DISCOUNT INTEGER,
IS_PERCENT_DISCOUNT INTEGER,
DISCOUNT_NAME VARCHAR(50),
DISCOUNT_STATUS INTEGER,
DISCOUNT_VALUE NUMERIC(15,4),
START_DATETIME TIMESTAMP,
LAST_CUSTOMER_CNT INTEGER,
ID_PROGRAM_LEVEL INTEGER,
CARD_CODE VARCHAR(50))
 AS
 BEGIN SUSPEND; END
^

/* empty dependent procedure body */
/* Clear: MANAGE_COMMON for: ENDWORK_IN_PROGRESS */
ALTER PROCEDURE MANAGE_COMMON(ID_CLIENT_POS INTEGER,
ID_SMETKA_MANAGE INTEGER,
ID_SMETKA_HEAD INTEGER,
MANAGE_TYPE VARCHAR(30),
ID_REASON INTEGER,
ID_REASON_OVERRULE INTEGER,
MANAGE_DATA VARCHAR(100),
OPERATION VARCHAR(20))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_SMETKA_MANAGE INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* Alter (ENDWORK_IN_PROGRESS) */
ALTER PROCEDURE ENDWORK_IN_PROGRESS(ID_CLIENT_POS INTEGER,
ID_END_WORK INTEGER,
EW_USER INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
ID_END_WORK_REAL INTEGER)
 AS
declare variable dbg varchar(2000);
  declare variable current_id_object integer;
begin
  /*  Description:
  ||  CLIENTS MUST BE LOGOUT AUTOMATICALLY WHEN SOMEONE STARTS END_WORK !!
  ||  TILL NOW THIS IS NOT 100% SURE, SO THIS IS THE PLACE TO CHECK
  ||  IF THE GUI IS WORKING WITH THE LAST END_WORK.
  ||
  ||  Because of pending END_WORK between POS and FRONT we must add another
  ||  check here - if the object is not suppressed for work.
  ||  Suppression is done automatically on the POS END WORK.
  */
  err_code = 0;
  err_text = '';
  if (:ew_user is not null) then begin
    err_code = -152;
    exit;
  end

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_OBJECT')
  returning_values  :current_id_object;

  execute procedure NOM_MODIFY_OBJECT_SUPPRESS(:id_client_pos, :current_id_object, 'check')
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_EW')
  returning_values  :id_end_work_real;
  if (:id_end_work <> :id_end_work_real) then begin
    err_code = -159;
  end
end
^

/* Alter (ENDWORK_PROCESS) */
ALTER PROCEDURE ENDWORK_PROCESS(ID_CLIENT_POS INTEGER,
END_WORK_KIND VARCHAR(30),
NEXT_DATE DATE,
EW_USER_LIST VARCHAR(3000),
ID_CURRENT_EW INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
UPD_NEXT_DATE DATE,
UPD_NEXT_ID_EW INTEGER)
 AS
declare variable id_object integer;
  declare variable id_sales integer;
  declare variable user_name varchar(30);
  declare variable prev_date date;
  declare variable replication integer;
  declare variable id_current_day_ew integer;
  declare variable ew_user_name varchar(30);
  declare variable no_use integer;
  declare variable suppress_object integer;
begin
  err_code = 0;
  err_text = ''; replication = 0; /* MUST BE A SETTING */
  upd_next_id_ew = null;
  /* Description
  ||
  */
  if (:end_work_kind = 'SERVER_ALL') then end_work_kind = 'SERVER';
  if (:end_work_kind not in ('DAY', 'SERVER', 'OBJECT')) then begin
    err_code = -1;
    err_text = 'end_work_kind = '||:end_work_kind;
    exit;
  end
  /*  user expiration*/

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_USER')
  returning_values  :user_name;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_EW')
  returning_values  :id_current_day_ew;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_OBJECT')
  returning_values  :id_object;

  select  O.SYSTEM_DATE
  from   NOM_OBJECT O
  where  O.ID_OBJECT = :id_object
  into   :prev_date;

  RDB$SET_CONTEXT('USER_TRANSACTION', 'ENDWORK_PROCESS', :id_current_day_ew);

  if (:end_work_kind = 'DAY') then begin
    execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'SUPPRESS_OBJECT')
    returning_values  :suppress_object;
    if (:suppress_object = 1) then begin
      execute procedure NOM_MODIFY_OBJECT_SUPPRESS(:id_client_pos, :id_object, 'rise')
      returning_values  :err_code, :err_text;
      if (:err_code < 0) then exit;
    end
    insert into SYSTEM_END_WORK(ID_END_WORK, ID_OBJECT, PREV_DATE, NEXT_DATE,
      EW_USER, EW_KIND, ID_DAY_MASTER)
    values (:id_current_ew, :id_object, :prev_date, :next_date,
      :user_name, 2, :id_current_ew);

    update SYSTEM_END_WORK SEW
    set    SEW.ID_DAY_MASTER = :id_current_ew
    where  SEW.ID_OBJECT = :id_object
           and SEW.ID_DAY_MASTER is null;

    update SYSTEM_NOMERATOR N
    set    N.NUM_NEXT = 1
    where  N.NUM_CLASS = 'BILL'
           and N.NUM_OBJECT = :id_object;

    /* archive */
    execute procedure ENDWORK_SUB_ARCHIVE(:id_current_day_ew)
    returning_values  :err_code;
    if (:err_code < 0) then exit;

    if (:replication = 0) then begin
      /* summarize  */
      execute procedure ENDWORK_SUB_SUMMARY(:id_current_day_ew, :id_object, :prev_date)
      returning_values  :err_code;
      if (:err_code < 0) then exit;

      execute procedure ENDWORK_SUB_CLEAR(:id_current_day_ew)
      returning_values  :err_code;
      if (:err_code < 0) then exit;
    end
    upd_next_date = :next_date;
    execute procedure ENDWORK_GETID(:id_object, 'JUST_GEN', '')
    returning_values  :err_code, :err_text, :upd_next_id_ew, :no_use;
  end else if (:end_work_kind = 'OBJECT') then begin
    /* INTERFASE_TRADE */
    execute procedure EAI_EFFECT(:id_current_day_ew, :id_current_ew, :id_object, :prev_date)
    returning_values  :err_code, :id_sales;

    insert into SALES_HEAD (
      ID_SALES, ID_OBJECT, ID_END_WORK, SALE_DATE, IS_ACTIVE, IS_VALID, NOTE, SALE_NUM)
    select
      SH.ID_SALE_HEAD, SH.ID_OBJECT, SH.END_WORK_DAY, SH.SALE_DATE, SH.IS_ACTIVE, 1, SH.NOTE, SH.ID_SALE_HEAD
    from   EAI_EFFECT_SALE SH
    where  SH.ID_SALE_HEAD = :id_sales;
    
    insert into SALES_LINE (
      ID_SALE_LINE, ID_SALES, ID_STOCK, ID_INVENT, SALE_QTY, SALE_PRICE,
      BASE_PRICE, IS_DDS, DDS_STAVKA, DDS_GROUP, POS_CODE, IS_FISCAL, ID_MENU,
      ID_SMETKA, ID_TYPE_PAYMENT)
    select
      SL.ID_SALE_LINE, SL.ID_SALE_HEAD, SL.ID_POST_ITEM, SL.ID_INVENT_DELIVERY, SL.SALE_QTY, 0,
      0, 1, SL.VAT_VALUE, SL.VAT_NAME, SL.POS_CODE, 1, -1,
      -1, null
    from   EAI_EFFECT_LINE SL
    where  SL.ID_SALE_HEAD = :id_sales;

    update SMETKA_HEAD SH
    set    SH.END_WORK_OBJECT = :id_current_ew
    where  SH.ID_END_WORK = :id_current_day_ew
           and SH.END_WORK_OBJECT is null;

    insert into SYSTEM_END_WORK(ID_END_WORK, ID_OBJECT, PREV_DATE, NEXT_DATE,
      EW_USER, EW_KIND, ID_DAY_MASTER)
    values (:id_current_ew, :id_object, :prev_date, null,
      :user_name, 1, null);
  end else if (:end_work_kind = 'SERVER') then begin
    for
      select SSP.ITEM
      from   SYSTEM_STRING_PARSER(:ew_user_list, ',') SSP
      into   :ew_user_name
    do begin
      update SMETKA_HEAD SH
      set    SH.END_WORK_USER = :id_current_ew
      where  SH.ID_END_WORK = :id_current_day_ew
             and SH.END_WORK_USER is null
             and SH.USER_OWNER = :ew_user_name;
    end

    insert into SYSTEM_END_WORK(ID_END_WORK, ID_OBJECT, PREV_DATE, NEXT_DATE,
      EW_USER, EW_KIND, ID_DAY_MASTER)
    values (:id_current_ew, :id_object, :prev_date, null,
      :user_name, 0, null);
  end

  RDB$SET_CONTEXT('USER_TRANSACTION', 'ENDWORK_PROCESS', null);
end
^

/* Alter (ENDWORK_REGENERATE) */
ALTER PROCEDURE ENDWORK_REGENERATE(ID_DAY_EW INTEGER,
OPTIONS VARCHAR(255))
 RETURNS(ERR_CODE INTEGER)
 AS
declare variable dbg varchar(2000);
  declare variable id_object integer;
  declare variable fiscal_date date;
  declare variable id_invent_ew integer;
  declare variable no_use varchar(20);
begin
  /*  Description:
  ||
  */
  select EW.ID_OBJECT, EW.PREV_DATE
  from   SYSTEM_END_WORK EW
  where  EW.ID_END_WORK = :id_day_ew
  into   :id_object, :fiscal_date;

  execute procedure ENDWORK_UNDO(:id_day_ew, 'REVERT');
  
  execute procedure ENDWORK_SUB_ARCHIVE(:id_day_ew)
  returning_values  :err_code;
  
  execute procedure ENDWORK_SUB_SUMMARY(:id_day_ew, :id_object, :fiscal_date)
  returning_values  :err_code;

  if (:options = 'with_effect_export') then begin
    for
      select EW.ID_END_WORK
      from   SYSTEM_END_WORK EW
      where  EW.ID_DAY_MASTER = :id_day_ew
             and EW.EW_KIND = 1
      into   :id_invent_ew
    do begin
      delete from EAI_EFFECT_SALE S
      where  S.END_WORK_DAY = :id_invent_ew;
      update SMETKA_HEAD SH
      set    SH.END_WORK_OBJECT = null
      where  SH.END_WORK_OBJECT = :id_invent_ew;
      execute procedure EAI_EFFECT(:id_day_ew, :id_invent_ew, :id_object, :fiscal_date)
      returning_values  :err_code, :no_use;
    end
  end
  execute procedure ENDWORK_SUB_CLEAR(:id_day_ew)
  returning_values  :err_code;
end
^

/* Alter (ENDWORK_SKIP_DAYS) */
ALTER PROCEDURE ENDWORK_SKIP_DAYS(ID_CLIENT_POS INTEGER,
ID_OBJECT INTEGER,
NEW_SYSTEM_DATE DATE)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable dbg varchar(2000);
  declare variable id_current_ew integer;
  declare variable next_id_ew integer;
  declare variable prev_date date;
  declare variable no_use varchar(200);
  declare variable curr_user_name varchar(50);
begin
  execute procedure SYSTEM_CHECK_RIGHT(:id_client_pos, 'EW_DAY')
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_USER')
  returning_values  :curr_user_name;

  select O.ID_EW_NEXT, O.SYSTEM_DATE
  from   NOM_OBJECT O
  where  O.ID_OBJECT = :id_object
  into   :id_current_ew, :prev_date;

  if (:prev_date >= :new_system_date) then begin
    err_code = -165;
    err_text = 'new = '||:new_system_date||' old = '||:prev_date;
    exit;
  end
  if (exists(
     select * from SMETKA_HEAD SH
     where  SH.ID_END_WORK = :id_current_ew)
  ) then begin
    err_code = -200;
    err_text = 'Standart Day end work must be done first!';
    exit;
  end

  execute procedure NOM_MODIFY_OBJECT_SUPPRESS(:id_client_pos, :id_object, 'rise')
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;

  insert into SYSTEM_END_WORK(ID_END_WORK, ID_OBJECT, PREV_DATE, NEXT_DATE,
    EW_USER, EW_KIND, ID_DAY_MASTER)
  values (:id_current_ew, :id_object, :prev_date, :new_system_date,
    :curr_user_name, 2, :id_current_ew);

  update SYSTEM_END_WORK SEW
  set    SEW.ID_DAY_MASTER = :id_current_ew
  where  SEW.ID_OBJECT = :id_object
         and SEW.ID_DAY_MASTER is null;

  execute procedure ENDWORK_GETID(:id_object, 'JUST_GEN', '')
  returning_values  :err_code, :err_text, :next_id_ew, :no_use;
  if (:err_code < 0) then exit;

  update NOM_OBJECT O
  set    O.SYSTEM_DATE = :new_system_date,
         O.ID_EW_NEXT = :next_id_ew
  where  O.ID_OBJECT = :id_object;

  execute procedure NOM_MODIFY_OBJECT_SUPPRESS(:id_client_pos, :id_object, 'clear')
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;
end
^

/* Alter (ENDWORK_SUB_SUMMARY) */
ALTER PROCEDURE ENDWORK_SUB_SUMMARY(ID_END_WORK INTEGER,
ID_OBJECT INTEGER,
DATE_FISCAL DATE)
 RETURNS(ERR_CODE INTEGER)
 AS
begin
  err_code = 0;
  /* SUM_STOCK */
  execute procedure SUMMARY_STOCK(:id_end_work, :id_object, :date_fiscal)
  returning_values  :err_code;

  /* SUM_DAY */
  execute procedure SUMMARY_DAY(:id_end_work, :id_object, :date_fiscal)
  returning_values  :err_code;

  /* SUM_DISCOUNT */
  insert   into SUM_DISCOUNT (ID_END_WORK, ID_OBJECT, DATE_FISCAL, DATE_REAL,
           ID_DISCOUNT, DISCOUNT_BASE, DISCOUNT_SUM, DISCOUNT_CNT, IS_SURCHARGE)
  select   :id_end_work, :id_object, :date_fiscal, SH.START_DATE,
           SD.ID_DISCOUNT, sum(SD.DISCOUNT_BASE), sum(SD.DISCOUNT_SUM), count(*), 0
  from     SMETKA_HEAD SH
           join SMETKA_DISCOUNT SD on SD.ID_SMETKA_HEAD = SH.ID_SMETKA_HEAD
  where    SH.ID_END_WORK = :id_end_work
           and SH.STATUS > 0
  group by SH.START_DATE, SD.ID_DISCOUNT;

  /* SUM_VOID */
  insert   into SUM_VOID (ID_END_WORK, ID_OBJECT, DATE_FISCAL, DATE_REAL,
           ID_VOID_REASON, VOID_SUM, VOID_CNT, VOID_QTY)
  select   :id_end_work, :id_object, :date_fiscal, SH.START_DATE,
           SM.ID_REASON, sum(SL.VOID_SUM), count(*), sum(SL.QTY_VOID)
  from     SMETKA_MANAGE SM
           join SMETKA_HEAD SH on SH.ID_SMETKA_HEAD = SM.ID_SMETKA_HEAD
           join SMETKA_LINE SL on SL.ID_LINE_VOID = SM.ID_SMETKA_MANAGE
  where    SM.ID_END_WORK = :id_end_work
/*           and SM.MANAGE_TYPE = 'LINE_VOID' MISSING 'OPEN_VOID', etc.*/
  group by SH.START_DATE, SM.ID_REASON;

  /* SUM_PAY */
  insert   into SUM_PAY (ID_END_WORK, ID_OBJECT, DATE_FISCAL, DATE_REAL,
           ID_PAYMENT_TYPE, PAY_CNT, PAY_SUM, FISC_STATUS)
  select   :id_end_work, :id_object, :date_fiscal, SH.START_DATE,
           SP.ID_PAYMENT_TYPE, count(*), sum(SP.PAYMENT_VALUE), SP.FISC_STATUS+(SP.STATUS-1)
  from     SMETKA_HEAD SH
           join SMETKA_PAYMENT SP on SP.ID_SMETKA_HEAD = SH.ID_SMETKA_HEAD
  where    SH.ID_END_WORK = :id_end_work
  group by SH.START_DATE, SP.ID_PAYMENT_TYPE, SP.FISC_STATUS, SP.STATUS;
/*
FISC_STATUS       0   1   2
SUM_FISC_STATUS  -3  -2  -1
*/
end
^

/* Alter (MANAGE_CHANGE_OWNER) */
ALTER PROCEDURE MANAGE_CHANGE_OWNER(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
NEW_OWNER VARCHAR(30))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable id_smetka_manage integer;
  declare variable smetka_status integer;
  declare variable id_object integer;
begin
  select SH.STATUS, SH.ID_OBJECT
  from   SMETKA_HEAD SH
  where  SH.ID_SMETKA_HEAD = :id_smetka_head
  into   :smetka_status, :id_object;
  if (:smetka_status is null) then err_code = -158;
  else if (:smetka_status <> 1) then err_code = -153;
  if (:err_code < 0) then exit;

  execute procedure SYSTEM_CHECK_RIGHT(:id_client_pos, 'BILL_CHANGE_OWNER')
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;

  execute procedure MANAGE_COMMON(:id_client_pos, null,
    :id_smetka_head, 'CHANGE_OWNER', null, null, '', 'START')
  returning_values  :err_code, :err_text, :id_smetka_manage;
  if (:err_code < 0) then exit;

  execute procedure BILL_LOCK (-:ID_SMETKA_HEAD, :ID_CLIENT_POS, :id_object, :NEW_OWNER);

  update SMETKA_HEAD SH
  set    SH.USER_OWNER = :new_owner
  where  SH.ID_SMETKA_HEAD = :id_smetka_head;

  execute procedure MANAGE_COMMON(null, null, :id_smetka_head, null,
    null, null, null, 'STOP')
  returning_values  :err_code, :err_text, :id_smetka_manage;
  if (:err_code < 0) then exit;

  execute procedure BILL_LOCK (-:ID_SMETKA_HEAD, :ID_CLIENT_POS, null, null);
END
^

/* empty dependent procedure body */
/* Clear: BILL_PAYMENT_VOID for: MANAGE_COMMON */
ALTER PROCEDURE BILL_PAYMENT_VOID(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_VOID_REASON INTEGER,
ID_VOID_OVERRULE INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

/* empty dependent procedure body */
/* Clear: BILL_POST_ADD_VOID for: MANAGE_COMMON */
ALTER PROCEDURE BILL_POST_ADD_VOID(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_REASON INTEGER,
ID_REASON_OVERRULE INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_LINE_VOID INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* empty dependent procedure body */
/* Clear: FISCALIZE_MARK_DOC$FISC for: MANAGE_COMMON */
ALTER PROCEDURE FISCALIZE_MARK_DOC$FISC(ID_DOC_HEAD INTEGER,
IS_MANUAL INTEGER,
FISCAL_DEVICE_ID VARCHAR(10))
 AS
 BEGIN EXIT; END
^

/* Alter (MANAGE_COMMON) */
ALTER PROCEDURE MANAGE_COMMON(ID_CLIENT_POS INTEGER,
ID_SMETKA_MANAGE INTEGER,
ID_SMETKA_HEAD INTEGER,
MANAGE_TYPE VARCHAR(30),
ID_REASON INTEGER,
ID_REASON_OVERRULE INTEGER,
MANAGE_DATA VARCHAR(100),
OPERATION VARCHAR(20))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_SMETKA_MANAGE INTEGER)
 AS
declare variable user_name varchar(30);
  declare variable id_ew_current integer;
  declare variable id_end_work integer;
  declare variable id_object integer;
  declare variable ew_user integer;
  declare variable user_owner varchar(30);
begin
  /*  Description:
  ||
  */
  err_code = 0;
  err_text = '';
  if (:operation = 'START') then begin
    select SH.ID_END_WORK, SH.END_WORK_USER, SH.USER_OWNER
    from   SMETKA_HEAD SH
    where  SH.ID_SMETKA_HEAD = :id_smetka_head
    into   :id_end_work, :ew_user, :user_owner;
  
    execute procedure ENDWORK_IN_PROGRESS(:id_client_pos, :id_end_work, :ew_user)
    returning_values  :err_code, :err_text, :id_ew_current;
    if (:err_code < 0) then exit;

    execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_OBJECT')
    returning_values  :id_object;
  
    execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_USER')
    returning_values  :user_name;

    execute procedure BILL_LOCK (:ID_SMETKA_HEAD, :ID_CLIENT_POS, :id_object, :user_owner);

    if (:id_smetka_manage is null) then new_id_smetka_manage = gen_id(gen_smetka_manage_id, 1);
    else new_id_smetka_manage = :id_smetka_manage;
    insert into SMETKA_MANAGE (ID_SMETKA_MANAGE, ID_SMETKA_HEAD, MANAGE_TYPE, ID_REASON,
      ID_REASON_OVERRULE, USER_NAME, MANAGE_DATA, ID_END_WORK)
    values (:new_id_smetka_manage, :id_smetka_head, :manage_type, :id_reason,
      :id_reason_overrule, :user_name, :manage_data, :id_ew_current);
  end else if (:operation = 'STOP') then begin
    -- unlock the bill
    execute procedure BILL_LOCK (:ID_SMETKA_HEAD, :ID_CLIENT_POS, null, null);

  end else if (:operation = 'LOG') then begin
    select SH.ID_END_WORK, SH.END_WORK_USER
    from   SMETKA_HEAD SH
    where  SH.ID_SMETKA_HEAD = :id_smetka_head
    into   :id_end_work, :ew_user;
  
    execute procedure ENDWORK_IN_PROGRESS(:id_client_pos, :id_end_work, :ew_user)
    returning_values  :err_code, :err_text, :id_ew_current;
    if (:err_code < 0) then exit;

    execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_USER')
    returning_values  :user_name;
  
    if (:id_smetka_manage is null) then new_id_smetka_manage = gen_id(gen_smetka_manage_id, 1);
    else new_id_smetka_manage = :id_smetka_manage;
    insert into SMETKA_MANAGE (ID_SMETKA_MANAGE, ID_SMETKA_HEAD, MANAGE_TYPE, ID_REASON,
      ID_REASON_OVERRULE, USER_NAME, MANAGE_DATA, ID_END_WORK)
    values (:new_id_smetka_manage, :id_smetka_head, :manage_type, :id_reason,
      :id_reason_overrule, :user_name, :manage_data, :id_ew_current);
  end else begin
    err_code = -1;
    err_text = :operation;
  end
END
^

/* Alter (MANAGE_MOVE_BILL) */
ALTER PROCEDURE MANAGE_MOVE_BILL(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
NEW_TABLE_NO INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable id_smetka_manage integer;
  declare variable sh_dbkey char(8);
  declare variable status integer;
  declare variable smetka_status integer;
  declare variable dbg varchar(2000);
begin
  /*  Description:
  ||  PREHVYRLIANE SMETKATA NA DRUGA MASA
  */
  err_code = 0;
  err_text = '';
  select SH.STATUS
  from   SMETKA_HEAD SH
  where  SH.ID_SMETKA_HEAD = :id_smetka_head
  into   :smetka_status;
  if (:smetka_status is null) then err_code = -158;
  else if (:smetka_status <> 1) then err_code = -153;
  if (:err_code < 0) then exit;

  execute procedure SYSTEM_CHECK_RIGHT(:id_client_pos, 'BILL_CHANGE_TABLE')
  returning_values  :err_code, :err_text;
  if (:err_code < 0) then exit;

  execute procedure MANAGE_COMMON(:id_client_pos, null, :id_smetka_head, 'MOVE_BILL',
    null, null, '', 'START')
  returning_values  :err_code, :err_text, :id_smetka_manage;
  if (:err_code < 0) then exit;

  select SH.RDB$DB_KEY, SH.STATUS
  from   SMETKA_HEAD SH
  where  SH.ID_SMETKA_HEAD = :id_smetka_head
  into   :sh_dbkey, :status;
  if (:status <> 1) then err_code = -153;

  update SMETKA_HEAD SH
  set    SH.TABLE_NO = :new_table_no
  where  SH.RDB$DB_KEY = :sh_dbkey;

  execute procedure MANAGE_COMMON(null, null, :id_smetka_head, null,
    null, null, null, 'STOP')
  returning_values  :err_code, :err_text, :id_smetka_manage;
END
^

/* Alter (RIGHTS_MODIFY_AUDIT_USER) */
ALTER PROCEDURE RIGHTS_MODIFY_AUDIT_USER(USER_PASSWORD VARCHAR(50),
SYSUSER_NAME VARCHAR(20),
SYSUSER_PASSWORD VARCHAR(20),
OPERATION VARCHAR(10))
 RETURNS(USER_NAME VARCHAR(30),
ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable is_expired smallint;
  declare variable lang_code varchar(10);
  declare variable user_operation varchar(10);
  declare variable user_name_long varchar(50);
  declare variable id_client_pos integer;
begin
  id_client_pos = RDB$GET_CONTEXT('USER_SESSION', 'ID_CLIENT_POS');

  execute procedure SYSTEM_CHECK_RIGHT(:id_client_pos, 'RIGHTS_AUDIT_MANAGE')
  returning_values (:ERR_CODE, :ERR_TEXT);
  if (:ERR_CODE <> 0) then exit;

  USER_NAME = '_AUDITOR_';
  user_name_long = 'Clock audit system user';
  lang_code = 'bg';
  is_expired = iif(:OPERATION = 'activate', 0, 1);

  if (:OPERATION = 'activate' and not exists (select * from RIGHT_USER u where u.USER_NAME = :USER_NAME)) then
    user_operation = 'add';
  else
    user_operation = 'mod';

  execute procedure RIGHTS_MODIFY_USER(:user_name, :user_name_long, :USER_PASSWORD,
          null, :lang_code, :SYSUSER_NAME, :SYSUSER_PASSWORD, 1, null, :is_expired, null, :user_operation)
  returning_values (:ERR_CODE, :ERR_TEXT);

  if (:user_operation = 'add' and coalesce(:ERR_CODE, 0) = 0) then begin
    update RIGHT_USER ru
    set    ru.DB_ROLE = 'AUDITOR_ROLE'
    where  ru.USER_NAME = :USER_NAME;
  end
end
^

/* Restore proc. body: BILL_OPEN */
ALTER PROCEDURE BILL_OPEN(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
TABLE_NO INTEGER,
CUSTOMER_CNT INTEGER,
OPEN_TYPE VARCHAR(10),
ID_END_WORK INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_SMETKA_HEAD INTEGER,
NEW_ID_SMETKA_TRANS INTEGER,
DEFAULT_PRICE_LIST INTEGER,
MANUAL_PRICE_LIST INTEGER,
SMETKA_NUM INTEGER,
ID_CONTRAGENT INTEGER,
CONTRAGENT_NAME VARCHAR(50),
ID_SMETKA_DISCOUNT INTEGER,
ID_SURCHARGE INTEGER,
SURCHARGE_NAME VARCHAR(50),
SURCHARGE_VALUE NUMERIC(15,4),
IS_PERCENT_SURCHARGE INTEGER,
ID_DISCOUNT INTEGER,
IS_PERCENT_DISCOUNT INTEGER,
DISCOUNT_NAME VARCHAR(50),
DISCOUNT_STATUS INTEGER,
DISCOUNT_VALUE NUMERIC(15,4),
START_DATETIME TIMESTAMP,
LAST_CUSTOMER_CNT INTEGER,
ID_PROGRAM_LEVEL INTEGER,
CARD_CODE VARCHAR(50))
 AS
declare variable smetka_date date;
  declare variable id_object integer;
  declare variable active_user varchar(50);
  declare variable id_menu_price_list integer;
  declare variable status integer;
begin
  err_code = 0;
  err_text = '';
  if ((:open_type = 'OPEN') and (not exists(
    select * from SMETKA_HEAD SH where SH.ID_SMETKA_HEAD = :id_smetka_head and SH.STATUS = 1)
  )) then begin
    new_id_smetka_head = gen_id(gen_smetka_head_id, 1);
    execute procedure BILL_OPEN(:id_client_pos, :new_id_smetka_head, :table_no, :customer_cnt, 'CREATE', :id_end_work)
    returning_values  :err_code, :err_text, :new_id_smetka_head, :new_id_smetka_trans,
                      :default_price_list, :manual_price_list, :smetka_num, :id_contragent,
                      :contragent_name, :id_smetka_discount, :id_surcharge, :surcharge_name,
                      :surcharge_value, :is_percent_surcharge, :id_discount, :is_percent_discount,
                      :discount_name, :discount_status, :discount_value, :start_datetime,
                      :last_customer_cnt, :id_program_level, :card_code;
    exit;
  end

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_USER')
  returning_values  :active_user;

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_OBJECT')
  returning_values  :id_object;

  execute procedure BILL_TRANSACTION(null, :id_end_work, :active_user, 0, 0, :ID_CLIENT_POS, 'START')
  returning_values  :err_code, :err_text, :new_id_smetka_trans;

  if (:open_type = 'CREATE') then begin
    smetka_num = 0;
    id_contragent = 0;

    execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'SYSTEM_DATE')
    returning_values  :smetka_date;

    execute procedure ENDWORK_IN_PROGRESS(:id_client_pos, :id_end_work, null)
    returning_values  :err_code, :err_text, :id_end_work;
    if (:err_code < 0) then exit;

    new_id_smetka_head = :id_smetka_head;
    insert into SMETKA_HEAD(ID_SMETKA_HEAD, SMETKA_DATE, TABLE_NO, SMETKA_NUM,
      ID_OBJECT, ID_CONTRAGENT, ID_CONTRAGENT_OVERRULE, CUSTOMER_CNT, USER_OWNER,
      STATUS, ID_END_WORK, ID_CLIENT_POS)
    values (:new_id_smetka_head, :smetka_date, :table_no, :smetka_num,
      :id_object, :id_contragent, null, :customer_cnt, :active_user,
      1, :id_end_work, :id_client_pos);

    surcharge_value = null;
    id_discount = null;
    discount_name = null;
    discount_value = null;
    id_smetka_discount = null;
    discount_status = null;
    id_surcharge = null;
    surcharge_name = null;
    surcharge_value = null;
    start_datetime = current_timestamp;
    last_customer_cnt = :customer_cnt;

  end else if (:open_type in ('OPEN', 'PREVIEW')) then begin
    new_id_smetka_head = :id_smetka_head;
    select SH.ID_MANUAL_PRICE_LIST, SH.ID_CONTRAGENT, SH.SURCHARGE_VALUE,
           SH.SMETKA_NUM, D.IS_PERCENT, SH.ID_SMETKA_DISCOUNT, SD.STATUS,
           D.ID_DISCOUNT, D.DISCOUNT_NAME, SD.DISCOUNT_VALUE,
           SH.ID_SURCHARGE, DS.DISCOUNT_NAME, DS.IS_PERCENT,
           SH.START_DATE+SH.START_TIME, SH.CUSTOMER_CNT, SH.STATUS, SH.CARD_CODE, sh.SMETKA_DATE
    from   SMETKA_HEAD SH
           left outer join SMETKA_DISCOUNT SD on SD.ID_SMETKA_DISCOUNT = SH.ID_SMETKA_DISCOUNT
           left outer join NOM_DISCOUNT D on D.ID_DISCOUNT = SD.ID_DISCOUNT
           left outer join NOM_DISCOUNT DS on DS.ID_DISCOUNT = SH.ID_SURCHARGE
    where  SH.ID_SMETKA_HEAD = :id_smetka_head
    into   :manual_price_list, :id_contragent, :SURCHARGE_VALUE,
           :smetka_num, :is_percent_discount, :id_smetka_discount, :discount_status,
           :id_discount, :discount_name, :discount_value,
           :id_surcharge, :surcharge_name, :is_percent_surcharge,
           :start_datetime, :last_customer_cnt, :status, :card_code, :smetka_date;
    if ((:open_type = 'OPEN') and (:status <> 1)) then begin err_code = -153; exit; end
  end
  /* sledvastite redove moje da se premestiat v GUI */
  execute procedure BILL_POST_CHECKMENU(:manual_price_list, :id_object)
  returning_values  :err_code, :err_text;
  if (:err_code <> 0) then begin
    if (:err_code > 0) then err_code = 0;
    execute procedure SCHEDULER_FIND_POSITION(:id_object, 'OBJECT')
    returning_values  :err_code, :err_text, :default_price_list;
    if (:default_price_list is null) then begin
      /* IF HAPPY HOUR IS NOT PRESENT THEN GET THE FLAT DEFAULT */
      execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'DEFAULT_PRICE_LIST')
      returning_values  :default_price_list;
    end
    execute procedure BILL_POST_CHECKMENU(:default_price_list, :id_object)
    returning_values  :err_code, :err_text;
    if (:err_code < 0) then exit;

    id_menu_price_list = :default_price_list;
  end else begin
    id_menu_price_list = :manual_price_list;
    default_price_list = null;
  end

  /* GATHER SURCHARGE DATA FOR GUI IF IT IS NOT SET MANUALLY */
  if (:id_surcharge is null) then
    select D.DISCOUNT_NAME, D.DISCOUNT_VALUE, D.IS_PERCENT, D.ID_DISCOUNT
    from   MENU_HEAD MH
           join MENU_PRICE_LIST MPL on MPL.ID_MENU_HEAD = MH.ID_MENU_HEAD
           join NOM_DISCOUNT D on D.ID_DISCOUNT = MPL.ID_SURCHARGE
    where  MPL.ID_MENU_PRICE_LIST = :id_menu_price_list
    into   :surcharge_name, :surcharge_value, :is_percent_surcharge, :id_surcharge;

  if (:id_contragent = 0) then begin
    contragent_name = '-';
    id_program_level = 0;
  end else begin
    select C.CONTRAGENT_NAME, C.ID_PROGRAM_LEVEL
    from   CONTRAGENT C
    where  C.ID_CONTRAGENT = :id_contragent
    into   :contragent_name, :id_program_level;
  end
end
^

/* Restore proc. body: BILL_PAYMENT_VOID */
ALTER PROCEDURE BILL_PAYMENT_VOID(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_VOID_REASON INTEGER,
ID_VOID_OVERRULE INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable id_smetka_manage integer;
  declare variable old_id_smetka_trans integer;
  declare variable sp_dbkey char(8);
  declare variable id_pool integer;
  declare variable pool_value numeric (15,4);
  declare variable id_contragent integer;
  declare variable post_reason varchar(100);
  declare variable payment_name varchar(30);
  declare variable smetka_num integer;
  declare variable smetka_date date;
  declare variable payment_value numeric(15,4);
  declare variable object_name varchar(30);
  declare variable unique_sales_number varchar(30);
begin
  err_code = 0;
  err_text = '';

  execute procedure MANAGE_COMMON(:id_client_pos, null, :id_smetka_head, 'PAY_VOID',
    :id_void_reason, :id_void_overrule, '', 'LOG')
  returning_values  :err_code, :err_text, :id_smetka_manage;
  if (:err_code < 0) then exit;

  for
    select distinct SP.ID_SMETKA_TRANS
    from   SMETKA_PAYMENT SP
    where  SP.ID_SMETKA_HEAD = :id_smetka_head
           and SP.ID_PAYMENT_VOID is null
    into   :old_id_smetka_trans
  do begin
    for
      select CPC.ID_POOL, CPC.POOL_VALUE, CPC.POST_REASON, CPC.ID_CONTRAGENT
      from   CONTRAGENT_POOL_CHRONOLOGY CPC
      where  CPC.ID_SMETKA_TRANS = :old_id_smetka_trans
             and CPC.POST_STATUS = 3 /* PAYMENT */
      into   :id_pool, :pool_value, :post_reason, :id_contragent
    do begin
      post_reason = substring(('VOID '||:post_reason) from 1 for 100);
      pool_value = -1*:pool_value;
      execute procedure CL_POST_POOL_VALUE(:id_client_pos, :id_smetka_head, :id_contragent,
        :id_pool, :pool_value, 1, :post_reason, :id_smetka_trans, 3)
      returning_values  :err_code, :err_text;
      if (:err_code < 0) then exit;
    end
  end

  for
    select SP.RDB$DB_KEY, h.SMETKA_NUM, pt.PAYMENT_NAME, h.SMETKA_DATE, sp.PAYMENT_VALUE,
           o.OBJECT_NAME, h.UNIQUE_SALES_NUMBER
    from   SMETKA_PAYMENT SP
           join NOM_PAYMENT_TYPE pt on pt.ID_PAYMENT_TYPE = sp.ID_PAYMENT_TYPE
           join SMETKA_HEAD h on h.ID_SMETKA_HEAD = sp.ID_SMETKA_HEAD
           join NOM_OBJECT o on o.ID_OBJECT = h.ID_OBJECT
    where  SP.ID_SMETKA_HEAD = :id_smetka_head
           and SP.ID_PAYMENT_VOID is null
    into   :sp_dbkey, :smetka_num, :payment_name, :smetka_date, :payment_value,
           :object_name, :unique_sales_number
  do begin
    update SMETKA_PAYMENT SP2
    set    SP2.ID_PAYMENT_VOID = :id_smetka_manage,
           SP2.ID_SMETKA_TRANS = :id_smetka_trans,
           SP2.STATUS = -2
    where  SP2.rdb$db_key = :sp_dbkey;

    execute procedure SYSTEM_LOG_ADD('BILL', :ID_SMETKA_HEAD, 'BILL_PAYMENT_VOID',
            f_character(29 ) || :payment_name || f_character(28) || :smetka_num || f_character(28) || :object_name || f_character(28)
            || :smetka_date || f_character(28) || float_to_str(:payment_value, 'F;0.00') || f_character(28) || :unique_sales_number);
  end
END
^

/* Restore proc. body: BILL_POST_ADD_VOID */
ALTER PROCEDURE BILL_POST_ADD_VOID(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_REASON INTEGER,
ID_REASON_OVERRULE INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_LINE_VOID INTEGER)
 AS
begin
  err_code = 0;
  err_text = '';

  execute procedure MANAGE_COMMON(:id_client_pos, null, :id_smetka_head, 'LINE_VOID',
    :id_reason, :id_reason_overrule, '', 'LOG')
  returning_values  :err_code, :err_text, :new_id_line_void;
END
^

/* Restore proc. body: FISCALIZE_MARK_DOC$FISC */
ALTER PROCEDURE FISCALIZE_MARK_DOC$FISC(ID_DOC_HEAD INTEGER,
IS_MANUAL INTEGER,
FISCAL_DEVICE_ID VARCHAR(10))
 AS
declare variable dbg varchar(2000);
  declare variable fisc_status integer;
  declare variable smetka_status integer;
  declare variable sp_dbkey char(8);
  declare variable manage_type varchar(20);
  declare variable err_code integer;
  declare variable id_client_pos integer;
  declare variable id_object integer;
  declare variable curr_fiscal_device_id varchar(10);
  declare variable curr_storno_fiscal_device_id varchar(10);
begin
  fisc_status = null;

  select h.STATUS, H.ID_OBJECT, fd.FISCAL_DEVICE_ID, fd.STORNO_FISCAL_DEVICE_ID
  from   SMETKA_FISCAL_DATA fd
         join SMETKA_HEAD h on h.ID_SMETKA_HEAD = fd.ID_SMETKA_HEAD
  where  h.ID_SMETKA_HEAD = :ID_DOC_HEAD
  into   :smetka_status, :id_object, :curr_fiscal_device_id, :curr_storno_fiscal_device_id;

  if (:smetka_status = 2) then begin
    -- Fiscalization mark
    if (:curr_fiscal_device_id is not null) then
      exception FISCALIZE_EXCEPTION '-315';

    for
      select SP.RDB$DB_KEY, SP.FISC_STATUS
      from   SMETKA_PAYMENT SP
      where  SP.ID_SMETKA_HEAD = :id_doc_head
             and SP.ID_PAYMENT_VOID is null
      into   :sp_dbkey, :fisc_status
    do begin
      if (:fisc_status = 0) then begin
        exit;  -- ?????
      end else if (:fisc_status = 2) then begin
        exception FISCALIZE_EXCEPTION '-315';
      end
  
      update SMETKA_PAYMENT SP
      set    SP.FISC_STATUS = 2
      where  SP.RDB$DB_KEY = :sp_dbkey;
    end
  
    if (:fisc_status is null) then
      exception FISCALIZE_EXCEPTION '-316';

    if (:is_manual = 0) then manage_type = 'FISCALIZE';
    else manage_type = 'REFISCALIZE';
  
    update SMETKA_FISCAL_DATA FD
    set    FD.FISCAL_DEVICE_ID = :FISCAL_DEVICE_ID
    where  fd.ID_SMETKA_HEAD = :id_doc_head;

  end else if (:smetka_status = -3) then begin
    -- Voided fiscalization mark
    if (:curr_storno_fiscal_device_id is not null) then
      exception FISCALIZE_EXCEPTION '-314';

    update SMETKA_FISCAL_DATA FD
    set    FD.STORNO_FISCAL_DEVICE_ID = :FISCAL_DEVICE_ID
    where  fd.ID_SMETKA_HEAD = :id_doc_head;

    manage_type = 'VOID_FISCALIZE';
  end

  id_client_pos = RDB$GET_CONTEXT('USER_SESSION', 'ID_CLIENT_POS');
  if (:id_client_pos is null) then begin
    select first 1 SC.ID_CLIENT_POS
    from   SYSTEM_CLIENT SC
    where  SC.CLIENT_KIND = 'POS'
           and SC.ID_OBJECT = :id_object
           and sc.ACTIVE_USER is not null
    into   :id_client_pos;
  end

  execute procedure MANAGE_COMMON(:id_client_pos, null, :id_doc_head, :manage_type, null, null, null, 'LOG')
  returning_values  :err_code, :dbg, :dbg;

  if (:err_code < 0) then exception FISCALIZE_EXCEPTION 'err_code = '||:err_code;
end
^

SET TERM ; ^

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_SMETKA_LINE POSITION 1;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_SMETKA_TRANS POSITION 2;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_SMETKA_HEAD POSITION 3;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_TRANSFER_SOURCE_LINE POSITION 4;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_END_WORK POSITION 5;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_STOCK POSITION 6;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_INVENT POSITION 7;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_VAT POSITION 8;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN QTY_POST POSITION 9;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN QTY_VOID POSITION 10;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN QTY POSITION 11;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN COST_PRICE POSITION 12;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN SALE_PRICE POSITION 13;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN LINE_SUM POSITION 14;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN VOID_SUM POSITION 15;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN DISCOUNT_SUM POSITION 16;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_MENU_PRICE_LIST POSITION 17;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_PRICE_LIST_OVERRULE POSITION 18;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_VOIDED_LINE POSITION 19;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_LINE_VOID POSITION 20;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_LINE_DISCOUNT POSITION 21;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN POST_STATUS POSITION 22;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN STATUS POSITION 23;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_SMETKA_BON POSITION 24;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_MOD_SESSION POSITION 25;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN NETO_SUM POSITION 26;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN SURCHARGE_SUM POSITION 27;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN NETO_WOT_TAX POSITION 28;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN TAX_PERCENT POSITION 29;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN VAT_CODE POSITION 30;

ALTER TABLE MENU_LINE ALTER COLUMN ID_MENU_LINE POSITION 1;

ALTER TABLE MENU_LINE ALTER COLUMN STOCK_NAME POSITION 2;

ALTER TABLE MENU_LINE ALTER COLUMN STOCK_NAME_SEARCH POSITION 3;

ALTER TABLE MENU_LINE ALTER COLUMN ID_MENU_HEAD POSITION 4;

ALTER TABLE MENU_LINE ALTER COLUMN ID_INVENT POSITION 5;

ALTER TABLE MENU_LINE ALTER COLUMN ID_STOCK POSITION 6;

ALTER TABLE MENU_LINE ALTER COLUMN ID_MENU_GROUP POSITION 7;

ALTER TABLE MENU_LINE ALTER COLUMN ID_VAT_GROUP POSITION 8;

ALTER TABLE MENU_LINE ALTER COLUMN TAG POSITION 9;

ALTER TABLE MENU_LINE ALTER COLUMN MENU_GROUP_LINK POSITION 10;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_SMETKA_LINE POSITION 1;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_SMETKA_TRANS POSITION 2;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_SMETKA_HEAD POSITION 3;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_TRANSFER_SOURCE_LINE POSITION 4;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_END_WORK POSITION 5;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_STOCK POSITION 6;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_INVENT POSITION 7;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_VAT POSITION 8;

ALTER TABLE SMETKA_LINE ALTER COLUMN QTY_POST POSITION 9;

ALTER TABLE SMETKA_LINE ALTER COLUMN QTY_VOID POSITION 10;

ALTER TABLE SMETKA_LINE ALTER COLUMN QTY POSITION 11;

ALTER TABLE SMETKA_LINE ALTER COLUMN COST_PRICE POSITION 12;

ALTER TABLE SMETKA_LINE ALTER COLUMN SALE_PRICE POSITION 13;

ALTER TABLE SMETKA_LINE ALTER COLUMN LINE_SUM POSITION 14;

ALTER TABLE SMETKA_LINE ALTER COLUMN VOID_SUM POSITION 15;

ALTER TABLE SMETKA_LINE ALTER COLUMN DISCOUNT_SUM POSITION 16;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_MENU_PRICE_LIST POSITION 17;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_PRICE_LIST_OVERRULE POSITION 18;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_VOIDED_LINE POSITION 19;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_LINE_VOID POSITION 20;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_LINE_DISCOUNT POSITION 21;

ALTER TABLE SMETKA_LINE ALTER COLUMN POST_STATUS POSITION 22;

ALTER TABLE SMETKA_LINE ALTER COLUMN STATUS POSITION 23;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_SMETKA_BON POSITION 24;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_MOD_SESSION POSITION 25;

ALTER TABLE SMETKA_LINE ALTER COLUMN NETO_SUM POSITION 26;

ALTER TABLE SMETKA_LINE ALTER COLUMN SURCHARGE_SUM POSITION 27;

ALTER TABLE SMETKA_LINE ALTER COLUMN NETO_WOT_TAX POSITION 28;

ALTER TABLE SMETKA_LINE ALTER COLUMN TAX_PERCENT POSITION 29;

ALTER TABLE SMETKA_LINE ALTER COLUMN VAT_CODE POSITION 30;

ALTER TABLE STOCK ALTER COLUMN ID_STOCK POSITION 1;

ALTER TABLE STOCK ALTER COLUMN STOCK_NAME POSITION 2;

ALTER TABLE STOCK ALTER COLUMN STOCK_NAME_SEARCH POSITION 3;

ALTER TABLE STOCK ALTER COLUMN COST_PRICE POSITION 4;

ALTER TABLE STOCK ALTER COLUMN ID_STOCK_GROUP POSITION 5;

ALTER TABLE STOCK ALTER COLUMN POS_CODE POSITION 6;

ALTER TABLE STOCK ALTER COLUMN IS_USE POSITION 7;

ALTER TABLE STOCK ALTER COLUMN NOTE POSITION 8;

ALTER TABLE STOCK ALTER COLUMN IS_SERVICE POSITION 9;

ALTER TABLE STOCK ALTER COLUMN IS_FREE_VOID POSITION 10;

ALTER TABLE STOCK ALTER COLUMN IS_FREE_PRICE POSITION 11;

ALTER TABLE STOCK ALTER COLUMN IS_BARCODE POSITION 12;

ALTER TABLE STOCK ALTER COLUMN TRADE_CODE POSITION 13;

ALTER TABLE STOCK ALTER COLUMN IS_MODIFIER POSITION 14;

ALTER TABLE STOCK ALTER COLUMN UUID POSITION 15;

ALTER TABLE STOCK ALTER COLUMN CREATED_AT POSITION 16;

ALTER TABLE STOCK ALTER COLUMN UPDATED_AT POSITION 17;

ALTER TABLE STOCK ALTER COLUMN ARCHIVED_AT POSITION 18;

ALTER TABLE STOCK ALTER COLUMN ID_VAT_GROUP POSITION 19;

