Выгрузка в Партнер (Катрен)

Материал из wiki.standart-n.ru
Перейти к: навигация, поиск

Разработана выгрузка в систему Партнер от поставщика Катрен


Формат файлов для выгрузки

Выгрузка происходит ежедневно в конце рабочего дня формируются два файла 1. файл с раширением .OST содержит текущие остатки 2. файл с раширением .MOV содержит движение за последние 24 часа

формат данных файлов

Наименование элемента Наименование тэга Тип данных Описание Комментарий
1 Тип данных по строке D_TYPE Число Возможные значения:

0 – остаток,

10 - приход от поставщика,

19 – другие виды прихода,

20 – продажа товара через кассу конечному потребителю,

29 - другие виды расхода.


Операцию сторнирования или возврата от покупателя передавать 19 типом данных.

Информация о строке документа

Наименование элемента Наименование тэга Тип данных Описание Комментарий
2 Номер документа из программы участника N_DOK Строка Для файла «Остатки товара» номер документа первого прихода этой партии в аптеку. Уникальный в пределах одного дня.
3 Дата создания или изменения строки документа из программы участника D_DOK Дата формата DDMMYYYY Для файла «Остатки товара» - дата на которую формируется файл, например, остаток на 2.10.2015 указать «02102015».

Для файла «Движение товаров» - дата создания документа движения в ПО.

Наименование элемента Наименование тэга Тип данных Описание Комментарий
4 Поставщик Supplier Строка В случае поступления товара из другого подразделения указать первого поставщика товара.
5 ИНН Поставщика Supplier_INN Число

Информация о чеках. Заполняется только для расхода типа продажа, в остальных случаях пустые поля. Для документов продажи одна строка файла – одна строка чека.

Наименование элемента Наименование тэга Тип данных Описание Комментарий
6 Номер ККМ N_KKM Строка Номер ККМ или рабочего места в случае отсутствия чекового принтера.
7 Номер чека из программы участника N_Chek Строка Номер чека из системы учёта товародвижения или чекового принтера, значение должно быть уникальным внутри одного документа.
8 ФИО кассира FIO_Chek Строка ФИО сотрудника пробившего чек.
9 Тип скидки по строке чека Disk_T Строка Составное поле из типа скидки и доп. информации.

Значения типов:

0 – без скидки,

1- скидка, предоставленная по условиям проекта,

2-другие скидки.

10 Сумма скидки по строке чека Disk_Sum Число, с точностью до 2 разряда Сумма в рублях, округление до целых копеек
11 Закупочная сумма по строке чека Sum_Zak Число, с точностью до 2 разряда Сумма в рублях, округление до целых копеек
12 Розничная сумма по строке чека Sum_Rozn Число, с точностью до 2 разряда Сумма в рублях, округление до целых копеек Не вычитая сумму скидки по строке чека.
13 Признак использования модуля «Приоритетная рекомендация» по строке чека PP_Teg Число Возможные значения:

0-без использования,

1-с использованием.

Информация о товаре из документа или данных остатков:

Наименование элемента Наименование тэга Тип данных Описание Комментарий
14 Код товара по справочнику товаров Drug_Code Строка Не изменяемое значение, однозначно соответствующее одному наименованию товара из справочника товаров. Используется для передачи информации из системы Партнёр Участнику.
15 Наименование товара по справочнику товаров Drug_Name Строка Постоянное значение, изменение написания строки (изменение, добавление, удаление любого символа) рассматривается как внесение нового наименования.
16 Код производителя по справочнику производителей Drug_Producer_Code Строка Используется аналогично полю 14.
17 Наименование производителя по справочнику производителей Drug_Producer_Name Строка Постоянное значение, изменение написания строки (изменение, добавление, удаление любого символа) рассматривается как внесение нового наименования.
18 Название страны производителя Drug_ Producer_Country Строка
19 Штрих код завода изготовителя Drug_Bar Строка Штрих-код в формате EAN-13 Обязательное поле для товаров участвующих в контрактах с производителями.
20 Цена за единицу закупочная в рублях, округление до целых копеек Cena_Zak Число, с точностью до 2 разряда
21 Цена за единицу розничная в рублях, округление до целых копеек. Cena_Rozn Число, с точностью до 2 разряда
22 Количество Quant Число, с точностью до 4 разряда, если в поле «Комментарий» не указано иное Значение больше нуля. Не целое передаётся в виде десятичной дроби. Без округления передаётся в той разрядности как храниться в Программе Участника.
23 Серия товара Serial Строка
24 Срок годности товара Godn Дата формата DDMMYYYY
25 Уникальный код партии из системы учёта товародвижения, в формате штрих кода EAN-13 Barecode Строка Штрих-код в формате EAN-13


Описание метода работы

Существует в двух форматах для SpacePro (сети) и для Менеджера (Единичные аптеки)

Выгрузка осуществляется на фтп - partner.melzdrav.ru

для выгрузки партнер должен нам предоставить код клиента в формате - partner16666 и пароль

выгрузки делятся по регионам Уфа,Москва,Казань путь выгрузки не меняется меняются ответственные лица которые дают доступ

1. Сводная база (единое окно) устанавливаем в базу две процедуры

Процедура выгрузки движения товара

Временная таблица для движения

/******************************************************************************/
/***               Generated by IBExpert 05.04.2019 10:13:03                ***/
/******************************************************************************/

/******************************************************************************/
/***      Following SET SQL DIALECT is just for the Database Comparer       ***/
/******************************************************************************/
SET SQL DIALECT 3;



/******************************************************************************/
/***                                 Tables                                 ***/
/******************************************************************************/


CREATE GENERATOR GEN_PARTNER_LOAD_MOVE_ID;

CREATE TABLE PARTNER_LOAD_MOVE (
    ID                     DM_ID /* DM_ID = BIGINT NOT NULL */,
    PARTNER_ID             DM_ID /* DM_ID = BIGINT NOT NULL */,
    DRUG_NAME              DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    DRUG_CODE              DM_ID /* DM_ID = BIGINT NOT NULL */,
    DOCNUM                 DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    DOCDATE                DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    IZG_ID                 DM_UUID_NULL /* DM_UUID_NULL = CHAR(36) */,
    DRUG_PRODUCER_NAME     DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    DRUG_PRODUCER_COUNTRY  DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    BARCODE                DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    CENA_ZAK               DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */,
    GODENDO_DATE           DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    SERIA                  DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    QUANT                  DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */,
    BCODEIZG               DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    DISK_T                 DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */,
    DISK_SUM               DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */,
    SUM_ZAK                DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */,
    SUM_ROZN               DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */,
    CENA_ROZN              DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */,
    D_TYPE                 DM_ID /* DM_ID = BIGINT NOT NULL */,
    SUPPLIER               DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    SUPPLIER_INN           DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    DEVICE_NUM             DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    N_CHEK                 DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    FIO_CHEK               DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    PP_TEG                 DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    G$PROFILE_ID           DM_ID_NULL /* DM_ID_NULL = BIGINT */,
    INSERTDT               DM_DATETIME /* DM_DATETIME = TIMESTAMP */,
    DOC_COMMITDATE         DM_DATETIME /* DM_DATETIME = TIMESTAMP */
);




/******************************************************************************/
/***                                Triggers                                ***/
/******************************************************************************/


SET TERM ^ ;



/******************************************************************************/
/***                          Triggers for tables                           ***/
/******************************************************************************/



/* Trigger: PARTNER_LOAD_MOVE_BI */
CREATE OR ALTER TRIGGER PARTNER_LOAD_MOVE_BI FOR PARTNER_LOAD_MOVE
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.id is null) then
    new.id = gen_id(gen_PARTNER_LOAD_MOVE_id,1);
end
^


/* Trigger: PARTNER_LOAD_MOVE_BI0 */
CREATE OR ALTER TRIGGER PARTNER_LOAD_MOVE_BI0 FOR PARTNER_LOAD_MOVE
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  new.insertdt=current_timestamp;
end
^


SET TERM ; ^



/******************************************************************************/
/***                               Privileges                               ***/
/******************************************************************************/

PR_LOAD_MOVE_PARTNER для сводника

SET TERM ^ ;

create or alter procedure PR_LOAD_MOVE_PARTNER (
    DATESTART DM_DATE,
    DATEEND DM_DATE)
returns (
    PARTNER_ID integer,
    DRUG_NAME DM_TEXT,
    DRUG_CODE integer,
    DOCNUM DM_TEXT,
    DOCDATE DM_DATETIME,
    IZG_ID DM_UUID_NULL,
    DRUG_PRODUCER_NAME DM_TEXT,
    DRUG_PRODUCER_COUNTRY DM_TEXT,
    BARCODE DM_TEXT,
    CENA_ZAK DM_DOUBLE,
    GODENDO_DATE DM_DATE,
    SERIA DM_TEXT,
    G$PROFILE_ID_OUT integer,
    QUANT DM_DOUBLE,
    BCODEIZG DM_TEXT,
    DISK_T DM_DOUBLE,
    DISK_SUM DM_DOUBLE,
    SUM_ZAK DM_DOUBLE,
    SUM_ROZN DM_DOUBLE,
    CENA_ROZN DM_DOUBLE,
    D_TYPE integer,
    SUPPLIER DM_TEXT,
    SUPPLIER_INN DM_TEXT,
    DEVICE_NUM DM_TEXT,
    N_CHEK DM_TEXT,
    FIO_CHEK DM_TEXT,
    PP_TEG DM_TEXT)
as
declare variable DOC_ID integer;
declare variable G$PROFILE_ID integer;
declare variable MAXDATE DM_DATETIME;
declare variable MINDATE DM_DATETIME;
begin
maxdate=(select max(plm.doc_commitdate)from partner_load_move plm );--Дата последней выгрузки
mindate=(select min(plm.doc_commitdate)from partner_load_move plm );--Дата самых старых данных в выгрузке
if (maxdate is null) then maxdate=:datestart; --если данных нет в таблице то выгружаем с указанной даты
if (:datestart<>maxdate) then datestart=maxdate; -- Если дата выгрузки больше или меньше даты последней выгрузки, выгружаем с даты последних данных

if (mindate<:datestart-93) then delete from partner_load_move where doc_commitdate<:datestart-93;-- Удаляет даные относящиеся к предыдущему периоду выгрузки (прошлый квартал)

 for select g.id from g$profiles g where g.parent_id is not null -- формируем все профили по которым должна быть выгрузка
 into :g$profile_id
 do
 begin
     for select
             dd.part_id as Drug_code,
             dd.doc_id,
            cast(abs(sum(dd.quant)) as dm_double) as quant,
            iif ((abs (dd.discount)>0),1,0) as disk_T,
            cast(abs(dd.sum_dsc) as numeric(9,2)) as Disk_Sum,
             abs(dd.summa_o) as Sum_Zak,
             abs(dd.summa) as Sum_Rozn,
             abs(dd.price) as Cena_Rozn,
             dd.g$profile_id
    
            from doc_detail dd
    
         where dd.doc_id is not null and dd.doc_commitdate between :DATESTART and :DATEEND and dd.g$profile_id = :g$profile_id
          and (select (select Upper(a1.caption) from agents a1 where a1.id=pr.agent_id and a1.g$profile_id=:g$profile_id ) from pr_getmotherpart(dd.part_id, :g$profile_id) pr) containing Upper('Катрен')
         group by dd.part_id, dd.doc_id,dd.discount,dd.sum_dsc,dd.summa_o,dd.summa,dd.price,dd.g$profile_id
         into :drug_code, :doc_id, :quant,  :disk_T, :disk_sum, :Sum_Zak, :Sum_Rozn, :Cena_Rozn , :g$profile_id_out
         do
             begin --заполняем таблицу данными для выгрузки движения
                INSERT INTO partner_load_move (partner_id,d_type,docnum,docdate,supplier,supplier_inn,device_num,n_chek,fio_chek,pp_teg,drug_name,izg_id,drug_producer_name,bcodeizg,drug_producer_country,
                                                cena_zak,seria,godendo_date,barcode,drug_code,quant,disk_t,disk_sum,sum_zak,sum_rozn,cena_rozn,g$profile_id,doc_commitdate)
                select  g.partner_id,
                     iif (d.doc_type=1,10,iif(d.doc_type=3,20,d.doc_type))as d_type,
                     left(d.docnum,iif(position(' ',d.docnum)=0,char_length(d.docnum), position(' ',d.docnum)))as docnum,
                     cast(d.docdate as date)as docdate,
                     a.caption as Supplier,
                     a.inn as Supplier_INN,
                     d.device_num, 
                     iif(d.doc_type=3,d.docnum, '')as N_Chek,
                     u.username as FIO_Chek,
                     0 as pp_teg,
                     vname.svalue as Drug_name,
                      w.izg_id,
                     vorig_izg.svalue as Drug_Producer_Name,
                     w.barcode as bcodeizg,
                     vcountry.svalue as Drug_Producer_country,
                      p.price_o as Cena_Zak,
                      p.seria,
                      iif (p.godendo is not null, cast(p.godendo as date),'01.01.1990') as godendo_date,
                      p.barcode,
                      :drug_code,
                      :quant,  :disk_T, :disk_sum, :Sum_Zak, :Sum_Rozn, :Cena_Rozn , :g$profile_id_out,d.commitdate
            
            
                from docs d
                    left join parts p on p.id = :drug_code and p.g$profile_id=d.g$profile_id
                    left join users u on u.id=d.owner and u.g$profile_id=d.g$profile_id
                    left join agents a on a.id = d.agent_id and a.g$profile_id=p.g$profile_id
                    left join wares w on w.id=p.ware_id
                    left join vals vorig_izg on vorig_izg.id=w.izg_id
                    left join vals vcountry on vcountry.id=w.country_id
                    left join vals vname on vname.id=w.name_id
                    left join g$profiles g on g.id = p.g$profile_id
                    where  d.g$profile_id = :G$PROFILE_ID_OUT  and d.doc_type in (1,2,3,6,9)
                    and d.id=:doc_id
                       ;
        
             end
 suspend;
 end

end^

SET TERM ; ^

/* Following GRANT statetements are generated automatically */

GRANT SELECT,INSERT,DELETE ON PARTNER_LOAD_MOVE TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON G$PROFILES TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON DOC_DETAIL TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON AGENTS TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT EXECUTE ON PROCEDURE PR_GETMOTHERPART TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON DOCS TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON PARTS TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON USERS TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON WARES TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON VALS TO PROCEDURE PR_LOAD_MOVE_PARTNER;

/* Existing privileges on this procedure */

GRANT EXECUTE ON PROCEDURE PR_LOAD_MOVE_PARTNER TO SYSDBA;

PR_LOAD_MOVE_PARTNER для сводника(старого) Стандарт-М

SET TERM ^ ;

create or alter procedure PR_LOAD_MOVE_PARTNER (
    DATESTART DM_DATE,
    DATEEND DM_DATE)
returns (
    PARTNER_ID integer,
    DRUG_NAME DM_TEXT,
    DRUG_CODE integer,
    DOCNUM DM_TEXT,
    DOCDATE DM_DATETIME,
    IZG_ID DM_UUID_NULL,
    DRUG_PRODUCER_NAME DM_TEXT,
    DRUG_PRODUCER_COUNTRY DM_TEXT,
    BARCODE DM_TEXT,
    CENA_ZAK DM_DOUBLE,
    GODENDO_DATE DM_DATE,
    SERIA DM_TEXT,
    G$PROFILE_ID_OUT integer,
    QUANT DM_DOUBLE,
    BCODEIZG DM_TEXT,
    DISK_T DM_DOUBLE,
    DISK_SUM DM_DOUBLE,
    SUM_ZAK DM_DOUBLE,
    SUM_ROZN DM_DOUBLE,
    CENA_ROZN DM_DOUBLE,
    D_TYPE integer,
    SUPPLIER DM_TEXT,
    SUPPLIER_INN DM_TEXT,
    DEVICE_NUM DM_TEXT,
    N_CHEK DM_TEXT,
    FIO_CHEK DM_TEXT,
    PP_TEG DM_TEXT)
as
declare variable DOC_ID integer;
declare variable G$PROFILE_ID integer;
declare variable MAXDATE DM_DATETIME;
declare variable MINDATE DM_DATETIME;
begin
maxdate=(select max(plm.doc_commitdate)from partner_load_move plm );--Дата последней выгрузки
mindate=(select min(plm.doc_commitdate)from partner_load_move plm );--Дата самых старых данных в выгрузке
if (maxdate is null) then maxdate=:datestart; --если данных нет в таблице то выгружаем с указанной даты
if (:datestart<>maxdate) then datestart=maxdate; -- Если дата выгрузки больше или меньше даты последней выгрузки, выгружаем с даты последних данных

if (mindate<:datestart-93) then delete from partner_load_move where doc_commitdate<:datestart-93;-- Удаляет даные относящиеся к предыдущему периоду выгрузки (прошлый квартал)

 for select g.id from g$profiles g where g.parent_id is not null -- формируем все профили по которым должна быть выгрузка
 into :g$profile_id
 do
 begin
     for select
             dd.part_id as Drug_code,
             dd.doc_id,
            cast(abs(sum(dd.quant)) as dm_double) as quant,
            iif ((abs (dd.discount)>0),1,0) as disk_T,
            cast(abs(dd.sum_dsc) as numeric(9,2)) as Disk_Sum,
             abs(dd.summa_o) as Sum_Zak,
             abs(dd.summa) as Sum_Rozn,
             abs(dd.price) as Cena_Rozn,
             dd.g$profile_id
    
            from doc_detail dd
    
         where dd.doc_id is not null and dd.doc_commitdate between :DATESTART and :DATEEND and dd.g$profile_id = :g$profile_id
          and (select (select Upper(a1.caption) from agents a1 where a1.id=pr.agent_id and a1.g$profile_id=:g$profile_id ) from pr_getmotherpart(dd.part_id, :g$profile_id) pr) containing Upper('Катрен')
         group by dd.part_id, dd.doc_id,dd.discount,dd.sum_dsc,dd.summa_o,dd.summa,dd.price,dd.g$profile_id
         into :drug_code, :doc_id, :quant,  :disk_T, :disk_sum, :Sum_Zak, :Sum_Rozn, :Cena_Rozn , :g$profile_id_out
         do
             begin --заполняем таблицу данными для выгрузки движения
                INSERT INTO partner_load_move (partner_id,d_type,docnum,docdate,supplier,supplier_inn,device_num,n_chek,fio_chek,pp_teg,drug_name,izg_id,drug_producer_name,bcodeizg,drug_producer_country,
                                                cena_zak,seria,godendo_date,barcode,drug_code,quant,disk_t,disk_sum,sum_zak,sum_rozn,cena_rozn,g$profile_id,doc_commitdate)
                select  g.partner_id,
                     iif (d.doc_type=1,10,iif(d.doc_type=3,20,d.doc_type))as d_type,
                     left(d.docnum,iif(position(' ',d.docnum)=0,char_length(d.docnum), position(' ',d.docnum)))as docnum,
                     cast(d.docdate as date)as docdate,
                     a.caption as Supplier,
                     a.inn as Supplier_INN,
                     d.device_num, 
                     iif(d.doc_type=3,d.docnum, '')as N_Chek,
                     u.username as FIO_Chek,
                     0 as pp_teg,
                     vname.svalue as Drug_name,
                      w.izg_id,
                     vorig_izg.svalue as Drug_Producer_Name,
                     w.barcode as bcodeizg,
                     vcountry.svalue as Drug_Producer_country,
                      p.price_o as Cena_Zak,
                      p.seria,
                      iif (p.godendo is not null, cast(p.godendo as date),'01.01.1990') as godendo_date,
                      p.barcode,
                      :drug_code,
                      :quant,  :disk_T, :disk_sum, :Sum_Zak, :Sum_Rozn, :Cena_Rozn , :g$profile_id_out,d.commitdate
            
            
                from docs d
                    left join parts p on p.id = :drug_code and p.g$profile_id=d.g$profile_id
                    left join users u on u.id=d.owner and u.g$profile_id=d.g$profile_id
                    left join agents a on a.id = d.agent_id and a.g$profile_id=p.g$profile_id
                    left join wares w on w.id=p.ware_id  and w.g$profile_id=d.g$profile_id
                    left join vals vorig_izg on vorig_izg.id=w.izg_id and vorig_izg.g$profile_id=d.g$profile_id
                    left join vals vcountry on vcountry.id=w.country_id and vcountry.g$profile_id=d.g$profile_id
                    left join vals vname on vname.id=w.name_id and vname.g$profile_id=d.g$profile_id
                    left join g$profiles g on g.id = p.g$profile_id
                    where  d.g$profile_id = :G$PROFILE_ID_OUT  and d.doc_type in (1,2,3,6,9)
                    and d.id=:doc_id
                       ;
        
             end
 suspend;
 end

end^

SET TERM ; ^

/* Following GRANT statetements are generated automatically */

GRANT SELECT,INSERT,DELETE ON PARTNER_LOAD_MOVE TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON G$PROFILES TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON DOC_DETAIL TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON AGENTS TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT EXECUTE ON PROCEDURE PR_GETMOTHERPART TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON DOCS TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON PARTS TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON USERS TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON WARES TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON VALS TO PROCEDURE PR_LOAD_MOVE_PARTNER;

/* Existing privileges on this procedure */

GRANT EXECUTE ON PROCEDURE PR_LOAD_MOVE_PARTNER TO SYSDBA;

PR_LOAD_MOVE_PARTNER для менеджера

 
SET TERM ^ ;

create or alter procedure PR_LOAD_MOVE_PARTNER (
    DATESTART DM_DATE,
    DATEEND DM_DATE)
returns (
    DRUG_NAME DM_TEXT,
    DRUG_CODE integer,
    DOCNUM DM_TEXT,
    DOCDATE DM_DATETIME,
    IZG_ID DM_UUID_NULL,
    DRUG_PRODUCER_NAME DM_TEXT,
    DRUG_PRODUCER_COUNTRY DM_TEXT,
    BARCODE DM_TEXT,
    CENA_ZAK DM_DOUBLE,
    GODENDO_DATE DM_DATE,
    SERIA DM_TEXT,
    QUANT DM_DOUBLE,
    BCODEIZG DM_TEXT,
    DISK_T DM_DOUBLE,
    DISK_SUM DM_DOUBLE,
    SUM_ZAK DM_DOUBLE,
    SUM_ROZN DM_DOUBLE,
    CENA_ROZN DM_DOUBLE,
    D_TYPE integer,
    SUPPLIER DM_TEXT,
    SUPPLIER_INN DM_TEXT,
    DEVICE_NUM DM_TEXT,
    N_CHEK DM_TEXT,
    FIO_CHEK DM_TEXT,
    PP_TEG DM_TEXT)
as
declare variable DOC_ID integer;
declare variable MAXDATE DM_DATETIME;
declare variable MINDATE DM_DATETIME;
begin
maxdate=(select max(plm.doc_commitdate)from partner_load_move plm );--Дата последней выгрузки
mindate=(select min(plm.doc_commitdate)from partner_load_move plm );--Дата самых старых данных в выгрузке
if (maxdate is null) then maxdate=:datestart; --если данных нет в таблице то выгружаем с указанной даты
if (:datestart<>maxdate) then datestart=maxdate; -- Если дата выгрузки больше или меньше даты последней выгрузки, выгружаем с даты последних данных

if (mindate<:datestart-93) then delete from partner_load_move where doc_commitdate<:datestart-93;-- Удаляет даные относящиеся к предыдущему периоду выгрузки (прошлый квартал)

 for select
         dd.part_id as Drug_code,
         dd.doc_id,
        cast(abs(sum(dd.quant)) as dm_double) as quant,
        iif ((abs (dd.discount)>0),1,0) as disk_T,
        cast(abs(dd.sum_dsc) as numeric(9,2)) as Disk_Sum,
         abs(dd.summa_o) as Sum_Zak,
         abs(dd.summa) as Sum_Rozn,
         abs(dd.price) as Cena_Rozn


        from doc_detail dd

     where dd.doc_id is not null and dd.doc_commitdate between :DATESTART and :DATEEND
     group by dd.part_id, dd.doc_id,dd.discount,dd.sum_dsc,dd.summa_o,dd.summa,dd.price
     into :drug_code, :doc_id, :quant,  :disk_T, :disk_sum, :Sum_Zak, :Sum_Rozn, :Cena_Rozn do
 begin
 INSERT INTO partner_load_move (d_type,docnum,docdate,supplier,supplier_inn,device_num,n_chek,fio_chek,pp_teg,drug_name,izg_id,drug_producer_name,bcodeizg,drug_producer_country,
                                                cena_zak,seria,godendo_date,barcode,drug_code,quant,disk_t,disk_sum,sum_zak,sum_rozn,cena_rozn,doc_commitdate)
               
    select
         iif (d.doc_type=1,10,iif(d.doc_type=3,20,d.doc_type))as d_type,
         left(d.docnum,iif(position(' ',d.docnum)=0,char_length(d.docnum), position(' ',d.docnum)))as docnum,
         cast(d.docdate as date)as docdate,
         a.caption as Supplier,
         a.inn as Supplier_INN,
         d.device_num, 
         iif(d.doc_type=3,d.docnum, '')as N_Chek,
         (select first 1 u.username from users u where u.id=d.owner)as FIO_Chek,
         0 as pp_teg,
         vname.svalue as Drug_name,
          w.izg_id,
         vorig_izg.svalue as Drug_Producer_Name,
         w.barcode as bcodeizg,
         vcountry.svalue as Drug_Producer_country,
          p.price_o as Cena_Zak,
          p.seria,
          iif (p.godendo is not null, cast(p.godendo as date),'01.01.1990') as godendo_date,
          p.barcode,
          :drug_code,
                      :quant,  :disk_T, :disk_sum, :Sum_Zak, :Sum_Rozn, :Cena_Rozn ,d.commitdate


    from docs d
        left join parts p on p.id = :drug_code

        left join agents a on a.id = d.agent_id
        left join wares w on w.id=p.ware_id
        left join vals vorig_izg on vorig_izg.id=w.izg_id
        left join vals vcountry on vcountry.id=w.country_id
        left join vals vname on vname.id=w.name_id
        where   d.doc_type in (1,2,3,6,9)
        and d.id=:doc_id  -- and d.docdate between :DATESTART and :DATEEND
        --and d.docdate is not null ;
          ;

--            into :d_type, :docnum, :docdate, :supplier, :supplier_inn, :device_num, :n_chek, :fio_chek, :pp_teg, :drug_name, :izg_id, :drug_producer_name,
--                 :bcodeizg, :drug_producer_country, :cena_zak, :seria, :godendo_date, :barcode;

     suspend;
 end

end^

SET TERM ; ^

/* Following GRANT statetements are generated automatically */

GRANT SELECT,INSERT,DELETE ON PARTNER_LOAD_MOVE TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON DOC_DETAIL TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON USERS TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON DOCS TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON PARTS TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON AGENTS TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON WARES TO PROCEDURE PR_LOAD_MOVE_PARTNER;
GRANT SELECT ON VALS TO PROCEDURE PR_LOAD_MOVE_PARTNER;

/* Existing privileges on this procedure */

GRANT EXECUTE ON PROCEDURE PR_LOAD_MOVE_PARTNER TO SYSDBA;

процедура выгрузки остатков

Временная таблица для остатков

/******************************************************************************/
/***               Generated by IBExpert 08.04.2019 11:25:05                ***/
/******************************************************************************/

/******************************************************************************/
/***      Following SET SQL DIALECT is just for the Database Comparer       ***/
/******************************************************************************/
SET SQL DIALECT 3;



/******************************************************************************/
/***                                 Tables                                 ***/
/******************************************************************************/


CREATE GENERATOR GEN_PARTNER_LOAD_ID;

CREATE TABLE PARTNER_LOAD (
    ID              DM_ID /* DM_ID = BIGINT */,
    SNAME           DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    PART_ID         DM_ID /* DM_ID = BIGINT */,
    DOCNUM          DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    DOCDATE         DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    DOCAGENT        DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    IZG_ID          DM_UUID_NULL /* DM_UUID_NULL = CHAR(36) */,
    SIZG            DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    SCOUNTRY        DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    BARCODE         DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    PRICE_O         DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */,
    PRICE           DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */,
    GODENDO_DATE    DM_DATE /* DM_DATE = DATE */,
    SERIA           DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    QUANT           DM_DOUBLE /* DM_DOUBLE = DOUBLE PRECISION */,
    INN             DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    BCODE_IZG       DM_TEXT /* DM_TEXT = VARCHAR(250) */,
    DOC_COMMITDATE  DM_DATETIME /* DM_DATETIME = TIMESTAMP */,
    INSERTDT        DM_DATETIME /* DM_DATETIME = TIMESTAMP */
);




/******************************************************************************/
/***                                Indices                                 ***/
/******************************************************************************/

CREATE INDEX PARTNER_LOAD_IDX1 ON PARTNER_LOAD (ID);


/******************************************************************************/
/***                                Triggers                                ***/
/******************************************************************************/


SET TERM ^ ;



/******************************************************************************/
/***                          Triggers for tables                           ***/
/******************************************************************************/



/* Trigger: PARTNER_LOAD_BI */
CREATE OR ALTER TRIGGER PARTNER_LOAD_BI FOR PARTNER_LOAD
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.id is null) then
    new.id = gen_id(gen_partner_load_id,1);
end
^


/* Trigger: PARTNER_LOAD_BI0 */
CREATE OR ALTER TRIGGER PARTNER_LOAD_BI0 FOR PARTNER_LOAD
ACTIVE BEFORE INSERT OR UPDATE POSITION 0
AS
begin
  new.insertdt=current_timestamp;
end
^


SET TERM ; ^



/******************************************************************************/
/***                               Privileges                               ***/
/******************************************************************************/

PR_LOAD_PARTNER для сводника

SET TERM ^ ;

create or alter procedure PR_LOAD_PARTNER (
    DATEEND DM_DATE,
    G$PROFILE_ID integer)
returns (
    PARTNER_ID integer,
    SNAME DM_TEXT,
    PART_ID integer,
    DOCNUM DM_TEXT,
    DOCDATE DM_DATETIME,
    DOCAGENT DM_TEXT,
    IZG_ID DM_UUID_NULL,
    SIZG DM_TEXT,
    SCOUNTRY DM_TEXT,
    BARCODE DM_TEXT,
    PRICE_O DM_DOUBLE,
    PRICE DM_DOUBLE,
    GODENDO_DATE DM_DATE,
    SERIA DM_TEXT,
    G$PROFILE_ID_OUT integer,
    QUANT DM_DOUBLE,
    INN DM_TEXT,
    BCODE_IZG DM_TEXT)
as
begin
 for select  dd.part_id,cast(abs(sum(dd.quant)) as dm_double) as quant, g$profile_id
         from doc_detail dd
     where dd.doc_commitdate<=:DATEEND and dd.g$profile_id = :g$profile_id
 group by dd.part_id, g$profile_id
 having abs(sum(dd.quant))>0.001 into  :part_id, :quant, :G$PROFILE_ID_OUT  do
 begin
    select  g.partner_id,
         :DATEEND as docdate,
        (select (select a.caption from agents a where a.id=pr.agent_id and a.g$profile_id=p.g$profile_id ) from pr_getmotherpart(p.id, :G$PROFILE_ID) pr)as docagent,
        left(d.docnum,iif(position(' ',d.docnum)=0,char_length(d.docnum), position(' ',d.docnum)))as docnum,
        (select a.inn from  agents a where d.agent_id=a.id and a.g$profile_id=p.g$profile_id) as INN,
        w.izg_id,
        v_izg.svalue as sizg,
        v_strana.svalue as scountry,
        v_sname.svalue as sname,
        w.barcode as bcode_izg,
        cast (abs(p.price_o) as numeric(9,2)) as price_o,
        cast (abs(p.price) as numeric(9,2)) as price,
        iif (p.godendo is not null, cast(p.godendo as date),'01.01.1900') as godendo_date,
        p.seria,
        p.barcode
    from parts p
        left join docs d on d.id=p.doc_id and d.g$profile_id=p.g$profile_id
        left join wares w on w.id=p.ware_id
        left join vals v_izg on v_izg.id=w.izg_id
        left join vals v_strana on v_strana.id=w.country_id
        left join vals v_sname on v_sname.id=w.name_id
        left join g$profiles g on g.id = p.g$profile_id
        where p.id = :part_id and p.g$profile_id = :G$PROFILE_ID_OUT  
            into :partner_id, :docdate, :docagent, :docnum, :INN, :izg_id, :sizg, :scountry, :sname, :bcode_izg, :price_o, :price,:godendo_date, :seria, :barcode;
     suspend;
 end

end^

SET TERM ; ^

/* Following GRANT statements are generated automatically */

GRANT SELECT ON DOC_DETAIL TO PROCEDURE PR_LOAD_PARTNER;
GRANT SELECT ON AGENTS TO PROCEDURE PR_LOAD_PARTNER;
GRANT EXECUTE ON PROCEDURE PR_GETMOTHERPART TO PROCEDURE PR_LOAD_PARTNER;
GRANT SELECT ON PARTS TO PROCEDURE PR_LOAD_PARTNER;
GRANT SELECT ON DOCS TO PROCEDURE PR_LOAD_PARTNER;
GRANT SELECT ON WARES TO PROCEDURE PR_LOAD_PARTNER;
GRANT SELECT ON VALS TO PROCEDURE PR_LOAD_PARTNER;
GRANT SELECT ON G$PROFILES TO PROCEDURE PR_LOAD_PARTNER;


/* Existing privileges on this procedure */

GRANT EXECUTE ON PROCEDURE PR_LOAD_PARTNER TO SYSDBA; 

PR_LOAD_PARTNER для менеджера

 
SET TERM ^ ;

create or alter procedure PR_LOAD_PARTNER (
    DATEEND DM_DATETIME)
returns (
    SNAME DM_TEXT,
    PART_ID integer,
    DOCNUM DM_TEXT,
    DOCDATE DM_DATETIME,
    DOCAGENT DM_TEXT,
    IZG_ID DM_UUID_NULL,
    SIZG DM_TEXT,
    SCOUNTRY DM_TEXT,
    BARCODE DM_TEXT,
    PRICE_O DM_DOUBLE,
    PRICE DM_DOUBLE,
    GODENDO_DATE DM_DATE,
    SERIA DM_TEXT,
    QUANT DM_DOUBLE,
    INN DM_TEXT,
    BCODE_IZG DM_TEXT)
as
declare variable MAXDATE DM_DATETIME;
declare variable MINDATE DM_DATETIME;
declare variable DATESTART DM_DATETIME;
begin
maxdate=(select max(plm.doc_commitdate)from partner_load plm );--Дата последней выгрузки
mindate=(select min(plm.doc_commitdate)from partner_load plm );--Дата самых старых данных в выгрузке
if (maxdate is null) then datestart=:dateend; --если данных нет в таблице то выгружаем с указанной даты
if (:dateend<>maxdate) then datestart=maxdate; -- Если дата выгрузки больше или меньше даты последней выгрузки, выгружаем с даты последних данных

if (mindate<:dateend-93) then delete from partner_load where doc_commitdate<:dateend-93;-- Удаляет даные относящиеся к предыдущему периоду выгрузки (прошлый квартал)

     while (datestart<>dateend+1)  do
      begin
         for
        
          select  dd.part_id,cast(abs(sum(dd.quant)) as dm_double) as quant
                 from doc_detail dd
             where dd.doc_commitdate<=:datestart
         group by dd.part_id
         having abs(sum(dd.quant))>0.001 into  :part_id, :quant  do
         begin
           insert into partner_load (docdate,docagent,docnum, inn,izg_id,sizg,scountry,sname,bcode_izg,price_o,price,godendo_date,seria,barcode,doc_commitdate,part_id,quant)
            select
                :datestart as docdate,
                (select (select a.caption from agents a where a.id=pr.agent_id  ) from pr_getmotherpart(p.id) pr)as docagent,
                left(d.docnum,iif(position(' ',d.docnum)=0,char_length(d.docnum), position(' ',d.docnum)))as docnum,
                (select a.inn from  agents a where d.agent_id=a.id ) as INN,
                w.izg_id,
                v_izg.svalue as sizg,
                v_strana.svalue as scountry,
                v_sname.svalue as sname,
                w.barcode as bcode_izg,
                cast (abs(p.price_o) as numeric(9,2)) as price_o,
                cast (abs(p.price) as numeric(9,2)) as price,
                iif (p.godendo is not null, cast(p.godendo as date),'01.01.1900') as godendo_date,
                p.seria,
                p.barcode,
                :dateend,
                :part_id,
                :quant
            from parts p
                left join docs d on d.id=p.doc_id
                left join wares w on w.id=p.ware_id
                left join vals v_izg on v_izg.id=w.izg_id
                left join vals v_strana on v_strana.id=w.country_id
                left join vals v_sname on v_sname.id=w.name_id
        
                where p.id = :part_id ;
        --            into  :docdate, :docagent, :docnum, :INN, :izg_id, :sizg, :scountry, :sname, :bcode_izg, :price_o, :price,:godendo_date, :seria, :barcode;

         end
     datestart=datestart+1;
     end
     suspend;


end^

SET TERM ; ^

/* Following GRANT statetements are generated automatically */

GRANT SELECT,INSERT,DELETE ON PARTNER_LOAD TO PROCEDURE PR_LOAD_PARTNER;
GRANT SELECT ON DOC_DETAIL TO PROCEDURE PR_LOAD_PARTNER;
GRANT SELECT ON AGENTS TO PROCEDURE PR_LOAD_PARTNER;
GRANT EXECUTE ON PROCEDURE PR_GETMOTHERPART TO PROCEDURE PR_LOAD_PARTNER;
GRANT SELECT ON PARTS TO PROCEDURE PR_LOAD_PARTNER;
GRANT SELECT ON DOCS TO PROCEDURE PR_LOAD_PARTNER;
GRANT SELECT ON WARES TO PROCEDURE PR_LOAD_PARTNER;
GRANT SELECT ON VALS TO PROCEDURE PR_LOAD_PARTNER;

/* Existing privileges on this procedure */

GRANT EXECUTE ON PROCEDURE PR_LOAD_PARTNER TO SYSDBA; 

Необходимые папки и файлы записи в БД

Параметры передачи данных

INSERT INTO PARAMS ( PARENT_ID, PARAM_ID, PARAM_CAPTION, PARAM_TYPE, PARAM_VALUE, AUDIT_ID,    SORTING)
 VALUES            ( 0,        'PARTNER_ID', 'ИД в системе партнер', 1,        NULL,       10308,        5);
INSERT INTO PARAMS ( PARENT_ID, PARAM_ID, PARAM_CAPTION, PARAM_TYPE, PARAM_VALUE, AUDIT_ID,    SORTING)
 VALUES            ( 0,        'PARTNER_PASS', 'Пароль в системе партнер', 1,        NULL,       10308,        5);
INSERT INTO PARAMS ( PARENT_ID, PARAM_ID, PARAM_CAPTION, PARAM_TYPE, PARAM_VALUE, AUDIT_ID,    SORTING)
 VALUES            ( 0,        'PARTNER_PATH', 'Путь выгрузки данных для передачи', 1,        NULL,       10308,        5);
INSERT INTO PARAMS ( PARENT_ID, PARAM_ID, PARAM_CAPTION, PARAM_TYPE, PARAM_VALUE, AUDIT_ID,    SORTING)
 VALUES            ( 0,        'PARTNER_LAST', 'Дата последней выгрузки', 6,        NULL,       10308,        5);

Для сетей аптек

В таблице G$PROFILES нужно создать поле PARTNER_ID

ALTER TABLE G$PROFILES
ADD PARTNER_ID DM_ID_NULL 

данное поле в дальнейшем надо заполнить кодами клиента партнера используя только числовые значения

ПРИМЕР код partner12000  в поле вводим 12000

коды берутся у региональных представителей компании Катрен

так же для логов

создаем файл по пути - c:\standart-n\spacepro - partner.log

для всех выгрузок

Выгрузка производится в соответствующую папку, ее требуется создать для работы ТМС

создаем папку -  c:\standart-n\Partner

в этой папке будет создаваться файлы выгрузки а так же должен лежать клиент ФТП - ncftpput.exe


после подготовительной работы создаем ТМС

ТМС выгрузки для сетей аптек (SpacePro)

uses
  unDM, cfIBUtils, unFrameCustomDict, need, cfUtils,
  inifiles, unMain,  unFRFramePreview,
  Classes, Graphics, Controls, Forms, Dialogs, AdvPanel,
  AdvGlowButton, DB, IBDatabase, IBQuery, ExtCtrls, StdCtrls,
  dxExEdtr, dxCntner, dxTL, dxDBCtrl, dxDBTL, Buttons, ComCtrls,
  AdvOfficePager,dateUtils, ImgList, ShellApi,Windows,unDM,sysUtils;
const
 //Пути выгрузки по профилям                                                                                             
 path='\Standart-N\partner\';


 //Доступ профилей на ФТП                           
 login='partner15339';                                
 pass='AYJXS-wlubj-4ami-5uvo-ksbzn';


 url='partner.melzdrav.ru';

                                          

var q,q1,q3: TIBQuery;                                                       
    sl,sl1: TStringList;                   
    SQL,t,t1,f,f1,org_name,org_inn,codeClient,path1: String;
    date_start,date_end:date;
    today:Tdatetime;
    fsLog:  TFileStream;


procedure LogIt(s: string);
begin
  s:=formatdatetime('dd.mm.yyyy hh:nn:ss',now)+#9+s+#13#10;
  cfStreamWrite(fsLog,s);
// fsLog.Write(s,length(s));
end;


function filename:String;
var
t,y,m,d:String;
begin
 d:=Copy(DatetoStr(date_end),0,2);
 m:=Copy(DatetoStr(date_end),4,2);
 y:=Copy(Datetostr(date_end),7,4);
 t:=StringReplace(time,':','',1);
 if Length(t)<6 then t:='0'+t;
 result:=y+m+d+t;
end;

//Архивируем файл
Procedure ZIP (f:string);
var
fz:string;
begin
fz:=' a -tzip -sdel '+f+'.zip '+ f ;
LogIt(fz);
shellExecuteA(0,'open','C:\Program Files\7-Zip\7z.exe',fz,'',5);

end;

//Посылаем по ФТП
Procedure FTP (f,login,pass,path:string);
const
files=extractfiledrive(application.ExeName)+path;

begin
  t:='-F -DD -u '+login+' -p '+pass+' '+url+' \ '+files+f;
  frmSpacePro.logit(t);
     ShellExecuteA(0, 'open',files+'ncftpput.exe', t, '', 5);


end;



//проверяем наличие файла в директории
Function CheckFiles (codeClient,FileName1,pathz:String):String;
var
fn:string
begin
     fn:=Filename;
     sl:= TStringList.Create;
     sl1:= TStringList.Create;
     result:=extractfiledrive(application.ExeName)+pathz+codeClient+'$'+fn+FileName1;
     if FileExists(result) then
     begin
       deletefile(result);
     end

end;

//получаем данные из запроса
Function GetSQLResult(SQL:String):TIBQuery;
var
q2:TIBQuery;
begin
try
 LogIt(SQL);
 q2:=dm.TempQuery(nil);
 q2.Active:=false;
 q2.SQL.Text:=SQL;
 q2.Active:=true;
    except
      frmSpacePro.logit('неверный запрос-'+SQL);
      q2.Transaction.Rollback;
    end;
 result:=q2;
end;

Procedure ExtractBase(i,partner_id:integer;path:String); //Выгрузка остатков
 Begin
   SQL:='select * from pr_load_partner('''+DateToStr(date_start)+''','+IntToStr(i)+') where Docnum is not null ';

   // frmSpacePro.logit(SQL);
    q:=GetSQLResult(SQL);

   f:=CheckFiles(InttoStr(partner_id),'.ost',path);
    logit(f);
    frmSpacePro.logit('Выгружаем остатки');

    {  t:='Тип Данных по строке;Номер Документа из программы участника;Дата создания или изменения строки документа из программы участника'+
      ';Поставщик;ИНН Поставщика;Номер ККМ;Номер чека из программы участника;ФИО Кассира;Тип скидки по строке чека;'+
      'Cумма скидки по строке чека;Закупочная сумма по строке чека;Розничная сумма по строке чека;Признак использования модуля "Приоритетная рекомендация" по строке чека;'+
      'Код Товара по справочнику товаров;Наименование Товара по справочнику товаров;Код производителя по справочнику производителей;'+
      'Наименование Производителя по справочнику производителей;Название страны производителя;Штрих код завода изготовителя;'
      +'Цена за единицу закупочная в рублях, округление до целых копеек;Цена за единицу розничная в рублях,округление до целых копеек;Количество;Серия товара;Срок годности товара;'+
      'Уникальный код партии из системы учета товародвижения,в формате штрих кода EAN-13;';
      sl.Add(t);}
      while not q.eof do
      begin
         t:=
          '0;'+                                                            //1
         q.fieldbyname('Docnum').AsString+';'                             //2
         +StringReplace(DateToStr(date_end),'.','',1) +';'  //3
         +q.fieldbyname('docagent').AsString+';'                          //4
         +q.fieldbyname('INN').AsString+';'                               //5
         +';'                                                             //6
         +';'                                                             //7
         +';'                                                             //8
         +';'                                                             //9
          +';' +';'                                                       //10-11
         +';'                                                             //12
         +';'                                                             //13
         +q.fieldbyname('PART_ID').AsString+';'                           //14
         +StringReplace(StringReplace(q.fieldbyname('SNAME').AsString,';',' ',1),#13#10,'',1)+';'    //15
         +q.fieldbyname('IZG_ID').AsString+';'                            //16
         +StringReplace(q.fieldbyname('SIZG').AsString,'"','',1)+';'                              //17
         +q.fieldbyname('scountry').AsString+';'                          //18
          +StringReplace(q.fieldbyname('bcode_izg').AsString,#13#10,'',1)+';'
         +q.fieldbyname('price_o').AsString+';'
         +q.fieldbyname('price').AsString+';'
         +q.fieldbyname('quant').AsString+';'
         +q.fieldbyname('seria').AsString+';'
         +StringReplace(q.fieldbyname('godendo_date').AsString,'.','',1)+';'
         +q.fieldbyname('barcode').AsString+';';
         sl.Add(t);
       // frmSpacePro.logit(t);
         q.next;
      end;

      try
      sl.SaveToFile(f);
      Logit('SavetoFile-'+f);
      sl.Free;
       sleep(1000);
      zip(f);



      except
     frmSpacePro.logit('неверный путь');
    end;
                                    
  //  frmSpacePro.logit('Остатки выгружены');
end;

Procedure ExtractMove(i,partner_id:integer;pathe:string);//Выгрузка движения
Begin
 SQL:='select * from pr_load_move_partner('''+DateToStr(date_start)+''','''+DateToStr(date_end)+''','+IntToStr(i)+') where d_type is not null';
//frmSpacePro.logit(SQL);
q:=GetSQLResult(SQL);
f:=CheckFiles(InttoStr(partner_id),'.mov',pathe);
   logit(f);
   frmSpacePro.logit('Выгружаем Движение');

     {t:='Тип Данных по строке;Номер Документа из программы участника;Дата создания или изменения строки документа из программы участника'+
      ';Поставщик;ИНН Поставщика;Номер ККМ;Номер чека из программы участника;ФИО Кассира;Тип скидки по строке чека;'+
      'Cумма скидки по строке чека;Закупочная сумма по строке чека;Розничная сумма по строке чека;Признак использования модуля "Приоритетная рекомендация" по строке чека;'+
      'Код Товара по справочнику товаров;Наименование Товара по справочнику товаров;Код производителя по справочнику производителей;'+
      'Наименование Производителя по справочнику производителей;Название страны производителя;Штрих код завода изготовителя;'
      +'Цена за единицу закупочная в рублях, округление до целых копеек;Цена за единицу розничная в рублях,округление до целых копеек;Количество;Серия товара;Срок годности товара;'+
      'Уникальный код партии из системы учета товародвижения,в формате штрих кода EAN-13;';
      sl.Add(t);
      }

      while not q.eof do
      begin

         t:=
      +q.fieldbyname('d_type').AsString+';'
         +q.fieldbyname('docnum').AsString+';'
         +StringReplace(q.fieldbyname('docdate').AsString,'.','',1) +';'
         +q.fieldbyname('Supplier').AsString+';'
         +q.fieldbyname('Supplier_INN').AsString+';'
         +q.fieldbyname('device_num').AsString+';'
         +q.fieldbyname('N_Chek').AsString+';'
         +q.fieldbyname('FIO_Chek').AsString+';'
         +q.fieldbyname('disk_T').AsString+';'
         +q.fieldbyname('Disk_Sum').AsString+';'
         +q.fieldbyname('Sum_Zak').AsString+';'
         +q.fieldbyname('Sum_Rozn').AsString+';'
         +q.fieldbyname('pp_teg').AsString+';'
         +q.fieldbyname('Drug_code').AsString+';'
         +StringReplace(q.fieldbyname('Drug_name').AsString,#13#10,'',1)+';'
         +q.fieldbyname('izg_id').AsString+';'
          +StringReplace(q.fieldbyname('Drug_name').AsString,';',' ',1)+';'
        //
         +q.fieldbyname('Drug_Producer_country').AsString+';'
          +StringReplace(q.fieldbyname('bcodeizg').AsString,#13#10,'',1)+';'
         +q.fieldbyname('Cena_Zak').AsString+';'
         +q.fieldbyname('Cena_Rozn').AsString+';'
         +q.fieldbyname('quant').AsString+';'
         +q.fieldbyname('seria').AsString+';'
         +StringReplace(q.fieldbyname('godendo_date').AsString,'.','',1) +';'
         +q.fieldbyname('barcode').AsString+';'
         ;
         sl.Add(t);
         q.next;
      end;


     try
      sl.SaveToFile(f);
       Logit('SavetoFile-'+f);
      sleep(1000);
      Zip(f);


      except
     frmSpacePro.logit('неверный путь');
    end;                                                                                                                                                                      


End;                   
Procedure InitVar;
begin
 //Базовые переменные - периуд отчета.
  date_start:=date-1;//  DateToStr(date-1);  //        strtoDate('30.09.2018');//
  date_end:=date;// StrToDate('02.10.2018');//DatetoStr(date);//
end;

begin
                                            
InitVar;
  try
  //if not fileexists(extractfilepath(application.ExeName)+'Partner.log') then
    //TFileStream.Create(extractfilepath(application.ExeName)+'Partner.log',fmCreate).Free;
    fsLog:=TFileStream.Create(extractfilepath(application.ExeName)+'Partner.log',fmOpenReadWrite);


//  logit(DatetoStr(date_start));
  logit('Начали -'+TimetoStr( time));


 //Выгружаем остатки по точкам
  SQL:='select  id,partner_id from g$profiles where partner_id is not null order by partner_id';
  q1:=GetSQLResult(SQL);
  while not q1.eof do
      begin
       path1:=path;
       LogIt(q1.fieldbyname('id').AsString);         logit(path1);
       ExtractBase(q1.fieldbyname('id').AsInteger,q1.fieldbyname('partner_id').AsInteger,path1);
       q1.Next;
      end;

 //выгрузка движение


  SQL:='select id,partner_id from g$profiles where partner_id is not null  order by partner_id ';
  q3:=GetSQLResult(SQL);                                            
  while not q3.eof do
      begin
      logit(q3.fieldbyname('id').AsString);
      InitVar;
       path1:=path;
       //logit(path1+' -- '+q3.fieldbyname('BASE_AGENT_ID').AsString);
     //  while date_end<>date do
       //    begin

               ExtractMove(q3.fieldbyname('id').AsInteger,q3.fieldbyname('partner_id').AsInteger,path1);
         //      date_end:=date_end+1;
         //      date_start:=date_start+1;
         //  end;                     
      q3.Next;
     end;


ftp('*.zip',login,pass,path);




    logit('Готово -'+TimetoStr( time));
    q.Free;

   finally
     fsLog.Free;
   end;
end; 

ТМС выгрузки для одиночных аптек (ManagerXP2)

 
uses
  unDM, cfIBUtils, unFrameCustomDict, need, cfUtils,
  inifiles, unMain,
  Classes, Graphics, Controls, Forms, Dialogs, AdvPanel,
  AdvGlowButton, DB, IBDatabase, IBQuery, ExtCtrls, StdCtrls,
  dxExEdtr, dxCntner, dxTL, dxDBCtrl, dxDBTL, Buttons, ComCtrls,
  AdvOfficePager,dateUtils, ImgList, ShellApi,Windows,unDM,sysUtils;
const
 //Пути выгрузки по профилям
 path='\Standart-N\partner\';    
 partner_id='15375';

 //Доступ профилей на ФТП
 login='partner15375';

 pass='vz4p-YQSQA-5FSV-gev8r-z5qc';



 url='partner.melzdrav.ru';



var q,q1,q3: TIBQuery;
    sl,sl1: TStringList;
    SQL,t,t1,f,f1,org_name,org_inn,codeClient,path1: String;
    date_start,date_end:date;
    today:Tdatetime;
    fsLog:  TFileStream;





function filename:String;
var
t,y,m,d:String;
begin
 d:=Copy(DatetoStr(date_end),0,2);
 m:=Copy(DatetoStr(date_end),4,2);
 y:=Copy(Datetostr(date_end),7,4);
 t:=StringReplace(time,':','',1);
 if Length(t)<6 then t:='0'+t;
 result:=y+m+d+t;
end;

//Архивируем файл
Procedure ZIP (f:string);
var
fz:string;
begin
fz:=' a -tzip -sdel '+f+'.zip '+ f ;
//LogIt(fz);
shellExecuteA(0,'open','C:\Program Files\7-Zip\7z.exe',fz,'',5);

end;

//Посылаем по ФТП
Procedure FTP (f,login,pass,path:string);
const
files=extractfiledrive(application.ExeName)+path;

begin
  t:='-F -DD -u '+login+' -p '+pass+' '+url+' \ '+files+f;
  //frmSpacePro.logit(t);
     ShellExecuteA(0, 'open',files+'ncftpput.exe', t, '', 5);


end;



//проверяем наличие файла в директории
Function CheckFiles (codeClient,FileName1,pathz:String):String;
var
fn:string
begin
     fn:=Filename;
     sl:= TStringList.Create;
     sl1:= TStringList.Create;
     result:=extractfiledrive(application.ExeName)+pathz+codeClient+'$'+fn+FileName1;
     if FileExists(result) then
     begin
       deletefile(result);
     end

end;

//получаем данные из запроса
Function GetSQLResult(SQL:String):TIBQuery;
var
q2:TIBQuery;
begin
try
 //LogIt(SQL);
 q2:=dm.TempQuery(nil);
 q2.Active:=false;
 q2.SQL.Text:=SQL;
 q2.Active:=true;
    except
      frmManagerXP2.logit('неверный запрос');
      q2.Transaction.Rollback;
    end;
 result:=q2;
end;

Procedure ExtractBase(partner_id:integer;path:String); //Выгрузка остатков
 Begin
   SQL:='select * from pr_load_partner('''+DateToStr(date_start)+''') where Docnum is not null ';

   // frmSpacePro.logit(SQL);
    q:=GetSQLResult(SQL);

   f:=CheckFiles(InttoStr(partner_id),'.ost',path);
   // logit(f);
    frmManagerXP2.logit('Выгружаем остатки');

    {  t:='Тип Данных по строке;Номер Документа из программы участника;Дата создания или изменения строки документа из программы участника'+
      ';Поставщик;ИНН Поставщика;Номер ККМ;Номер чека из программы участника;ФИО Кассира;Тип скидки по строке чека;'+
      'Cумма скидки по строке чека;Закупочная сумма по строке чека;Розничная сумма по строке чека;Признак использования модуля "Приоритетная рекомендация" по строке чека;'+
      'Код Товара по справочнику товаров;Наименование Товара по справочнику товаров;Код производителя по справочнику производителей;'+
      'Наименование Производителя по справочнику производителей;Название страны производителя;Штрих код завода изготовителя;'
      +'Цена за единицу закупочная в рублях, округление до целых копеек;Цена за единицу розничная в рублях,округление до целых копеек;Количество;Серия товара;Срок годности товара;'+
      'Уникальный код партии из системы учета товародвижения,в формате штрих кода EAN-13;';
      sl.Add(t);}
      while not q.eof do
      begin
         t:=
          '0;'+                                                            //1
         q.fieldbyname('Docnum').AsString+';'                             //2
         +StringReplace(DateToStr(date_end),'.','',1) +';'  //3
         +q.fieldbyname('docagent').AsString+';'                          //4
         +q.fieldbyname('INN').AsString+';'                               //5
         +';'                                                             //6
         +';'                                                             //7
         +';'                                                             //8
         +';'                                                             //9
          +';' +';'                                                       //10-11
         +';'                                                             //12
         +';'                                                             //13
         +q.fieldbyname('PART_ID').AsString+';'                           //14
         +StringReplace(q.fieldbyname('SNAME').AsString,';',' ',1)+';'    //15
         +q.fieldbyname('IZG_ID').AsString+';'                            //16
         +StringReplace(q.fieldbyname('SIZG').AsString,'"','',1)+';'                              //17
         +q.fieldbyname('scountry').AsString+';'                          //18
          +q.fieldbyname('bcode_izg').AsString+';'
         +q.fieldbyname('price_o').AsString+';'
         +q.fieldbyname('price').AsString+';'
         +q.fieldbyname('quant').AsString+';'
         +q.fieldbyname('seria').AsString+';'
         +StringReplace(q.fieldbyname('godendo_date').AsString,'.','',1)+';'
         +q.fieldbyname('barcode').AsString+';';
         sl.Add(t);
       // frmSpacePro.logit(t);
         q.next;
      end;

      try
      sl.SaveToFile(f);
   //   Logit('SavetoFile-'+f);
      sl.Free;
       sleep(1000);
      zip(f);



      except
     frmManagerXP2.logit('неверный путь');
    end;

  //  frmSpacePro.logit('Остатки выгружены');
end;

Procedure ExtractMove(partner_id:integer;pathe:string);//Выгрузка движения
Begin
 SQL:='select * from pr_load_move_partner('''+DateToStr(date_start)+''','''+DateToStr(date_end)+''') where d_type is not null';
//frmSpacePro.logit(SQL);
q:=GetSQLResult(SQL);
f:=CheckFiles(InttoStr(partner_id),'.mov',pathe);
  // logit(f);
   frmManagerXP2.logit('Выгружаем Движение');

     {t:='Тип Данных по строке;Номер Документа из программы участника;Дата создания или изменения строки документа из программы участника'+
      ';Поставщик;ИНН Поставщика;Номер ККМ;Номер чека из программы участника;ФИО Кассира;Тип скидки по строке чека;'+
      'Cумма скидки по строке чека;Закупочная сумма по строке чека;Розничная сумма по строке чека;Признак использования модуля "Приоритетная рекомендация" по строке чека;'+
      'Код Товара по справочнику товаров;Наименование Товара по справочнику товаров;Код производителя по справочнику производителей;'+
      'Наименование Производителя по справочнику производителей;Название страны производителя;Штрих код завода изготовителя;'
      +'Цена за единицу закупочная в рублях, округление до целых копеек;Цена за единицу розничная в рублях,округление до целых копеек;Количество;Серия товара;Срок годности товара;'+
      'Уникальный код партии из системы учета товародвижения,в формате штрих кода EAN-13;';
      sl.Add(t);
      }

      while not q.eof do
      begin

         t:=
      +q.fieldbyname('d_type').AsString+';'
         +q.fieldbyname('docnum').AsString+';'
         +StringReplace(q.fieldbyname('docdate').AsString,'.','',1) +';'
         +q.fieldbyname('Supplier').AsString+';'
         +q.fieldbyname('Supplier_INN').AsString+';'
         +q.fieldbyname('device_num').AsString+';'
         +q.fieldbyname('N_Chek').AsString+';'
         +q.fieldbyname('FIO_Chek').AsString+';'
         +q.fieldbyname('disk_T').AsString+';'
         +q.fieldbyname('Disk_Sum').AsString+';'
         +q.fieldbyname('Sum_Zak').AsString+';'
         +q.fieldbyname('Sum_Rozn').AsString+';'
         +q.fieldbyname('pp_teg').AsString+';'
         +q.fieldbyname('Drug_code').AsString+';'
         +q.fieldbyname('Drug_name').AsString+';'
         +q.fieldbyname('izg_id').AsString+';'
          +StringReplace(q.fieldbyname('Drug_name').AsString,';',' ',1)+';'
        //
         +q.fieldbyname('Drug_Producer_country').AsString+';'
          +q.fieldbyname('bcodeizg').AsString+';'
         +q.fieldbyname('Cena_Zak').AsString+';'
         +q.fieldbyname('Cena_Rozn').AsString+';'
         +q.fieldbyname('quant').AsString+';'
         +q.fieldbyname('seria').AsString+';'
         +StringReplace(q.fieldbyname('godendo_date').AsString,'.','',1) +';'
         +q.fieldbyname('barcode').AsString+';'
         ;
         sl.Add(t);
         q.next;
      end;


     try
      sl.SaveToFile(f);
     //  Logit('SavetoFile-'+f);
      sleep(1000);
      Zip(f);


      except
     frmManagerXP2.logit('неверный путь');
    end;


End;
Procedure InitVar;
begin
 //Базовые переменные - периуд отчета.
  date_start:=StrToDate('31.10.2018');//DateToStr(date-1);  //
  date_end:=strtoDate('01.11.2018');//DatetoStr(date);//
end;

begin

InitVar;
  try
  //if not fileexists(extractfilepath(application.ExeName)+'Partner.log') then
    //TFileStream.Create(extractfilepath(application.ExeName)+'Partner.log',fmCreate).Free;
   // fsLog:=TFileStream.Create(extractfilepath(application.ExeName)+'partner.txt',fmOpenReadWrite);


//  logit(DatetoStr(date_start));
 // logit('Начали -'+TimetoStr( time));


 //Выгружаем остатки по точкам
  ExtractBase(partner_id,path);

 //выгрузка движение



  //    InitVar;
  //     while date_end<>date do
    //      begin

               ExtractMove(partner_id,path);
    //           date_end:=date_end+1;
    //           date_start:=date_start+1;
     //     end;


 ftp('*.zip',login,pass,path);




  //  logit('Готово -'+TimetoStr( time));
    q.Free;

   finally
    // fsLog.Free;
   end;
end;

Если файлы не формируются возможно у вас старая версия архиватора 7ZIP обновите до последней версии.

Финальным этапом после проверки что все формирует и выгружает требуется добавить данную ТМС в планировщик задач. Задачу запускать ежедневно по окончании рабочего времени

Возможные ошибки и методы их устранения

Самое первое что бывает в 99% случаев

ОШИБКА: Компьютер выключается раньше срабатывания задания РЕШЕНИЕ: Дать по шее человеку который выключает компьютер, и думаю выставить счет на повторную выгрузку =)

Проверка выгрузки

1. Смотрим есть ли ТМС - Выгрузка в партнер

2. Смотрим срабатывает ли задача в планировщике

3. берем из ТМС логин пароль на ФТП заходим смотрим глазами есть ли свежие файлы


Если пп1 и 2 в норме а случился 99% случай

в ТМС идем в часть которая отвечает за выгрузку движения и раскомментируем цикл

затем чуть выше где задаются данные периода ставим День начала выгрузки-1 и день Выгрузки

запускаем заново ТМС

После завершения работы ТМС все возвращаем как было