/* 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 ARCHIVE_LINE ADD ID_TRANSFER_SOURCE_LINE ID_REF;

ALTER TABLE SMETKA_LINE ADD ID_TRANSFER_SOURCE_LINE ID_REF;

/* Alter Procedure... */
/* empty dependent procedure body */
/* Clear: BILL_POST_ADD for: BILL_POST_ADD */
SET TERM ^ ;

ALTER PROCEDURE BILL_POST_ADD(ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_MENU_PRICE_LIST INTEGER,
ID_PRICE_LIST_OVERRULE INTEGER,
ID_STOCK INTEGER,
ID_INVENT INTEGER,
ID_VAT INTEGER,
QTY NUMERIC(15,4),
SALE_PRICE NUMERIC(15,4),
LINE_SUM NUMERIC(15,4),
ID_LINE_DISCOUNT INTEGER,
ID_LINE_VOID INTEGER,
EDIT_KIND VARCHAR(10),
ID_MASTER_LINE INTEGER,
LINE_TEXT VARCHAR(2000),
MOD_CNT INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_MOD_SESSION INTEGER)
 AS
 BEGIN SUSPEND; END
^

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

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

/* Alter (BILL_POST_ADD) */
ALTER PROCEDURE BILL_POST_ADD(ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_MENU_PRICE_LIST INTEGER,
ID_PRICE_LIST_OVERRULE INTEGER,
ID_STOCK INTEGER,
ID_INVENT INTEGER,
ID_VAT INTEGER,
QTY NUMERIC(15,4),
SALE_PRICE NUMERIC(15,4),
LINE_SUM NUMERIC(15,4),
ID_LINE_DISCOUNT INTEGER,
ID_LINE_VOID INTEGER,
EDIT_KIND VARCHAR(10),
ID_MASTER_LINE INTEGER,
LINE_TEXT VARCHAR(2000),
MOD_CNT INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
NEW_ID_MOD_SESSION INTEGER)
 AS
declare variable cost_price numeric(15, 4);
  declare variable status integer;
  declare variable vqty numeric(15, 4);
  declare variable vsl_dbkey char(8);
  declare variable qty_post numeric(15, 4);
  declare variable qty_void numeric(15, 4);
  declare variable id_voided_discount integer;
  declare variable discount_sum numeric(15, 4);
  declare variable void_sum numeric(15, 4);
  declare variable post_status integer;
  declare variable is_service integer;
  declare variable is_use integer;
  declare variable new_line_text integer;
  declare variable tax_percent numeric(15,4);
  declare variable unique_sales_number varchar(30);
  declare variable stock_name varchar(30);
  declare variable object_name varchar(30);
  declare variable smetka_date date;
  declare variable smetka_num integer;
  declare variable fiscal_device_id varchar(10);
  declare variable new_id_line_void integer;
  declare variable id_client_pos integer;
  declare variable id_void_reason integer;
  declare variable id_transfer_source_line integer;
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
  from   TAX_GROUP TG
  where  TG.ID_TAX_GROUP = :ID_VAT
  into   :tax_percent;

  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, 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, :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, 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, :id_transfer_source_line);

END
^

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

/* Alter (BILL_POST_ADD$PDA) */
ALTER PROCEDURE BILL_POST_ADD$PDA(ID_CLIENT_POS INTEGER,
ID_END_WORK INTEGER,
ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255),
TOTAL_SUM NUMERIC(15,4))
 AS
declare variable dbg varchar(2000);

  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 active_user varchar(50);
  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
  /*  Description:
  ||
  */
  err_code = 0;
  err_text = '';
  execute procedure SYSTEM_GET_VALUE(:id_client_pos, 'CURRENT_USER')
  returning_values  :active_user;


  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.ID_VAT_GROUP, 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, :id_vat, :is_modifier
  do begin
    select ML.ID_INVENT
    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;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/* empty dependent procedure body */
/* Clear: BILL_POST_FINALIZE for: BILL_POST_FINALIZE_BON */
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
^

/* Alter (BILL_POST_FINALIZE_BON) */
ALTER PROCEDURE BILL_POST_FINALIZE_BON(ID_SMETKA_HEAD INTEGER,
ID_SMETKA_TRANS INTEGER,
ID_END_WORK INTEGER)
 RETURNS(ERR_CODE INTEGER,
ERR_TEXT VARCHAR(255))
 AS
declare variable id_invent integer;
  declare variable bon_status integer;
  declare variable id_smetka_bon integer;
  declare variable nid_invent integer;
  declare variable nbon_status integer;
  declare variable id_voided_line integer;
  declare variable id_voided_bon integer;
  declare variable is_print_on_bon integer;
  declare variable line_dbkey char(8);
  declare variable stock_out_key char(8);
  declare variable qty_required numeric(15,4);
  declare variable qty_available numeric(15,4);
  declare variable qty_remaining numeric(15,4);
  declare variable stock_name varchar(50);
begin
  err_code      = 0;
  err_text      = '';
  id_invent     = 0;
  bon_status    = 0;
  id_smetka_bon = null;

--  savedbg('BILL_POST_FINALIZE_BON(:id_smetka_head=>' || :id_smetka_head || ')');

  for
    select SL.RDB$DB_KEY, SL.ID_INVENT, SL.STATUS, VR.IS_PRINT_ON_BON,
           SL.ID_VOIDED_LINE, so.rdb$db_key, sl.qty, so.qty_available, (so.qty_available - sl.qty) as qty_remaining,
           ml.stock_name
    from   SMETKA_LINE SL
           join SMETKA_HEAD h on h.ID_SMETKA_HEAD = sl.ID_SMETKA_HEAD
           join MENU_LINE_PRICE pll on pll.id_menu_price_list = coalesce(sl.id_price_list_overrule, sl.id_menu_price_list)
           join MENU_LINE ml on ml.id_menu_line=pll.id_menu_line and ml.id_stock=sl.id_stock
           left outer join SMETKA_MANAGE SM on SM.ID_SMETKA_MANAGE = SL.ID_LINE_VOID
           left outer join NOM_VOID_REASON VR on VR.ID_VOID_REASON = SM.ID_REASON
           left outer join SMETKA_STOCKOUT so on so.id_stock = sl.id_stock and so.ID_OBJECT = h.ID_OBJECT
    where  SL.ID_SMETKA_TRANS = :id_smetka_trans
           and SL.ID_SMETKA_HEAD = :id_smetka_head
           and SL.STATUS > -20 /* NON PRINTABLE (CORRECTIONS)*/
           and SL.ID_SMETKA_BON is null
           and SL.ID_TRANSFER_SOURCE_LINE is null
    order by SL.ID_INVENT asc, SL.STATUS asc
    into   :line_dbkey, :nid_invent, :nbon_status /* 1, -10 */, :is_print_on_bon,
           :id_voided_line, :stock_out_key, :qty_required, :qty_available, :qty_remaining,
           :stock_name
  do begin
    if (:qty_remaining is not null) then begin
      if (0 > :qty_remaining) then begin
        err_code = -308;
        if (:qty_available < 0) then begin
          qty_available = 0;
        end
        err_text = :stock_name || ' (' || :qty_required || ' / ' || :qty_available || ')';

        exit;
      end

      update SMETKA_STOCKOUT so
      set    so.qty_available = :qty_remaining
      where  so.rdb$db_key = :stock_out_key;
    end

    if ((:is_print_on_bon is null) or (:is_print_on_bon <> 0)) then begin
      if ((:nid_invent<>:id_invent) or (:nbon_status<>:bon_status)) then begin
        /* CREATE NEW BON */
        id_smetka_bon = gen_id(gen_smetka_bon_id, 1);
        if (:nbon_status = -10) then begin
          select SL.ID_SMETKA_BON
          from   SMETKA_LINE SL
          where  SL.ID_SMETKA_LINE = :id_voided_line
          into   :id_voided_bon;
        end else begin
          id_voided_bon = null;
        end
  
        insert into SMETKA_BON_INVENT (ID_SMETKA_INVENT, ID_END_WORK, ID_SMETKA_HEAD, ID_SMETKA_TRANS,
          ID_INVENT, STATUS, ID_VOIDED_BON, BON_NUM)
        values (:id_smetka_bon, :id_end_work, :id_smetka_head, :id_smetka_trans,
          :nid_invent, :nbon_status, :id_voided_bon, -1*:id_smetka_bon);
  
        bon_status = :nbon_status;
        id_invent  = :nid_invent;
      end

      update SMETKA_LINE SL2
      set    SL2.ID_SMETKA_BON = :id_smetka_bon
      where  SL2.RDB$DB_KEY = :line_dbkey;
    end
  end
END
^

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  delete from ARCHIVE_BON_INVENT
  where id_end_work = :id_end_work;

  delete from ARCHIVE_DISCOUNT
  where id_end_work = :id_end_work;

  delete from ARCHIVE_FOOTER
  where id_end_work = :id_end_work;

  delete from ARCHIVE_FRONT
  where id_end_work = :id_end_work;

  delete from ARCHIVE_HEAD
  where id_end_work = :id_end_work;

  delete from ARCHIVE_LINE
  where id_end_work = :id_end_work;

  delete from SMETKA_LINE_TEXT
  where id_end_work = :id_end_work;

  delete from SMETKA_MODIFFIER
  where id_end_work = :id_end_work;

  delete from ARCHIVE_MANAGE
  where id_end_work = :id_end_work;

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

  delete from ARCHIVE_TAX
  where  ID_END_WORK = :id_end_work;

  delete from SUM_DAY
  where id_end_work = :id_end_work;

  delete from SUM_STOCK
  where id_end_work = :id_end_work;

  delete from SUM_DISCOUNT
  where id_end_work = :id_end_work;

  delete from SUM_VOID
  where id_end_work = :id_end_work;

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

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

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

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

  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 <> 2) then exception FISCALIZE_EXCEPTION '-312';

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

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


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

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

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

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

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

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

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_END_WORK POSITION 4;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_STOCK POSITION 5;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_INVENT POSITION 6;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_VAT POSITION 7;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN QTY_POST POSITION 8;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN QTY_VOID POSITION 9;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN QTY POSITION 10;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN COST_PRICE POSITION 11;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN SALE_PRICE POSITION 12;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN LINE_SUM POSITION 13;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN VOID_SUM POSITION 14;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN DISCOUNT_SUM POSITION 15;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_MENU_PRICE_LIST POSITION 16;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_PRICE_LIST_OVERRULE POSITION 17;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_VOIDED_LINE POSITION 18;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_LINE_VOID POSITION 19;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_LINE_DISCOUNT POSITION 20;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN POST_STATUS POSITION 21;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN STATUS POSITION 22;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_SMETKA_BON POSITION 23;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_MOD_SESSION POSITION 24;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN NETO_SUM POSITION 25;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN SURCHARGE_SUM POSITION 26;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN NETO_WOT_TAX POSITION 27;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN TAX_PERCENT POSITION 28;

ALTER TABLE ARCHIVE_LINE ALTER COLUMN ID_TRANSFER_SOURCE_LINE POSITION 29;

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_END_WORK POSITION 4;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_STOCK POSITION 5;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_INVENT POSITION 6;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_VAT POSITION 7;

ALTER TABLE SMETKA_LINE ALTER COLUMN QTY_POST POSITION 8;

ALTER TABLE SMETKA_LINE ALTER COLUMN QTY_VOID POSITION 9;

ALTER TABLE SMETKA_LINE ALTER COLUMN QTY POSITION 10;

ALTER TABLE SMETKA_LINE ALTER COLUMN COST_PRICE POSITION 11;

ALTER TABLE SMETKA_LINE ALTER COLUMN SALE_PRICE POSITION 12;

ALTER TABLE SMETKA_LINE ALTER COLUMN LINE_SUM POSITION 13;

ALTER TABLE SMETKA_LINE ALTER COLUMN VOID_SUM POSITION 14;

ALTER TABLE SMETKA_LINE ALTER COLUMN DISCOUNT_SUM POSITION 15;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_MENU_PRICE_LIST POSITION 16;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_PRICE_LIST_OVERRULE POSITION 17;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_VOIDED_LINE POSITION 18;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_LINE_VOID POSITION 19;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_LINE_DISCOUNT POSITION 20;

ALTER TABLE SMETKA_LINE ALTER COLUMN POST_STATUS POSITION 21;

ALTER TABLE SMETKA_LINE ALTER COLUMN STATUS POSITION 22;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_SMETKA_BON POSITION 23;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_MOD_SESSION POSITION 24;

ALTER TABLE SMETKA_LINE ALTER COLUMN NETO_SUM POSITION 25;

ALTER TABLE SMETKA_LINE ALTER COLUMN SURCHARGE_SUM POSITION 26;

ALTER TABLE SMETKA_LINE ALTER COLUMN NETO_WOT_TAX POSITION 27;

ALTER TABLE SMETKA_LINE ALTER COLUMN TAX_PERCENT POSITION 28;

ALTER TABLE SMETKA_LINE ALTER COLUMN ID_TRANSFER_SOURCE_LINE POSITION 29;

