| 18554 |
amit.gupta |
1 |
from datetime import date, datetime, timedelta
|
| 18010 |
manish.sha |
2 |
from elixir import metadata, setup_all, session
|
| 18554 |
amit.gupta |
3 |
from email import encoders
|
|
|
4 |
from email.mime.base import MIMEBase
|
|
|
5 |
from email.mime.multipart import MIMEMultipart
|
|
|
6 |
from email.mime.text import MIMEText
|
| 18010 |
manish.sha |
7 |
from shop2020.clients.CatalogClient import CatalogClient
|
|
|
8 |
from shop2020.clients.InventoryClient import InventoryClient
|
|
|
9 |
from shop2020.clients.TransactionClient import TransactionClient
|
|
|
10 |
from shop2020.purchase.main.model.Invoice import Invoice
|
|
|
11 |
from shop2020.purchase.main.model.LineItem import LineItem
|
|
|
12 |
from shop2020.purchase.main.model.Purchase import Purchase
|
| 18554 |
amit.gupta |
13 |
from shop2020.purchase.main.model.PurchaseOrder import PurchaseOrder
|
| 18010 |
manish.sha |
14 |
from shop2020.purchase.main.model.PurchaseReturn import PurchaseReturn
|
| 18554 |
amit.gupta |
15 |
from shop2020.purchase.main.model.PurchaseReturnSettlement import \
|
|
|
16 |
PurchaseReturnSettlement
|
| 18010 |
manish.sha |
17 |
from shop2020.purchase.main.model.RevisionedPurchaseOrder import \
|
|
|
18 |
RevisionedPurchaseOrder
|
|
|
19 |
from shop2020.purchase.main.model.Supplier import Supplier
|
|
|
20 |
from shop2020.thriftpy.generic.ttypes import ExceptionType
|
|
|
21 |
from shop2020.thriftpy.model.v1.inventory.ttypes import WarehouseType, \
|
|
|
22 |
InventoryType, ItemStockPurchaseParams
|
|
|
23 |
from shop2020.thriftpy.model.v1.order.ttypes import OrderStatus
|
|
|
24 |
from shop2020.thriftpy.purchase.ttypes import PurchaseServiceException, POStatus, \
|
| 18554 |
amit.gupta |
25 |
PurchaseOrder as TPurchaseOrder, LineItem as TLineItem, POType, \
|
| 18010 |
manish.sha |
26 |
PurchaseReturnType, PurchaseReturnInventoryType
|
|
|
27 |
from shop2020.utils.Utils import to_py_date
|
|
|
28 |
from sqlalchemy import create_engine
|
|
|
29 |
from sqlalchemy.sql.expression import or_
|
|
|
30 |
from xlrd import open_workbook
|
|
|
31 |
from xlwt.Workbook import Workbook
|
| 18554 |
amit.gupta |
32 |
import logging
|
| 18010 |
manish.sha |
33 |
import smtplib
|
| 18554 |
amit.gupta |
34 |
import sys
|
| 18010 |
manish.sha |
35 |
import time
|
| 18554 |
amit.gupta |
36 |
import traceback
|
| 18010 |
manish.sha |
37 |
import xlwt
|
|
|
38 |
|
|
|
39 |
|
|
|
40 |
XLS_O_FILENAME = "allPendingPOs.xls"
|
|
|
41 |
SENDER = "adwords@shop2020.in"
|
|
|
42 |
PASSWORD = "adwords_shop2020"
|
|
|
43 |
SUBJECT = "Pending Purchase Order " + date.today().isoformat()
|
|
|
44 |
SMTP_SERVER = "smtp.gmail.com"
|
|
|
45 |
SMTP_PORT = 587
|
|
|
46 |
boldStyle = xlwt.XFStyle()
|
|
|
47 |
f = xlwt.Font()
|
|
|
48 |
f.bold = True
|
|
|
49 |
boldStyle.font = f
|
|
|
50 |
i = -1
|
|
|
51 |
|
|
|
52 |
datetime_format = xlwt.XFStyle()
|
|
|
53 |
datetime_format.num_format_str = 'dd/mm/yyyy HH:MM AM/PM'
|
|
|
54 |
|
|
|
55 |
class PurchaseHandler:
|
|
|
56 |
'''
|
|
|
57 |
classdocs
|
|
|
58 |
'''
|
|
|
59 |
|
|
|
60 |
def __init__(self, dbname='warehouse', db_hostname='localhost', echoOn=True):
|
|
|
61 |
'''
|
|
|
62 |
Constructor
|
|
|
63 |
'''
|
|
|
64 |
engine = create_engine('mysql://root:shop2020@' + db_hostname + '/' + dbname, pool_recycle=7200)
|
|
|
65 |
metadata.bind = engine
|
|
|
66 |
metadata.bind.echo = echoOn
|
|
|
67 |
setup_all(True)
|
|
|
68 |
|
|
|
69 |
def getSuppliers(self,):
|
|
|
70 |
"""
|
|
|
71 |
Returns all the valid suppliers
|
|
|
72 |
"""
|
|
|
73 |
return [Supplier.to_thrift_object(supplier) for supplier in Supplier.query.all()]
|
|
|
74 |
|
|
|
75 |
def getPendingPurchaseOrders(self, warehouseId):
|
|
|
76 |
"""
|
|
|
77 |
Creates purchase order objects from pending orders
|
|
|
78 |
|
|
|
79 |
Parameters:
|
|
|
80 |
- warehouseId
|
|
|
81 |
"""
|
| 18474 |
manish.sha |
82 |
errorsMap={}
|
| 18010 |
manish.sha |
83 |
try:
|
|
|
84 |
purchaseOrders = []
|
|
|
85 |
|
|
|
86 |
transactionClient = TransactionClient().get_client()
|
| 18425 |
manish.sha |
87 |
pending_orders = transactionClient.getOrdersInBatch([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.ACCEPTED, OrderStatus.COD_VERIFICATION_PENDING], 0, 0, warehouseId, 0)
|
| 23124 |
ashik.ali |
88 |
|
|
|
89 |
|
| 18010 |
manish.sha |
90 |
if not pending_orders:
|
| 23124 |
ashik.ali |
91 |
print "pendingOrders empty"
|
| 18474 |
manish.sha |
92 |
return purchaseOrders, errorsMap
|
| 18010 |
manish.sha |
93 |
|
|
|
94 |
inventory_client = InventoryClient().get_client()
|
|
|
95 |
availability = {}
|
| 18425 |
manish.sha |
96 |
virtualInventory = {}
|
| 18010 |
manish.sha |
97 |
|
|
|
98 |
ourGoodWarehouseIds = [w.id for w in inventory_client.getWarehouses(WarehouseType.OURS, InventoryType.GOOD, 0, None, warehouseId)]
|
| 18429 |
manish.sha |
99 |
ourVirtualWarehouseIds = [w.id for w in inventory_client.getWarehouses(WarehouseType.THIRD_PARTY, InventoryType.GOOD, 0, None, None)]
|
| 18010 |
manish.sha |
100 |
itemInventorySnapshot = inventory_client.getInventorySnapshot(0)
|
|
|
101 |
for itemId, itemInventory in itemInventorySnapshot.iteritems():
|
|
|
102 |
'''item = self.__get_item_from_master(itemId)'''
|
|
|
103 |
for warehouseId, quantity in itemInventory.availability.iteritems():
|
|
|
104 |
if warehouseId in ourGoodWarehouseIds:
|
|
|
105 |
if availability.has_key(itemId):
|
|
|
106 |
availability[itemId] = [availability[itemId][0] + quantity]
|
|
|
107 |
else:
|
|
|
108 |
availability[itemId] = [quantity]
|
| 18425 |
manish.sha |
109 |
|
|
|
110 |
if warehouseId in ourVirtualWarehouseIds:
|
|
|
111 |
if virtualInventory.has_key(itemId):
|
|
|
112 |
virtualInventory[itemId] = [virtualInventory[itemId][0] + quantity]
|
|
|
113 |
else:
|
|
|
114 |
virtualInventory[itemId] = [quantity]
|
|
|
115 |
|
| 18010 |
manish.sha |
116 |
previouslyOrderedQty = {}
|
|
|
117 |
unfulfilledPurchaseOrders = PurchaseOrder.query.filter(or_(PurchaseOrder.status == POStatus.PARTIALLY_FULFILLED, PurchaseOrder.status == POStatus.READY)).filter(PurchaseOrder.type == POType.REAL).all()
|
|
|
118 |
for purchaseOrder in unfulfilledPurchaseOrders:
|
|
|
119 |
for lineitem in purchaseOrder.lineitems:
|
|
|
120 |
if previouslyOrderedQty.has_key(lineitem.itemId):
|
|
|
121 |
previouslyOrderedQty[lineitem.itemId] = previouslyOrderedQty[lineitem.itemId] + lineitem.unfulfilledQuantity
|
|
|
122 |
else:
|
|
|
123 |
previouslyOrderedQty[lineitem.itemId] = lineitem.unfulfilledQuantity
|
|
|
124 |
|
|
|
125 |
if availability.has_key(lineitem.itemId):
|
|
|
126 |
availability[lineitem.itemId] = [availability[lineitem.itemId][0] + lineitem.unfulfilledQuantity]
|
|
|
127 |
else:
|
|
|
128 |
'''item = self.__get_item_from_master(lineitem.itemId)'''
|
|
|
129 |
availability[lineitem.itemId] = [lineitem.unfulfilledQuantity]
|
|
|
130 |
|
|
|
131 |
codRequirements = {}
|
|
|
132 |
requirements = {}
|
| 18425 |
manish.sha |
133 |
verificationPendingOrders = {}
|
| 18010 |
manish.sha |
134 |
for order in pending_orders:
|
|
|
135 |
if order.purchaseOrderId:
|
|
|
136 |
continue
|
|
|
137 |
for lineitem in order.lineitems:
|
|
|
138 |
if (requirements.has_key(lineitem.item_id)):
|
| 18425 |
manish.sha |
139 |
requirements[lineitem.item_id] = requirements.get(lineitem.item_id) + lineitem.quantity
|
| 18010 |
manish.sha |
140 |
else:
|
|
|
141 |
requirements[lineitem.item_id] = lineitem.quantity
|
|
|
142 |
|
|
|
143 |
if order.cod:
|
|
|
144 |
if (codRequirements.has_key(lineitem.item_id)):
|
| 18425 |
manish.sha |
145 |
codRequirements[lineitem.item_id] = codRequirements.get(lineitem.item_id) + lineitem.quantity
|
| 18010 |
manish.sha |
146 |
else:
|
|
|
147 |
codRequirements[lineitem.item_id] = lineitem.quantity
|
| 18425 |
manish.sha |
148 |
|
|
|
149 |
if order.status == OrderStatus.COD_VERIFICATION_PENDING:
|
|
|
150 |
if (verificationPendingOrders.has_key(lineitem.item_id)):
|
|
|
151 |
verificationPendingOrders[lineitem.item_id] = verificationPendingOrders.get(lineitem.item_id) + lineitem.quantity
|
|
|
152 |
else:
|
|
|
153 |
verificationPendingOrders[lineitem.item_id] = lineitem.quantity
|
| 18010 |
manish.sha |
154 |
|
|
|
155 |
advancedPOParameters = {}
|
|
|
156 |
SKUListForPO = []
|
|
|
157 |
inventory_client = InventoryClient().get_client()
|
|
|
158 |
itemStockPurchaseParams = inventory_client.getNonZeroItemStockPurchaseParams()
|
|
|
159 |
for itemStockPurchaseParam in itemStockPurchaseParams:
|
|
|
160 |
inventory_client = InventoryClient().get_client()
|
|
|
161 |
oosStatuses = inventory_client.getOosStatusesForXDaysForItem(itemStockPurchaseParam.item_id, 0, 3)
|
|
|
162 |
salesCount = 0
|
|
|
163 |
numDaysInStock = 0
|
|
|
164 |
rtoCount = 0
|
|
|
165 |
avgSales = 0.0
|
| 23241 |
amit.gupta |
166 |
lastXdaysSale =""
|
| 23277 |
amit.gupta |
167 |
oosStatus = None
|
| 18010 |
manish.sha |
168 |
for oosStatus in oosStatuses:
|
|
|
169 |
if oosStatus.is_oos == False:
|
|
|
170 |
salesCount = salesCount + oosStatus.num_orders
|
|
|
171 |
numDaysInStock = numDaysInStock + 1
|
|
|
172 |
lastXdaysSale = lastXdaysSale + str(oosStatus.num_orders) + "-"
|
|
|
173 |
else:
|
|
|
174 |
lastXdaysSale = lastXdaysSale + "X-"
|
| 23241 |
amit.gupta |
175 |
if oosStatus and oosStatus.rto_orders is not None:
|
| 18010 |
manish.sha |
176 |
rtoCount = oosStatus.rto_orders
|
|
|
177 |
lastXdaysSale = lastXdaysSale[:-1]
|
|
|
178 |
if numDaysInStock>0:
|
|
|
179 |
avgSales = float(salesCount)/numDaysInStock
|
|
|
180 |
advancedPOParameters[itemStockPurchaseParam.item_id] = [round(avgSales * itemStockPurchaseParam.numOfDaysStock), round(avgSales,2) , numDaysInStock, itemStockPurchaseParam.minStockLevel, itemStockPurchaseParam.numOfDaysStock, lastXdaysSale, rtoCount]
|
|
|
181 |
if itemInventorySnapshot.has_key(itemStockPurchaseParam.item_id):
|
|
|
182 |
itemAvailability = itemInventorySnapshot.get(itemStockPurchaseParam.item_id)
|
|
|
183 |
currentAvailability = 0
|
|
|
184 |
currentReserved = 0
|
|
|
185 |
for wId, rQty in itemAvailability.reserved.iteritems():
|
|
|
186 |
if wId in ourGoodWarehouseIds:
|
|
|
187 |
currentReserved = currentReserved + rQty
|
|
|
188 |
#Key Condition Added By Manish Sharma
|
|
|
189 |
if availability.has_key(itemStockPurchaseParam.item_id):
|
|
|
190 |
if availability[itemStockPurchaseParam.item_id] is None:
|
|
|
191 |
availability[itemStockPurchaseParam.item_id] = [0]
|
|
|
192 |
else:
|
|
|
193 |
availability[itemStockPurchaseParam.item_id] = [0]
|
|
|
194 |
if (availability[itemStockPurchaseParam.item_id][0] - currentReserved) < max(advancedPOParameters[itemStockPurchaseParam.item_id][0], advancedPOParameters[itemStockPurchaseParam.item_id][3]):
|
|
|
195 |
SKUListForPO.append(itemStockPurchaseParam.item_id)
|
|
|
196 |
else:
|
|
|
197 |
SKUListForPO.append(itemStockPurchaseParam.item_id)
|
|
|
198 |
|
|
|
199 |
for key in requirements:
|
|
|
200 |
if advancedPOParameters.has_key(key):
|
|
|
201 |
continue
|
|
|
202 |
print "Item Id ---", key
|
|
|
203 |
inventory_client = InventoryClient().get_client()
|
|
|
204 |
oosStatuses = inventory_client.getOosStatusesForXDaysForItem(key, 0, 3)
|
|
|
205 |
salesCount = 0
|
|
|
206 |
numDaysInStock = 0
|
|
|
207 |
rtoCount = 0
|
|
|
208 |
avgSales = 0.0
|
|
|
209 |
lastXdaysSale = ""
|
| 23124 |
ashik.ali |
210 |
oosStatus = None
|
| 18010 |
manish.sha |
211 |
for oosStatus in oosStatuses:
|
|
|
212 |
if oosStatus.is_oos == False:
|
|
|
213 |
salesCount = salesCount + oosStatus.num_orders
|
|
|
214 |
numDaysInStock = numDaysInStock + 1
|
|
|
215 |
lastXdaysSale = lastXdaysSale + str(oosStatus.num_orders) + "-"
|
|
|
216 |
else:
|
|
|
217 |
lastXdaysSale = lastXdaysSale + "X-"
|
|
|
218 |
lastXdaysSale = lastXdaysSale[:-1]
|
| 23124 |
ashik.ali |
219 |
if oosStatus and oosStatus.rto_orders:
|
| 18010 |
manish.sha |
220 |
rtoCount = oosStatus.rto_orders
|
|
|
221 |
if numDaysInStock>0:
|
|
|
222 |
avgSales = float(salesCount)/float(numDaysInStock)
|
| 18555 |
amit.gupta |
223 |
itemStockPurchaseParam = None
|
| 18010 |
manish.sha |
224 |
try:
|
|
|
225 |
itemStockPurchaseParam = inventory_client.getItemStockPurchaseParams(key)
|
|
|
226 |
except Exception as e:
|
| 18464 |
manish.sha |
227 |
if errorsMap.has_key(key):
|
|
|
228 |
errorsMap[key] = errorsMap.get(key) + "| Item Stock Purchase Param Missing"
|
|
|
229 |
else:
|
|
|
230 |
errorsMap[key] = "Item Stock Purchase Param Missing "
|
|
|
231 |
continue
|
| 18010 |
manish.sha |
232 |
inventory_client.updateItemStockPurchaseParams(key, 0, 0)
|
|
|
233 |
itemStockPurchaseParam = inventory_client.getItemStockPurchaseParams(key)
|
| 18555 |
amit.gupta |
234 |
|
| 18556 |
amit.gupta |
235 |
if itemStockPurchaseParam.numOfDaysStock is None:
|
| 18555 |
amit.gupta |
236 |
itemStockPurchaseParam.minStockLevel = 0
|
|
|
237 |
itemStockPurchaseParam.numOfDaysStock = 0
|
|
|
238 |
itemStockPurchaseParam.item_id = key
|
|
|
239 |
|
| 18010 |
manish.sha |
240 |
advancedPOParameters[key] = [round(avgSales * itemStockPurchaseParam.numOfDaysStock), round(avgSales,2), numDaysInStock, itemStockPurchaseParam.minStockLevel, itemStockPurchaseParam.numOfDaysStock, lastXdaysSale, rtoCount]
|
|
|
241 |
|
|
|
242 |
cumulativeRequirementsItemIds = list(set(requirements.keys()+SKUListForPO))
|
|
|
243 |
netRequirements = {}
|
|
|
244 |
for itemId in cumulativeRequirementsItemIds:
|
|
|
245 |
print "Item Id for Preferred Vendor", itemId
|
|
|
246 |
requirementsCount = requirements.get(itemId)
|
|
|
247 |
if requirementsCount is None:
|
|
|
248 |
requirementsCount = 0.0
|
|
|
249 |
if availability.has_key(itemId):
|
|
|
250 |
availabilityCount = availability.get(itemId)[0]
|
| 18505 |
manish.sha |
251 |
item = self.get_item_from_master(itemId)
|
| 18010 |
manish.sha |
252 |
if requirementsCount > availabilityCount or itemId in SKUListForPO:
|
|
|
253 |
if item.preferredVendor is None:
|
| 18467 |
manish.sha |
254 |
if errorsMap.has_key(itemId):
|
|
|
255 |
errorsMap[itemId] = errorsMap.get(itemId) + "| Preferred Vendor is Missing"
|
| 18464 |
manish.sha |
256 |
else:
|
| 18467 |
manish.sha |
257 |
errorsMap[itemId] = "Preferred Vendor is Missing "
|
| 18464 |
manish.sha |
258 |
continue
|
| 18010 |
manish.sha |
259 |
if (netRequirements.has_key(item.preferredVendor)):
|
|
|
260 |
netRequirements[item.preferredVendor].append([item, requirementsCount - availabilityCount])
|
|
|
261 |
else:
|
|
|
262 |
netRequirements[item.preferredVendor] = [[item, requirementsCount - availabilityCount]];
|
|
|
263 |
else:
|
| 18505 |
manish.sha |
264 |
item = self.get_item_from_master(itemId)
|
| 18010 |
manish.sha |
265 |
if item.preferredVendor is None:
|
| 18473 |
manish.sha |
266 |
if errorsMap.has_key(itemId):
|
| 18467 |
manish.sha |
267 |
errorsMap[itemId] = errorsMap.get(itemId) + "| Preferred Vendor is Missing"
|
| 18464 |
manish.sha |
268 |
else:
|
| 18467 |
manish.sha |
269 |
errorsMap[itemId] = "Preferred Vendor is Missing "
|
| 18464 |
manish.sha |
270 |
continue
|
| 18010 |
manish.sha |
271 |
if (netRequirements.has_key(item.preferredVendor)):
|
|
|
272 |
netRequirements[item.preferredVendor].append([item, requirementsCount])
|
|
|
273 |
else:
|
|
|
274 |
netRequirements[item.preferredVendor] = [[item, requirementsCount]];
|
|
|
275 |
|
|
|
276 |
if not netRequirements:
|
| 18474 |
manish.sha |
277 |
return purchaseOrders, errorsMap
|
| 18010 |
manish.sha |
278 |
|
|
|
279 |
|
|
|
280 |
suppliersMap = {}
|
|
|
281 |
for supplier in self.getSuppliers():
|
|
|
282 |
suppliersMap[supplier.id] = supplier
|
|
|
283 |
|
|
|
284 |
|
|
|
285 |
for vendorId in netRequirements.keys():
|
|
|
286 |
t_purchase_order = {}
|
|
|
287 |
supplier = suppliersMap.get(vendorId)
|
|
|
288 |
t_purchase_order['SupplierName'] = supplier.name
|
|
|
289 |
t_purchase_order['lineitems']= []
|
|
|
290 |
for key in netRequirements.get(vendorId):
|
|
|
291 |
item = key[0]
|
|
|
292 |
quantity = key[1]
|
|
|
293 |
|
|
|
294 |
t_po_lineitem = {}
|
|
|
295 |
t_po_lineitem['productGroup'] = item.productGroup
|
|
|
296 |
t_po_lineitem['brand'] = item.brand
|
|
|
297 |
t_po_lineitem['modelNumber'] = item.modelNumber
|
|
|
298 |
t_po_lineitem['modelName'] = item.modelName
|
|
|
299 |
t_po_lineitem['color'] = item.color
|
|
|
300 |
t_po_lineitem['itemId'] = item.id
|
|
|
301 |
t_po_lineitem['packQuantity'] = item.packQuantity
|
|
|
302 |
if quantity <0: #TODO Check this logic
|
|
|
303 |
quantity=0
|
|
|
304 |
t_po_lineitem['quantity'] = quantity
|
|
|
305 |
t_po_lineitem['availableQuantity'] = 0
|
|
|
306 |
if availability.has_key(item.id):
|
|
|
307 |
if previouslyOrderedQty.has_key(item.id):
|
|
|
308 |
t_po_lineitem['availableQuantity'] = availability[item.id][0] - previouslyOrderedQty[item.id]
|
|
|
309 |
else:
|
|
|
310 |
t_po_lineitem['availableQuantity'] = availability[item.id][0]
|
|
|
311 |
if requirements.has_key(item.id):
|
|
|
312 |
t_po_lineitem['reservedQuantity'] = requirements[item.id]
|
|
|
313 |
additionalQty = max(advancedPOParameters[item.id][0], advancedPOParameters[item.id][3])
|
|
|
314 |
additionalQty = max(0,(additionalQty - (advancedPOParameters[item.id][6]/2)))
|
|
|
315 |
suggestedQuantity = additionalQty +key[1]
|
|
|
316 |
t_po_lineitem['suggestedQuantity'] = max(0,suggestedQuantity)
|
|
|
317 |
#t_po_lineitem.suggestedQuantity = max(advancedPOParameters[item.id][0], advancedPOParameters[item.id][3]) + key[1]
|
|
|
318 |
t_po_lineitem['avgSales'] = advancedPOParameters[item.id][1]
|
|
|
319 |
t_po_lineitem['numberOfDaysInStock'] = advancedPOParameters[item.id][2]
|
|
|
320 |
t_po_lineitem['minStockLevel'] = advancedPOParameters[item.id][3]
|
|
|
321 |
t_po_lineitem['numberOfDaysStock'] = advancedPOParameters[item.id][4]
|
|
|
322 |
t_po_lineitem['lastXdaysSale'] = advancedPOParameters[item.id][5]
|
|
|
323 |
t_po_lineitem['rtoOrders'] = advancedPOParameters[item.id][6]
|
| 18425 |
manish.sha |
324 |
if verificationPendingOrders.has_key(item.id):
|
|
|
325 |
t_po_lineitem['verificationPending'] = verificationPendingOrders[item.id]
|
|
|
326 |
else:
|
|
|
327 |
t_po_lineitem['verificationPending'] = 0
|
|
|
328 |
|
|
|
329 |
if virtualInventory.has_key(item.id):
|
| 18429 |
manish.sha |
330 |
t_po_lineitem['virtualStock'] = virtualInventory[item.id][0]
|
| 18425 |
manish.sha |
331 |
else:
|
|
|
332 |
t_po_lineitem['virtualStock'] = 0
|
| 18010 |
manish.sha |
333 |
if previouslyOrderedQty.has_key(item.id):
|
|
|
334 |
t_po_lineitem['previouslyOrderedQty'] = previouslyOrderedQty[item.id]
|
|
|
335 |
else:
|
|
|
336 |
t_po_lineitem['previouslyOrderedQty'] = 0
|
|
|
337 |
if codRequirements.has_key(item.id):
|
|
|
338 |
t_po_lineitem['codCount'] = min(codRequirements[item.id], quantity)
|
|
|
339 |
try:
|
|
|
340 |
item_pricing = inventory_client.getItemPricing(item.id, vendorId)
|
|
|
341 |
except Exception as e:
|
| 18467 |
manish.sha |
342 |
if errorsMap.has_key(item.id):
|
|
|
343 |
errorsMap[item.id] = errorsMap.get(item.id) + "| Could not find transfer price for vendor id: " + str(vendorId) +" "
|
| 18464 |
manish.sha |
344 |
else:
|
| 18467 |
manish.sha |
345 |
errorsMap[item.id] = "Could not find transfer price for vendor id: " + str(vendorId) +" "
|
| 18010 |
manish.sha |
346 |
print 'Could not find transfer price for Item id: ' + str(item.id) + ' and vendor id: ' + str(vendorId)
|
|
|
347 |
print e
|
| 18504 |
manish.sha |
348 |
t_po_lineitem['unitPrice'] = item_pricing.transferPrice
|
|
|
349 |
t_po_lineitem['nlc'] = item_pricing.nlc
|
|
|
350 |
t_po_lineitem['mrp'] = item.mrp
|
|
|
351 |
t_purchase_order['lineitems'].append(t_po_lineitem)
|
|
|
352 |
purchaseOrders.append(t_purchase_order)
|
| 18464 |
manish.sha |
353 |
continue
|
| 18010 |
manish.sha |
354 |
t_po_lineitem['unitPrice'] = item_pricing.transferPrice
|
|
|
355 |
t_po_lineitem['nlc'] = item_pricing.nlc
|
|
|
356 |
t_po_lineitem['mrp'] = item.mrp
|
|
|
357 |
t_purchase_order['lineitems'].append(t_po_lineitem)
|
|
|
358 |
purchaseOrders.append(t_purchase_order)
|
| 23124 |
ashik.ali |
359 |
print "errorMap : ", errorsMap
|
| 18474 |
manish.sha |
360 |
return purchaseOrders, errorsMap
|
| 18010 |
manish.sha |
361 |
except Exception as e:
|
| 18554 |
amit.gupta |
362 |
traceback.print_exc()
|
| 18010 |
manish.sha |
363 |
finally:
|
|
|
364 |
self.close_session()
|
|
|
365 |
|
|
|
366 |
def close_session(self):
|
|
|
367 |
if session.is_active:
|
|
|
368 |
print "session is active. closing it."
|
|
|
369 |
session.close()
|
|
|
370 |
|
| 18505 |
manish.sha |
371 |
def get_item_from_master(self, item_id):
|
| 18010 |
manish.sha |
372 |
client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
|
|
|
373 |
return client.getItem(item_id)
|
|
|
374 |
|
|
|
375 |
def inc():
|
|
|
376 |
global i
|
|
|
377 |
i+=1
|
|
|
378 |
return i
|
|
|
379 |
|
|
|
380 |
def sendmail(email, message, title, *varargs):
|
|
|
381 |
if email == "":
|
|
|
382 |
return
|
|
|
383 |
mailServer = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
|
|
|
384 |
mailServer.ehlo()
|
|
|
385 |
mailServer.starttls()
|
|
|
386 |
mailServer.ehlo()
|
|
|
387 |
|
|
|
388 |
# Create the container (outer) email message.
|
|
|
389 |
msg = MIMEMultipart()
|
|
|
390 |
msg['Subject'] = title
|
|
|
391 |
msg.preamble = title
|
|
|
392 |
html_msg = MIMEText(message, 'html')
|
|
|
393 |
msg.attach(html_msg)
|
|
|
394 |
|
|
|
395 |
#snapdeal more to be added here
|
|
|
396 |
for fileName in varargs:
|
|
|
397 |
snapdeal = MIMEBase('application', 'vnd.ms-excel')
|
|
|
398 |
snapdeal.set_payload(file(fileName).read())
|
|
|
399 |
encoders.encode_base64(snapdeal)
|
|
|
400 |
snapdeal.add_header('Content-Disposition', 'attachment;filename=' + fileName)
|
|
|
401 |
msg.attach(snapdeal)
|
|
|
402 |
|
|
|
403 |
|
|
|
404 |
MAILTO = email
|
|
|
405 |
mailServer.login(SENDER, PASSWORD)
|
|
|
406 |
mailServer.sendmail(SENDER, MAILTO, msg.as_string())
|
|
|
407 |
|
|
|
408 |
def main():
|
|
|
409 |
global i
|
|
|
410 |
i = -1
|
|
|
411 |
row = 0
|
|
|
412 |
wb = xlwt.Workbook()
|
|
|
413 |
worksheet = wb.add_sheet("All Pending Purchase Orders")
|
|
|
414 |
worksheet.write(row, inc(), 'Supplier Name', boldStyle)
|
|
|
415 |
worksheet.write(row, inc(), 'Item Id', boldStyle)
|
|
|
416 |
worksheet.write(row, inc(), 'Product Name', boldStyle)
|
|
|
417 |
worksheet.write(row, inc(), 'Quantity', boldStyle)
|
|
|
418 |
worksheet.write(row, inc(), 'COD', boldStyle)
|
|
|
419 |
worksheet.write(row, inc(), 'Prepaid', boldStyle)
|
|
|
420 |
worksheet.write(row, inc(), 'Transfer price', boldStyle)
|
|
|
421 |
worksheet.write(row, inc(), 'Nlc', boldStyle)
|
|
|
422 |
worksheet.write(row, inc(), 'Total amount', boldStyle)
|
| 18016 |
manish.sha |
423 |
worksheet.write(row, inc(), 'Pack Quantity', boldStyle)
|
| 18425 |
manish.sha |
424 |
worksheet.write(row, inc(), 'Available Quantity', boldStyle)
|
| 18427 |
manish.sha |
425 |
worksheet.write(row, inc(), 'Reserved Quantity', boldStyle)
|
| 18425 |
manish.sha |
426 |
worksheet.write(row, inc(), 'Virtual Stock', boldStyle)
|
| 18010 |
manish.sha |
427 |
worksheet.write(row, inc(), 'NetPendingOrderQty', boldStyle)
|
|
|
428 |
worksheet.write(row, inc(), 'PreviouslyOrderedQty', boldStyle)
|
|
|
429 |
worksheet.write(row, inc(), 'AverageSale', boldStyle)
|
|
|
430 |
worksheet.write(row, inc(), 'Pending RTOs', boldStyle)
|
| 18425 |
manish.sha |
431 |
worksheet.write(row, inc(), 'COD Pending Orders', boldStyle)
|
| 18010 |
manish.sha |
432 |
worksheet.write(row, inc(), 'NumDaysStock', boldStyle)
|
|
|
433 |
worksheet.write(row, inc(), 'MinStockReq', boldStyle)
|
|
|
434 |
worksheet.write(row, inc(), 'Additional Qty', boldStyle)
|
| 18464 |
manish.sha |
435 |
worksheet.write(row, inc(), 'Errors', boldStyle)
|
| 18010 |
manish.sha |
436 |
|
|
|
437 |
|
|
|
438 |
purchaseHandler = PurchaseHandler()
|
| 23240 |
amit.gupta |
439 |
pendingPurchaseOrders, errorsMap = purchaseHandler.getPendingPurchaseOrders(7573)
|
| 18475 |
manish.sha |
440 |
print errorsMap
|
| 18010 |
manish.sha |
441 |
print pendingPurchaseOrders
|
| 18504 |
manish.sha |
442 |
|
|
|
443 |
for itemId, error in errorsMap.items():
|
|
|
444 |
row += 1
|
|
|
445 |
i=-1
|
|
|
446 |
worksheet.write(row, inc(), "Not_defined")
|
|
|
447 |
worksheet.write(row, inc(), str(itemId))
|
| 18505 |
manish.sha |
448 |
item = purchaseHandler.get_item_from_master(itemId)
|
| 18506 |
manish.sha |
449 |
worksheet.write(row, inc(), item.brand+" "+item.modelName+" "+item.modelNumber+" "+item.color)
|
| 18504 |
manish.sha |
450 |
worksheet.write(row, inc(), 0)
|
|
|
451 |
|
|
|
452 |
worksheet.write(row, inc(), 0)
|
|
|
453 |
worksheet.write(row, inc(), 0)
|
|
|
454 |
worksheet.write(row, inc(), 0)
|
|
|
455 |
worksheet.write(row, inc(), 0)
|
|
|
456 |
worksheet.write(row, inc(), 0)
|
|
|
457 |
worksheet.write(row, inc(), 0)
|
|
|
458 |
worksheet.write(row, inc(), 0)
|
|
|
459 |
worksheet.write(row, inc(), 0)
|
|
|
460 |
worksheet.write(row, inc(), 0)
|
|
|
461 |
worksheet.write(row, inc(), 0)
|
|
|
462 |
worksheet.write(row, inc(), 0)
|
|
|
463 |
worksheet.write(row, inc(), "Not_defined")
|
|
|
464 |
worksheet.write(row, inc(), 0)
|
|
|
465 |
worksheet.write(row, inc(), 0)
|
|
|
466 |
worksheet.write(row, inc(), 0)
|
|
|
467 |
worksheet.write(row, inc(), 0)
|
|
|
468 |
worksheet.write(row, inc(), 0)
|
|
|
469 |
worksheet.write(row, inc(), error)
|
|
|
470 |
|
| 18010 |
manish.sha |
471 |
for purchaseOrder in pendingPurchaseOrders:
|
|
|
472 |
for lineitem in purchaseOrder.get('lineitems'):
|
|
|
473 |
row += 1
|
|
|
474 |
i=-1
|
|
|
475 |
worksheet.write(row, inc(), purchaseOrder.get('SupplierName'))
|
|
|
476 |
worksheet.write(row, inc(), lineitem.get('itemId'))
|
|
|
477 |
worksheet.write(row, inc(), lineitem.get('brand')+" "+lineitem.get('modelName')+" "+lineitem.get('modelNumber')+" "+lineitem.get('color'))
|
|
|
478 |
worksheet.write(row, inc(), lineitem.get('suggestedQuantity'))
|
|
|
479 |
codCount =0;
|
|
|
480 |
if lineitem.get('codCount') is not None:
|
|
|
481 |
codCount = lineitem.get('codCount')
|
|
|
482 |
worksheet.write(row, inc(), codCount)
|
|
|
483 |
worksheet.write(row, inc(), long(lineitem.get('quantity'))-long(codCount))
|
|
|
484 |
worksheet.write(row, inc(), lineitem.get('unitPrice'))
|
|
|
485 |
worksheet.write(row, inc(), lineitem.get('nlc'))
|
|
|
486 |
worksheet.write(row, inc(), float(lineitem.get('suggestedQuantity')) * float(lineitem.get('unitPrice')))
|
| 18016 |
manish.sha |
487 |
worksheet.write(row, inc(), lineitem.get('packQuantity'))
|
| 18010 |
manish.sha |
488 |
reservedCount = 0
|
|
|
489 |
if lineitem.get('reservedQuantity') is not None:
|
|
|
490 |
reservedCount = lineitem.get('reservedQuantity')
|
| 18425 |
manish.sha |
491 |
worksheet.write(row, inc(), long(lineitem.get('availableQuantity')))
|
| 18427 |
manish.sha |
492 |
worksheet.write(row, inc(), long(reservedCount))
|
| 18425 |
manish.sha |
493 |
worksheet.write(row, inc(), lineitem.get('virtualStock'))
|
|
|
494 |
worksheet.write(row, inc(), long(reservedCount)-long(lineitem.get('availableQuantity')))
|
| 18010 |
manish.sha |
495 |
worksheet.write(row, inc(), lineitem.get('previouslyOrderedQty'))
|
|
|
496 |
worksheet.write(row, inc(), "("+lineitem.get('lastXdaysSale')+")"+str(lineitem.get('avgSales')))
|
|
|
497 |
worksheet.write(row, inc(), lineitem.get('rtoOrders'))
|
| 18425 |
manish.sha |
498 |
worksheet.write(row, inc(), lineitem.get('verificationPending'))
|
| 18010 |
manish.sha |
499 |
worksheet.write(row, inc(), lineitem.get('numberOfDaysStock'))
|
|
|
500 |
worksheet.write(row, inc(), lineitem.get('minStockLevel'))
|
|
|
501 |
|
|
|
502 |
stockThroughAvgSales = float(lineitem.get('avgSales')) * float(lineitem.get('numberOfDaysStock'))
|
|
|
503 |
additionalQty = 0
|
|
|
504 |
if stockThroughAvgSales > float(lineitem.get('minStockLevel')):
|
|
|
505 |
additionalQty = stockThroughAvgSales
|
|
|
506 |
else:
|
|
|
507 |
additionalQty = float(lineitem.get('minStockLevel'))
|
|
|
508 |
|
|
|
509 |
if float(lineitem.get('rtoOrders')) >1:
|
|
|
510 |
additionalQty = additionalQty - (float(lineitem.get('rtoOrders'))/2)
|
|
|
511 |
|
|
|
512 |
if additionalQty<0:
|
|
|
513 |
additionalQty = 0
|
|
|
514 |
worksheet.write(row, inc(), additionalQty)
|
| 18464 |
manish.sha |
515 |
error = "NA"
|
|
|
516 |
if errorsMap.has_key(lineitem.get('itemId')):
|
|
|
517 |
error = errorsMap.get(lineitem.get('itemId'))
|
|
|
518 |
worksheet.write(row, inc(), error)
|
| 18010 |
manish.sha |
519 |
wb.save(XLS_O_FILENAME)
|
|
|
520 |
|
| 23839 |
amit.gupta |
521 |
sendmail(["amit.gupta@shop2020.in", "ritesh.chauhan@shop2020.in", "rahul.kandpal@smartdukaan.com"], "", "All Pending Purchase Orders", XLS_O_FILENAME)
|
| 18010 |
manish.sha |
522 |
#sendmail(["manish.sharma@shop2020.in"], "", "All Pending Purchase Orders", XLS_O_FILENAME)
|
|
|
523 |
|
|
|
524 |
if __name__ == '__main__':
|
|
|
525 |
main()
|