Электронный магазин запчастей SHEL-AUTO.RU на web-сервисах EMEX.RU.
Судя по количеству денег, которые я вижу в базе - это мой самый коммерчески удачный проект за всю историю, через базу прошли заказы на миллионы долларов, несмотря что я ее периодически очищал, чтобы сократить размеры.
Этот проект оттачивался много лет, а потом по непонятным для меня причинам был закрыт заказчиком. Закрыт после доведения всего проекта до совершенства, после вылизывания малейших шероховатостей. Только за последний год существования проекта было добавлено множество фишек:
- Отслеживание товара, удачно заказанного в EMEX, но реально поступившего не в полном объеме.
- Была добавлена возможность скупки оптом мелких разорившихся магазинов.
- Автоматического оприходование товара на склад сканером - //www.vb-net.com/Scaner/Index.htm
- Приходование товара от независимых импортеров - Текстовый загрузчик/конвертер данных с FTP в базу
- Компания могла выступать дилером других компаний, а не только самостоятельно принимать заказы - была добавлена публикация дилерского прайса. Періодична публікація дилерського прайсу.
Проект был идеально вылизан, приносил огромные деньги и ... вдруг закрылся. Я так и не понял почему. Причем расстались мы с владельцем бизнеса отлично, напоследок он мне дал вот такую рекомендацию. Ну вероятно по какой-то причине изменились планы владельца этого бизнеса.
Теперь, когда этот проект никому не нужен, я буду потихоньку показать некоторые его отдельные части, ниже вы видите формы админки.
Этот проект я написал на MVC и он был достаточно крученым. Он базировался на сервисах EMEX.RU
И ниже я покажу один из многих-многих своих модулей общения с сервисом EMEX.
1: Public Class Emex
2:
3: Dim PACKETSIZE As Integer = 20
4:
5: 'State - Текущий статус клиента, он может быть установлен вручную админом
6: 'Status - фактический статус корзины EmexStatus
7:
8: 'State_i State_Name State_Comment
9: '0 Не заказано Товар отобран в корзину, но заказ не оформлен клиентом магазина
10: '1 Заказ принят Заказ принят магазином SHEL
11: '2 Basket Начальное состояние корзины Эмекса
12: '3 Order Состояние корзины Эмекса - офорлен заказ
13: '4 Нет ответа Заказанного товара нет в корзине Эмекса.
14: '5 Заказано Заказ принят корзиной Эмекса (начальное состояние обработки заказа в Emex)
15: '6 В заказе Принято поставщиком, но всё ещё не выкуплено у владельца.
16: '7 Выкуплено Выкуплено Эмексом у поставщика, для последующего поступления на склад.
17: '8 В пути Находится в пути на склад Эмекса
18: '9 Пришло Заказ находится на складе, но все ещё не выдан заказчику.
19: '10 Выдано Финальная стадия для движения товара у Эмекса.
20: '11 Нет в наличии Товара нет в наличии.
21: '12 Ошибка заказа Не удалось добавить товар в корзину Эмекса.
22: '13 Отменено SHEL отменил отправку заказа в корзину Эмекса.
23: '14 Пришло рег Пришло на региональный склад
24: '15 Отправлено ОМСК Выдано региональный склад
25: '16 Ошибка заказа2 Ошибка заказа - 2
26: '17 Ошибка заказа3 Ошибка заказа - 3
27: '18 Ошибка заказа4 Ошибка заказа - 4
28: '19 В корзине Возвращено в корзину потребителя
29: '20 В заказ Обработка данных для выполнения заказа
30: '21 В заказ Отправлено потребителем в заказ и ожидает обработки системой
31: '22 Заморожено Отправка в Эмекс приостановлена до получения оплаты
32: '23 Поступило ОМСК Поступило на склад в ОМСК
33:
34: Function SurveyFilter(RawEmexRows As System.Collections.Generic.List(Of EmexBasket1)) As System.Collections.Generic.List(Of EmexBasket1)
35: Dim EmexRows As New System.Collections.Generic.List(Of EmexBasket1)
36: 'Удалить все записи, где статусы модифицированы вручную
37: For Each One As EmexBasket1 In RawEmexRows
38: If IsDBNull(One.SetManualState) Then
39: 'опрос не производить для состояний (Не заказано, Заказ принят, Ошибка заказа, Нет в наличии, Отменено, Выдано рег)
40: If One.State <> 0 And One.State <> 1 And One.State <> 12 And One.State <> 11 And One.State <> 13 And One.State <> 15 Then
41: EmexRows.Add(One)
42: End If
43: ElseIf One.SetManualState = 0 Then
44: 'опрос не производить для состояний (Не заказано, Заказ принят, Ошибка заказа, Нет в наличии, Отменено, Выдано рег)
45: If One.State <> 0 And One.State <> 1 And One.State <> 12 And One.State <> 11 And One.State <> 13 And One.State <> 15 Then
46: EmexRows.Add(One)
47: End If
48: End If
49: Next
50: Return EmexRows
51: End Function
52:
53: #Region "Обновление State запускается периодически процессом из Global.asax"
54: 'запускается периодически процессом из Global.asax
55: Public Sub RefreshState()
56: Dim db1 As New OmskDataContext
57: Dim EmexRowsRaw As System.Collections.Generic.List(Of EmexBasket1) = DB.AdminReadSavedEmexBastet1(0, db1)
58: Dim EmexRows As System.Collections.Generic.List(Of EmexBasket1)
59: EmexRows = SurveyFilter(EmexRowsRaw)
60: If EmexRows IsNot Nothing Then
61: If EmexRows.Count > 0 Then
62: Dim X As New Emex
63: X.RefreshForEachRowState(db1, EmexRows)
64: End If
65: End If
66: End Sub
67:
68: 'запускается периодически процессом из Global.asax
69: Sub RefreshForEachRowState(db1 As OmskDataContext, EmexRows As System.Collections.Generic.List(Of EmexBasket1))
70: Dim Arr1(EmexRows.Count - 1) As Long
71: Dim Arr2(EmexRows.Count - 1) As Int32
72: For i As Integer = 0 To EmexRows.Count - 1
73: Arr1(i) = EmexRows(i).EmexNum
74: Arr2(i) = EmexRows(i).EmexNum
75: db1.RequestLogs.InsertOnSubmit(New RequestLog With {.CrDate = Now, .id = EmexRows(i).id, .Type = 0})
76: Next
77: db1.SubmitChanges()
78: Try
79: Dim Arr1_1(PACKETSIZE - 1) As Long
80: Dim Arr2_1(PACKETSIZE - 1) As Int32
81: For J As Integer = 0 To ((EmexRows.Count - 1) \ PACKETSIZE) - 1
82: Array.Copy(Arr1, J * PACKETSIZE, Arr1_1, 0, PACKETSIZE)
83: Array.Copy(Arr2, J * PACKETSIZE, Arr2_1, 0, PACKETSIZE)
84: RefreshEmexState100(Arr1_1, Arr2_1, db1, EmexRows)
85: System.Threading.Thread.Sleep(100)
86: Next
87: Dim Reminder As Integer = (EmexRows.Count - 1) Mod PACKETSIZE
88: ReDim Arr1_1(Reminder)
89: ReDim Arr2_1(Reminder)
90: Array.Copy(Arr1, EmexRows.Count - 1 - Reminder, Arr1_1, 0, Reminder + 1)
91: Array.Copy(Arr2, EmexRows.Count - 1 - Reminder, Arr2_1, 0, Reminder + 1)
92: System.Threading.Thread.Sleep(100)
93: RefreshEmexState100(Arr1_1, Arr2_1, db1, EmexRows)
94:
95: Catch ex As Exception
96: db1.TraceAdd("RefreshEmexState Error", ex.Message)
97: End Try
98: End Sub
99:
100: 'запускается периодически процессом из Global.asax
101: Public Sub RefreshEmexState100(Arr1() As Long, Arr2() As Int32, db1 As OmskDataContext, EmexRows As System.Collections.Generic.List(Of EmexBasket1))
102: 'это обработка заказов в корзине, по которым движение не началось
103: Dim EmEx_Basket As New ru.emex.EmEx_Basket.EmEx_Basket
104: Dim XML_Result As String = EmEx_Basket.Basket_ByGlobalId2(Long.Parse(System.Configuration.ConfigurationManager.AppSettings("EmexLogin1")), System.Configuration.ConfigurationManager.AppSettings("EmexPass1"), Arr2, ru.emex.EmEx_Basket.BasketPart.all)
105: If XML_Result <> "" And XML_Result <> "<Basket xmlns=""http://tempuri.org/Basket.xsd"" />" Then
106: 'сначала обработка заказов по которым еще нет движения
107: ProcessBasketResponse2(XML_Result, db1, EmexRows)
108: End If
109: 'это обработка заказов, по которым уже началось движение в Эмексе
110: Dim EmEx_InMotion As New ru.emex.EmExInmotion.EmExInmotion
111: Dim InmotionResult As ru.emex.EmExInmotion.InmConsumer() = EmEx_InMotion.InMotion_Consumer_ByGlobalIdAdv(Long.Parse(System.Configuration.ConfigurationManager.AppSettings("EmexLogin1")), System.Configuration.ConfigurationManager.AppSettings("EmexPass1"), Arr1)
112: If InmotionResult IsNot Nothing Then
113: If InmotionResult.Count > 0 Then
114: For Each One As ru.emex.EmExInmotion.InmConsumer In InmotionResult
115: For Each OneRow As EmexBasket1 In EmexRows
116: If OneRow.id.ToString = One.PotrebitelReference Then
117: 'мои статусы ставятся по таблице State
118: Select Case One.State
119: Case 1 'Принято поставщиком, но всё ещё не выкуплено у владельца.
120: db1.ChangeState(6, OneRow.id)
121: db1.AddLog(OneRow.id, "Emex-RefreshEmexState100", Nothing, 6, Nothing, Nothing)
122: Case 3 'Находится в пути на склад Эмекса
123: db1.ChangeState(8, OneRow.id)
124: db1.AddLog(OneRow.id, "Emex-RefreshEmexState100", Nothing, 8, Nothing, Nothing)
125: Case 4 'Заказ находится на складе Эмекса, но все ещё не выдан заказчику.
126: db1.ChangeState(9, OneRow.id)
127: db1.AddLog(OneRow.id, "Emex-RefreshEmexState100", Nothing, 9, Nothing, Nothing)
128: Case 5 'Заказ выдан заказчику, финальная стадия для движения EmEx.
129: db1.ChangeState(10, OneRow.id)
130: db1.AddLog(OneRow.id, "Emex-RefreshEmexState100", Nothing, 10, Nothing, Nothing)
131: Case 7 'Только для региональных складов. "Пришло".
132: db1.SetRealKol(One.AccPriceOrdPotrRUR, One.AccPriceLastPotrRUR, One.AccQuantity, OneRow.id)
133: db1.ChangeState(14, OneRow.id)
134: db1.AddLog(OneRow.id, "Emex-RefreshEmexState100", Nothing, 14, Nothing, Nothing)
135: Case 8 'Только для региональных складов. "Выдано".
136: db1.ChangeState(15, OneRow.id)
137: db1.AddLog(OneRow.id, "Emex-RefreshEmexState100", Nothing, 15, Nothing, Nothing)
138: Case 10 'В корзине
139: db1.ChangeState(19, OneRow.id)
140: db1.AddLog(OneRow.id, "Emex-RefreshEmexState100", Nothing, 19, Nothing, Nothing)
141: Case 21 'Выкуплено у поставщика, для последующего поступления на склад Эмекса
142: db1.ChangeState(7, OneRow.id)
143: db1.AddLog(OneRow.id, "Emex-RefreshEmexState100", Nothing, 7, Nothing, Nothing)
144: Case 22 'Нет в наличии. Ответ поставщика
145: db1.ChangeState(11, OneRow.id)
146: db1.AddLog(OneRow.id, "Emex-RefreshEmexState100", Nothing, 11, Nothing, Nothing)
147: Case 30 'В заказ
148: db1.ChangeState(20, OneRow.id)
149: db1.AddLog(OneRow.id, "Emex-RefreshEmexState100", Nothing, 20, Nothing, Nothing)
150: Case 32 'В заказ
151: db1.ChangeState(21, OneRow.id)
152: db1.AddLog(OneRow.id, "Emex-RefreshEmexState100", Nothing, 21, Nothing, Nothing)
153: Case Else
154: db1.TraceAdd("RefreshEmexState NewState", One.State)
155: End Select
156: Exit For
157: End If
158: Next
159: Next
160: End If
161: End If
162: End Sub
163:
164: 'запускается периодически процессом из Global.asax
165: Public Sub ProcessBasketResponse2(XMLString1 As String, db1 As OmskDataContext, EmexRows As System.Collections.Generic.List(Of EmexBasket1))
166: Dim XML1 As New System.Xml.XmlDocument
167: XML1.LoadXml(XMLString1)
168: Dim BasketNamespace As System.Xml.XmlNamespaceManager = New System.Xml.XmlNamespaceManager(XML1.NameTable)
169: BasketNamespace.AddNamespace("bk", "http://tempuri.org/Basket.xsd")
170: If XML1.SelectNodes("bk:Basket/bk:Data", BasketNamespace) IsNot Nothing Then
171: If XML1.SelectNodes("bk:Basket/bk:Data", BasketNamespace).Count > 0 Then
172: For Each OneRow As EmexBasket1 In EmexRows
173: For i As Integer = 0 To XML1.SelectNodes("bk:Basket/bk:Data", BasketNamespace).Count - 1
174: Dim CurrentNode As System.Xml.XmlNode = XML1.SelectNodes("bk:Basket/bk:Data", BasketNamespace)(i)
175: If CurrentNode.SelectNodes("bk:Reference", BasketNamespace)(0).InnerText = OneRow.id.ToString Then
176: Select Case CurrentNode.SelectNodes("bk:BasketPart", BasketNamespace)(0).InnerText
177: Case "Basket"
178: db1.ChangeState(2, OneRow.id)
179: db1.AddLog(OneRow.id, "Emex-ProcessBasketResponse2", Nothing, 2, Nothing, Nothing)
180: Case "Order"
181: db1.ChangeState(3, OneRow.id)
182: db1.AddLog(OneRow.id, "Emex-ProcessBasketResponse2", Nothing, 3, Nothing, Nothing)
183: Case Else
184: db1.TraceAdd("ProcessBasketResponse NewState", XMLString1)
185: End Select
186: GoTo NodePtocessed
187: End If
188: Next
189: 'db1.ChangeState(4, OneRow.id)
190: 'db1.AddLog(OneRow.id, "Emex-ProcessBasketResponse2", Nothing, 4, Nothing, Nothing)
191: NodePtocessed:
192: Next
193: End If
194: End If
195: End Sub
196:
197: #End Region
198: 'надстройка над ручным изменением статуса, чтобы форма открывалась быстрее
199: Public Sub RefreshEmexAuto()
200: Dim db1 As New OmskDataContext
201: Try
202: Dim EmexRows As System.Collections.Generic.List(Of EmexBasket1) = DB.AdminReadSavedEmexBastet1(0, db1)
203: If EmexRows IsNot Nothing Then
204: If EmexRows.Count > 0 Then
205: '
206: Dim X As New Emex
207: X.RefreshEmexStatus(db1, EmexRows)
208: '
209: End If
210: End If
211: Catch ex As Exception
212: '
213: End Try
214: End Sub
215:
216: 'отбор записей у которых нет Glogal ID
217: Public Sub GetNothingGlobalIDRows()
218: Dim db1 As New OmskDataContext
219: Dim EmexRows As System.Collections.Generic.List(Of Basket) = (From X In db1.Baskets Take 100 Select X Where X.Archive = 0 And X.EmexNum = 0 Order By X.i Descending).ToList
220: For Each OneRow As Basket In EmexRows
221: GetStatusFromRowID(db1, OneRow)
222: Next
223: End Sub
224:
225:
226: 'опрос корзины Эмекса не по Global_ID а по нашему RowID
227: Sub GetStatusFromRowID(db1 As OmskDataContext, OneRow As Basket)
228: Try
229: Dim EmEx_Basket As New ru.emex.EmEx_NewBasket.EmEx_Basket
230: EmEx_Basket.Timeout = 10000
231: '
232: Dim Result() As ru.emex.EmEx_NewBasket.BasketConsumer
233: Dim DelayCount As Integer = 0
234: While DelayCount <= 10
235: Result = EmEx_Basket.Basket_ByFilterAdv(Long.Parse(System.Configuration.ConfigurationManager.AppSettings("EmexLogin1")), System.Configuration.ConfigurationManager.AppSettings("EmexPass1"), ru.emex.EmEx_NewBasket.BasketPart.all, "Reference==""" & OneRow.id.ToString & """")
236: Threading.Thread.Sleep(300)
237: If Result IsNot Nothing Then
238: If Result.Count > 0 Then
239: 'товар попал в корзину - отмечаем его идентификатор GlobalID (построчно по всем товарам)
240: OneRow.EmexNum = Result(0).GlobalId
241: db1.SubmitChanges()
242: Exit Sub
243: End If
244: End If
245: DelayCount = DelayCount + 1
246: End While
247:
248: Catch ex As Exception
249: db1.TraceAdd("GetStatusFromRowID Error 17C", ex.Message & " " & OneRow.id.ToString)
250: End Try
251:
252: End Sub
253:
254: #Region "Установка Status - фактического статуса корзины EmexStatus (действие по кнопке ОБНОВИТЬ у админа)"
255: 'прочитать состояние заказа - действие по кнопке ОБНОВИТЬ у админа
256: Public Sub RefreshEmexStatus(db1 As OmskDataContext, RawEmexRows As System.Collections.Generic.List(Of EmexBasket1))
257: Dim EmexRows As System.Collections.Generic.List(Of EmexBasket1)
258: EmexRows = SurveyFilter(RawEmexRows)
259: Dim Arr1(EmexRows.Count - 1) As Long
260: Dim Arr2(EmexRows.Count - 1) As Int32
261: For i As Integer = 0 To EmexRows.Count - 1
262: Arr1(i) = EmexRows(i).EmexNum
263: Arr2(i) = EmexRows(i).EmexNum
264: db1.RequestLogs.InsertOnSubmit(New RequestLog With {.CrDate = Now, .id = EmexRows(i).id, .Type = 1})
265: Next
266: db1.SubmitChanges()
267: Try
268: Dim Arr1_1(PACKETSIZE - 1) As Long
269: Dim Arr2_1(PACKETSIZE - 1) As Int32
270: For J As Integer = 0 To ((EmexRows.Count - 1) \ PACKETSIZE) - 1
271: Array.Copy(Arr1, J * PACKETSIZE, Arr1_1, 0, PACKETSIZE)
272: Array.Copy(Arr2, J * PACKETSIZE, Arr2_1, 0, PACKETSIZE)
273: RefreshEmexStatus100(Arr1_1, Arr2_1, db1, EmexRows)
274: System.Threading.Thread.Sleep(100)
275: Next
276: Dim Reminder As Integer = (EmexRows.Count - 1) Mod PACKETSIZE
277: ReDim Arr1_1(Reminder)
278: ReDim Arr2_1(Reminder)
279: Array.Copy(Arr1, EmexRows.Count - 1 - Reminder, Arr1_1, 0, Reminder + 1)
280: Array.Copy(Arr2, EmexRows.Count - 1 - Reminder, Arr2_1, 0, Reminder + 1)
281: System.Threading.Thread.Sleep(100)
282: RefreshEmexStatus100(Arr1_1, Arr2_1, db1, EmexRows)
283: Catch ex As Exception
284: db1.TraceAdd("RefreshEmexStatus Error", ex.Message)
285: End Try
286: End Sub
287:
288:
289: 'в одном запросе не более 100 GlobalID - действие по кнопке ОБНОВИТЬ у админа
290: Sub RefreshEmexStatus100(Arr1() As Long, Arr2() As Int32, db1 As OmskDataContext, EmexRows As System.Collections.Generic.List(Of EmexBasket1))
291: 'это обработка заказов в корзине, по которым движение не началось
292: Dim EmEx_Basket As New ru.emex.EmEx_Basket.EmEx_Basket
293: Dim XML_Result As String = EmEx_Basket.Basket_ByGlobalId2(Long.Parse(System.Configuration.ConfigurationManager.AppSettings("EmexLogin1")), System.Configuration.ConfigurationManager.AppSettings("EmexPass1"), Arr2, ru.emex.EmEx_Basket.BasketPart.all)
294: If XML_Result <> "" And XML_Result <> "<Basket xmlns=""http://tempuri.org/Basket.xsd"" />" Then
295: 'сначала обработка заказов по которым еще нет движения
296: ProcessBasketResponse(XML_Result, db1, EmexRows)
297: End If
298: 'это обработка заказов, по которым уже началось движение в Эмексе
299: Dim EmEx_InMotion As New ru.emex.EmExInmotion.EmExInmotion
300: Dim InmotionResult As ru.emex.EmExInmotion.InmConsumer() = EmEx_InMotion.InMotion_Consumer_ByGlobalIdAdv(Long.Parse(System.Configuration.ConfigurationManager.AppSettings("EmexLogin1")), System.Configuration.ConfigurationManager.AppSettings("EmexPass1"), Arr1)
301: If InmotionResult IsNot Nothing Then
302: If InmotionResult.Count > 0 Then
303: For Each One As ru.emex.EmExInmotion.InmConsumer In InmotionResult
304: For Each OneRow As EmexBasket1 In EmexRows
305: If OneRow.id.ToString = One.PotrebitelReference Then
306: 'мои статусы ставятся по таблице State
307: Select Case One.State
308: Case 1 'Принято поставщиком, но всё ещё не выкуплено у владельца.
309: db1.ChangeEmexStatus(6, OneRow.id)
310: db1.AddLog(OneRow.id, "Emex-RefreshEmexStatus100", Nothing, Nothing, Nothing, 6)
311: Case 3 'Находится в пути на склад Эмекса
312: db1.ChangeEmexStatus(8, OneRow.id)
313: db1.AddLog(OneRow.id, "Emex-RefreshEmexStatus100", Nothing, Nothing, Nothing, 8)
314: Case 4 'Заказ находится на складе Эмекса, но все ещё не выдан заказчику.
315: db1.ChangeEmexStatus(9, OneRow.id)
316: db1.AddLog(OneRow.id, "Emex-RefreshEmexStatus100", Nothing, Nothing, Nothing, 9)
317: Case 5 'Заказ выдан заказчику, финальная стадия для движения EmEx.
318: db1.ChangeEmexStatus(10, OneRow.id)
319: db1.AddLog(OneRow.id, "Emex-RefreshEmexStatus100", Nothing, Nothing, Nothing, 10)
320: Case 7 'Только для региональных складов. "Пришло".
321: db1.SetRealKol(One.AccPriceOrdPotrRUR, One.AccPriceLastPotrRUR, One.AccQuantity, OneRow.id)
322: db1.ChangeEmexStatus(14, OneRow.id)
323: db1.AddLog(OneRow.id, "Emex-RefreshEmexStatus100", Nothing, Nothing, Nothing, 14)
324: Case 8 'Только для региональных складов. "Выдано".
325: db1.ChangeEmexStatus(15, OneRow.id)
326: db1.AddLog(OneRow.id, "Emex-RefreshEmexStatus100", Nothing, Nothing, Nothing, 15)
327: Case 10 'В корзине
328: db1.ChangeEmexStatus(19, OneRow.id)
329: db1.AddLog(OneRow.id, "Emex-RefreshEmexStatus100", Nothing, Nothing, Nothing, 19)
330: Case 21 'Выкуплено у поставщика, для последующего поступления на склад Эмекса
331: db1.ChangeEmexStatus(7, OneRow.id)
332: db1.AddLog(OneRow.id, "Emex-RefreshEmexStatus100", Nothing, Nothing, Nothing, 7)
333: Case 22 'Нет в наличии. Ответ поставщика
334: db1.ChangeEmexStatus(11, OneRow.id)
335: db1.AddLog(OneRow.id, "Emex-RefreshEmexStatus100", Nothing, Nothing, Nothing, 11)
336: Case 30 'В заказ
337: db1.ChangeEmexStatus(20, OneRow.id)
338: db1.AddLog(OneRow.id, "Emex-RefreshEmexStatus100", Nothing, Nothing, Nothing, 20)
339: Case 32 'В заказ
340: db1.ChangeEmexStatus(21, OneRow.id)
341: db1.AddLog(OneRow.id, "Emex-RefreshEmexStatus100", Nothing, Nothing, Nothing, 21)
342: Case Else
343: db1.TraceAdd("RefreshEmexStatus NewStatus", One.State)
344: End Select
345: Exit For
346: End If
347: Next
348: Next
349: End If
350: End If
351: End Sub
352:
353: 'действие по кнопке ОБНОВИТЬ у админа
354: Public Sub ProcessBasketResponse(XMLString1 As String, db1 As OmskDataContext, EmexRows As System.Collections.Generic.List(Of EmexBasket1))
355: Dim XML1 As New System.Xml.XmlDocument
356: XML1.LoadXml(XMLString1)
357: Dim BasketNamespace As System.Xml.XmlNamespaceManager = New System.Xml.XmlNamespaceManager(XML1.NameTable)
358: BasketNamespace.AddNamespace("bk", "http://tempuri.org/Basket.xsd")
359: If XML1.SelectNodes("bk:Basket/bk:Data", BasketNamespace) IsNot Nothing Then
360: If XML1.SelectNodes("bk:Basket/bk:Data", BasketNamespace).Count > 0 Then
361: For Each OneRow As EmexBasket1 In EmexRows
362: For i As Integer = 0 To XML1.SelectNodes("bk:Basket/bk:Data", BasketNamespace).Count - 1
363: Dim CurrentNode As System.Xml.XmlNode = XML1.SelectNodes("bk:Basket/bk:Data", BasketNamespace)(i)
364: If CurrentNode.SelectNodes("bk:Reference", BasketNamespace)(0).InnerText = OneRow.id.ToString Then
365: Select Case CurrentNode.SelectNodes("bk:BasketPart", BasketNamespace)(0).InnerText
366: Case "Basket"
367: db1.ChangeEmexStatus(2, OneRow.id)
368: db1.AddLog(OneRow.id, "Emex-ProcessBasketResponse", Nothing, Nothing, Nothing, 2)
369: Case "Order"
370: db1.ChangeEmexStatus(3, OneRow.id)
371: db1.AddLog(OneRow.id, "Emex-ProcessBasketResponse", Nothing, Nothing, Nothing, 3)
372: Case Else
373: db1.TraceAdd("ProcessBasketResponse NewStatus", XMLString1)
374: End Select
375: GoTo NodePtocessed
376: End If
377: Next
378: 'db1.ChangeEmexStatus(4, OneRow.id)
379: 'db1.AddLog(OneRow.id, "Emex-ProcessBasketResponse", Nothing, Nothing, Nothing, 4)
380: NodePtocessed:
381: Next
382: End If
383: End If
384: End Sub
385: #End Region
386:
387:
388: 'отправка одного товара в корзину асинхронно
389: Public Sub SendToBasket(db1 As OmskDataContext, OneRow As Basket)
390: Dim EmEx_Basket As New ru.emex.EmEx_NewBasket.EmEx_Basket
391: EmEx_Basket.Timeout = 10000
392: '
393: Dim Num As Integer = 0
394: Dim ePrices(1) As ru.emex.EmEx_NewBasket.EPrice
395: '
396: Dim KeyStr As String = OneRow.Keys
397: Dim Key() As String = KeyStr.Split("~|~")
398:
399: 'журнал
400: Dim XML1 As String
401: XML1 = "<Data>" & _
402: "<Num>" & Num & "</Num>" & _
403: "<MLogo>" & Key(20) & "</MLogo>" & _
404: "<DNum>" & Key(2) & "</DNum>" & _
405: "<Name>" & Key(4) & "</Name>" & _
406: "<Quan>" & OneRow.Kol & "</Quan>" & _
407: "<Price>" & Key(6) & "</Price>" & _
408: "<PLogo>" & Key(12) & "</PLogo>" & _
409: "<DLogo>" & Key(18) & "</DLogo>" & _
410: "<DeliveryRegionType>PRI</DeliveryRegionType>" & _
411: "<Ref>" & OneRow.id.ToString & "</Ref>" & _
412: "<Com>" & OneRow.Comment & "</Com>" & _
413: "<Notc></Notc>" & _
414: "</Data>"
415: '
416: 'Num - номер по порядку
417: 'MLogo - лого изготовителя
418: 'DNum - уникальный номер детали
419: 'Name - наименование детали русское
420: 'Quan - количество деталей
421: 'Price - цена рублевая
422: 'PLogo - лого прайса детали
423: 'DLogo - лого доставки
424: 'DeliveryRegionType - тип доставки по региону. Если этот элемент не задан, то сохраняется значение PRI
425: 'Ref - поле reference
426: 'Com - поле комментария. Также в этом поле можно задавать разрешенные признаки детали. Вводить их в любом порядке, через пробел. Например BRAND ONLY
427: 'Notc - признак безналичной оплаты
428: '
429: ePrices(0) = New ru.emex.EmEx_NewBasket.EPrice
430: ePrices(0).Num = Num
431: ePrices(0).Ref = OneRow.id.ToString
432: ePrices(0).Com = OneRow.Comment
433: ePrices(0).Name = Key(4)
434: ePrices(0).Price = Key(6)
435: ePrices(0).DNum = Key(2)
436: ePrices(0).DLogo = Key(18)
437: ePrices(0).MLogo = Key(20)
438: ePrices(0).PLogo = Key(12)
439: ePrices(0).Quan = OneRow.Kol
440: 'ePrices.DeliveryRegionType
441: 'ePrices.Notc
442: '
443: 'выполнили общий учет запроса
444: db1.TraceAdd("InsertToBasket2Async RequestA", XML1)
445: '
446: OneRow.State = 5
447: db1.AddLog(OneRow.id, "Emex-SendToBasketA2AsyncA", Nothing, 5, Nothing, Nothing)
448: '
449: 'теперь собственно запрос на помещение в корзину и учет ответа
450: Try
451: EmEx_Basket.InsertToBasket2Async(Long.Parse(System.Configuration.ConfigurationManager.AppSettings("EmexLogin1")), System.Configuration.ConfigurationManager.AppSettings("EmexPass1"), ePrices)
452: '
453: Catch ex As Exception
454: OneRow.State = 18
455: db1.AddLog(OneRow.id, "Emex-SendToBasket-Err1A", Nothing, 18, Nothing, Nothing)
456: db1.TraceAdd("InsertToBasket2Async Error1A", ex.Message)
457: OneRow.EmexBasketError = ex.Message
458: db1.SubmitChanges()
459: End Try
460: '
461: 'построчный учет ответа по каждому товару
462: '
463: Try
464: Dim Result() As ru.emex.EmEx_NewBasket.BasketConsumer
465: Dim DelayCount As Integer = 0
466: While DelayCount <= 10
467: Result = EmEx_Basket.Basket_ByFilterAdv(Long.Parse(System.Configuration.ConfigurationManager.AppSettings("EmexLogin1")), System.Configuration.ConfigurationManager.AppSettings("EmexPass1"), ru.emex.EmEx_NewBasket.BasketPart.all, "Reference==""" & OneRow.id.ToString & """")
468: Threading.Thread.Sleep(300)
469: If Result IsNot Nothing Then
470: If Result.Count > 0 Then
471: 'товар попал в корзину - отмечаем его идентификатор GlobalID (построчно по всем товарам)
472: OneRow.EmexNum = Result(0).GlobalId
473: GoTo Ok1
474: End If
475: End If
476: DelayCount = DelayCount + 1
477: End While
478: '
479: OneRow.State = 12
480: db1.AddLog(OneRow.id, "Emex-SendToBasket-Err2A", Nothing, 12, Nothing, Nothing)
481: db1.TraceAdd("InsertToBasket2Async Error 12A", OneRow.id.ToString)
482: '
483: 'If Not XML_Result.ToString.Contains("<GlobalId />") Then
484: ' Dim GlobalID As String = ""
485: ' GlobalID = Emex.GetGlobalID_1(XML_Result)
486: ' If GlobalID <> "" Then
487: ' 'товар попал в корзину - отмечаем его идентификатор GlobalID (построчно по всем товарам)
488: ' OneRow.EmexNum = GlobalID
489: ' Else
490: ' OneRow.State = 12
491: ' db1.AddLog(OneRow.id, "Emex-SendToBasketA", Nothing, 12, Nothing, Nothing)
492: ' db1.TraceAdd("InsertToBasket Error 12A", XML_Result)
493: ' End If
494: 'Else
495: ' OneRow.State = 16
496: ' db1.AddLog(OneRow.id, "Emex-SendToBasketA", Nothing, 16, Nothing, Nothing)
497: 'End If
498: '
499: Ok1:
500: db1.SubmitChanges()
501:
502: '
503: Catch ex As Exception
504: OneRow.State = 17
505: db1.AddLog(OneRow.id, "Emex-SendToBasket-Err3A", Nothing, 17, Nothing, Nothing)
506: db1.TraceAdd("InsertToBasket2Async Error 17A", ex.Message & " " & OneRow.id.ToString)
507: OneRow.EmexBasketError = ex.Message
508: db1.SubmitChanges()
509: End Try
510:
511: End Sub
512:
513:
514: ''' <summary>
515: ''' Ответ сервиса на помещение в корзину
516: ''' </summary>
517: Public Shared Function GetGlobalID_1(ByVal XML_Result As String) As String
518: Dim GlobalID As String = ""
519: Dim Xml1 As New System.Xml.XmlDocument
520: Dim X_GlobalID As System.Xml.XmlNode
521: Try
522: Dim Mem As New IO.StringReader(XML_Result)
523: Xml1.Load(Mem)
524: X_GlobalID = Xml1.SelectNodes("DocumentElement/Data/GlobalId")(0)
525: GlobalID = X_GlobalID.InnerText
526: Return GlobalID
527: Catch ex As Exception
528: 'Lerr1.Text = ex.Message.Replace("<", "<").Replace(">", ">")
529: Return ""
530: End Try
531: '<DocumentElement>
532: '<Data>
533: '<Num>3</Num>
534: '<GlobalId />
535: '<Comment>Неправильный прайс. </Comment>
536: '</Data>
537: '</DocumentElement>
538: '
539: '<DocumentElement>
540: '<Data>
541: '<Num>3</Num>
542: '<GlobalId>10274508</GlobalId>
543: '<Comment />
544: '</Data>
545: '</DocumentElement>
546: End Function
547:
548: ''' <summary>
549: ''' Ответ сервиса на обзор корзины
550: ''' </summary>
551: Function GetGlobalID_2(ByVal XML_Result As String) As Collections.ArrayList
552: Dim GlobalID As New Collections.ArrayList
553: Dim Xml1 As New System.Xml.XmlDocument
554: Try
555: Dim Mem As New IO.StringReader(XML_Result)
556: Xml1.Load(Mem)
557: Dim BasketNamespace As System.Xml.XmlNamespaceManager = New System.Xml.XmlNamespaceManager(Xml1.NameTable)
558: BasketNamespace.AddNamespace("bk", "http://tempuri.org/Basket.xsd")
559: If Xml1.SelectNodes("bk:Basket/bk:Data/bk:GlobalId", BasketNamespace) IsNot Nothing Then
560: If Xml1.SelectNodes("bk:Basket/bk:Data/bk:GlobalId", BasketNamespace).Count > 0 Then
561: For i As Integer = 0 To Xml1.SelectNodes("bk:Basket/bk:Data/bk:GlobalId", BasketNamespace).Count - 1
562: GlobalID.Add(Xml1.SelectNodes("bk:Basket/bk:Data/bk:GlobalId", BasketNamespace)(i).InnerText)
563: Next
564: End If
565: End If
566: Return GlobalID
567: Catch ex As Exception
568: 'Lerr1.Text = ex.Message.Replace("<", "<").Replace(">", ">")
569: End Try
570:
571: '<Basket xmlns="http://tempuri.org/Basket.xsd">
572: ' <Data>
573: ' <GlobalId>10340377</GlobalId>
574: ' <timestamp>AAAAAAzy3hg=</timestamp>
575: ' <BasketAddDate>2010-08-24T19:17:48.273</BasketAddDate>
576: ' <OptovikComments></OptovikComments>
577: ' <OptovikReference>С/б передн рычага G2/PASS -88</OptovikReference>
578: ' <PotrebitelId>-1</PotrebitelId>
579: ' <PotrebitelReference></PotrebitelReference>
580: ' <DetailNameRusUser>С/Б ПЕРЕДН РЫЧАГА G2/PASS -88</DetailNameRusUser>
581: ' <MakeName>FEBI</MakeName>
582: ' <MakeLogo>FB</MakeLogo>
583: ' <DetailNum>07856</DetailNum>
584: ' <PriceLogo>VINC</PriceLogo>
585: ' <DestinationLogo>AFL</DestinationLogo>
586: ' <DetailQuantity>1</DetailQuantity>
587: ' <PricePotrPrevRUR>0.0000</PricePotrPrevRUR>
588: ' <PricePotrOrderRUR>0.0000</PricePotrOrderRUR>
589: ' <PricePotrDiffRUR>0.0000</PricePotrDiffRUR>
590: ' <PriceOptovPrevRUR>76.5600</PriceOptovPrevRUR>
591: ' <PriceOptovOrderRUR>76.5600</PriceOptovOrderRUR>
592: ' <PriceOptovDiffRUR>0.0000</PriceOptovDiffRUR>
593: ' <PriceOptovProfitRUR>0</PriceOptovProfitRUR>
594: ' <StatusCode>20</StatusCode>
595: ' <StatusDate>2010-08-24T19:17:48.273</StatusDate>
596: ' <StatusComments>Деталь добавлена в корзину</StatusComments>
597: ' <StatusUserId>30462</StatusUserId>
598: ' <bitComments> </bitComments>
599: ' <bitONLY>false</bitONLY>
600: ' <bitQUAN>false</bitQUAN>
601: ' <bitUNIT>false</bitUNIT>
602: ' <bitAGRE>false</bitAGRE>
603: ' <bitNOTC>false</bitNOTC>
604: ' <bitWAITSTOC>false</bitWAITSTOC>
605: ' <bitWAIT>false</bitWAIT>
606: ' <bitBRAND>false</bitBRAND>
607: ' <DeliverTimeAverage>2</DeliverTimeAverage>
608: ' <DeliverTimeGuaranteed>4</DeliverTimeGuaranteed>
609: ' <DeliveredInTimePercent>0.0000000000000</DeliveredInTimePercent>
610: ' <PotrebitelName>Иванова И.</PotrebitelName>
611: ' <PotrebitelLogo>KDEC</PotrebitelLogo>
612: ' <BasketPart>Basket</BasketPart>
613: ' <StatusCommentsDict>Добавлено в корзину оптовика.</StatusCommentsDict>
614: ' <CalcCustomerName>KDEC Иванова И.</CalcCustomerName>
615: ' <Reference>С/б передн рычага G2/PASS -88</Reference>
616: ' </Data>
617: '</Basket>
618: ''
619: End Function
620:
621:
622: '<Basket xmlns="http://tempuri.org/Basket.xsd">
623: ' <Data>
624: ' <GlobalId>32889802</GlobalId>
625: ' <timestamp>AAAAADB2w10=</timestamp>
626: ' <BasketAddDate>2012-07-06T19:24:34.08</BasketAddDate>
627: ' <PotrebitelReference>360c189f-a270-41c9-a00b-c1b0372b699d</PotrebitelReference>
628: ' <DetailNameRusUser></DetailNameRusUser>
629: ' <MakeName>Harley Davidson</MakeName>
630: ' <MakeLogo>HD</MakeLogo>
631: ' <DetailNum>11111</DetailNum>
632: ' <PriceLogo>USAG</PriceLogo>
633: ' <DestinationLogo>CRG</DestinationLogo>
634: ' <DetailQuantity>1</DetailQuantity>
635: ' <PricePotrPrevRUR>39.9600</PricePotrPrevRUR>
636: ' <PricePotrOrderRUR>39.9600</PricePotrOrderRUR>
637: ' <PricePotrDiffRUR>0.0000</PricePotrDiffRUR>
638: ' <StatusCode>10</StatusCode>
639: ' <StatusDate>2012-07-06T19:24:34.08</StatusDate>
640: ' <StatusComments>Деталь добавлена в корзину</StatusComments>
641: ' <StatusUserId>92223</StatusUserId>
642: ' <bitComments> </bitComments>
643: ' <bitONLY>false</bitONLY>
644: ' <bitQUAN>false</bitQUAN>
645: ' <bitUNIT>false</bitUNIT>
646: ' <bitAGRE>false</bitAGRE>
647: ' <bitNOTC>false</bitNOTC>
648: ' <bitWAITSTOC>false</bitWAITSTOC>
649: ' <bitWAIT>false</bitWAIT>
650: ' <bitBRAND>false</bitBRAND>
651: ' <DeliverTimeAverage>14</DeliverTimeAverage>
652: ' <DeliverTimeGuaranteed>50</DeliverTimeGuaranteed>
653: ' <DeliveredInTimePercent>0.0000000000000</DeliveredInTimePercent>
654: ' <BasketPart>Basket</BasketPart>
655: ' <StatusCommentsDict>Возвращено в корзину потребителя.</StatusCommentsDict>
656: ' <CalcCustomerName></CalcCustomerName>
657: ' <Reference>360c189f-a270-41c9-a00b-c1b0372b699d</Reference>
658: ' </Data>
659: ' <Data>
660: ' ...
661: ' </Data>
662: '</Basket>
663: End Class
664:
Проект был достаточно крученый, вы можете это увидеть даже по нестандартному усложненному роутингу URL и количеству форм.
Ну, пожалуй, покажу вам еще один какой-нибудь свой контрольчик для этого проекта.
1: <%@ Control Language="VB" Inherits="System.Web.Mvc.ViewUserControl (Of OMSK1.WrapperEmex)" %>
2:
3:
4: <tr id='<%:"emex_" & Model.i %>' bgcolor="#C4C4C4" align="center" style="font-size: 11;">
5: <td><%: Model.i + 1%></td>
6: <td>
7: <%-- <%= Model.Current.MakeName%>--%>
8: <% If model.Previous.MakeName <> Model.Current.MakeName Then%>
9: <%= Model.Current.MakeName%>
10: <%End If%>
11: </td>
12: <td>
13: <b>
14: <%-- <%= Model.Current.DetailNum%></b> <font size="1" style="color: #FFFFFF; text-decoration: none;"><%= Model.Current.GroupId%></font><br />--%>
15: <% If model.Previous.DetailNum <> Model.Current.DetailNum Or model.Previous.MakeName <> Model.Current.MakeName Then%>
16: <%= Model.Current.DetailNum%></b> <br />
17: <%--<font size="1" style="color: #FFFFFF; text-decoration: none;">[<%= Model.Current.GroupId%>]</font>--%>
18: <%End If%>
19: </td>
20: <td>
21: <%-- <%= Model.Current.DetailNameRus%> <font size="1" style="color: #FFFFFF; text-decoration: none;">(<%= Model.Current.PriceGroup.ToString%>)</font><br /> --%>
22: <% If model.Previous.DetailNameRus <> Model.Current.DetailNameRus Or model.Previous.MakeName <> Model.Current.MakeName Or model.Previous.PriceGroup <> Model.Current.PriceGroup Or model.Previous.DetailNum <> Model.Current.DetailNum Then%>
23: <%= Model.Current.DetailNameRus%> <br />
24: <font size="1" style="color: #FFFFFF; text-decoration: none;">(<%= OMSK1.GlobalFunction.GetRusNameForPriceGroup(Model.Current.PriceGroup.ToString)%>)</font>
25: <%End If%>
26:
27: </td>
28: <td>
29: <b>
30: <%: OMSK1.GlobalFunction.GetEmexResultCostWithMargin(Model.Current.ResultPrice).ToString("N2", Globalization.CultureInfo.CreateSpecificCulture("ru-RU"))%>
31: </b>
32: </td>
33: <td>
34: <%If Model.Current.Quantity IsNot Nothing Then%>
35: <%: Model.Current.Quantity.ToString%>
36: <%End If%>
37: </td>
38: <td>
39: <%: Model.Current.PriceCountry%>
40: <br>
41: <font size="1" style="color: #FFFFFF; text-decoration: none;"> <%: Model.Current.PriceLogo%></font>
42: </td>
43: <td>
44: <%= Model.Current.ADDays%>(<%: Model.Current.DeliverTimeGuaranteed%>)<br /><font size="1" style="color: #FFFFFF; text-decoration: none;"><%: CInt(Model.Current.DDPercent).ToString & "%"%></font>
45: </td>
46: <td>
47: <% Dim FullName As String%>
48: <%If Model.Current.Quantity IsNot Nothing Then%>
49: <%Fullname = Server.HtmlEncode(Model.Current.MakeName & "~|~" & Model.Current.DetailNum & "~|~" & Model.Current.DetailNameRus & "~|~" & Model.Current.ResultPrice.ToString("N2") & "~|~" & Model.Current.Quantity.ToString & "~|~" & Model.Current.PriceCountry & "~|~" & Model.Current.PriceLogo & "~|~" & Model.Current.ADDays & "~|~" & Model.Current.DeliverTimeGuaranteed & "~|~" & Model.Current.DestinationLogo & "~|~" & Model.Current.MakeLogo)%>
50: <%Else%>
51: <%FullName = Server.HtmlEncode(Model.Current.MakeName & "~|~" & Model.Current.DetailNum & "~|~" & Model.Current.DetailNameRus & "~|~" & Model.Current.ResultPrice.ToString("N2") & "~|~" & "" & "~|~" & Model.Current.PriceCountry & "~|~" & Model.Current.PriceLogo & "~|~" & Model.Current.ADDays & "~|~" & Model.Current.DeliverTimeGuaranteed & "~|~" & Model.Current.DestinationLogo & "~|~" & Model.Current.MakeLogo)%>
52: <%End If%>
53: <%: Html.TextBox(FullName, 0, New With {.size = 1})%>
54: <img width="3" height="0" src="../../Image/p.gif" />
55: <input type="submit" value="" style="background-image: url('../../Image/basket.gif');
56: width: 17; height: 16; background-repeat: no-repeat; background-color: #C4C4C4;
57: cursor: pointer; border-style: none; border-width: 0;" />
58: </td>
59: </tr>
60:
|