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