nordk
Joined: 27 Jun 2005 Posts: 1000 Location: Горбунов Константин Occupation: БЭСТ-Партнер Interests: СПб
|
Posted: 29 Mar 2007 15:14 Post subject: |
|
|
Code: | FUNCTION METRO_XML(cXml)
LOCAL oXml,tables,table,i,aInsDbf:={},k,aNodes,cInsDbf
PRIVATE aStr:={},aStr2:={},aFileStruc:={},aField1,aField2,n,aDat,aField3
PRIVATE aTmc:={}
// Имя XML-файла заявки. Тут лучше доработать запрос имени файла
*cXml:='E:\TEMP\ecr.xml'
//Перечень основных узлов(разделов) по которым идет обработка
aNodes:={"UNH","BGM","DTM","SG1","SG2", ;
"SG7","SG28","UNS","MOA","CNT",;
"UNT"}
//Перечень узлов-полей баз данных ( имя поля совпадает с именем узла)
aField1:={"E0062","E0065","E0052","E0054","E0051", ;
"E0057","E1001","E1004","E1225","E1153", ;
"E1154","E3035","E3039","E3055","E1156", ;
"E4000","E1060","E5125","E5118","E0081", ;
"E5025","E5004","E6069","E6066","E0074", ;
"E6345","E6347","E6343"}
//Перечень узлов формирующих дату и время
aField2:={"E2005","E2380","E2379"}
//Перечень основных узлов в разделе списка товара
aField3:={"LIN","PIA","IMD","QTY","MOA","SG32"}
// Структура файла - шапки заказа
aadd(aStr,{"E0062","C",14,0}) //Номер электронного сообщения
aadd(aStr,{"E0065","C",6,0}) //Тип сообщения
aadd(aStr,{"E0052","C",3,0}) //Номер версии
aadd(aStr,{"E0054","C",3,0}) //Номер выпуска
aadd(aStr,{"E0051","C",2,0}) //Код ведущей организации
aadd(aStr,{"E1057","C",6,0}) //Номер версии присвоенный EAN
aadd(aStr,{"E1001","C",3,0}) //Код документа сообщения 220=Заказ
aadd(aStr,{"E1004","C",15,0}) //Номер заказа
aadd(aStr,{"E1225","C",3,0}) //Тип заказа 9=оригинал,5=замена,31=копия
//
aadd(aStr,{"datdoc","D",8,0}) // Дата заказа
aadd(aStr,{"timedoc","C",4,0})// время заказа
aadd(aStr,{"datpost","D",8,0})// Требуемая дата поставки
aadd(aStr,{"timepost","C",4,0})//Требуемое время поставки
aadd(aStr,{"E6347","C",3,0}) //Тип валюты
aadd(aStr,{"E6345","C",3,0}) //Код Валюты
aadd(aStr,{"E6343","C",3,0}) //Тип курса 4=курс Инвойса 9=курс заказа
aadd(aStr,{"E6348","C",4,0}) //Курс валюты
aadd(aStr,{"E0081","C",1,0}) //Разделитель зон ХML
aadd(aStr,{"E5025","C",3,0}) //Вид суммы 128=сумма по строке
aadd(aStr,{"E5004","C",35,0}) //Значение суммы
aadd(aStr,{"E6069","C",3,0}) //Тип итоговой информации 2=Кол-во товарных позиций
aadd(aStr,{"E6066","C",18,0}) //Значение кол-ва
aadd(aStr,{"E0074","C",6,0}) //Общее число сегментов в сообщении
//Структура файла с описанием сторон и других документов упоминаемых в заказе
aadd(aStr2,{"SG","N",1,0}) //Код сегмента SG1 или SG2
aadd(aStr2,{"E1153","C",3,0}) //Вид документа PD=Промо-акция CT=контракт
aadd(aStr2,{"E1154","C",70,0}) //Номер документа
aadd(aStr2,{"E3035","C",3,0}) //Квалификатор сторон BY=покупатель
//DP=адрес доставки IV=Кому выписан счет
//SR= поставщик PE=плательщик
//YC1=доп.код для Метро - код поставщика Метро
aadd(aStr2,{"E3039","C",35,0}) //Индификационный GLN-номер стороны
aadd(aStr2,{"E3055","C",3,0}) //Код ведущей организации 9=EAN
aadd(aStr2,{"E1156","C",6,0}) //Идентификатор документа ссылки
aadd(aStr2,{"E4000","C",35,0}) //Индетификатор версии ссылки
aadd(aStr2,{"E1060","C",6,0}) //Идентификатор ревизии ссылки
//Структура файла с перечнем ТМЦ в заявке
//В начале идут поля обязательные для импорта строк ТМЦ в БЭСТ-4
//В модуле Учет Товаров без учета дополнительных полей импорта
//За ними идут значения взятые из заявки
aadd(aFileStruc,{"GRUP","C",5,0}) //Поля необходимые для
aadd(aFileStruc,{"NNUM","C",13,0}) //импорта строк
aadd(aFileStruc,{"CODPART_I","C",5,0}) // ТМЦ в модуле
aadd(aFileStruc,{"ED_I","C",5,0}) // "Товары.Готовая продукция"
aadd(aFileStruc,{"KOL_I","N",19,4}) // в программе
aadd(aFileStruc,{"CENA_I","N",19,8}) // БЭСТ4+
aadd(aFileStruc,{"NUMDOC","C",6,0}) //
aadd(aFileStruc,{"E1082","C",6,0}) //Порядковый номер
aadd(aFileStruc,{"VID","C",3,0}) //Тип кода идентификации товара
//SRV=глобальный номер товара GTIN
// в системе EAN.UCC
aadd(aFileStruc,{"CODE","C",14,0}) //GTIN-код товара
aadd(aFileStruc,{"BCODE","C",14,0}) //внутренний код покупателя
aadd(aFileStruc,{"SCODE","C",14,0}) //внутренний код поставщика
aadd(aFileStruc,{"NAME","C",512,0}) //Описание товара
aadd(aFileStruc,{"KOL","N",19,4}) //Заказываемое количество
aadd(aFileStruc,{"INBOX","N",19,4}) //Кол-во в упаковке
aadd(aFileStruc,{"SUMMA","N",19,4}) //Сумма по строке
aadd(aFileStruc,{"E5125","C",3,0}) //Квалификатор цены ААА=цена без налогов
aadd(aFileStruc,{"E5118","C",15,0}) //Цена
// Создаем временные файлы, начальные значения
FOR i:=1 to 3
cInsDBF := TempFile(GlobalTmpPath,"DBF")
AADD(aInsDbf,cInsDbf)
NEXT
n:=0
aDat:={0,' ',0}
DBCREATE(aInsDbf[1],aStr)
NetUseExc('ZAKAZ',aInsDBF[1])
DBCREATE(aInsDbf[2],aStr2)
NetUseExc('PARTY',aInsDBF[2])
DBCREATE(aInsDbf[3],aFileStruc)
NetUseExc('TMC',aInsDBF[3])
//Открываем XML
TRY
oXml := CreateObject("MSXML2.DomDocument.4.0")
CATCH
Alert( "MsXml не доступен!")
RETURN aVal
END
oXml:setProperty("NewParser",.T.)
cOldTrapShift := TRAPSHIFT("")
oXml:async:=.F.
oXml:load(cXml)
// Обработка файла-заявки
busy(.T.,"Загрузка данных")
tables := oXml:selectNodes("/*/*")
ZAKAZ->( ADDREC() )
ZAKAZ->( F_DBUNLOCK() )
FOR i:=0 TO tables:length-1
table:=tables:item(i)
cTable:=table:nodeName
k:=ASCAN(aNodes,cTable)
DO CASE
CASE k>0.AND.k<4
ZAKAZ->( RECLOCK() )
SBORXML(@table,'zakaz',.F.)
ZAKAZ->( F_DBUNLOCK() )
CASE k>3.AND.k<6
PARTY->( ADDREC() )
PARTY->SG:=k-3
SBORXML(@table,'party',.F.)
PARTY->( F_DBUNLOCK() )
CASE k=6
ZAKAZ->( RECLOCK() )
SBORXML(@table,'zakaz',.F.)
ZAKAZ->( F_DBUNLOCK() )
CASE k=7
TMC->( ADDREC() )
TMCWR(@table)
TMC->( F_DBUNLOCK() )
CASE k>7
ZAKAZ->( RECLOCK() )
SBORXML(@table,'zakaz',.F.)
ZAKAZ->( F_DBUNLOCK() )
ENDCASE
NEXT
// В этом месте временные файлы при необходимости можно переименовывать
// или как-то по своему использовать в своих решениях в БЭСТе
// Файл строк ТМС подлежит обработке : необходимо определить группу,номер
// единицу измерения, перенести из соседнего поля кол-во и если надо цену
// Если в поле SCODE группа+номер - то брать оттуда, если штрих-код
// то по индексу поиск в MLABEL по полю в котором этот штрих-код лежит
// и дальше GRUP,NNUM,ED_I заполняем из MLABEL
ZAKAZ->( DBCOMMIT() )
PARTY->( DBCOMMIT() )
TMC->( DBCOMMIT() )
*PARTY->( DBCLOSEAREA() )
*ZAKAZ->( DBCLOSEAREA() )
*TMC->( DBCLOSEAREA() )
RETURN aInsDbf
// Функция сбора данных из узлов с записью во временную БД или массив
FUNCTION SBORXML(xTabl,cAlias,lAr)
// xTabl - узел обрабатываемый
// сAlias - имя алиаса в который пишем
// lAr - пишем в базу с алиасом cAlias либо в массив aTmc
LOCAL i,cTable,cNam,ar
cTable:=xTabl:childnodes()
FOR i:=0 to cTable:length-1
cNam:=cTable:item(i):NodeName
IF LEFT(cNam,1) == 'E'
DO CASE
CASE ASCAN(aField1,cNam)>0.AND.!lAr
(cAlias)->( FIELDPUT(FIELDPOS(cNam),cTable:item(i):ChildNodes():Item(0):NodeValue ) )
CASE ASCAN(aField2,cNam)>0
DATEWR(cNam,cTable:item(i):ChildNodes():Item(0):NodeValue)
CASE lAr
AADD(aTmc,{cNam,ALLTRIM(cTable:item(i):ChildNodes():Item(0):NodeValue)})
OTHERWISE
SayAndWait(cNam)
ENDCASE
ELSE
SBORXML(@cTable:Item(i),cAlias,lAr)
ENDIF
NEXT
RETURN NIL
//Функция записи даты заявки и даты и времени желательной поставки
FUNCTION DATEWR(xNam,xVal)
LOCAL lFlag,dDat,cTime
//xNam - имя узла
//xVal - значение в узле
n++
IF aField2[n]==xNam
lFlag:=.T.
IF n<>2
aDat[n]:=VAL(xVal)
ELSE
aDat[n]:=ALLTRIM(xVal)
ENDIF
ELSE
lFlag:=.F.
n:=0
ENDIF
IF n=3.AND.lFlag
IF aDat[3]=102
dDat:=CTOD(RIGHT(aDat[2],2)+'/'+SUBSTR(aDat[2],5,2)+'/'+LEFT(aDat[2],4))
cTime:=' '
ELSEIF aDat[3]=203
dDat:=CTOD(SUBSTR(aDat[2],7,2)+'/'+SUBSTR(aDat[2],5,2)+'/'+LEFT(aDat[2],4))
cTime:=RIGHT(aDat[2],4)
ELSE
dDat:=CTOD(' / / ')
cTime:=' '
ENDIF
IF aDat[1]=137
ZAKAZ->datdoc:=dDat
ZAKAZ->timedoc:=cTime
ELSEIF aDat[1]=2
ZAKAZ->datpost:=dDat
ZAKAZ->timepost:=cTime
ENDIF
n:=0
ENDIF
RETURN NIL
// Функция записи списка ТМЦ
FUNCTION TMCWR(xTabl)
LOCAL i,cTable,cNam,j,n,cTmc
cTable:=xTabl:childnodes()
FOR i:=0 to cTable:length-1
cNam:=cTable:item(i):NodeName
j:=ASCAN(aField3,cNam)
DO CASE
CASE j=1
SBORXML(@cTable:Item(i),,.T.)
IF aTmc[1,1]=='E1082'.AND.j=1
TMC->E1082:=aTmc[1,2]
ENDIF
IF aTmc[3,1]=='E7143'
TMC->VID:=aTmc[3,2]
TMC->CODE:=aTMC[2,2]
ENDIF
aTmc:={}
CASE j=2
SBORXML(@cTable:Item(i),,.T.)
IF aTmc[3,2]=='IN'
TMC->BCODE:=aTmc[2,2]
ELSEIF aTmc[3,2]=='SA'
TMC->SCODE:=aTmc[2,2]
ENDIF
aTmc:={}
CASE j=3
SBORXML(@cTable:Item(i),,.T.)
cTmc:=""
FOR n=1 TO LEN(aTmc)
IF aTmc[n,1]=='E7008'
cTmc+=aTmc[n,2]
ENDIF
NEXT
IF !EMPTY(cTmc)
TMC->NAME:=AnsiToOem(cTmc)
ENDIF
aTmc:={}
CASE j=4
SBORXML(@cTable:Item(i),,.T.)
IF aTmc[1,1]=='E6063'
DO CASE
CASE VAL(aTmc[1,2])=21.AND.aTmc[2,1]=='E6060'
TMC->KOL:=VAL(aTmc[2,2])
CASE VAL(aTmc[1,2])=59.AND.aTmc[2,1]=='E6060'
TMC->INBOX:=VAL(aTmc[2,2])
ENDCASE
ENDIF
aTmc:={}
CASE j=5
SBORXML(@cTable:Item(i),,.T.)
IF aTmc[1,1]=='E5025'.AND.VAL(aTmc[1,2])=128
IF aTmc[2,1]=='E5004'
TMC->SUMMA:=VAL(aTmc[2,2])
ENDIF
ENDIF
aTmc:={}
CASE j=6
SBORXML(@cTable:Item(i),'TMC',.F.)
ENDCASE
NEXT
RETURN NIL |
|
|