Настройка акций в Кассире — различия между версиями
Материал из wiki.standart-n.ru
Agk (обсуждение | вклад) |
Agk (обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
=Настройка ТМС Акции в кассире= | =Настройка ТМС Акции в кассире= | ||
− | ===Пример №2 (старый мех-м) | + | ==Заменить версию Кассира== |
+ | Заменить '''zkassa.exe''' на версию '''2.2.1.17''' от апреля 2016 г. или более новую. | ||
+ | |||
+ | ==Выполняем скрипт== | ||
+ | <pre> | ||
+ | /******************************************************************************/ | ||
+ | /*** Generated by IBExpert 15.04.2016 9:50:31 ***/ | ||
+ | /******************************************************************************/ | ||
+ | |||
+ | /******************************************************************************/ | ||
+ | /*** Following SET SQL DIALECT is just for the Database Comparer ***/ | ||
+ | /******************************************************************************/ | ||
+ | SET SQL DIALECT 3; | ||
+ | |||
+ | |||
+ | |||
+ | /******************************************************************************/ | ||
+ | /*** Tables ***/ | ||
+ | /******************************************************************************/ | ||
+ | |||
+ | |||
+ | |||
+ | CREATE TABLE DSC_RULES ( | ||
+ | ID INTEGER NOT NULL, | ||
+ | DATE_BEG DM_DATE NOT NULL /* DM_DATE = DATE */, | ||
+ | DATE_END DM_DATE NOT NULL /* DM_DATE = DATE */, | ||
+ | MMBSH1 DM_TEXT /* DM_TEXT = VARCHAR(250) */, | ||
+ | NDS_O1 DM_ID_NULL /* DM_ID_NULL = BIGINT */, | ||
+ | SNAME1 DM_TEXT /* DM_TEXT = VARCHAR(250) */, | ||
+ | SNAME2 DM_TEXT /* DM_TEXT = VARCHAR(250) */, | ||
+ | SNAME3 DM_TEXT /* DM_TEXT = VARCHAR(250) */, | ||
+ | SNAME4 DM_TEXT /* DM_TEXT = VARCHAR(250) */, | ||
+ | SNAME5 DM_TEXT /* DM_TEXT = VARCHAR(250) */, | ||
+ | PRICE_MIN DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */, | ||
+ | PRICE_MAX DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */, | ||
+ | QUANT_DIV DM_ID_NULL /* DM_ID_NULL = BIGINT */, | ||
+ | QUANT_DSC DM_ID_NULL /* DM_ID_NULL = BIGINT */, | ||
+ | SUM_DSC DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */, | ||
+ | PERC_DSC DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */, | ||
+ | STATUS SMALLINT NOT NULL, | ||
+ | COMMENTS DM_TEXT /* DM_TEXT = VARCHAR(250) */, | ||
+ | D$UUID DM_UUID /* DM_UUID = CHAR(36) NOT NULL */, | ||
+ | D$SRVUPDDT DM_DATETIME /* DM_DATETIME = TIMESTAMP */ | ||
+ | ); | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | /******************************************************************************/ | ||
+ | /*** Triggers ***/ | ||
+ | /******************************************************************************/ | ||
+ | |||
+ | |||
+ | SET TERM ^ ; | ||
+ | |||
+ | |||
+ | |||
+ | /******************************************************************************/ | ||
+ | /*** Triggers for tables ***/ | ||
+ | /******************************************************************************/ | ||
+ | |||
+ | |||
+ | |||
+ | /* Trigger: DSC_RULES_AD_DISTR */ | ||
+ | CREATE OR ALTER TRIGGER DSC_RULES_AD_DISTR FOR DSC_RULES | ||
+ | ACTIVE AFTER DELETE POSITION 0 | ||
+ | AS | ||
+ | begin | ||
+ | update or insert into g$distribute (TABLENAME,UUID,SOPER,FROM_PROFILE_ID) values ('DSC_RULES',old.d$uuid,2,null) | ||
+ | matching (TABLENAME,UUID); | ||
+ | end | ||
+ | ^ | ||
+ | |||
+ | |||
+ | /* Trigger: DSC_RULES_BI0 */ | ||
+ | CREATE OR ALTER TRIGGER DSC_RULES_BI0 FOR DSC_RULES | ||
+ | ACTIVE BEFORE INSERT POSITION 0 | ||
+ | AS | ||
+ | begin | ||
+ | select max(id)+1 from DSC_RULES into new.id; | ||
+ | if (new.id is null) then new.id = 1; | ||
+ | end | ||
+ | ^ | ||
+ | |||
+ | |||
+ | /* Trigger: DSC_RULES_BIU0 */ | ||
+ | CREATE OR ALTER TRIGGER DSC_RULES_BIU0 FOR DSC_RULES | ||
+ | ACTIVE BEFORE INSERT OR UPDATE POSITION 0 | ||
+ | AS | ||
+ | begin | ||
+ | new.mmbsh1 = UPPER(new.mmbsh1); | ||
+ | new.sname1 = UPPER(new.sname1); | ||
+ | new.sname2 = UPPER(new.sname2); | ||
+ | new.sname3 = UPPER(new.sname3); | ||
+ | new.sname4 = UPPER(new.sname4); | ||
+ | new.sname5 = UPPER(new.sname5); | ||
+ | end | ||
+ | ^ | ||
+ | |||
+ | |||
+ | /* Trigger: DSC_RULES_BI_DISTR */ | ||
+ | CREATE OR ALTER TRIGGER DSC_RULES_BI_DISTR FOR DSC_RULES | ||
+ | ACTIVE BEFORE INSERT POSITION 9999 | ||
+ | AS | ||
+ | begin | ||
+ | if (new.d$uuid is null) then | ||
+ | begin | ||
+ | new.d$uuid=UUID_TO_CHAR(GEN_UUID()); | ||
+ | new.d$srvupddt='2000-01-01'; | ||
+ | update or insert into g$distribute (TABLENAME,UUID,SOPER,FROM_PROFILE_ID) values ('DSC_RULES',new.d$uuid,0,null) matching (TABLENAME,UUID); | ||
+ | end | ||
+ | end | ||
+ | ^ | ||
+ | |||
+ | |||
+ | /* Trigger: DSC_RULES_BU_DISTR */ | ||
+ | CREATE OR ALTER TRIGGER DSC_RULES_BU_DISTR FOR DSC_RULES | ||
+ | ACTIVE BEFORE UPDATE POSITION 0 | ||
+ | AS | ||
+ | begin | ||
+ | if (new.D$SRVUPDDT=old.D$SRVUPDDT) then | ||
+ | update or insert into g$distribute (TABLENAME,UUID,SOPER,FROM_PROFILE_ID) values ('DSC_RULES',new.d$uuid,1,null) | ||
+ | matching (TABLENAME,UUID); | ||
+ | end | ||
+ | ^ | ||
+ | |||
+ | |||
+ | SET TERM ; ^ | ||
+ | |||
+ | |||
+ | |||
+ | /******************************************************************************/ | ||
+ | /*** Privileges ***/ | ||
+ | /******************************************************************************/ | ||
+ | |||
+ | SET TERM ^ ; | ||
+ | |||
+ | create or alter procedure PR_GET_DSC_RULES ( | ||
+ | PART_ID_IN DM_ID, | ||
+ | DOC_ID DM_ID, | ||
+ | DEL integer = 0) | ||
+ | returns ( | ||
+ | PART_ID_OUT integer, | ||
+ | DISCOUNT DM_DOUBLE) | ||
+ | as | ||
+ | declare variable SNAME DM_TEXT; | ||
+ | declare variable PRICE DM_DOUBLE; | ||
+ | declare variable QUANT DM_DOUBLE; | ||
+ | declare variable SNAME1 DM_TEXT; | ||
+ | declare variable SNAME2 DM_TEXT; | ||
+ | declare variable SNAME3 DM_TEXT; | ||
+ | declare variable SNAME4 DM_TEXT; | ||
+ | declare variable SNAME5 DM_TEXT; | ||
+ | declare variable PRICE_MIN DM_DOUBLE; | ||
+ | declare variable PRICE_MAX DM_DOUBLE; | ||
+ | declare variable QUANT_DIV DM_ID; | ||
+ | declare variable QUANT_DSC DM_ID; | ||
+ | declare variable SUM_DSC DM_DOUBLE; | ||
+ | declare variable PERC_DSC DM_DOUBLE; | ||
+ | declare variable MAX_PART_ID DM_ID; | ||
+ | declare variable SUM_QUANT DM_DOUBLE; | ||
+ | declare variable NO_DSC integer; | ||
+ | declare variable CONST_MAX_PRICE integer; | ||
+ | declare variable MMBSH DM_TEXT1024; | ||
+ | declare variable NDS_O DM_ID_NULL; | ||
+ | declare variable MMBSH1 DM_TEXT; | ||
+ | declare variable NDS_O1 DM_ID_NULL; | ||
+ | begin | ||
+ | -------------------- Описание параметров --------------------------------------------------- | ||
+ | --Процедура вызывается в кассире в событиях -305 и -332 | ||
+ | --PART_ID_IN - партия, по которой изменили кол-во/добавили/удалили в чеке, и на которую необходимо рассчитать скидку | ||
+ | --DOC_ID - чек | ||
+ | --DEL - признак, что партию удаляют из чека | ||
+ | |||
+ | --PART_ID_OUT - список партий по которым нужно обновить скидку | ||
+ | --DISCOUNT - скидка в рублях | ||
+ | |||
+ | ------------------- Описание DSC_RULES ------------------------------------------------------ | ||
+ | --DATE_BEG и DATE_END - период действия скидки | ||
+ | --MMBSH1 - группа товара | ||
+ | --NDS_O1 - ставка НДС опт (10,18,12 ....) | ||
+ | --SNAME1 ... SNAME5 - слова, которым должна соответствовать позиция для того, чтобы скидка назначилась (все не обязательны) | ||
+ | --PRICE_MIN и PRICE_MAX - ценовой диапазон, которому должна соответствовать позиция, чтобы скидка назначилась (все не обязательны) | ||
+ | --QUANT_DIV и QUANT_DSC, для условий типа: при покупке 4х штук (QUANT_DIV) одна(QUANT_DSC) в подарок | ||
+ | --SUM_DSC - суммовая скидка на позицию в рублях | ||
+ | --PERC_DSC - процентная скидка на позицию в % (например 0.15) | ||
+ | --STATUS, 1 - правило активно, 0 - неактивно | ||
+ | |||
+ | CONST_MAX_PRICE = 99999; | ||
+ | DISCOUNT = 0; | ||
+ | PART_ID_OUT = PART_ID_IN; | ||
+ | |||
+ | select UPPER(sname), price, abs(quant), coalesce(nds,0), UPPER(mmbsh) from vw_doc_detail_active where doc_id = :doc_id and part_id = :part_id_in into :sname, :price, :quant, :nds_o, :mmbsh; | ||
+ | |||
+ | for select MMBSH1, NDS_O1, SNAME1,SNAME2,SNAME3,SNAME4,SNAME5,PRICE_MIN,PRICE_MAX,QUANT_DIV,QUANT_DSC,SUM_DSC,PERC_DSC | ||
+ | from DSC_RULES dr where status = 1 and dr.date_beg <= current_date and dr.date_end >= current_date | ||
+ | into :MMBSH1, :NDS_O1, :SNAME1,:SNAME2,:SNAME3,:SNAME4,:SNAME5,:PRICE_MIN,:PRICE_MAX,:QUANT_DIV,:QUANT_DSC,:SUM_DSC,:PERC_DSC do | ||
+ | begin | ||
+ | NO_DSC = 0; | ||
+ | |||
+ | if (:MMBSH1 is null) then MMBSH1 = ''; | ||
+ | if (:SNAME1 is null) then SNAME1 = ''; | ||
+ | if (:SNAME2 is null) then SNAME2 = ''; | ||
+ | if (:SNAME3 is null) then SNAME3 = ''; | ||
+ | if (:SNAME4 is null) then SNAME4 = ''; | ||
+ | if (:SNAME5 is null) then SNAME5 = ''; | ||
+ | |||
+ | --Проверка на группу | ||
+ | if (NO_DSC = 0) then | ||
+ | if ( Not(MMBSH containing MMBSH1) ) Then | ||
+ | NO_DSC = 1; | ||
+ | |||
+ | --Проверка на НДС | ||
+ | if (NO_DSC = 0) then | ||
+ | if((:NDS_O1 is not null) and (:NDS_O1 <> :NDS_O)) Then | ||
+ | NO_DSC = 1; | ||
+ | |||
+ | --Проверка на наименование | ||
+ | if (NO_DSC = 0) then | ||
+ | if (Not((sname containing SNAME1) and (sname containing SNAME2) and (sname containing SNAME3) and (sname containing SNAME4) and (sname containing SNAME5))) Then | ||
+ | NO_DSC = 1; | ||
+ | |||
+ | --Проверка на цену | ||
+ | if (NO_DSC = 0) then | ||
+ | if ( (price < coalesce(PRICE_MIN,0)) or | ||
+ | (price > coalesce(PRICE_MAX,CONST_MAX_PRICE)) ) Then | ||
+ | NO_DSC = 1; | ||
+ | |||
+ | --Проверка на кратность | ||
+ | if (NO_DSC = 0) then | ||
+ | if (QUANT_DIV is not null) then | ||
+ | begin | ||
+ | --Определяем партию на которую будем назначать скидку | ||
+ | select max(part_id), abs(sum(quant)), min(price) from vw_doc_detail_active da where doc_id = :doc_id | ||
+ | and UPPER(da.sname) containing :SNAME1 | ||
+ | and UPPER(da.sname) containing :SNAME2 | ||
+ | and UPPER(da.sname) containing :SNAME3 | ||
+ | and UPPER(da.sname) containing :SNAME4 | ||
+ | and UPPER(da.sname) containing :SNAME5 | ||
+ | and ( ((:DEL = 1) and (part_id <> :PART_ID_IN)) or (:DEL = 0) ) | ||
+ | and (price >= coalesce(:PRICE_MIN,0)) and (price <= coalesce(:PRICE_MAX,:CONST_MAX_PRICE)) | ||
+ | and UPPER(da.MMBSH) containing :MMBSH1 | ||
+ | and ( (:NDS_O1 is null) or ((:NDS_O1 is not null) and (:NDS_O1 = NDS)) ) | ||
+ | into :max_part_id, :sum_quant, :price; | ||
+ | --Скидка назначается только на партию с максимальным ID и если условие кратности соблюдается | ||
+ | --По всем остальным партиям скидку сбрасываем | ||
+ | for select part_id from vw_doc_detail_active da where doc_id = :doc_id and UPPER(da.sname) containing :SNAME1 | ||
+ | and UPPER(da.sname) containing :SNAME2 | ||
+ | and UPPER(da.sname) containing :SNAME3 | ||
+ | and UPPER(da.sname) containing :SNAME4 | ||
+ | and UPPER(da.sname) containing :SNAME5 | ||
+ | and ( ((:DEL = 1) and (part_id <> :PART_ID_IN)) or (:DEL = 0) ) | ||
+ | and (price >= coalesce(:PRICE_MIN,0)) and (price <= coalesce(:PRICE_MAX,:CONST_MAX_PRICE)) | ||
+ | and UPPER(da.MMBSH) containing :MMBSH1 | ||
+ | and ( (:NDS_O1 is null) or ((:NDS_O1 is not null) and (:NDS_O1 = NDS)) ) | ||
+ | into :PART_ID_OUT do | ||
+ | Begin | ||
+ | if ((max_part_id = PART_ID_OUT) and (Trunc(sum_quant/QUANT_DIV) > 0)) then | ||
+ | begin | ||
+ | if (QUANT_DSC is not null) then DISCOUNT = QUANT_DSC*:price*Trunc(sum_quant/QUANT_DIV); | ||
+ | if (SUM_DSC is not null) then DISCOUNT = SUM_DSC*Trunc(sum_quant/QUANT_DIV); | ||
+ | if (PERC_DSC is not null) then DISCOUNT = :quant*:price*PERC_DSC; | ||
+ | end | ||
+ | else | ||
+ | DISCOUNT = 0; | ||
+ | suspend; | ||
+ | End | ||
+ | exit; | ||
+ | End | ||
+ | |||
+ | --Суммовая скидка | ||
+ | if ((NO_DSC = 0) and (DEL = 0) and (SUM_DSC is not null)) then | ||
+ | Begin | ||
+ | DISCOUNT = :quant*SUM_DSC; | ||
+ | suspend; | ||
+ | exit; | ||
+ | End | ||
+ | |||
+ | --Процентная скидка | ||
+ | if ((NO_DSC = 0) and (DEL = 0) and (PERC_DSC is not null)) then | ||
+ | Begin | ||
+ | DISCOUNT = :quant*:price*PERC_DSC; | ||
+ | suspend; | ||
+ | exit; | ||
+ | End | ||
+ | |||
+ | End | ||
+ | end^ | ||
+ | |||
+ | SET TERM ; ^ | ||
+ | |||
+ | /* Following GRANT statetements are generated automatically */ | ||
+ | |||
+ | GRANT SELECT ON VW_DOC_DETAIL_ACTIVE TO PROCEDURE PR_GET_DSC_RULES; | ||
+ | GRANT SELECT ON DSC_RULES TO PROCEDURE PR_GET_DSC_RULES; | ||
+ | |||
+ | /* Existing privileges on this procedure */ | ||
+ | |||
+ | GRANT EXECUTE ON PROCEDURE PR_GET_DSC_RULES TO SYSDBA; | ||
+ | |||
+ | </PRE> | ||
+ | |||
+ | ==Создаем в кассире ТМС== | ||
+ | <PRE> | ||
+ | uses | ||
+ | Graphics, Controls, Forms, Dialogs, StdCtrls, | ||
+ | ComCtrls, ExtCtrls, ibquery, DB, ChequeList, FR, | ||
+ | ScriptRes, Barcode,ZKassa, StrUtils, Windows, Classes, | ||
+ | IBDataBase, SysUtils, DateUtils, chequelist; | ||
+ | |||
+ | Procedure RecalcDSC(del:integer) | ||
+ | var iq: tibquery; | ||
+ | begin | ||
+ | Try | ||
+ | iq := tibquery.create(nil); | ||
+ | iq.transaction := CreateRT(CurrDB); | ||
+ | iq.transaction.starttransaction; | ||
+ | iq.active := False; | ||
+ | |||
+ | iq.sql.text := 'select * from PR_GET_DSC_RULES('+IntToStr(ChequeList.ActivePID)+','+IntToStr(ChequeList.Active.ID)+','+IntToStr(del)+')'; | ||
+ | iq.active := True; | ||
+ | while not (iq.Eof) do | ||
+ | begin | ||
+ | ChequeList.Active.P_Index:= ChequeList.Active.IndexByPartID(iq.FieldByName('part_id_out').AsInteger); | ||
+ | ChequeList.Active.P_SetDiscount(-1*iq.FieldByName('DISCOUNT').AsFloat) | ||
+ | iq.next; | ||
+ | End; | ||
+ | |||
+ | finally | ||
+ | iq.active := False; | ||
+ | iq.transaction.free; | ||
+ | iq.free; | ||
+ | end; | ||
+ | |||
+ | |||
+ | end; | ||
+ | </PRE> | ||
+ | |||
+ | '''Вызываем PR_GET_DSC_RULES в ТМС''' | ||
+ | '''-305 как RecalcDSC(0); ''' | ||
+ | '''-332 как RecalcDSC(1); ''' | ||
+ | |||
+ | ==Пример №2 (старый мех-м)== | ||
* акция действует всегда пока включен переключатель в параметрах системы | * акция действует всегда пока включен переключатель в параметрах системы | ||
<PRE> | <PRE> |
Версия 10:47, 15 апреля 2016
Содержание
Настройка ТМС Акции в кассире
Заменить версию Кассира
Заменить zkassa.exe на версию 2.2.1.17 от апреля 2016 г. или более новую.
Выполняем скрипт
/******************************************************************************/ /*** Generated by IBExpert 15.04.2016 9:50:31 ***/ /******************************************************************************/ /******************************************************************************/ /*** Following SET SQL DIALECT is just for the Database Comparer ***/ /******************************************************************************/ SET SQL DIALECT 3; /******************************************************************************/ /*** Tables ***/ /******************************************************************************/ CREATE TABLE DSC_RULES ( ID INTEGER NOT NULL, DATE_BEG DM_DATE NOT NULL /* DM_DATE = DATE */, DATE_END DM_DATE NOT NULL /* DM_DATE = DATE */, MMBSH1 DM_TEXT /* DM_TEXT = VARCHAR(250) */, NDS_O1 DM_ID_NULL /* DM_ID_NULL = BIGINT */, SNAME1 DM_TEXT /* DM_TEXT = VARCHAR(250) */, SNAME2 DM_TEXT /* DM_TEXT = VARCHAR(250) */, SNAME3 DM_TEXT /* DM_TEXT = VARCHAR(250) */, SNAME4 DM_TEXT /* DM_TEXT = VARCHAR(250) */, SNAME5 DM_TEXT /* DM_TEXT = VARCHAR(250) */, PRICE_MIN DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */, PRICE_MAX DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */, QUANT_DIV DM_ID_NULL /* DM_ID_NULL = BIGINT */, QUANT_DSC DM_ID_NULL /* DM_ID_NULL = BIGINT */, SUM_DSC DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */, PERC_DSC DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */, STATUS SMALLINT NOT NULL, COMMENTS DM_TEXT /* DM_TEXT = VARCHAR(250) */, D$UUID DM_UUID /* DM_UUID = CHAR(36) NOT NULL */, D$SRVUPDDT DM_DATETIME /* DM_DATETIME = TIMESTAMP */ ); /******************************************************************************/ /*** Triggers ***/ /******************************************************************************/ SET TERM ^ ; /******************************************************************************/ /*** Triggers for tables ***/ /******************************************************************************/ /* Trigger: DSC_RULES_AD_DISTR */ CREATE OR ALTER TRIGGER DSC_RULES_AD_DISTR FOR DSC_RULES ACTIVE AFTER DELETE POSITION 0 AS begin update or insert into g$distribute (TABLENAME,UUID,SOPER,FROM_PROFILE_ID) values ('DSC_RULES',old.d$uuid,2,null) matching (TABLENAME,UUID); end ^ /* Trigger: DSC_RULES_BI0 */ CREATE OR ALTER TRIGGER DSC_RULES_BI0 FOR DSC_RULES ACTIVE BEFORE INSERT POSITION 0 AS begin select max(id)+1 from DSC_RULES into new.id; if (new.id is null) then new.id = 1; end ^ /* Trigger: DSC_RULES_BIU0 */ CREATE OR ALTER TRIGGER DSC_RULES_BIU0 FOR DSC_RULES ACTIVE BEFORE INSERT OR UPDATE POSITION 0 AS begin new.mmbsh1 = UPPER(new.mmbsh1); new.sname1 = UPPER(new.sname1); new.sname2 = UPPER(new.sname2); new.sname3 = UPPER(new.sname3); new.sname4 = UPPER(new.sname4); new.sname5 = UPPER(new.sname5); end ^ /* Trigger: DSC_RULES_BI_DISTR */ CREATE OR ALTER TRIGGER DSC_RULES_BI_DISTR FOR DSC_RULES ACTIVE BEFORE INSERT POSITION 9999 AS begin if (new.d$uuid is null) then begin new.d$uuid=UUID_TO_CHAR(GEN_UUID()); new.d$srvupddt='2000-01-01'; update or insert into g$distribute (TABLENAME,UUID,SOPER,FROM_PROFILE_ID) values ('DSC_RULES',new.d$uuid,0,null) matching (TABLENAME,UUID); end end ^ /* Trigger: DSC_RULES_BU_DISTR */ CREATE OR ALTER TRIGGER DSC_RULES_BU_DISTR FOR DSC_RULES ACTIVE BEFORE UPDATE POSITION 0 AS begin if (new.D$SRVUPDDT=old.D$SRVUPDDT) then update or insert into g$distribute (TABLENAME,UUID,SOPER,FROM_PROFILE_ID) values ('DSC_RULES',new.d$uuid,1,null) matching (TABLENAME,UUID); end ^ SET TERM ; ^ /******************************************************************************/ /*** Privileges ***/ /******************************************************************************/ SET TERM ^ ; create or alter procedure PR_GET_DSC_RULES ( PART_ID_IN DM_ID, DOC_ID DM_ID, DEL integer = 0) returns ( PART_ID_OUT integer, DISCOUNT DM_DOUBLE) as declare variable SNAME DM_TEXT; declare variable PRICE DM_DOUBLE; declare variable QUANT DM_DOUBLE; declare variable SNAME1 DM_TEXT; declare variable SNAME2 DM_TEXT; declare variable SNAME3 DM_TEXT; declare variable SNAME4 DM_TEXT; declare variable SNAME5 DM_TEXT; declare variable PRICE_MIN DM_DOUBLE; declare variable PRICE_MAX DM_DOUBLE; declare variable QUANT_DIV DM_ID; declare variable QUANT_DSC DM_ID; declare variable SUM_DSC DM_DOUBLE; declare variable PERC_DSC DM_DOUBLE; declare variable MAX_PART_ID DM_ID; declare variable SUM_QUANT DM_DOUBLE; declare variable NO_DSC integer; declare variable CONST_MAX_PRICE integer; declare variable MMBSH DM_TEXT1024; declare variable NDS_O DM_ID_NULL; declare variable MMBSH1 DM_TEXT; declare variable NDS_O1 DM_ID_NULL; begin -------------------- Описание параметров --------------------------------------------------- --Процедура вызывается в кассире в событиях -305 и -332 --PART_ID_IN - партия, по которой изменили кол-во/добавили/удалили в чеке, и на которую необходимо рассчитать скидку --DOC_ID - чек --DEL - признак, что партию удаляют из чека --PART_ID_OUT - список партий по которым нужно обновить скидку --DISCOUNT - скидка в рублях ------------------- Описание DSC_RULES ------------------------------------------------------ --DATE_BEG и DATE_END - период действия скидки --MMBSH1 - группа товара --NDS_O1 - ставка НДС опт (10,18,12 ....) --SNAME1 ... SNAME5 - слова, которым должна соответствовать позиция для того, чтобы скидка назначилась (все не обязательны) --PRICE_MIN и PRICE_MAX - ценовой диапазон, которому должна соответствовать позиция, чтобы скидка назначилась (все не обязательны) --QUANT_DIV и QUANT_DSC, для условий типа: при покупке 4х штук (QUANT_DIV) одна(QUANT_DSC) в подарок --SUM_DSC - суммовая скидка на позицию в рублях --PERC_DSC - процентная скидка на позицию в % (например 0.15) --STATUS, 1 - правило активно, 0 - неактивно CONST_MAX_PRICE = 99999; DISCOUNT = 0; PART_ID_OUT = PART_ID_IN; select UPPER(sname), price, abs(quant), coalesce(nds,0), UPPER(mmbsh) from vw_doc_detail_active where doc_id = :doc_id and part_id = :part_id_in into :sname, :price, :quant, :nds_o, :mmbsh; for select MMBSH1, NDS_O1, SNAME1,SNAME2,SNAME3,SNAME4,SNAME5,PRICE_MIN,PRICE_MAX,QUANT_DIV,QUANT_DSC,SUM_DSC,PERC_DSC from DSC_RULES dr where status = 1 and dr.date_beg <= current_date and dr.date_end >= current_date into :MMBSH1, :NDS_O1, :SNAME1,:SNAME2,:SNAME3,:SNAME4,:SNAME5,:PRICE_MIN,:PRICE_MAX,:QUANT_DIV,:QUANT_DSC,:SUM_DSC,:PERC_DSC do begin NO_DSC = 0; if (:MMBSH1 is null) then MMBSH1 = ''; if (:SNAME1 is null) then SNAME1 = ''; if (:SNAME2 is null) then SNAME2 = ''; if (:SNAME3 is null) then SNAME3 = ''; if (:SNAME4 is null) then SNAME4 = ''; if (:SNAME5 is null) then SNAME5 = ''; --Проверка на группу if (NO_DSC = 0) then if ( Not(MMBSH containing MMBSH1) ) Then NO_DSC = 1; --Проверка на НДС if (NO_DSC = 0) then if((:NDS_O1 is not null) and (:NDS_O1 <> :NDS_O)) Then NO_DSC = 1; --Проверка на наименование if (NO_DSC = 0) then if (Not((sname containing SNAME1) and (sname containing SNAME2) and (sname containing SNAME3) and (sname containing SNAME4) and (sname containing SNAME5))) Then NO_DSC = 1; --Проверка на цену if (NO_DSC = 0) then if ( (price < coalesce(PRICE_MIN,0)) or (price > coalesce(PRICE_MAX,CONST_MAX_PRICE)) ) Then NO_DSC = 1; --Проверка на кратность if (NO_DSC = 0) then if (QUANT_DIV is not null) then begin --Определяем партию на которую будем назначать скидку select max(part_id), abs(sum(quant)), min(price) from vw_doc_detail_active da where doc_id = :doc_id and UPPER(da.sname) containing :SNAME1 and UPPER(da.sname) containing :SNAME2 and UPPER(da.sname) containing :SNAME3 and UPPER(da.sname) containing :SNAME4 and UPPER(da.sname) containing :SNAME5 and ( ((:DEL = 1) and (part_id <> :PART_ID_IN)) or (:DEL = 0) ) and (price >= coalesce(:PRICE_MIN,0)) and (price <= coalesce(:PRICE_MAX,:CONST_MAX_PRICE)) and UPPER(da.MMBSH) containing :MMBSH1 and ( (:NDS_O1 is null) or ((:NDS_O1 is not null) and (:NDS_O1 = NDS)) ) into :max_part_id, :sum_quant, :price; --Скидка назначается только на партию с максимальным ID и если условие кратности соблюдается --По всем остальным партиям скидку сбрасываем for select part_id from vw_doc_detail_active da where doc_id = :doc_id and UPPER(da.sname) containing :SNAME1 and UPPER(da.sname) containing :SNAME2 and UPPER(da.sname) containing :SNAME3 and UPPER(da.sname) containing :SNAME4 and UPPER(da.sname) containing :SNAME5 and ( ((:DEL = 1) and (part_id <> :PART_ID_IN)) or (:DEL = 0) ) and (price >= coalesce(:PRICE_MIN,0)) and (price <= coalesce(:PRICE_MAX,:CONST_MAX_PRICE)) and UPPER(da.MMBSH) containing :MMBSH1 and ( (:NDS_O1 is null) or ((:NDS_O1 is not null) and (:NDS_O1 = NDS)) ) into :PART_ID_OUT do Begin if ((max_part_id = PART_ID_OUT) and (Trunc(sum_quant/QUANT_DIV) > 0)) then begin if (QUANT_DSC is not null) then DISCOUNT = QUANT_DSC*:price*Trunc(sum_quant/QUANT_DIV); if (SUM_DSC is not null) then DISCOUNT = SUM_DSC*Trunc(sum_quant/QUANT_DIV); if (PERC_DSC is not null) then DISCOUNT = :quant*:price*PERC_DSC; end else DISCOUNT = 0; suspend; End exit; End --Суммовая скидка if ((NO_DSC = 0) and (DEL = 0) and (SUM_DSC is not null)) then Begin DISCOUNT = :quant*SUM_DSC; suspend; exit; End --Процентная скидка if ((NO_DSC = 0) and (DEL = 0) and (PERC_DSC is not null)) then Begin DISCOUNT = :quant*:price*PERC_DSC; suspend; exit; End End end^ SET TERM ; ^ /* Following GRANT statetements are generated automatically */ GRANT SELECT ON VW_DOC_DETAIL_ACTIVE TO PROCEDURE PR_GET_DSC_RULES; GRANT SELECT ON DSC_RULES TO PROCEDURE PR_GET_DSC_RULES; /* Existing privileges on this procedure */ GRANT EXECUTE ON PROCEDURE PR_GET_DSC_RULES TO SYSDBA;
Создаем в кассире ТМС
uses Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls, ibquery, DB, ChequeList, FR, ScriptRes, Barcode,ZKassa, StrUtils, Windows, Classes, IBDataBase, SysUtils, DateUtils, chequelist; Procedure RecalcDSC(del:integer) var iq: tibquery; begin Try iq := tibquery.create(nil); iq.transaction := CreateRT(CurrDB); iq.transaction.starttransaction; iq.active := False; iq.sql.text := 'select * from PR_GET_DSC_RULES('+IntToStr(ChequeList.ActivePID)+','+IntToStr(ChequeList.Active.ID)+','+IntToStr(del)+')'; iq.active := True; while not (iq.Eof) do begin ChequeList.Active.P_Index:= ChequeList.Active.IndexByPartID(iq.FieldByName('part_id_out').AsInteger); ChequeList.Active.P_SetDiscount(-1*iq.FieldByName('DISCOUNT').AsFloat) iq.next; End; finally iq.active := False; iq.transaction.free; iq.free; end; end;
Вызываем PR_GET_DSC_RULES в ТМС -305 как RecalcDSC(0); -332 как RecalcDSC(1);
Пример №2 (старый мех-м)
- акция действует всегда пока включен переключатель в параметрах системы
INSERT INTO PARAMS ( PARENT_ID, PARAM_ID, PARAM_CAPTION, PARAM_TYPE, PARAM_VALUE, AUDIT_ID, IMAGEINDEX, STATUS, INSERTDT, SORTING, PARAM_TYPE_DATA, PACKET) VALUES ( -30, 'AKCCII_TOGGLE', 'Включение акций', 14, '0', 3229, NULL, 0, '19-DEC-2015 10:45:34.828', NULL, 'FIXEDITEMS SHOWONLYVALUES RETURNNAME 0=выключено 1=включено');
- если переключатель включен - в кассире при продаже активируется скидка = разнице между заполненными колонками price и ещё одной ценовой колонкой, ниже использована PRICE_R
uses Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls, ibquery, DB, ChequeList, FR, ScriptRes, Barcode,ZKassa, StrUtils, Windows, Classes, IBDataBase, SysUtils, DateUtils, chequelist; var iq: tibquery; dsc, part_id: integer; discount: float; begin Try iq := tibquery.create(nil); iq.transaction := CreateRT(CurrDB); iq.transaction.starttransaction; iq.active := False; iq.sql.text := 'select wb.part_id,wb.PRICE_R,(select p.param_value from params p where p.param_id = ''AKCCII_TOGGLE'') from vw_warebase wb where wb.part_id = '+ IntToStr(ChequeList.ActivePID); iq.active := True; if not(iq.Eof) then if ( not iq.FieldByName('param_value').AsInteger=0 )then if ( not iq.FieldByName('PRICE_R').isNull )then if (iq.FieldByName('PRICE_R').AsFloat>0) then begin ChequeList.Active.P_Index := ChequeList.Active.IndexByPartID(iq.FieldByName('part_id').AsInteger); temp := -(ChequeList.Active.P_Price - iq.FieldByName('PRICE_R').AsFloat); ChequeList.Active.P_SetDiscount(temp); end; finally iq.active := False; iq.transaction.free; iq.free; end;
Отправка ТМС по синхронизации
Выгружаем тмс из базы из blob поля в файл
Тмс можно найти спомощью запроса:
select * from groups g where g.id=-305
Затем сохраняем на жесткий диск тмс из поля data.
Загружаем ТМС в серверную базу
- В таблице g$profiles выбираем blob поле, которое будем использовать для отправки, например TMP_BLOB1.
- Убеждаемся, что данная таблица синхронизируется в двухстороннем направлении.
- Загружаем в это поле например первому профилю наш ТМС скрипт.
- Ждем когда это обновление придет всем по синхронизации.
Применяем всем ТМС
По g$tasks отправляем запрос нужным профилям:
update groups gp set gp.data = (select g.tmp_blob1 from G$PROFILES g where g.id = 1) where gp.id = -305;