/* 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 SMETKA_FISCAL_DATA DROP CONSTRAINT PK_SMETKA_FISCAL_DATA;

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

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
^


/* Drop Procedure... */
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
^

SET TERM ; ^

DROP PROCEDURE FISCALIZE_PREPARE_LINES$INT;


ALTER TABLE ARCHIVE_LINE ADD SURCHARGE_VALUE CURRENCY_LOW;

ALTER TABLE ARCHIVE_MODIFFIER ADD SURCHARGE_VALUE CURRENCY_LOW;

ALTER TABLE SMETKA_FISCAL_DATA ADD ID_FISCAL_DATA ID_REF NOT NULL;

ALTER TABLE SMETKA_FISCAL_DATA ADD FISCAL_AMOUNT CURRENCY_LOW;

ALTER TABLE SMETKA_FISCAL_DATA ADD FISCAL_GROUP_LIST NAME_50;

ALTER TABLE SMETKA_FISCAL_DATA ADD SMETKA_DISCOUNTS TEXT_BLOB;

ALTER TABLE SMETKA_FISCAL_DATA ADD SMETKA_SURCHARGES TEXT_BLOB;

ALTER TABLE SMETKA_LINE ADD SURCHARGE_VALUE CURRENCY_LOW;

COMMENT ON COLUMN SMETKA_LINE.SURCHARGE_VALUE IS
'!!! Included in NETO_SUM';

ALTER TABLE SMETKA_MODIFFIER ADD SURCHARGE_VALUE CURRENCY_LOW;

ALTER TABLE SUM_CONTRAGENT ADD SURCHARGE_SUM CURRENCY_LOW;

/* Drop table-fields... */
/* Empty ENDWORK_SUB_ARCHIVE for drop ARCHIVE_LINE(SURCHARGE_SUM) */
SET TERM ^ ;

ALTER PROCEDURE ENDWORK_SUB_ARCHIVE(ID_END_WORK INTEGER)
 RETURNS(ERR_CODE INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* Empty ENDWORK_UNDO for drop ARCHIVE_LINE(SURCHARGE_SUM) */
ALTER PROCEDURE ENDWORK_UNDO(ID_END_WORK INTEGER,
UNDO_TYPE VARCHAR(20))
 AS
 BEGIN EXIT; END
^

SET TERM ; ^

DROP VIEW SALE_DETAIL;

DROP VIEW SALE_DETAIL_OPEN_VOID;

DROP VIEW SALE_DETAIL_VOID;

DROP VIEW SALE_TOTAL;

ALTER TABLE ARCHIVE_LINE ALTER SURCHARGE_SUM TO "_SURCHARGE_SUM";

ALTER TABLE ARCHIVE_MODIFFIER ALTER SURCHARGE_SUM TO "_SURCHARGE_SUM";

/* Empty BILL_CLEANUP_NETO for drop SMETKA_LINE(SURCHARGE_SUM) */
SET TERM ^ ;

ALTER PROCEDURE BILL_CLEANUP_NETO(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

/* Empty BILL_POST_FINALIZE_DEDUCT for drop SMETKA_LINE(SURCHARGE_SUM) */
ALTER PROCEDURE BILL_POST_FINALIZE_DEDUCT(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_DISCOUNT INTEGER,
SURCHARGE_BASE NUMERIC(15,4),
SURCHARGE_SUM NUMERIC(15,4))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
 BEGIN SUSPEND; END
^

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 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
^

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
 BEGIN SUSPEND; END
^

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
 BEGIN SUSPEND; END
^

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
 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;

ALTER TABLE SMETKA_LINE ALTER SURCHARGE_SUM TO "_SURCHARGE_SUM";

COMMENT ON COLUMN SMETKA_LINE."_SURCHARGE_SUM" IS
'!!!Old, deprecated, not-included in NETO_SUM';

ALTER TABLE SMETKA_LINE ADD TOTAL_SUM COMPUTED BY (NETO_SUM + coalesce("_SURCHARGE_SUM", 0));

COMMENT ON COLUMN SMETKA_LINE.TOTAL_SUM IS
'Total line sum, that includes old (deprecated) SURCHARGE_SUM, excluded of NETO_SUM';

/* Empty BILL_POST_ADD$PDA for drop SMETKA_MODIFFIER(SURCHARGE_SUM) */
SET TERM ^ ;

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
^

SET TERM ; ^

ALTER TABLE SMETKA_MODIFFIER ALTER SURCHARGE_SUM TO "_SURCHARGE_SUM";

ALTER TABLE SMETKA_MODIFFIER ADD TOTAL_SUM COMPUTED BY (NETO_SUM + coalesce("_SURCHARGE_SUM", 0));

COMMENT ON COLUMN SMETKA_MODIFFIER.TOTAL_SUM IS
'Total line sum, that includes old (deprecated) SURCHARGE_SUM, excluded of NETO_SUM';

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

CREATE PROCEDURE FISCALIZE_DISCOUNT$FISC(ID_FISCAL_DATA INTEGER)
 RETURNS(FISC_SUM NUMERIC(15,4),
FISC_TEXT VARCHAR(100))
 AS
 BEGIN SUSPEND; END
^

CREATE PROCEDURE FISCALIZE_SURCHARGE$FISC(ID_FISCAL_DATA INTEGER)
 RETURNS(FISC_SUM NUMERIC(15,4),
FISC_TEXT VARCHAR(100))
 AS
 BEGIN SUSPEND; END
^


/* Create Views... */
/* Create view: BILL_NETO */
SET TERM ; ^

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,
SURCHARGE_VALUE,
NETO_SUM,
"_SURCHARGE_SUM",
TOTAL_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,
       coalesce(SL.SURCHARGE_VALUE, 0) + coalesce((
         select sum(SM2.SURCHARGE_VALUE)
         from   SMETKA_MODIFFIER SM2
         where  SL.ID_MOD_SESSION = SM2.ID_MOD_SESSION), 0) as surcharge_value,
       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,
       coalesce(SL."_SURCHARGE_SUM", 0) + coalesce((
         select sum(SM2."_SURCHARGE_SUM")
         from   SMETKA_MODIFFIER SM2
         where  SL.ID_MOD_SESSION = SM2.ID_MOD_SESSION), 0) as "_surcharge_sum", --compatibility issue #5918
       SL.TOTAL_SUM + coalesce((
         select sum(SM1.TOTAL_SUM)
         from   SMETKA_MODIFFIER SM1
         where  SL.ID_MOD_SESSION = SM1.ID_MOD_SESSION), 0) as neto_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
;

/* Create view: RECORD_MULTIPLIER */
CREATE VIEW RECORD_MULTIPLIER(
TAG)
 AS 
select cast(0 as smallint) as tag
from   RDB$DATABASE
union
select cast(1 as smallint)
from   RDB$DATABASE
;

/* Create view: SMETKA_FISCAL_BONS */
CREATE VIEW SMETKA_FISCAL_BONS(
ID_FISCAL_DATA,
ID_SMETKA_HEAD,
IS_STORNO_BON,
UNIQUE_SALES_NUMBER,
FISCAL_DEVICE_ID,
FISCALIZATION_DETAILS,
FISCAL_AMOUNT,
FISCAL_LINES,
FISCAL_DISCOUNTS,
FISCAL_SURCHARGES,
FISCAL_PAYMENTS,
FISCAL_GROUP_LIST,
SMETKA_STATUS)
 AS 
select f.ID_FISCAL_DATA,
       f.ID_SMETKA_HEAD,
       vr.tag as is_storno_bon,
       f.UNIQUE_SALES_NUMBER,
       iif(vr.tag = 0, f.FISCAL_DEVICE_ID, f.STORNO_FISCAL_DEVICE_ID) as FISCAL_DEVICE_ID,
       iif(vr.tag = 0, f.FISCALIZATION_DETAILS, f.STORNO_FISCALIZATION_DETAILS) as FISCALIZATION_DETAILS,
       f.FISCAL_AMOUNT,
       f.SMETKA_LINES,
       f.SMETKA_DISCOUNTS,
       f.SMETKA_SURCHARGES,
       f.SMETKA_PAYMENTS,
       f.FISCAL_GROUP_LIST,
       d.STATUS
from   SMETKA_FISCAL_DATA f
       left join (select sh.ID_SMETKA_HEAD, sh.STATUS from SMETKA_HEAD sh
             union all
             select ah.ID_SMETKA_HEAD, ah.STATUS from ARCHIVE_HEAD ah) d on d.ID_SMETKA_HEAD = f.ID_SMETKA_HEAD
       join RECORD_MULTIPLIER vr on (
         (vr.TAG = 0) or (d.STATUS = -3 and vr.TAG =1 and f.FISCAL_DEVICE_ID is not null)
       )
;

/* Create view: FISCAL_BONS_PENDING */
CREATE VIEW FISCAL_BONS_PENDING(
ID_FISCAL_DATA,
ID_DOC_HEAD,
IS_STORNO_BON,
UNIQUE_SALES_NUMBER,
FISCAL_DEVICE_ID,
FISCALIZATION_DETAILS,
FISCAL_AMOUNT,
FISCAL_LINES,
FISCAL_DISCOUNTS,
FISCAL_SURCHARGES,
FISCAL_PAYMENTS,
FISCAL_GROUP_LIST)
 AS 
select ID_FISCAL_DATA,
       ID_SMETKA_HEAD,
       IS_STORNO_BON,
       UNIQUE_SALES_NUMBER,
       FISCAL_DEVICE_ID,
       (select fd.FISCALIZATION_DETAILS
        from   SMETKA_FISCAL_DATA fd
        where  fd.ID_FISCAL_DATA = fb.ID_FISCAL_DATA
               and fb.IS_STORNO_BON = 1) as FISCALIZATION_DETAILS,
       FISCAL_AMOUNT,
       FISCAL_LINES,
       FISCAL_DISCOUNTS,
       FISCAL_SURCHARGES,
       FISCAL_PAYMENTS,
       FISCAL_GROUP_LIST
from   SMETKA_FISCAL_BONS fb
where  fb.FISCAL_DEVICE_ID is null
       and not (fb.SMETKA_STATUS = -3 and fb.IS_STORNO_BON = 0)
;

/* 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,
    SURCHARGE_VALUE,
    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.SURCHARGE_VALUE,
       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.SURCHARGE_VALUE,
       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
;

/* 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,
    SURCHARGE_VALUE,
    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.SURCHARGE_VALUE,
       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.SURCHARGE_VALUE,
       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
;

/* 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,
    SURCHARGE_VALUE,
    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.SURCHARGE_VALUE,
       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.SURCHARGE_VALUE,
       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
;

CREATE VIEW SALE_TOTAL(
    UNIQUE_SALES_NUMBER,
    ID_BILL,
    ID_OBJECT,
    OBJECT_NAME,
    SMETKA_DATE,
    START_DATE,
    START_TIME,
    ID_CLIENT_POS,
    USER_NAME,
    USER_CODE,
    NETO_SUM,
    DISCOUNT_SUM,
    SURCHARGE_VALUE,
    TAX_SUM,
    TOTAL_SUM,
    INVOICE_NUM,
    INVOICE_DATE,
    END_DATE,
    END_TIME,
    CLIENT_NUM,
    HOTEL_ROOM)
AS
select h.UNIQUE_SALES_NUMBER,
       h.ID_SMETKA_HEAD,
       o.ID_OBJECT,
       o.OBJECT_NAME,
       h.SMETKA_DATE,
       h.START_DATE,
       h.START_TIME,
       h.ID_CLIENT_POS as workplace_num,
       u.USER_NAME,
       u.CODE as user_code,
       (select sum(t.TAXABLE_VALUE)
        from   SMETKA_TAX t
        where  t.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD) as NETO_SUM,
       h.DISCOUNT_SUM,
       h.SURCHARGE_SUM,
       (select sum(t.TAX_VALUE)
        from   SMETKA_TAX t
        where  t.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD) as TAX_SUM,
       h.GRAND_TOTAL_SUM,
       null as INVOICE_NUM,
       null as INVOICE_DATE,
       cast(h.STOP_DATETIME as date) as END_DATE,
       cast(h.STOP_DATETIME as time) as END_TIME,
       c.ID_CONTRAGENT as CLIENT_NUM,
       cast(sf.ROOM_NAME || ' | ' || sf.GUEST_NAME as varchar(140)) as hotel_room
from   SMETKA_HEAD h
       join NOM_OBJECT o on o.ID_OBJECT = h.ID_OBJECT
       join RIGHT_USER u on u.USER_NAME = h.USER_OWNER
       left outer join CONTRAGENT c on c.ID_CONTRAGENT = h.ID_CONTRAGENT and c.ID_CONTRAGENT > 0
       left outer join SMETKA_FRONT sf on sf.ID_SMETKA_FRONT = h.ID_SMETKA_FRONT
where  h.status > 0
union all
select h.UNIQUE_SALES_NUMBER,
       h.ID_SMETKA_HEAD,
       o.ID_OBJECT,
       o.OBJECT_NAME,
       h.SMETKA_DATE,
       h.START_DATE,
       h.START_TIME,
       h.ID_CLIENT_POS,
       u.USER_NAME,
       u.CODE as user_code,
       (select sum(t.TAXABLE_VALUE)
        from   ARCHIVE_TAX t
        where  t.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD) as NETO_SUM,
       h.DISCOUNT_SUM,
       h.SURCHARGE_SUM,
       (select sum(t.TAX_VALUE)
        from   ARCHIVE_TAX t
        where  t.ID_SMETKA_HEAD = h.ID_SMETKA_HEAD) as TAX_SUM,
       h.GRAND_TOTAL_SUM,
       null as INVOICE_NUM,
       null as INVOICE_DATE,
       cast(h.STOP_DATETIME as date) as END_DATE,
       cast(h.STOP_DATETIME as time) as END_TIME,
       c.ID_CONTRAGENT,
       cast(sf.ROOM_NAME || ' | ' || sf.GUEST_NAME as varchar(140)) as hotel_room
from   ARCHIVE_HEAD h
       join NOM_OBJECT o on o.ID_OBJECT = h.ID_OBJECT
       join RIGHT_USER u on u.USER_NAME = h.USER_OWNER
       left outer join CONTRAGENT c on c.ID_CONTRAGENT = h.ID_CONTRAGENT and c.ID_CONTRAGENT > 0
       left outer join ARCHIVE_FRONT sf on sf.ID_SMETKA_FRONT = h.ID_SMETKA_FRONT
where  h.status > 0
;


/* Create index... */
CREATE INDEX SMETKA_FISCAL_DATA_IDX1 ON SMETKA_FISCAL_DATA(ID_SMETKA_HEAD);


/* Create generator... */
CREATE GENERATOR GEN_SMETKA_FISCAL_DATA_ID;


/*  Empty IMPORT_MENU_LINE_PRICE$ENT for LOOKUP_PRICE_LIST$ENT(param list change)  */
SET TERM ^ ;

ALTER PROCEDURE IMPORT_MENU_LINE_PRICE$ENT(ID_MENU_HEAD INTEGER,
ID_MENU_LINE INTEGER,
PRICE_LIST_NAME VARCHAR(50),
PROFIT_PERCENT NUMERIC(15,4),
SALE_PRICE NUMERIC(15,4))
 AS
 BEGIN EXIT; END
^

/* Alter empty procedure LOOKUP_PRICE_LIST$ENT with new param-list */
ALTER PROCEDURE LOOKUP_PRICE_LIST$ENT(ID_MENU_HEAD INTEGER,
PRICE_LIST_NAME VARCHAR(50))
 RETURNS(ID_PRICE_LIST INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* Alter Procedure... */
/* Alter (BILL_CLEANUP_NETO) */
ALTER PROCEDURE BILL_CLEANUP_NETO(ID_CLIENT_POS INTEGER,
ID_SMETKA_HEAD INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable sl_dbkey char(8);
  declare variable id_mod_session integer;
  declare variable id_line_discount integer;
  declare variable sm_dbkey char(8);
begin
  err_code = 0;
  err_text = '';

  for
    select SL.rdb$db_key, SL.ID_MOD_SESSION, SL.ID_LINE_DISCOUNT
    from   SMETKA_LINE SL
    where  SL.ID_SMETKA_HEAD = :id_smetka_head
    into   :sl_dbkey, :id_mod_session, :id_line_discount
  do begin
    if (:id_line_discount is null) then begin
      update SMETKA_LINE SL2
      set    SL2.DISCOUNT_SUM = 0,
             SL2.SURCHARGE_VALUE = 0,
             SL2.NETO_SUM = SL2.LINE_SUM
      where  SL2.rdb$db_key = :sl_dbkey;
    end else begin
      update SMETKA_LINE SL2
      set    SL2.SURCHARGE_VALUE = 0
      where  SL2.rdb$db_key = :sl_dbkey;
    end
    for
      select SM.rdb$db_key
      from   SMETKA_MODIFFIER SM
      where  SM.ID_MOD_SESSION = :id_mod_session
      into   :sm_dbkey
    do begin
      if (:id_line_discount is null) then begin
        update SMETKA_MODIFFIER SM2
        set    SM2.SURCHARGE_VALUE = 0,
               SM2.DISCOUNT_SUM = 0
        where  SM2.rdb$db_key = :sm_dbkey;
      end else begin
        update SMETKA_MODIFFIER SM2
        set    SM2.SURCHARGE_VALUE = 0
        where  SM2.rdb$db_key = :sm_dbkey;
      end
    end
  end
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_VALUE, 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_FINALIZE_DEDUCT) */
alter procedure BILL_POST_FINALIZE_DEDUCT (
    ID_CLIENT_POS integer,
    ID_SMETKA_HEAD integer,
    ID_SMETKA_DISCOUNT integer,
    SURCHARGE_BASE numeric(15,4),
    SURCHARGE_SUM numeric(15,4))
returns (
    ERR_CODE integer,
    ERR_TEXT varchar(255))
AS
  declare variable deduct_coefficient double precision;
  declare variable value_to_deduct numeric(15,4);
  declare variable round_to numeric(15,4);
  declare variable sl_dbkey char(8);
  declare variable sm_dbkey char(8);
  declare variable line_sum numeric (15,4);
  declare variable line_qty numeric (15,4);
  declare variable line_discount numeric (15,4);
  declare variable modifier_neto numeric (15,4);
  declare variable modifier_bruto numeric (15,4);
  declare variable id_mod_session integer;
begin
  /*  Description:
  ||
  */
  err_code = 0;
  err_text = '';

  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'ROUND_TO')
  returning_values  :round_to;
  /* BEGIN - GENERATING THE CLEAR NETO VALUE FOR POSTINGS WITH MOFIFIERS */
  for
    select SL.rdb$db_key, SL.QTY, SD.DISCOUNT_SUM,
           case
             when roundto(SD.DISCOUNT_BASE, 0.01) = 0 then 0
             else SD.DISCOUNT_SUM / SD.DISCOUNT_BASE
           end
    from   SMETKA_LINE SL
           left outer join SMETKA_DISCOUNT SD on SD.ID_SMETKA_DISCOUNT = SL.ID_LINE_DISCOUNT
    where  SL.ID_SMETKA_HEAD = :id_smetka_head
           and SL.STATUS > 0
    into   :sl_dbkey, :line_qty, :value_to_deduct, :deduct_coefficient
  do begin
    modifier_neto = 0;
    modifier_bruto = 0;
    if (:value_to_deduct is null) then value_to_deduct = 0;
    for
      select SM.rdb$db_key, roundto(SM.SALE_PRICE*:line_qty, :round_to)
      from   SMETKA_LINE SL
             join SMETKA_MODIFFIER SM on SM.ID_MOD_SESSION = SL.ID_MOD_SESSION
      where  SL.rdb$db_key = :sl_dbkey
      into   :sm_dbkey, :line_sum
    do begin
      /* IF THE MASTER LINE HAS DISCOUNT IT MUST BE DEDUCTED FROM ITSELF AND FROM IT'S MODIFIERS */
      if (:value_to_deduct > 0) then line_discount = roundto(:line_sum*:deduct_coefficient, :round_to);
      else begin
        line_discount = 0;
        value_to_deduct = 0;
      end
      update SMETKA_MODIFFIER SM2
      set    SM2.NETO_SUM   = (:line_sum - :line_discount)
      where  SM2.rdb$db_key = :sm_dbkey;
      value_to_deduct = :value_to_deduct - :line_discount;
      modifier_neto = :modifier_neto + (:line_sum - :line_discount);
      modifier_bruto = :modifier_bruto + :line_sum;
    end
    update SMETKA_LINE SL2
    set    SL2.DISCOUNT_SUM = :value_to_deduct,
           SL2.NETO_SUM     = SL2.LINE_SUM - :value_to_deduct - :modifier_bruto
    where  SL2.rdb$db_key   = :sl_dbkey;
  end
  /* END - GENERATING THE CLEAR NETO VALUE FOR POSTINGS WITH MOFIFIERS */

  if (:id_smetka_discount is not null) then begin
  /* BEGIN - GENERATING THE CLEAR NETO VALUE WITH DEDUCTING THE SMETKA DISCOUNT */
    select SD.DISCOUNT_SUM,
           case
             when roundto(SD.DISCOUNT_BASE, 0.01) = 0 then 0
             else cast(SD.DISCOUNT_SUM as double precision) / cast(SD.DISCOUNT_BASE as double precision)
           end
    from   SMETKA_DISCOUNT SD
    where  SD.ID_SMETKA_DISCOUNT = :id_smetka_discount
    into   :value_to_deduct, :deduct_coefficient;
    for
      select SL.rdb$db_key, SL.NETO_SUM, SL.QTY, SL.ID_MOD_SESSION
      from   SMETKA_LINE SL
      where  SL.ID_SMETKA_HEAD = :id_smetka_head
             and SL.STATUS > 0
             and SL.ID_LINE_DISCOUNT is null
      order by SL.NETO_SUM asc /* DIFFERENCE MUST BE DEDUCTED FROM THE GREATES LINE */
      into   :sl_dbkey, :line_sum, :line_qty, :id_mod_session
    do begin
      line_discount = roundto(:line_sum*:deduct_coefficient, :round_to);
      update SMETKA_LINE SL2
      set    SL2.DISCOUNT_SUM  = :line_discount,
             SL2.NETO_SUM      = (:line_sum - :line_discount)
      where  SL2.rdb$db_key = :sl_dbkey;
      value_to_deduct = :value_to_deduct - :line_discount;
      for
        /* MODIFIERS WITH SMETKA LINE DISCOUNT DOES NOT APPEAR HERE */
        select SM.rdb$db_key, SM.SALE_PRICE*:line_qty
        from   SMETKA_MODIFFIER SM
        where  SM.ID_MOD_SESSION = :id_mod_session
        into   :sm_dbkey, :line_sum
      do begin
        line_discount = roundto(:line_sum*:deduct_coefficient, :round_to);
        update SMETKA_MODIFFIER SM2
        set    SM2.NETO_SUM   = (:line_sum - :line_discount),
               SM2.DISCOUNT_SUM = :line_discount
        where  SM2.rdb$db_key = :sm_dbkey;
        value_to_deduct = :value_to_deduct - :line_discount;
      end
    end
    /* OBIRANE NA GRESHKATA */
    update SMETKA_LINE SL2
    set    SL2.DISCOUNT_SUM = SL2.DISCOUNT_SUM + :value_to_deduct,
           SL2.NETO_SUM     = SL2.NETO_SUM - :value_to_deduct
    where  SL2.rdb$db_key = :sl_dbkey;
  end
  /* END - GENERATING THE CLEAR NETO VALUE WITH DEDUCTING THE SMETKA DISCOUNT */

  if (:surcharge_sum > 0) then begin
  /* BEGIN - GENERATING THE CLEAR NETO VALUE WITH DEDUCTING THE SMETKA SURCHARGE */
    value_to_deduct = :surcharge_sum;
    deduct_coefficient = :surcharge_sum/:surcharge_base;
    for
      select SL.rdb$db_key, SL.NETO_SUM, SL.ID_MOD_SESSION
      from   SMETKA_LINE SL
      where  SL.ID_SMETKA_HEAD = :id_smetka_head
             and SL.STATUS > 0
      into   :sl_dbkey, :line_sum, :id_mod_session
    do begin
      line_discount = roundto(:line_sum*:deduct_coefficient, :round_to);
      update SMETKA_LINE SL2
      set    SL2.SURCHARGE_VALUE = :line_discount,
             SL2.NETO_SUM = :line_sum + :line_discount
      where  SL2.rdb$db_key = :sl_dbkey;
      value_to_deduct = :value_to_deduct - :line_discount;
      for
        select SM.rdb$db_key, SM.NETO_SUM
        from   SMETKA_MODIFFIER SM
        where  SM.ID_MOD_SESSION = :id_mod_session
        into   :sm_dbkey, :line_sum
      do begin
        line_discount = roundto(:line_sum*:deduct_coefficient, :round_to);
        update SMETKA_MODIFFIER SM2
        set    SM2.SURCHARGE_VALUE = :line_discount,
               SM2.NETO_SUM = :line_sum + :line_discount
        where  SM2.rdb$db_key = :sm_dbkey;
        value_to_deduct = :value_to_deduct - :line_discount;
      end
    end
    /* OBIRANE NA GRESHKATA */
    update SMETKA_LINE SL2
    set    SL2.SURCHARGE_VALUE = SL2.SURCHARGE_VALUE + :value_to_deduct,
           SL2.NETO_SUM = SL2.NETO_SUM + :value_to_deduct
    where  SL2.rdb$db_key = :sl_dbkey;
  end
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
^

/* empty dependent procedure body */
/* Clear: EAI_EVO_TRANSFER$P2E for: EAI_EVO_BILL_TRANSFER$INT */
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
^

/* Alter (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.TOTAL_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.TOTAL_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
^

/* Alter (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.TOTAL_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
^

/* 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
^

/* empty dependent procedure body */
/* Clear: EAI_FRONT for: EAI_FRONT_BILL_TRANSFER$INT */
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
^

/* Alter (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.TOTAL_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
^

/* Alter (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.TOTAL_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
^

/* 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_VALUE, "_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_VALUE, 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_VALUE, DISCOUNT_SUM, "_SURCHARGE_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_VALUE, SM.DISCOUNT_SUM, "_SURCHARGE_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_VALUE, "_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_VALUE, "_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, DISCOUNT_SUM, SURCHARGE_VALUE, "_SURCHARGE_SUM")
    select ID_SMETKA_MODIFFIER, ID_END_WORK, ID_MOD_SESSION,
        ID_STOCK, SALE_PRICE, NETO_SUM, DISCOUNT_SUM, SURCHARGE_VALUE, "_SURCHARGE_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
^

/* empty dependent procedure body */
/* Clear: BILL_PAYMENT_ADD for: FISCAL_DEVICE_STATUS_CHECK */
ALTER PROCEDURE BILL_PAYMENT_ADD(ID_CLIENT_POS INTEGER,
ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_PAYMENT_TYPE INTEGER,
ID_PAYMENT_OVERRULE INTEGER,
PAYMENT_VALUE NUMERIC(15,4),
CHANGE_VALUE NUMERIC(15,4))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_SMETKA_PAYMENT INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* empty dependent procedure body */
/* Clear: BILL_POST_ADD for: FISCAL_DEVICE_STATUS_CHECK */
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_FINALIZE for: FISCAL_DEVICE_STATUS_CHECK */
ALTER PROCEDURE BILL_POST_FINALIZE(ID_CLIENT_POS INTEGER,
ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_SMETKA_DISCOUNT INTEGER,
ID_CONTRAGENT INTEGER,
ID_CONTRAGENT_OVERRULE INTEGER,
OPEN_TYPE VARCHAR(10),
CLOSE_TYPE VARCHAR(10),
ID_MANUAL_MENU INTEGER,
ID_SURCHARGE INTEGER,
SURCHARGE_VALUE NUMERIC(15,4),
CNT_LINES INTEGER,
CNT_VOIDS INTEGER,
TOTAL_SUM NUMERIC(15,4),
DISCOUNT_SUM NUMERIC(15,4),
SURCHARGE_SUM NUMERIC(15,4),
GRAND_TOTAL_SUM NUMERIC(15,4),
CUSTOMER_CNT INTEGER,
CARD_CODE VARCHAR(50))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
VIP_LINES INTEGER)
 AS
 BEGIN SUSPEND; END
^

/* empty dependent procedure body */
/* Clear: UNIQUE_SALES_NUMBER_GEN for: FISCAL_DEVICE_STATUS_CHECK */
ALTER PROCEDURE UNIQUE_SALES_NUMBER_GEN(ID_CLIENT_POS INTEGER)
 RETURNS(UNIQUE_SALES_NUMBER VARCHAR(30))
 AS
 BEGIN SUSPEND; END
^

/* Alter (FISCAL_DEVICE_STATUS_CHECK) */
ALTER PROCEDURE FISCAL_DEVICE_STATUS_CHECK(ID_CLIENT_POS TYPE OF ID_TYPE)
 RETURNS(FISCAL_DEVICE_ID TYPE OF NAME_10)
 AS
declare variable fiscal_device_error varchar(255);
declare variable default_fiscal_device_id varchar(20) ;
begin
  default_fiscal_device_id = 'OO000000';

  if (:ID_CLIENT_POS is null) then ID_CLIENT_POS = RDB$GET_CONTEXT('USER_SESSION', 'ID_CLIENT_POS');

  select sc.FISCAL_DEVICE_ID, sc.FISCAL_DEVICE_ERROR
  from   SYSTEM_CLIENT SC
  where  SC.ID_CLIENT_POS = :ID_CLIENT_POS
         and sc.FISCAL_SESSION_ID = current_connection
  into   :FISCAL_DEVICE_ID, :fiscal_device_error;

  FISCAL_DEVICE_ID = coalesce(:FISCAL_DEVICE_ID, :default_fiscal_device_id);
  --if (:FISCAL_DEVICE_ID is null) then exception FISCALIZE_EXCEPTION '-318' || f_character(10) || coalesce(:fiscal_device_error, '');
end
^

/* Alter (FISCALIZE_LINE$FISC) */
ALTER PROCEDURE FISCALIZE_LINE$FISC(ID_FISCAL_DATA 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),
IS_ADVANCE SMALLINT)
 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_FISCAL_DATA = :ID_FISCAL_DATA
  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);
      IS_ADVANCE = 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 (FISCALIZE_MARK_DOC$FISC) */
ALTER PROCEDURE FISCALIZE_MARK_DOC$FISC(ID_FISCAL_DATA 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);
  declare variable id_smetka_head integer;
begin
  fisc_status = null;

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

  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_smetka_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_FISCAL_DATA = :ID_FISCAL_DATA;

  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_FISCAL_DATA = :ID_FISCAL_DATA;

    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_smetka_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
^

/* Alter (FISCALIZE_PAYMENT$FISC) */
ALTER PROCEDURE FISCALIZE_PAYMENT$FISC(ID_FISCAL_DATA INTEGER)
 RETURNS(FISC_SUM NUMERIC(15,4),
FISC_TEXT VARCHAR(100),
FISC_GRP VARCHAR(10))
 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 payments_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_PAYMENTS, 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_FISCAL_DATA = :ID_FISCAL_DATA
  into   :payments_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(:payments_data) <> '') do begin
    end_pos = position(:line_sep, :payments_data);
    line = substring(:payments_data from 1 for :end_pos);
    payments_data = substring(:payments_data from :end_pos + 1);
    if (:line <> '') then begin
      FISC_SUM = 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(:line_sep, :line)-1);
      suspend;
    end
    i= :i + 1;
    if (:i = 1000) then exit; -- Too many cycles, recursion prevents.
  end
end
^

/* Alter (FISCALIZE_PREPARE$FISC) */
ALTER PROCEDURE FISCALIZE_PREPARE$FISC(ID_DOC_HEAD INTEGER)
 RETURNS(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 surcharges_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;
  declare variable unique_sales_number varchar(30) ;
  declare variable fisc_price type of CURRENCY_LOW;
  declare variable fisc_qty type of CURRENCY_LOW;
  declare variable fisc_text type of NAME_30;
  declare variable fisc_grp type of NAME_10;
  declare variable fisc_discount_value type of CURRENCY_LOW;
  declare variable fisc_discount_text type of NAME_50;
begin
  fld_sep = f_character(28);
  line_sep = f_character(29);

  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 !!!

  if (exists(select fd.ID_FISCAL_DATA
             from   SMETKA_FISCAL_DATA fd
             where  fd.ID_SMETKA_HEAD = :ID_DOC_HEAD)) then exit; -- existing bon(s); re-fiscalization case

  lines_data = '';
  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
           and sl.SALE_PRICE <> 0
    group by 1, 2, 3, 4
    into   :fisc_grp, :fisc_text, :fisc_price, :fisc_discount_text, :fisc_qty, :fisc_discount_value
  do begin
    line = coalesce(:fisc_price, 0) || :fld_sep
           || coalesce(:fisc_qty, 0) || :fld_sep
           || coalesce(:fisc_text, '') || :fld_sep
           || coalesce(:fisc_grp, '') || :fld_sep
           || coalesce(:fisc_discount_value, '') || :fld_sep
           || coalesce(:fisc_discount_text, '') || :fld_sep
           || '0' || :line_sep;  -- IS_ADVANCE
    lines_data = :lines_data || :line;
  end

  surcharges_data = '';
  for
    select coalesce(SH.SURCHARGE_SUM, '') || :fld_sep
           || coalesce(D.DISCOUNT_NAME, 0) || :line_sep
    from   SMETKA_HEAD SH
           join NOM_DISCOUNT D on D.ID_DISCOUNT = SH.ID_SURCHARGE
    where  SH.ID_SMETKA_HEAD = :id_doc_head
           and sh.SURCHARGE_SUM <> 0
    into   :line
  do begin
    surcharges_data = :surcharges_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_SURCHARGES, SMETKA_PAYMENTS)
  values (:ID_DOC_HEAD, :unique_sales_number, :lines_data, :surcharges_data, :payments_data);
end
^

/* Alter (FISCALIZE_SET_DETAILS$FISC) */
ALTER PROCEDURE FISCALIZE_SET_DETAILS$FISC(ID_FISCAL_DATA INTEGER,
FISCALIZATION_DETAILS VARCHAR(255))
 AS
declare variable smetka_status integer;
  declare variable curr_fiscal_details varchar(255);
  declare variable curr_storno_fiscal_details varchar(255);
begin
  select h.STATUS, fd.FISCALIZATION_DETAILS, fd.STORNO_FISCALIZATION_DETAILS
  from   SMETKA_FISCAL_DATA fd
         join SMETKA_HEAD h on h.ID_SMETKA_HEAD = fd.ID_SMETKA_HEAD
  where  fd.ID_FISCAL_DATA = :ID_FISCAL_DATA
  into   :smetka_status, :curr_fiscal_details, :curr_storno_fiscal_details;

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

    update SMETKA_FISCAL_DATA FD
    set    FD.FISCALIZATION_DETAILS = :FISCALIZATION_DETAILS
    where  fd.ID_FISCAL_DATA = :ID_FISCAL_DATA;

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

    update SMETKA_FISCAL_DATA FD
    set    FD.STORNO_FISCALIZATION_DETAILS = :FISCALIZATION_DETAILS
    where  fd.ID_FISCAL_DATA = :ID_FISCAL_DATA;
  end
end
^

/* Alter (FISCALIZE_VOID_PREPARE$FISC) */
ALTER PROCEDURE FISCALIZE_VOID_PREPARE$FISC(ID_DOC_HEAD INTEGER)
 RETURNS(VOID_REASON VARCHAR(30),
DOC_DESCRIPTION TYPE OF NAME_100)
 AS
declare variable status integer;
  declare variable max_fisc_status integer;
  declare variable storno_fiscal_device_id varchar(10);
begin
  DOC_DESCRIPTION = null;

  select h.STATUS
  from   SMETKA_HEAD h
  where  h.ID_SMETKA_HEAD = :ID_DOC_HEAD
  into   :status;

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

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

  if (:max_fisc_status < 2) then exit;
  -- !!! Only fisc_status=2 allows to continue with VOID preparation !!!

  if (not exists (select f.ID_SMETKA_HEAD from SMETKA_FISCAL_DATA f where f.ID_SMETKA_HEAD = :ID_DOC_HEAD)) then
    exception FISCALIZE_EXCEPTION '-313';

  select r.VOID_REASON, f.STORNO_FISCAL_DEVICE_ID
  from   SMETKA_FISCAL_DATA f
         left outer join SMETKA_MANAGE m on m.ID_SMETKA_HEAD = f.ID_SMETKA_HEAD
                                            and m.MANAGE_TYPE = 'TOTAL_VOID'
         left outer join NOM_VOID_REASON r on r.ID_VOID_REASON = m.ID_REASON
  where  f.ID_SMETKA_HEAD = :ID_DOC_HEAD
  into   :VOID_REASON, :storno_fiscal_device_id;

  if (:storno_fiscal_device_id is not null) then exception FISCALIZE_EXCEPTION '-314';
end
^

ALTER PROCEDURE LOOKUP_PRICE_LIST$ENT(ID_MENU_HEAD INTEGER,
PRICE_LIST_NAME VARCHAR(50))
 RETURNS(ID_PRICE_LIST INTEGER)
 AS
begin
  ID_PRICE_LIST = null;
  if ((PRICE_LIST_NAME is null) or (ID_MENU_HEAD is null)) then begin
    exit;
  end

  select mpl.ID_MENU_PRICE_LIST
  from   MENU_PRICE_LIST mpl
  where  mpl.ID_MENU_HEAD = :ID_MENU_HEAD and mpl.PRICE_LIST_NAME = :PRICE_LIST_NAME
  into   :ID_PRICE_LIST;

  execute procedure CHECK_LOOKUP_VALUE$ENT(:ID_PRICE_LIST, :PRICE_LIST_NAME, 'PRICE_LIST');
end
^

/* Alter (IMPORT_MENU_LINE_PRICE$ENT) */
ALTER PROCEDURE IMPORT_MENU_LINE_PRICE$ENT(ID_MENU_HEAD INTEGER,
ID_MENU_LINE INTEGER,
PRICE_LIST_NAME VARCHAR(50),
PROFIT_PERCENT NUMERIC(15,4),
SALE_PRICE NUMERIC(15,4))
 AS
declare variable ID_PRICE_LIST integer;
begin
  execute procedure LOOKUP_PRICE_LIST$ENT(:ID_MENU_HEAD, :PRICE_LIST_NAME)
  returning_values :ID_PRICE_LIST;

  insert into MENU_LINE_PRICE
    (ID_MENU_LINE_PRICE, ID_MENU_LINE, ID_MENU_PRICE_LIST, PROFIT_PERCENT, SALE_PRICE)
  values
    (gen_id(GEN_MENU_LINE_PRICE_ID, 1), :ID_MENU_LINE, :ID_PRICE_LIST, :PROFIT_PERCENT, :SALE_PRICE);
end
^

/* Alter (IMPORT_SUM_CONTRAGENT$ENT) */
ALTER PROCEDURE IMPORT_SUM_CONTRAGENT$ENT(CONTRAGENT_NAME VARCHAR(50),
OBJECT_NAME VARCHAR(30),
DATE_FISCAL DATE,
BRUTO_SUM NUMERIC(15,4),
DISCOUNT_SUM NUMERIC(15,4),
SURCHARGE_SUM NUMERIC(15,4),
SERVICE_SUM NUMERIC(15,4),
NETO_SUM NUMERIC(15,4),
BILLS_CNT INTEGER,
STOCK_CNT INTEGER,
DATE_REAL DATE,
CARD_CODE VARCHAR(50),
ID_END_WORK INTEGER)
 AS
declare variable ID_CONTRAGENT integer;
declare variable ID_OBJECT integer;
declare variable ID_SUM_CONTRAGENT integer;
begin
  execute procedure LOOKUP_CONTRAGENT$ENT(:CONTRAGENT_NAME)
  returning_values :ID_CONTRAGENT;
  
  execute procedure LOOKUP_OBJECT$ENT(:OBJECT_NAME)
  returning_values :ID_OBJECT;

  ID_SUM_CONTRAGENT = gen_id(GEN_SUM_CONTRAGENT_ID, 1);

  insert into SUM_CONTRAGENT
    (ID_SUM_CONTRAGENT, ID_OBJECT, DATE_FISCAL, ID_CONTRAGENT, BRUTO_SUM, DISCOUNT_SUM,
    SURCHARGE_SUM, SERVICE_SUM, NETO_SUM, BILLS_CNT, STOCK_CNT, ID_END_WORK, DATE_REAL, CARD_CODE)
  values
    (:ID_SUM_CONTRAGENT, :ID_OBJECT, :DATE_FISCAL, :ID_CONTRAGENT, :BRUTO_SUM, :DISCOUNT_SUM,
     :SURCHARGE_SUM, :SERVICE_SUM, :NETO_SUM, :BILLS_CNT, :STOCK_CNT, :ID_END_WORK, :DATE_REAL, :CARD_CODE);
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 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, SURCHARGE_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_VALUE),  -- !New, included in NETO_SUM
           sum(SL."_SURCHARGE_SUM"), -- !Old, not-included in NETO_SUM, should be removed in next patch
           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: BILL_UNQ_SALES_NUMBER_SET for: UNIQUE_SALES_NUMBER_GEN */
ALTER PROCEDURE BILL_UNQ_SALES_NUMBER_SET(ID_SMETKA_HEAD INTEGER,
ID_CLIENT_POS INTEGER)
 RETURNS(UNIQUE_SALES_NUMBER VARCHAR(30))
 AS
 BEGIN SUSPEND; END
^

/* Alter (UNIQUE_SALES_NUMBER_GEN) */
ALTER PROCEDURE UNIQUE_SALES_NUMBER_GEN(ID_CLIENT_POS INTEGER)
 RETURNS(UNIQUE_SALES_NUMBER VARCHAR(30))
 AS
declare variable user_name varchar(30);
  declare variable num_class varchar(30);
  declare variable fiscal_device_id varchar(10) ;
  declare variable number integer;
  declare variable user_code integer;
begin
  execute procedure FISCAL_DEVICE_STATUS_CHECK(:ID_CLIENT_POS)
  returning_values (:fiscal_device_id);

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

  select u.CODE
  from   RIGHT_USER u
  where  u.USER_NAME = :user_name
  into   :user_code;

  if (:user_code is null) then exception MISSING_VALUE '-317';

  NUM_CLASS = 'FISCAL_DEVICE';
  if (not exists (select n.ID_SYSTEM_NOMERATOR
                  from   SYSTEM_NOMERATOR n
                  where  n.NUM_CLASS = :num_class
                         and n.NUM_OBJECT = :FISCAL_DEVICE_ID)) then
    insert into SYSTEM_NOMERATOR (NUM_CLASS, NUM_OBJECT, NUM_NEXT, LAST_DATE)
    values (:num_class, :FISCAL_DEVICE_ID, 1, current_date);

  execute procedure BILL_GET_NUM(:FISCAL_DEVICE_ID, :num_class)
  returning_values (:NUMBER);

  if (:number is null) then exception MISSING_VALUE 'Sales number is empty!';

  UNIQUE_SALES_NUMBER = :FISCAL_DEVICE_ID || '-' || lpad(:user_code, 4, '0') || '-' || lpad(:number, 7, '0');
end
^

/* Restore proc. body: BILL_PAYMENT_ADD */
ALTER PROCEDURE BILL_PAYMENT_ADD(ID_CLIENT_POS INTEGER,
ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_PAYMENT_TYPE INTEGER,
ID_PAYMENT_OVERRULE INTEGER,
PAYMENT_VALUE NUMERIC(15,4),
CHANGE_VALUE NUMERIC(15,4))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_SMETKA_PAYMENT INTEGER)
 AS
declare variable fisc_status integer;
  declare variable fiscal_device_id varchar(10);
begin
  execute procedure FISCAL_DEVICE_STATUS_CHECK(:ID_CLIENT_POS)
  returning_values :fiscal_device_id;

  err_code = 0;
  err_text = '';

  select PT.IS_FISCAL
  from   NOM_PAYMENT_TYPE PT
  where  PT.ID_PAYMENT_TYPE = :id_payment_type
  into   :fisc_status;

  new_id_smetka_payment = gen_id(gen_smetka_payment_id,1);
  insert into SMETKA_PAYMENT (ID_SMETKA_PAYMENT, ID_SMETKA_HEAD, ID_SMETKA_TRANS, ID_PAYMENT_TYPE, ID_PAYMENT_OVERRULE,
    PAYMENT_VALUE, CHANGE_VALUE, STATUS, FISC_STATUS, ID_END_WORK)
  values (:new_id_smetka_payment, :id_smetka_head, :id_smetka_trans, :id_payment_type, :id_payment_overrule,
    :payment_value, :change_value, 1, :fisc_status, :id_end_work);
END
^

/* Restore proc. body: 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
^

/* Restore proc. body: BILL_POST_FINALIZE */
ALTER PROCEDURE BILL_POST_FINALIZE(ID_CLIENT_POS INTEGER,
ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_SMETKA_DISCOUNT INTEGER,
ID_CONTRAGENT INTEGER,
ID_CONTRAGENT_OVERRULE INTEGER,
OPEN_TYPE VARCHAR(10),
CLOSE_TYPE VARCHAR(10),
ID_MANUAL_MENU INTEGER,
ID_SURCHARGE INTEGER,
SURCHARGE_VALUE NUMERIC(15,4),
CNT_LINES INTEGER,
CNT_VOIDS INTEGER,
TOTAL_SUM NUMERIC(15,4),
DISCOUNT_SUM NUMERIC(15,4),
SURCHARGE_SUM NUMERIC(15,4),
GRAND_TOTAL_SUM NUMERIC(15,4),
CUSTOMER_CNT INTEGER,
CARD_CODE VARCHAR(50))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
VIP_LINES INTEGER)
 AS
declare variable smetka_num integer;
  declare variable status integer;
  declare variable stop_datetime timestamp;
  declare variable old_contragent_overrule integer;
  declare variable old_contragent integer;
  declare variable old_status integer;
  declare variable vip_lines_bill integer;
  declare variable no_use varchar(255) ;
  declare variable paranoid_pay_exist integer;
  declare variable action_text varchar(255);
  declare variable object_name varchar(30);
  declare variable table_no integer;
  declare variable smetka_date date;
  declare variable action_code varchar(50);
  declare variable unique_sales_number varchar(30);
begin
  err_code = 0;
  err_text = '';
  stop_datetime = current_timestamp;
  if (exists(
    select SP.ID_SMETKA_PAYMENT
    from   SMETKA_PAYMENT SP
    where  SP.ID_SMETKA_HEAD = :id_smetka_head
           and SP.PAYMENT_VALUE > 0
           and SP.STATUS > 0
  )) then paranoid_pay_exist = 1;
  else paranoid_pay_exist = 0;

  execute procedure SYS_PARANOID_DEBUG(:paranoid_pay_exist, :id_client_pos,
    :id_end_work, :id_smetka_head, :id_smetka_trans, :open_type, :close_type, 1);

  select SH.ID_CONTRAGENT, SH.SMETKA_NUM,
         SH.ID_CONTRAGENT_OVERRULE, SH.STATUS, o.OBJECT_NAME,
         sh.TABLE_NO, sh.SMETKA_DATE, sh.UNIQUE_SALES_NUMBER
  from   SMETKA_HEAD SH
         join NOM_OBJECT o on o.ID_OBJECT = sh.ID_OBJECT
  where  sh.id_smetka_head = :id_smetka_head
  into   :old_contragent, :smetka_num,
         :old_contragent_overrule, :old_status, :object_name,
         :table_no, :smetka_date, :unique_sales_number;
  if (:old_contragent = :id_contragent) then id_contragent_overrule = :old_contragent_overrule;

  execute procedure BILL_TRANSACTION(:id_smetka_trans, :id_end_work, '', :cnt_voids, :cnt_lines, :id_client_pos, 'STOP')
  returning_values  :err_code, :err_text, :id_smetka_trans;

  delete
  from   SMETKA_LINE SL
  where  SL.ID_SMETKA_HEAD = :id_smetka_head
         and SL.QTY_POST = 0
         and SL.ID_LINE_VOID is null;

  execute procedure BILL_PROBE_VALID(:id_smetka_head)
  returning_values  :VIP_lines_bill;

  if (:open_type = 'CREATE') then begin
    if ((:VIP_lines_bill = 0) and (:close_type = 'CANCEL')) then begin /* WE DO NOT SUPPORT EMPTY BILLS */
      /* 'ORDER' & 'TOTAL' ARE MANAGED IN THE GUI => 'CANCEL' */
      delete from SMETKA_HEAD SH
      where  SH.ID_SMETKA_HEAD = :ID_SMETKA_HEAD;

    end else if ((:VIP_lines_bill = 0) and (:close_type <> 'ORDER')) then close_type = 'OPEN_VOID'; /* BILL MUST BE VOIDED */

  end else if ( :open_type = 'OPEN' ) then begin
    if ((:VIP_lines_bill = 0) and (:close_type in ('TOTAL', 'CANCEL'))) then close_type = 'OPEN_VOID';
  end

  if (:unique_sales_number is null) then begin
    execute procedure BILL_UNQ_SALES_NUMBER_SET(:ID_SMETKA_HEAD, :ID_CLIENT_POS)
    returning_values (:unique_sales_number);
  end

  if (:close_type = 'CANCEL') then begin
    execute procedure SYS_PARANOID_DEBUG(:paranoid_pay_exist, :id_client_pos,
      :id_end_work, :id_smetka_head, :id_smetka_trans, :open_type, :close_type, 2);
    exit;
  end else if (:close_type = 'TOTAL') then begin
    execute procedure FISCAL_DEVICE_STATUS_CHECK(:ID_CLIENT_POS)
    returning_values (:no_use);

    if (:old_status <> 1 /* OPEN (ORDER) */) then begin
      err_code = -153;
      exit;
    end
    status = 2;
  end else if (:close_type = 'ORDER') then begin
    status = 1;
    stop_datetime = null;
  end else if (:close_type in ('TOTAL_VOID', 'OPEN_VOID')) then begin
    execute procedure FISCAL_DEVICE_STATUS_CHECK(:ID_CLIENT_POS)
    returning_values (:no_use);

    if (:close_type = 'TOTAL_VOID') then status = -3;
    else if (:close_type = 'OPEN_VOID') then status = -4;
    /* FINAL PREPARATIOIN FOR VANISHING EVERYTHING */
    surcharge_value = 0;
    id_surcharge = null;
    customer_cnt = 0;
    id_smetka_discount = null;
  end

  update SMETKA_HEAD SH
  set    SH.STATUS = :status,
         SH.SMETKA_NUM = :smetka_num,
         SH.STOP_DATETIME = :stop_datetime,
         SH.TOTAL_SUM = :total_sum,
         SH.DISCOUNT_SUM = :discount_sum,
         SH.SURCHARGE_SUM = :surcharge_sum,
         SH.GRAND_TOTAL_SUM = :grand_total_sum,
         SH.ID_MANUAL_PRICE_LIST = :id_manual_menu,
         SH.ID_SMETKA_DISCOUNT = :id_smetka_discount,
         SH.ID_SURCHARGE = :id_surcharge,
         SH.SURCHARGE_VALUE = :surcharge_value,
         SH.ID_CONTRAGENT = :id_contragent,
         SH.ID_CONTRAGENT_OVERRULE = :id_contragent_overrule,
         SH.CUSTOMER_CNT = :customer_cnt,
         SH.CARD_CODE = :card_code
  where  SH.ID_SMETKA_HEAD = :ID_SMETKA_HEAD;

  if (exists(
    select count(distinct 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_smetka_head
           and SP.ID_PAYMENT_VOID is null
           and SH.STATUS = 2
    having count(distinct SP.FISC_STATUS) > 1
  )) then begin
    err_code = -307;
    exit;
  end

  execute procedure SYS_PARANOID_DEBUG(:paranoid_pay_exist, :id_client_pos,
    :id_end_work, :id_smetka_head, :id_smetka_trans, :OPEN_TYPE, :close_type, 3);

  if (:close_type in ('TOTAL_VOID', 'OPEN_VOID')) then begin
    action_text = f_character(29) || :smetka_num || f_character(28) || :object_name || f_character(28) || :table_no || f_character(28) || :smetka_date || f_character(28) || coalesce(:unique_sales_number, '');
    if (:close_type = 'OPEN_VOID') then action_code = 'BILL_VOID_OPEN';
    else if (:close_type = 'TOTAL_VOID') then action_code = 'BILL_VOID_CLOSED';

    execute procedure SYSTEM_LOG_ADD('BILL', :ID_SMETKA_HEAD, :action_code, :action_text);
  end

  delete from SMETKA_DISCOUNT SD
  where  SD.ID_SMETKA_HEAD = :id_smetka_head
         and SD.STATUS in (2, 3) /* TOTAL or CONTRAGENT */
         and ((:id_smetka_discount is null) or (SD.ID_SMETKA_DISCOUNT <> :id_smetka_discount));

  /* GENERATE BONS */
  if ((:close_type = 'TOTAL') and (:VIP_lines_bill = 0)) then exit;
  execute procedure BILL_PROBE_VALID(:id_smetka_head, :id_smetka_trans)
  returning_values  :VIP_lines;
  if ((:close_type = 'ORDER') and (:VIP_lines = 0)) then exit;

  execute procedure BILL_POST_FINALIZE_BON(:id_smetka_head, :id_smetka_trans, :id_end_work)
  returning_values  :err_code, :err_text;

  if ((:close_type = 'TOTAL') and (not exists(
    select *
    from   SMETKA_PAYMENT SP
    where  SP.ID_SMETKA_HEAD = :id_smetka_head
           and SP.STATUS > 0
  ))) then begin
    /* BILL WITH 100% DISCOUNT, WE MUST SET SPECIAL PAYMENT TYPE*/
    execute procedure BILL_PAYMENT_ADD(:id_client_pos, :id_end_work, :id_smetka_head, :id_smetka_trans, 0, null, 0, 0)
    returning_values  :err_code, :err_text, :no_use;
  end
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: BILL_UNQ_SALES_NUMBER_SET */
ALTER PROCEDURE BILL_UNQ_SALES_NUMBER_SET(ID_SMETKA_HEAD INTEGER,
ID_CLIENT_POS INTEGER)
 RETURNS(UNIQUE_SALES_NUMBER VARCHAR(30))
 AS
declare variable dbkey char(8);
begin
  select h.RDB$DB_KEY, h.UNIQUE_SALES_NUMBER
  from   SMETKA_HEAD h
  where  h.ID_SMETKA_HEAD = :ID_SMETKA_HEAD
  into   :dbkey, :UNIQUE_SALES_NUMBER;

  if ((:unique_sales_number is null) and (:dbkey is not null)) then begin
    if (:ID_CLIENT_POS is null) then ID_CLIENT_POS = RDB$GET_CONTEXT('USER_SESSION', 'ID_CLIENT_POS');

    execute procedure UNIQUE_SALES_NUMBER_GEN(:ID_CLIENT_POS)
    returning_values (:UNIQUE_SALES_NUMBER);

    update SMETKA_HEAD SH
    set    SH.UNIQUE_SALES_NUMBER = :UNIQUE_SALES_NUMBER
    where  SH.rdb$db_key = :dbkey;
  end
end
^

/* Restore proc. body: 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
^

/* 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_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: FISCALIZE_DISCOUNT$FISC */
ALTER PROCEDURE FISCALIZE_DISCOUNT$FISC(ID_FISCAL_DATA INTEGER)
 RETURNS(FISC_SUM NUMERIC(15,4),
FISC_TEXT VARCHAR(100))
 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 discounts_data blob sub_type 1 segment size 100;
  declare variable i integer;
begin
  select f.SMETKA_DISCOUNTS
  from   SMETKA_FISCAL_DATA f
  where  f.ID_FISCAL_DATA = :ID_FISCAL_DATA
  into   :discounts_data;

  i = 0;
  fld_sep = f_character(28);
  line_sep = f_character(29);
  while (trim(:discounts_data) <> '') do begin
    end_pos = position(:line_sep, :discounts_data);
    line = substring(:discounts_data from 1 for :end_pos);
    discounts_data = substring(:discounts_data from :end_pos + 1);
    if (:line <> '') then begin
      FISC_SUM = 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(:line_sep, :line)-1);
      suspend;
    end
    i= :i + 1;
    if (:i = 1000) then exit; -- Too many cycles, recursion prevents.
  end
end
^

/* Restore proc. body: FISCALIZE_SURCHARGE$FISC */
ALTER PROCEDURE FISCALIZE_SURCHARGE$FISC(ID_FISCAL_DATA INTEGER)
 RETURNS(FISC_SUM NUMERIC(15,4),
FISC_TEXT VARCHAR(100))
 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 surcharges_data blob sub_type 1 segment size 100;
  declare variable i integer;
begin
  select f.SMETKA_SURCHARGES
  from   SMETKA_FISCAL_DATA f
  where  f.ID_FISCAL_DATA = :ID_FISCAL_DATA
  into   :surcharges_data;

  i = 0;
  fld_sep = f_character(28);
  line_sep = f_character(29);
  while (trim(:surcharges_data) <> '') do begin
    end_pos = position(:line_sep, :surcharges_data);
    line = substring(:surcharges_data from 1 for :end_pos);
    surcharges_data = substring(:surcharges_data from :end_pos + 1);
    if (:line <> '') then begin
      FISC_SUM = 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(:line_sep, :line)-1);
      suspend;
    end
    i= :i + 1;
    if (:i = 1000) then exit; -- Too many cycles, recursion prevents.
  end
end
^

/* Creating trigger... */
CREATE TRIGGER SMETKA_FISCAL_DATA_BI FOR SMETKA_FISCAL_DATA
ACTIVE BEFORE INSERT POSITION 0 
as
begin
  if (new.ID_FISCAL_DATA is null) then
    new.ID_FISCAL_DATA = gen_id(GEN_SMETKA_FISCAL_DATA_ID,1);
end
^


/* Create Views... */

/* Alter Procedure... */
/* Alter (BILL_PAYMENT_ADD) */
ALTER PROCEDURE BILL_PAYMENT_ADD(ID_CLIENT_POS INTEGER,
ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_PAYMENT_TYPE INTEGER,
ID_PAYMENT_OVERRULE INTEGER,
PAYMENT_VALUE NUMERIC(15,4),
CHANGE_VALUE NUMERIC(15,4))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_SMETKA_PAYMENT INTEGER)
 AS
declare variable fisc_status integer;
  declare variable fiscal_device_id varchar(10);
begin
  execute procedure FISCAL_DEVICE_STATUS_CHECK(:ID_CLIENT_POS)
  returning_values :fiscal_device_id;

  err_code = 0;
  err_text = '';

  select PT.IS_FISCAL
  from   NOM_PAYMENT_TYPE PT
  where  PT.ID_PAYMENT_TYPE = :id_payment_type
  into   :fisc_status;

  new_id_smetka_payment = gen_id(gen_smetka_payment_id,1);
  insert into SMETKA_PAYMENT (ID_SMETKA_PAYMENT, ID_SMETKA_HEAD, ID_SMETKA_TRANS, ID_PAYMENT_TYPE, ID_PAYMENT_OVERRULE,
    PAYMENT_VALUE, CHANGE_VALUE, STATUS, FISC_STATUS, ID_END_WORK)
  values (:new_id_smetka_payment, :id_smetka_head, :id_smetka_trans, :id_payment_type, :id_payment_overrule,
    :payment_value, :change_value, 1, :fisc_status, :id_end_work);
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
^

/* Alter (BILL_POST_FINALIZE) */
ALTER PROCEDURE BILL_POST_FINALIZE(ID_CLIENT_POS INTEGER,
ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_SMETKA_DISCOUNT INTEGER,
ID_CONTRAGENT INTEGER,
ID_CONTRAGENT_OVERRULE INTEGER,
OPEN_TYPE VARCHAR(10),
CLOSE_TYPE VARCHAR(10),
ID_MANUAL_MENU INTEGER,
ID_SURCHARGE INTEGER,
SURCHARGE_VALUE NUMERIC(15,4),
CNT_LINES INTEGER,
CNT_VOIDS INTEGER,
TOTAL_SUM NUMERIC(15,4),
DISCOUNT_SUM NUMERIC(15,4),
SURCHARGE_SUM NUMERIC(15,4),
GRAND_TOTAL_SUM NUMERIC(15,4),
CUSTOMER_CNT INTEGER,
CARD_CODE VARCHAR(50))
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
VIP_LINES INTEGER)
 AS
declare variable smetka_num integer;
  declare variable status integer;
  declare variable stop_datetime timestamp;
  declare variable old_contragent_overrule integer;
  declare variable old_contragent integer;
  declare variable old_status integer;
  declare variable vip_lines_bill integer;
  declare variable no_use varchar(255) ;
  declare variable paranoid_pay_exist integer;
  declare variable action_text varchar(255);
  declare variable object_name varchar(30);
  declare variable table_no integer;
  declare variable smetka_date date;
  declare variable action_code varchar(50);
  declare variable unique_sales_number varchar(30);
begin
  err_code = 0;
  err_text = '';
  stop_datetime = current_timestamp;
  if (exists(
    select SP.ID_SMETKA_PAYMENT
    from   SMETKA_PAYMENT SP
    where  SP.ID_SMETKA_HEAD = :id_smetka_head
           and SP.PAYMENT_VALUE > 0
           and SP.STATUS > 0
  )) then paranoid_pay_exist = 1;
  else paranoid_pay_exist = 0;

  execute procedure SYS_PARANOID_DEBUG(:paranoid_pay_exist, :id_client_pos,
    :id_end_work, :id_smetka_head, :id_smetka_trans, :open_type, :close_type, 1);

  select SH.ID_CONTRAGENT, SH.SMETKA_NUM,
         SH.ID_CONTRAGENT_OVERRULE, SH.STATUS, o.OBJECT_NAME,
         sh.TABLE_NO, sh.SMETKA_DATE, sh.UNIQUE_SALES_NUMBER
  from   SMETKA_HEAD SH
         join NOM_OBJECT o on o.ID_OBJECT = sh.ID_OBJECT
  where  sh.id_smetka_head = :id_smetka_head
  into   :old_contragent, :smetka_num,
         :old_contragent_overrule, :old_status, :object_name,
         :table_no, :smetka_date, :unique_sales_number;
  if (:old_contragent = :id_contragent) then id_contragent_overrule = :old_contragent_overrule;

  execute procedure BILL_TRANSACTION(:id_smetka_trans, :id_end_work, '', :cnt_voids, :cnt_lines, :id_client_pos, 'STOP')
  returning_values  :err_code, :err_text, :id_smetka_trans;

  delete
  from   SMETKA_LINE SL
  where  SL.ID_SMETKA_HEAD = :id_smetka_head
         and SL.QTY_POST = 0
         and SL.ID_LINE_VOID is null;

  execute procedure BILL_PROBE_VALID(:id_smetka_head)
  returning_values  :VIP_lines_bill;

  if (:open_type = 'CREATE') then begin
    if ((:VIP_lines_bill = 0) and (:close_type = 'CANCEL')) then begin /* WE DO NOT SUPPORT EMPTY BILLS */
      /* 'ORDER' & 'TOTAL' ARE MANAGED IN THE GUI => 'CANCEL' */
      delete from SMETKA_HEAD SH
      where  SH.ID_SMETKA_HEAD = :ID_SMETKA_HEAD;

    end else if ((:VIP_lines_bill = 0) and (:close_type <> 'ORDER')) then close_type = 'OPEN_VOID'; /* BILL MUST BE VOIDED */

  end else if ( :open_type = 'OPEN' ) then begin
    if ((:VIP_lines_bill = 0) and (:close_type in ('TOTAL', 'CANCEL'))) then close_type = 'OPEN_VOID';
  end

  if (:unique_sales_number is null) then begin
    execute procedure BILL_UNQ_SALES_NUMBER_SET(:ID_SMETKA_HEAD, :ID_CLIENT_POS)
    returning_values (:unique_sales_number);
  end

  if (:close_type = 'CANCEL') then begin
    execute procedure SYS_PARANOID_DEBUG(:paranoid_pay_exist, :id_client_pos,
      :id_end_work, :id_smetka_head, :id_smetka_trans, :open_type, :close_type, 2);
    exit;
  end else if (:close_type = 'TOTAL') then begin
    execute procedure FISCAL_DEVICE_STATUS_CHECK(:ID_CLIENT_POS)
    returning_values (:no_use);

    if (:old_status <> 1 /* OPEN (ORDER) */) then begin
      err_code = -153;
      exit;
    end
    status = 2;
  end else if (:close_type = 'ORDER') then begin
    status = 1;
    stop_datetime = null;
  end else if (:close_type in ('TOTAL_VOID', 'OPEN_VOID')) then begin
    execute procedure FISCAL_DEVICE_STATUS_CHECK(:ID_CLIENT_POS)
    returning_values (:no_use);

    if (:close_type = 'TOTAL_VOID') then status = -3;
    else if (:close_type = 'OPEN_VOID') then status = -4;
    /* FINAL PREPARATIOIN FOR VANISHING EVERYTHING */
    surcharge_value = 0;
    id_surcharge = null;
    customer_cnt = 0;
    id_smetka_discount = null;
  end

  update SMETKA_HEAD SH
  set    SH.STATUS = :status,
         SH.SMETKA_NUM = :smetka_num,
         SH.STOP_DATETIME = :stop_datetime,
         SH.TOTAL_SUM = :total_sum,
         SH.DISCOUNT_SUM = :discount_sum,
         SH.SURCHARGE_SUM = :surcharge_sum,
         SH.GRAND_TOTAL_SUM = :grand_total_sum,
         SH.ID_MANUAL_PRICE_LIST = :id_manual_menu,
         SH.ID_SMETKA_DISCOUNT = :id_smetka_discount,
         SH.ID_SURCHARGE = :id_surcharge,
         SH.SURCHARGE_VALUE = :surcharge_value,
         SH.ID_CONTRAGENT = :id_contragent,
         SH.ID_CONTRAGENT_OVERRULE = :id_contragent_overrule,
         SH.CUSTOMER_CNT = :customer_cnt,
         SH.CARD_CODE = :card_code
  where  SH.ID_SMETKA_HEAD = :ID_SMETKA_HEAD;

  if (exists(
    select count(distinct 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_smetka_head
           and SP.ID_PAYMENT_VOID is null
           and SH.STATUS = 2
    having count(distinct SP.FISC_STATUS) > 1
  )) then begin
    err_code = -307;
    exit;
  end

  execute procedure SYS_PARANOID_DEBUG(:paranoid_pay_exist, :id_client_pos,
    :id_end_work, :id_smetka_head, :id_smetka_trans, :OPEN_TYPE, :close_type, 3);

  if (:close_type in ('TOTAL_VOID', 'OPEN_VOID')) then begin
    action_text = f_character(29) || :smetka_num || f_character(28) || :object_name || f_character(28) || :table_no || f_character(28) || :smetka_date || f_character(28) || coalesce(:unique_sales_number, '');
    if (:close_type = 'OPEN_VOID') then action_code = 'BILL_VOID_OPEN';
    else if (:close_type = 'TOTAL_VOID') then action_code = 'BILL_VOID_CLOSED';

    execute procedure SYSTEM_LOG_ADD('BILL', :ID_SMETKA_HEAD, :action_code, :action_text);
  end

  delete from SMETKA_DISCOUNT SD
  where  SD.ID_SMETKA_HEAD = :id_smetka_head
         and SD.STATUS in (2, 3) /* TOTAL or CONTRAGENT */
         and ((:id_smetka_discount is null) or (SD.ID_SMETKA_DISCOUNT <> :id_smetka_discount));

  /* GENERATE BONS */
  if ((:close_type = 'TOTAL') and (:VIP_lines_bill = 0)) then exit;
  execute procedure BILL_PROBE_VALID(:id_smetka_head, :id_smetka_trans)
  returning_values  :VIP_lines;
  if ((:close_type = 'ORDER') and (:VIP_lines = 0)) then exit;

  execute procedure BILL_POST_FINALIZE_BON(:id_smetka_head, :id_smetka_trans, :id_end_work)
  returning_values  :err_code, :err_text;

  if ((:close_type = 'TOTAL') and (not exists(
    select *
    from   SMETKA_PAYMENT SP
    where  SP.ID_SMETKA_HEAD = :id_smetka_head
           and SP.STATUS > 0
  ))) then begin
    /* BILL WITH 100% DISCOUNT, WE MUST SET SPECIAL PAYMENT TYPE*/
    execute procedure BILL_PAYMENT_ADD(:id_client_pos, :id_end_work, :id_smetka_head, :id_smetka_trans, 0, null, 0, 0)
    returning_values  :err_code, :err_text, :no_use;
  end
end
^

/* 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
^

/* Alter (BILL_UNQ_SALES_NUMBER_SET) */
ALTER PROCEDURE BILL_UNQ_SALES_NUMBER_SET(ID_SMETKA_HEAD INTEGER,
ID_CLIENT_POS INTEGER)
 RETURNS(UNIQUE_SALES_NUMBER VARCHAR(30))
 AS
declare variable dbkey char(8);
begin
  select h.RDB$DB_KEY, h.UNIQUE_SALES_NUMBER
  from   SMETKA_HEAD h
  where  h.ID_SMETKA_HEAD = :ID_SMETKA_HEAD
  into   :dbkey, :UNIQUE_SALES_NUMBER;

  if ((:unique_sales_number is null) and (:dbkey is not null)) then begin
    if (:ID_CLIENT_POS is null) then ID_CLIENT_POS = RDB$GET_CONTEXT('USER_SESSION', 'ID_CLIENT_POS');

    execute procedure UNIQUE_SALES_NUMBER_GEN(:ID_CLIENT_POS)
    returning_values (:UNIQUE_SALES_NUMBER);

    update SMETKA_HEAD SH
    set    SH.UNIQUE_SALES_NUMBER = :UNIQUE_SALES_NUMBER
    where  SH.rdb$db_key = :dbkey;
  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_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_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_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
^

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 SURCHARGE_VALUE POSITION 17;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN NETO_SUM POSITION 18;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN NETO_WOT_TAX POSITION 19;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN TAX_PERCENT POSITION 20;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN VAT_CODE POSITION 21;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_MENU_PRICE_LIST POSITION 22;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_PRICE_LIST_OVERRULE POSITION 23;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_VOIDED_LINE POSITION 24;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_LINE_VOID POSITION 25;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_LINE_DISCOUNT POSITION 26;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_SMETKA_BON POSITION 27;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN POST_STATUS POSITION 28;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN STATUS POSITION 29;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_MOD_SESSION POSITION 30;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN "_SURCHARGE_SUM" POSITION 31;

ALTER TABLE ARCHIVE_MODIFFIER ALTER COLUMN ID_SMETKA_MODIFFIER POSITION 1;

ALTER TABLE ARCHIVE_MODIFFIER ALTER COLUMN ID_END_WORK POSITION 2;

ALTER TABLE ARCHIVE_MODIFFIER ALTER COLUMN ID_MOD_SESSION POSITION 3;

ALTER TABLE ARCHIVE_MODIFFIER ALTER COLUMN ID_STOCK POSITION 4;

ALTER TABLE ARCHIVE_MODIFFIER ALTER COLUMN SALE_PRICE POSITION 5;

ALTER TABLE ARCHIVE_MODIFFIER ALTER COLUMN NETO_SUM POSITION 6;

ALTER TABLE ARCHIVE_MODIFFIER ALTER COLUMN DISCOUNT_SUM POSITION 7;

ALTER TABLE ARCHIVE_MODIFFIER ALTER COLUMN SURCHARGE_VALUE POSITION 8;

ALTER TABLE ARCHIVE_MODIFFIER ALTER COLUMN "_SURCHARGE_SUM" POSITION 9;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN ID_FISCAL_DATA POSITION 1;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN ID_SMETKA_HEAD POSITION 2;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN UNIQUE_SALES_NUMBER POSITION 3;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN FISCAL_AMOUNT POSITION 4;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN FISCAL_GROUP_LIST POSITION 5;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN SMETKA_LINES POSITION 6;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN SMETKA_DISCOUNTS POSITION 7;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN SMETKA_SURCHARGES POSITION 8;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN SMETKA_PAYMENTS POSITION 9;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN FISCAL_DEVICE_ID POSITION 10;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN FISCALIZATION_DETAILS POSITION 11;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN STORNO_FISCAL_DEVICE_ID POSITION 12;

ALTER TABLE SMETKA_FISCAL_DATA ALTER COLUMN STORNO_FISCALIZATION_DETAILS POSITION 13;

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 SURCHARGE_VALUE POSITION 17;

ALTER TABLE SMETKA_LINE ALTER COLUMN NETO_SUM POSITION 18;

ALTER TABLE SMETKA_LINE ALTER COLUMN NETO_WOT_TAX POSITION 19;

ALTER TABLE SMETKA_LINE ALTER COLUMN TAX_PERCENT POSITION 20;

ALTER TABLE SMETKA_LINE ALTER COLUMN VAT_CODE POSITION 21;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_MENU_PRICE_LIST POSITION 22;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_PRICE_LIST_OVERRULE POSITION 23;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_VOIDED_LINE POSITION 24;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_LINE_VOID POSITION 25;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_LINE_DISCOUNT POSITION 26;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_SMETKA_BON POSITION 27;

ALTER TABLE SMETKA_LINE ALTER COLUMN POST_STATUS POSITION 28;

ALTER TABLE SMETKA_LINE ALTER COLUMN STATUS POSITION 29;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_MOD_SESSION POSITION 30;

ALTER TABLE SMETKA_LINE ALTER COLUMN "_SURCHARGE_SUM" POSITION 31;

ALTER TABLE SMETKA_LINE ALTER COLUMN TOTAL_SUM POSITION 32;

ALTER TABLE SMETKA_MODIFFIER ALTER COLUMN ID_SMETKA_MODIFFIER POSITION 1;

ALTER TABLE SMETKA_MODIFFIER ALTER COLUMN ID_END_WORK POSITION 2;

ALTER TABLE SMETKA_MODIFFIER ALTER COLUMN ID_MOD_SESSION POSITION 3;

ALTER TABLE SMETKA_MODIFFIER ALTER COLUMN ID_STOCK POSITION 4;

ALTER TABLE SMETKA_MODIFFIER ALTER COLUMN SALE_PRICE POSITION 5;

ALTER TABLE SMETKA_MODIFFIER ALTER COLUMN NETO_SUM POSITION 6;

ALTER TABLE SMETKA_MODIFFIER ALTER COLUMN DISCOUNT_SUM POSITION 7;

ALTER TABLE SMETKA_MODIFFIER ALTER COLUMN SURCHARGE_VALUE POSITION 8;

ALTER TABLE SMETKA_MODIFFIER ALTER COLUMN "_SURCHARGE_SUM" POSITION 9;

ALTER TABLE SMETKA_MODIFFIER ALTER COLUMN TOTAL_SUM POSITION 10;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN ID_SUM_CONTRAGENT POSITION 1;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN ID_OBJECT POSITION 2;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN DATE_FISCAL POSITION 3;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN ID_CONTRAGENT POSITION 4;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN BRUTO_SUM POSITION 5;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN DISCOUNT_SUM POSITION 6;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN SURCHARGE_SUM POSITION 7;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN SERVICE_SUM POSITION 8;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN NETO_SUM POSITION 9;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN BILLS_CNT POSITION 10;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN STOCK_CNT POSITION 11;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN ID_END_WORK POSITION 12;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN DATE_REAL POSITION 13;

ALTER TABLE SUM_CONTRAGENT ALTER COLUMN CARD_CODE POSITION 14;

