Subversion Repositories SmartDukaan

Rev

Rev 18426 | Rev 21619 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4503 mandeep.dh 1
'''
2
Created on 29-Jul-2011
3
 
4
@author: Chandranshu
5
'''
6
from elixir import metadata, setup_all, session
4754 mandeep.dh 7
from shop2020.clients.CatalogClient import CatalogClient
5944 mandeep.dh 8
from shop2020.clients.InventoryClient import InventoryClient
4754 mandeep.dh 9
from shop2020.clients.TransactionClient import TransactionClient
5443 mandeep.dh 10
from shop2020.purchase.main.model.Invoice import Invoice
4503 mandeep.dh 11
from shop2020.purchase.main.model.LineItem import LineItem
12
from shop2020.purchase.main.model.Purchase import Purchase
6467 amar.kumar 13
from shop2020.purchase.main.model.PurchaseReturn import PurchaseReturn
13600 manish.sha 14
from shop2020.purchase.main.model.PurchaseReturnSettlement import PurchaseReturnSettlement
5110 mandeep.dh 15
from shop2020.purchase.main.model.RevisionedPurchaseOrder import \
16
    RevisionedPurchaseOrder
4503 mandeep.dh 17
from shop2020.purchase.main.model.Supplier import Supplier
6762 amar.kumar 18
from shop2020.purchase.main.model.PurchaseOrder import PurchaseOrder
5768 mandeep.dh 19
from shop2020.thriftpy.generic.ttypes import ExceptionType
5944 mandeep.dh 20
from shop2020.thriftpy.model.v1.inventory.ttypes import WarehouseType, \
6832 amar.kumar 21
    InventoryType, ItemStockPurchaseParams
4754 mandeep.dh 22
from shop2020.thriftpy.model.v1.order.ttypes import OrderStatus
23
from shop2020.thriftpy.purchase.ttypes import PurchaseServiceException, POStatus, \
6821 amar.kumar 24
    PurchaseOrder as TPurchaseOrder, LineItem as TLineItem, POType,\
10864 manish.sha 25
    PurchaseReturnType, PurchaseReturnInventoryType
5443 mandeep.dh 26
from shop2020.utils.Utils import to_py_date
4503 mandeep.dh 27
from sqlalchemy import create_engine
5238 mandeep.dh 28
from sqlalchemy.sql.expression import or_
4503 mandeep.dh 29
import datetime
30
import logging
4754 mandeep.dh 31
import sys
4503 mandeep.dh 32
 
33
 
34
logging.basicConfig(level=logging.DEBUG)
35
 
36
class PurchaseServiceHandler:
37
    '''
38
    classdocs
39
    '''
40
 
41
    def __init__(self, dbname='warehouse', db_hostname='localhost',  echoOn=True):
42
        '''
43
        Constructor
44
        '''
45
        engine = create_engine('mysql://root:shop2020@' + db_hostname + '/' + dbname, pool_recycle=7200)
46
        metadata.bind = engine
47
        metadata.bind.echo = echoOn
48
        setup_all(True)
49
 
6762 amar.kumar 50
    def getPOforOurExternalBilling(self):
51
        todayDate = datetime.datetime.now()
52
        todayDate = todayDate.replace(hour=0) 
6821 amar.kumar 53
        purchaseOrder = PurchaseOrder.query.filter(PurchaseOrder.supplierId == 1).filter(PurchaseOrder.createdAt > todayDate).filter(PurchaseOrder.type == POType.VIRTUAL).first()
6762 amar.kumar 54
        if purchaseOrder is None:
55
            t_purchaseOrder = TPurchaseOrder()
56
            t_purchaseOrder.supplierId = 1
57
            t_purchaseOrder.createdAt = datetime.datetime.now()
58
            t_purchaseOrder.status = 0
59
            t_purchaseOrder.totalCost = 0
8716 amar.kumar 60
            t_purchaseOrder.warehouseId = 9
6762 amar.kumar 61
            t_purchaseOrder.poNumber = 'Ours-Ext-' + str(todayDate.year) + "-" + str(todayDate.month) + "-" + str(todayDate.day)
6821 amar.kumar 62
            t_purchaseOrder.type = POType.VIRTUAL
6762 amar.kumar 63
            purchaseOrder = PurchaseOrder(t_purchaseOrder)
64
            session.commit()
65
        return purchaseOrder.id    
66
 
7672 rajveer 67
    def updatelineItemforOursExternalBilling(self, poId, itemId, unitPrice, nlc):
6762 amar.kumar 68
        lineItem = LineItem.get_by(purchaseOrder_id=poId, itemId=itemId)
69
        if lineItem is None:
70
            purchaseOrder = PurchaseOrder.get_by(id=poId)
71
            t_lineItem = TLineItem()
72
            t_lineItem.itemId = itemId
73
            t_lineItem.quantity = 1
74
            t_lineItem.unfulfilledQuantity = 1
75
            t_lineItem.createdAt = datetime.datetime.now()
76
            t_lineItem.unitPrice = unitPrice
7672 rajveer 77
            t_lineItem.nlc = nlc
6762 amar.kumar 78
            t_lineItem.fulfilled = False
79
            lineItem = LineItem(purchaseOrder, t_lineItem)
80
        else:
81
            lineItem.quantity = lineItem.quantity + 1
82
            lineItem.fulfilled = False
83
            lineItem.unfulfilledQuantity = lineItem.unfulfilledQuantity + 1
84
        session.commit()
85
 
86
    def receiveinvoiceforOursExternalBilling(self, invoiceNumber):
87
        invoice = Invoice()
88
        invoice.invoiceNumber = invoiceNumber
89
        invoice.date = datetime.datetime.now()
90
        invoice.numItems = 1
91
        invoice.receivedFrom = "Hotspot-Billing"
92
        invoice.supplierId = 1
11219 manish.sha 93
        invoice.invoiceDate = datetime.datetime.now()
6762 amar.kumar 94
        session.commit()
95
 
96
    def createPurchaseforOursExternalBilling(self, poId, invoiceNumber):
97
        purchaseOrder = PurchaseOrder.get_by(id=poId)
98
        purchase = Purchase(purchaseOrder, invoiceNumber, 0)
99
        session.commit()
100
        return purchase.id
101
 
4503 mandeep.dh 102
    def createPurchaseOrder(self, tPurchaseOrder):
103
        """
104
        Creates a purchase order based on the data in the given purchase order object.
105
        This method populates a number of missing fields
106
 
107
        Parameters:
108
         - purchaseOrder
109
        """
110
        try:
111
            purchaseOrder = PurchaseOrder(tPurchaseOrder)
112
            session.commit()
113
            purchaseOrder.set_po_number()
114
            session.commit()
115
            return purchaseOrder.id
116
        finally:
117
            self.close_session()
118
 
119
    def getAllPurchaseOrders(self, status):
120
        """
121
        Returns a list of all the purchase orders in the given state
122
 
123
        Parameters:
124
         - status
125
        """
126
        try:
6821 amar.kumar 127
            pos = PurchaseOrder.query.filter_by(status=status, type=POType.REAL).all()
4503 mandeep.dh 128
            return [po.to_thrift_object() for po in pos ]
129
        finally:
130
            self.close_session()
131
 
132
    def getPurchaseOrder(self, id):
133
        """
134
        Returns the purchase order with the given id. Throws an exception if there is no such purchase order.
135
 
136
        Parameters:
137
         - id
138
        """
139
        try:
140
            purchaseOrder = PurchaseOrder.get_by(id=id)
141
            if not purchaseOrder:
142
                raise PurchaseServiceException(101, "No purchase order can be found with id:" + str(id)) 
143
            return purchaseOrder.to_thrift_object()
144
        finally:
145
            self.close_session()
146
 
147
    def getSupplier(self, id):
148
        """
149
        Returns the supplier with the given order id. Throws an exception if there is no such supplier.
150
 
151
        Parameters:
152
         - id
153
        """
154
        try:
155
            return Supplier.get_by(id=id).to_thrift_object()
156
        finally:
157
            self.close_session()
158
 
11801 manish.sha 159
    def startPurchase(self, purchaseOrderId, invoiceNumber, freightCharges, purchaseComments):
4503 mandeep.dh 160
        """
161
        Creates a purchase for the given purchase order.
162
        Throws an exception if no more purchases are allowed against the given purchase order.
163
 
164
        Parameters:
165
         - purchaseOrderId
166
         - invoiceNumber
167
         - freightCharges
168
        """
169
        try:
6762 amar.kumar 170
            purchase_order = PurchaseOrder.get_by(id=purchaseOrderId)
11801 manish.sha 171
            purchase = Purchase(purchase_order, invoiceNumber, freightCharges, purchaseComments)
4503 mandeep.dh 172
            session.commit()
173
            return purchase.id
174
        finally:
175
            self.close_session()
176
 
177
    def closePurchase(self, purchaseId):
178
        """
179
        Marks a purchase as complete and updates the receivedOn time.
180
        Throws an exception if no such purchase exists.
181
 
182
        Parameters:
183
         - purchaseId
184
        """
185
        try:
186
            purchase = Purchase.get_by(id=purchaseId)
187
            purchase.receivedOn = datetime.datetime.now()
188
            session.commit()
189
        finally:
190
            self.close_session()
191
 
192
    def getAllPurchases(self, purchaseOrderId, open):
193
        """
194
        Returns all open or closed purchases for the given purchase order. Throws an exception if no such purchase order exists
195
 
196
        Parameters:
197
         - purchaseOrderId
198
         - open
199
        """
200
        try:
201
            if open:
6762 amar.kumar 202
                purchases = Purchase.query.filter_by(purchaseOrder_id=purchaseOrderId, receivedOn=None).all()
4503 mandeep.dh 203
            else:
6762 amar.kumar 204
                purchases = Purchase.query.filter_by(purchaseOrder_id=purchaseOrderId).filter(Purchase.receivedOn != None).all()
4503 mandeep.dh 205
 
206
            return [purchase.to_thrift_object() for purchase in purchases]
207
        finally:
208
            self.close_session()
6385 amar.kumar 209
 
210
    def getPurchasesForPO(self, purchaseOrderId):
211
        """
212
        Returns all purchases for the given purchase order. Throws an exception if no such purchase order exists
213
 
214
        Parameters:
215
         - purchaseOrderId
216
         - open
217
        """
218
        try:
6762 amar.kumar 219
            purchases = Purchase.query.filter_by(purchaseOrder_id=purchaseOrderId).all()
6385 amar.kumar 220
            return [purchase.to_thrift_object() for purchase in purchases]
221
        finally:
222
            self.close_session()
4503 mandeep.dh 223
 
6385 amar.kumar 224
 
4555 mandeep.dh 225
    def getPurchaseOrderForPurchase(self, purchaseId):
4503 mandeep.dh 226
        """
4555 mandeep.dh 227
        Returns the purchase order for a given purchase
4503 mandeep.dh 228
 
229
        Parameters:
230
         - purchaseId
231
        """
4555 mandeep.dh 232
        try:
6762 amar.kumar 233
            return self.getPurchaseOrder(Purchase.query.filter_by(id=purchaseId).one().purchaseOrder_id)
4555 mandeep.dh 234
        finally:
235
            self.close_session()
4503 mandeep.dh 236
 
4754 mandeep.dh 237
    def getPendingPurchaseOrders(self, warehouseId):
238
        """
239
        Creates purchase order objects from pending orders
240
 
241
        Parameters:
242
         - warehouseId
243
        """
244
        try:
245
            purchaseOrders = []
246
            if not warehouseId:
247
                raise PurchaseServiceException(101, "bad warehouse id")
248
 
249
            transactionClient = TransactionClient().get_client()
18426 manish.sha 250
            pending_orders = transactionClient.getOrdersInBatch([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.ACCEPTED, OrderStatus.COD_VERIFICATION_PENDING], 0, 0, warehouseId, 0)
4754 mandeep.dh 251
 
252
            if not pending_orders:
253
                return purchaseOrders
254
 
5944 mandeep.dh 255
            inventory_client = InventoryClient().get_client()
4754 mandeep.dh 256
            availability = {}
5110 mandeep.dh 257
 
5944 mandeep.dh 258
            ourGoodWarehouseIds = [w.id for w in inventory_client.getWarehouses(WarehouseType.OURS, InventoryType.GOOD, 0, None, warehouseId)]
259
            itemInventorySnapshot = inventory_client.getInventorySnapshot(0)
260
            for itemId, itemInventory in itemInventorySnapshot.iteritems():
7105 amar.kumar 261
                '''item = self.__get_item_from_master(itemId)'''
5944 mandeep.dh 262
                for warehouseId, quantity in itemInventory.availability.iteritems():
263
                    if warehouseId in ourGoodWarehouseIds:
7105 amar.kumar 264
                        if availability.has_key(itemId):
265
                            availability[itemId] = [availability[itemId][0] + quantity]
5944 mandeep.dh 266
                        else:
7105 amar.kumar 267
                            availability[itemId] = [quantity]
4754 mandeep.dh 268
 
6880 amar.kumar 269
            previouslyOrderedQty = {}
6821 amar.kumar 270
            unfulfilledPurchaseOrders = PurchaseOrder.query.filter(or_(PurchaseOrder.status == POStatus.PARTIALLY_FULFILLED, PurchaseOrder.status == POStatus.READY)).filter(PurchaseOrder.type == POType.REAL).all()
5238 mandeep.dh 271
            for purchaseOrder in unfulfilledPurchaseOrders:
272
                for lineitem in purchaseOrder.lineitems:
6880 amar.kumar 273
                    if previouslyOrderedQty.has_key(lineitem.itemId):
274
                        previouslyOrderedQty[lineitem.itemId] = previouslyOrderedQty[lineitem.itemId] + lineitem.unfulfilledQuantity
275
                    else:
276
                        previouslyOrderedQty[lineitem.itemId] = lineitem.unfulfilledQuantity
277
 
5238 mandeep.dh 278
                    if availability.has_key(lineitem.itemId):
7105 amar.kumar 279
                        availability[lineitem.itemId] = [availability[lineitem.itemId][0] + lineitem.unfulfilledQuantity]
5238 mandeep.dh 280
                    else:
7105 amar.kumar 281
                        '''item = self.__get_item_from_master(lineitem.itemId)'''
7106 amar.kumar 282
                        availability[lineitem.itemId] = [lineitem.unfulfilledQuantity]
5238 mandeep.dh 283
 
4754 mandeep.dh 284
            codRequirements = {}
285
            requirements = {}
286
            for order in pending_orders:
4758 mandeep.dh 287
                if order.purchaseOrderId:
4757 mandeep.dh 288
                    continue
4754 mandeep.dh 289
                for lineitem in order.lineitems:
290
                    if (requirements.has_key(lineitem.item_id)):
291
                        requirements[lineitem.item_id] += lineitem.quantity
292
                    else:
293
                        requirements[lineitem.item_id] = lineitem.quantity
294
 
295
                    if order.cod:
296
                        if (codRequirements.has_key(lineitem.item_id)):
297
                            codRequirements[lineitem.item_id] += lineitem.quantity
298
                        else:
299
                            codRequirements[lineitem.item_id] = lineitem.quantity
6821 amar.kumar 300
 
301
            advancedPOParameters = {}
6857 amar.kumar 302
            SKUListForPO = []
303
            inventory_client = InventoryClient().get_client()
304
            itemStockPurchaseParams = inventory_client.getNonZeroItemStockPurchaseParams()
305
            for itemStockPurchaseParam in itemStockPurchaseParams:
306
                inventory_client = InventoryClient().get_client()
9696 amar.kumar 307
                oosStatuses = inventory_client.getOosStatusesForXDaysForItem(itemStockPurchaseParam.item_id, 0, 3)
6857 amar.kumar 308
                salesCount = 0
309
                numDaysInStock = 0
8182 amar.kumar 310
                rtoCount = 0
6857 amar.kumar 311
                avgSales = 0.0
312
                lastXdaysSale ="" 
313
                for oosStatus in oosStatuses:
314
                    if oosStatus.is_oos == False:
315
                        salesCount = salesCount + oosStatus.num_orders
316
                        numDaysInStock = numDaysInStock + 1
317
                        lastXdaysSale = lastXdaysSale + str(oosStatus.num_orders) + "-" 
318
                    else:
319
                        lastXdaysSale = lastXdaysSale + "X-"
8221 amar.kumar 320
                if oosStatus.rto_orders is not None:
8182 amar.kumar 321
                    rtoCount = oosStatus.rto_orders
6857 amar.kumar 322
                lastXdaysSale = lastXdaysSale[:-1]
323
                if numDaysInStock>0:
324
                    avgSales = float(salesCount)/numDaysInStock
8182 amar.kumar 325
                advancedPOParameters[itemStockPurchaseParam.item_id] = [round(avgSales * itemStockPurchaseParam.numOfDaysStock), round(avgSales,2) , numDaysInStock, itemStockPurchaseParam.minStockLevel, itemStockPurchaseParam.numOfDaysStock, lastXdaysSale, rtoCount]
6857 amar.kumar 326
                if itemInventorySnapshot.has_key(itemStockPurchaseParam.item_id):
327
                    itemAvailability = itemInventorySnapshot.get(itemStockPurchaseParam.item_id)
328
                    currentAvailability = 0
329
                    currentReserved = 0
330
                    for wId, rQty in itemAvailability.reserved.iteritems():
331
                        if wId in ourGoodWarehouseIds:
332
                            currentReserved = currentReserved + rQty
9261 manish.sha 333
                    #Key Condition Added By Manish Sharma        
334
                    if availability.has_key(itemStockPurchaseParam.item_id):
335
                        if availability[itemStockPurchaseParam.item_id] is None:
336
                                availability[itemStockPurchaseParam.item_id] = [0]
337
                    else:
8182 amar.kumar 338
                        availability[itemStockPurchaseParam.item_id] = [0]
9261 manish.sha 339
                    if (availability[itemStockPurchaseParam.item_id][0] - currentReserved) < max(advancedPOParameters[itemStockPurchaseParam.item_id][0], advancedPOParameters[itemStockPurchaseParam.item_id][3]):
6857 amar.kumar 340
                        SKUListForPO.append(itemStockPurchaseParam.item_id)
341
                else:
342
                    SKUListForPO.append(itemStockPurchaseParam.item_id)
343
 
6821 amar.kumar 344
            for key in requirements:
6857 amar.kumar 345
                if advancedPOParameters.has_key(key):
346
                    continue
12175 manish.sha 347
                print "Item Id ---", key
6821 amar.kumar 348
                inventory_client = InventoryClient().get_client()
9696 amar.kumar 349
                oosStatuses = inventory_client.getOosStatusesForXDaysForItem(key, 0, 3)
6821 amar.kumar 350
                salesCount = 0
351
                numDaysInStock = 0
8182 amar.kumar 352
                rtoCount = 0
6857 amar.kumar 353
                avgSales = 0.0
354
                lastXdaysSale = ""
6821 amar.kumar 355
                for oosStatus in oosStatuses:
6832 amar.kumar 356
                    if oosStatus.is_oos == False:
6821 amar.kumar 357
                        salesCount = salesCount + oosStatus.num_orders
358
                        numDaysInStock = numDaysInStock + 1
6857 amar.kumar 359
                        lastXdaysSale = lastXdaysSale + str(oosStatus.num_orders) + "-" 
360
                    else:
361
                        lastXdaysSale = lastXdaysSale + "X-"
8182 amar.kumar 362
                lastXdaysSale = lastXdaysSale[:-1]
363
                if oosStatus.rto_orders:
364
                    rtoCount = oosStatus.rto_orders
6832 amar.kumar 365
                if numDaysInStock>0:
6857 amar.kumar 366
                    avgSales = float(salesCount)/float(numDaysInStock)
18588 manish.sha 367
                itemStockPurchaseParam = None
10864 manish.sha 368
                try:
369
                    itemStockPurchaseParam = inventory_client.getItemStockPurchaseParams(key)
370
                except Exception as e:
371
                    inventory_client.updateItemStockPurchaseParams(key, 0, 0)
372
                    itemStockPurchaseParam = inventory_client.getItemStockPurchaseParams(key)
18588 manish.sha 373
 
374
                if itemStockPurchaseParam.numOfDaysStock is None:
375
                    itemStockPurchaseParam.minStockLevel = 0
376
                    itemStockPurchaseParam.numOfDaysStock = 0
377
                    itemStockPurchaseParam.item_id = key
378
 
8182 amar.kumar 379
                advancedPOParameters[key] = [round(avgSales * itemStockPurchaseParam.numOfDaysStock), round(avgSales,2), numDaysInStock, itemStockPurchaseParam.minStockLevel, itemStockPurchaseParam.numOfDaysStock, lastXdaysSale, rtoCount]
6821 amar.kumar 380
 
6857 amar.kumar 381
            cumulativeRequirementsItemIds = list(set(requirements.keys()+SKUListForPO))
4754 mandeep.dh 382
            netRequirements = {}
6857 amar.kumar 383
            for itemId in cumulativeRequirementsItemIds:
12341 manish.sha 384
                print "Item Id for Preferred Vendor", itemId
4754 mandeep.dh 385
                requirementsCount = requirements.get(itemId)
6857 amar.kumar 386
                if requirementsCount is None:
387
                    requirementsCount = 0.0
4754 mandeep.dh 388
                if  availability.has_key(itemId):
389
                    availabilityCount = availability.get(itemId)[0]
7105 amar.kumar 390
                    item = self.__get_item_from_master(itemId)
6857 amar.kumar 391
                    if requirementsCount > availabilityCount or itemId in SKUListForPO:
5238 mandeep.dh 392
                        if item.preferredVendor is None:
393
                            raise PurchaseServiceException(101, 'Preferred Vendor missing for ' + " ".join([str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)]))
4754 mandeep.dh 394
                        if (netRequirements.has_key(item.preferredVendor)):
395
                            netRequirements[item.preferredVendor].append([item, requirementsCount - availabilityCount])
396
                        else:
397
                            netRequirements[item.preferredVendor] = [[item, requirementsCount - availabilityCount]];
398
                else:
5944 mandeep.dh 399
                    item = self.__get_item_from_master(itemId)
4754 mandeep.dh 400
                    if item.preferredVendor is None:
5238 mandeep.dh 401
                        raise PurchaseServiceException(101, 'Preferred Vendor missing for ' + " ".join([str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)]))
4754 mandeep.dh 402
                    if (netRequirements.has_key(item.preferredVendor)):
403
                        netRequirements[item.preferredVendor].append([item, requirementsCount])
404
                    else:
405
                        netRequirements[item.preferredVendor] = [[item, requirementsCount]];
5238 mandeep.dh 406
 
4754 mandeep.dh 407
            if not netRequirements:
408
                return purchaseOrders
409
 
410
            for vendorId in netRequirements.keys():
411
                t_purchase_order = TPurchaseOrder()
412
                t_purchase_order.supplierId = vendorId
413
                t_purchase_order.warehouseId = warehouseId
414
                t_purchase_order.lineitems = []
415
                for key in netRequirements.get(vendorId):
6762 amar.kumar 416
                    item = key[0]
4754 mandeep.dh 417
                    quantity = key[1]
418
                    t_po_lineitem = TLineItem()
419
                    t_po_lineitem.productGroup = item.productGroup
420
                    t_po_lineitem.brand = item.brand
421
                    t_po_lineitem.modelNumber = item.modelNumber
422
                    t_po_lineitem.modelName = item.modelName
423
                    t_po_lineitem.color = item.color
424
                    t_po_lineitem.itemId = item.id
6938 amar.kumar 425
                    if quantity <0: #TODO Check this logic
6882 amar.kumar 426
                        quantity=0
6861 amar.kumar 427
                    t_po_lineitem.quantity = quantity
6832 amar.kumar 428
                    t_po_lineitem.availableQuantity = 0
429
                    if availability.has_key(item.id):
6880 amar.kumar 430
                        if previouslyOrderedQty.has_key(item.id):
431
                            t_po_lineitem.availableQuantity = availability[item.id][0] - previouslyOrderedQty[item.id]
432
                        else:
433
                            t_po_lineitem.availableQuantity = availability[item.id][0]
6857 amar.kumar 434
                    if requirements.has_key(item.id):
435
                        t_po_lineitem.reservedQuantity = requirements[item.id]
8221 amar.kumar 436
                    additionalQty = max(advancedPOParameters[item.id][0], advancedPOParameters[item.id][3])
437
                    additionalQty = max(0,(additionalQty - (advancedPOParameters[item.id][6]/2)))
438
                    suggestedQuantity = additionalQty +key[1]
439
                    t_po_lineitem.suggestedQuantity = max(0,suggestedQuantity)
440
                    #t_po_lineitem.suggestedQuantity = max(advancedPOParameters[item.id][0], advancedPOParameters[item.id][3]) + key[1]
6821 amar.kumar 441
                    t_po_lineitem.avgSales = advancedPOParameters[item.id][1]
442
                    t_po_lineitem.numberOfDaysInStock = advancedPOParameters[item.id][2] 
443
                    t_po_lineitem.minStockLevel = advancedPOParameters[item.id][3]
6857 amar.kumar 444
                    t_po_lineitem.numberOfDaysStock = advancedPOParameters[item.id][4]
6880 amar.kumar 445
                    t_po_lineitem.lastXdaysSale = advancedPOParameters[item.id][5]
8182 amar.kumar 446
                    t_po_lineitem.rtoOrders = advancedPOParameters[item.id][6]
6880 amar.kumar 447
                    if previouslyOrderedQty.has_key(item.id):
448
                        t_po_lineitem.previouslyOrderedQty = previouslyOrderedQty[item.id]
449
                    else:
450
                        t_po_lineitem.previouslyOrderedQty = 0
4754 mandeep.dh 451
                    if codRequirements.has_key(item.id):
452
                        t_po_lineitem.codCount = min(codRequirements[item.id], quantity)
453
                    try:
5944 mandeep.dh 454
                        item_pricing = inventory_client.getItemPricing(item.id, vendorId)
4754 mandeep.dh 455
                    except Exception as e:
456
                        vendor = self.getSupplier(vendorId)
457
                        print 'Could not find transfer price for Item id: ' + str(item.id) + ' and vendor id: ' + str(vendorId)
458
                        print e
459
                        raise PurchaseServiceException(101, 'Transfer price missing for ' + vendor.name + ' and ' + " ".join([item.brand, item.modelName, item.modelNumber, item.color]))
460
                    t_po_lineitem.unitPrice = item_pricing.transferPrice
7672 rajveer 461
                    t_po_lineitem.nlc = item_pricing.nlc
9416 amar.kumar 462
                    t_po_lineitem.mrp = item.mrp
4754 mandeep.dh 463
                    t_purchase_order.lineitems.append(t_po_lineitem)
464
                purchaseOrders.append(t_purchase_order)
465
            return purchaseOrders
7105 amar.kumar 466
        except Exception as e:
467
            print e
8199 amar.kumar 468
            print sys.exc_info()[0]
4754 mandeep.dh 469
        finally:
470
            self.close_session()
471
 
6762 amar.kumar 472
    def getSuppliers(self,):
4754 mandeep.dh 473
        """
474
        Returns all the valid suppliers
475
        """
476
        try:
477
            return [Supplier.to_thrift_object(supplier) for supplier in Supplier.query.all()]
478
        finally:
479
            self.close_session()
480
 
5185 mandeep.dh 481
    def unFulfillPO(self, purchaseId, itemId, quantity):
482
        """
483
        Unfulfills a given purchase id and an item with its quantity.
484
 
485
        Parameters:
486
         - purchaseId
487
         - itemId
488
         - quantity
489
        """
490
        try:
6762 amar.kumar 491
            purchaseOrderId = Purchase.query.filter_by(id=purchaseId).one().purchaseOrder_id
492
            lineitems = LineItem.query.filter_by(purchaseOrder_id=purchaseOrderId, itemId=itemId).all()
5185 mandeep.dh 493
            if lineitems:
494
                fulfilledQuantity = lineitems[0].quantity - lineitems[0].unfulfilledQuantity
495
                if fulfilledQuantity < quantity:
496
                    raise PurchaseServiceException(101, 'Can UnFulfill only ' + str(fulfilledQuantity) + 'quantity')
497
                else:
5437 mandeep.dh 498
                    lineitems[0].unfulfilledQuantity = lineitems[0].unfulfilledQuantity + quantity
5185 mandeep.dh 499
                    lineitems[0].fulfilled = 0
500
                    purchaseOrder = PurchaseOrder.get_by(id=purchaseOrderId)
501
                    purchaseOrder.status = POStatus.PARTIALLY_FULFILLED
502
                    session.commit()
503
                    return
504
 
505
            raise PurchaseServiceException(101, 'No lineitem found with this itemId: ' + str(itemId) + ' in PO Id: ' + str(purchaseOrderId))
506
        finally:
507
            self.close_session()        
508
 
4754 mandeep.dh 509
    def fulfillPO(self, purchaseOrderId, itemId, quantity):
510
        """
511
        Fulfills a given purchase order with an item.
512
 
513
        Parameters:
514
         - purchaseOrderId
515
         - itemId
516
         - quantity
517
        """
518
        try:
6762 amar.kumar 519
            lineitems = LineItem.query.filter_by(purchaseOrder_id=purchaseOrderId, itemId=itemId).all()
4754 mandeep.dh 520
            if lineitems:
521
                if lineitems[0].unfulfilledQuantity < quantity:
5361 mandeep.dh 522
                    raise PurchaseServiceException(101, 'Can fulfill only ' + str(lineitems[0].unfulfilledQuantity) + ' quantity')
4754 mandeep.dh 523
                else:
5361 mandeep.dh 524
                    lineitems[0].unfulfilledQuantity = lineitems[0].unfulfilledQuantity - quantity
4754 mandeep.dh 525
                    if not lineitems[0].unfulfilledQuantity:
526
                        lineitems[0].fulfilled = 1
5361 mandeep.dh 527
                        session.commit()
6762 amar.kumar 528
                        if not LineItem.query.filter_by(purchaseOrder_id=purchaseOrderId, fulfilled=0).all():
5361 mandeep.dh 529
                            purchaseOrder = PurchaseOrder.get_by(id=purchaseOrderId)
4754 mandeep.dh 530
                            purchaseOrder.status = POStatus.CLOSED
531
                    session.commit()
532
                    return
533
 
6762 amar.kumar 534
            raise PurchaseServiceException(101, 'No lineitem found with this itemId: ' + str(itemId) + ' in PO Id: ' + str(purchaseOrderId))
4754 mandeep.dh 535
        finally:
536
            self.close_session()
537
 
538
    def updatePurchaseOrder(self, purchaseOrder):
539
        """
540
        Amends a PO sa per the new lineitems passed
541
 
542
        Parameters:
543
         - purchaseOrder
544
        """
545
        try:
6762 amar.kumar 546
            existingPurchaseOrder = PurchaseOrder.get_by(id=purchaseOrder.id)
4754 mandeep.dh 547
            maxRevision = 0
6762 amar.kumar 548
            existingRevisions = RevisionedPurchaseOrder.query.filter_by(purchaseOrderId=purchaseOrder.id).all()
4754 mandeep.dh 549
            if existingRevisions:
550
                maxRevision = max([a.revision for a in existingRevisions]) + 1
5147 mandeep.dh 551
 
552
            newPOItems = {}
553
            for t_lineitem in purchaseOrder.lineitems:
554
                newPOItems[t_lineitem.itemId] = t_lineitem
555
 
4754 mandeep.dh 556
            for lineitem in existingPurchaseOrder.lineitems:
5147 mandeep.dh 557
                fulfilledQuantity = lineitem.quantity - lineitem.unfulfilledQuantity
558
                if fulfilledQuantity:
559
                    if not newPOItems.has_key(lineitem.itemId):
560
                        raise PurchaseServiceException(101, 'Cannot remove fulfilled item id: ' + str(lineitem.itemId) + ' from PO')
561
                    else:
562
                        if newPOItems[lineitem.itemId].quantity < fulfilledQuantity:
563
                            raise PurchaseServiceException(101, 'More quantity already fulfilled for item id: ' + str(lineitem.itemId))
564
                        else:
5437 mandeep.dh 565
                            newPOItems[lineitem.itemId].unfulfilledQuantity = newPOItems[lineitem.itemId].unfulfilledQuantity - fulfilledQuantity
4754 mandeep.dh 566
                revisionedPurchaseOrder = RevisionedPurchaseOrder()
567
                revisionedPurchaseOrder.purchaseOrderId = purchaseOrder.id
568
                revisionedPurchaseOrder.revision = maxRevision
569
                revisionedPurchaseOrder.itemId = lineitem.itemId
570
                revisionedPurchaseOrder.unfulfilledQuantity = lineitem.unfulfilledQuantity
571
                revisionedPurchaseOrder.unitPrice = lineitem.unitPrice
7672 rajveer 572
                revisionedPurchaseOrder.nlc = lineitem.nlc
4754 mandeep.dh 573
                revisionedPurchaseOrder.createdAt = lineitem.createdAt
574
                revisionedPurchaseOrder.quantity = lineitem.quantity
575
                lineitem.delete()
576
            existingPurchaseOrder.lineitems = [LineItem(existingPurchaseOrder, t_lineitem) for t_lineitem in purchaseOrder.lineitems]
577
            existingPurchaseOrder.totalCost = sum([t_lineitem.quantity * t_lineitem.unitPrice for t_lineitem in purchaseOrder.lineitems])
578
            session.commit()
579
        finally:
580
            self.close_session()
581
 
4503 mandeep.dh 582
    def close_session(self):
583
        if session.is_active:
584
            print "session is active. closing it."
585
            session.close()
586
 
5443 mandeep.dh 587
    def getInvoices(self, date):
588
        """
589
        Fetches all invoices for a given date
590
 
591
        Parameters:
592
         - date
593
        """
594
        try:
595
            return [i.to_thrift_object() for i in Invoice.query.filter(Invoice.date > to_py_date(date)).all()]
596
        finally:
597
            self.close_session()
6630 amar.kumar 598
 
7410 amar.kumar 599
    def getInvoicesForWarehouse(self, warehouseId, supplierId, date):
600
        """
601
        Fetches all invoices for a given date for specified physical warehouse
602
 
603
        Parameters:
604
         - date
605
        """
606
        try:
607
            return [i.to_thrift_object() for i in Invoice.query.filter(Invoice.date > to_py_date(date)).filter(Invoice.warehouseId == warehouseId).filter(Invoice.supplierId == supplierId).all()]
608
        finally:
609
            self.close_session()
610
 
6630 amar.kumar 611
    def getInvoice(self, invoiceNumber, supplierId):
612
        """
613
        Fetches all invoices for  given invoiceNumber and supplierId 
5443 mandeep.dh 614
 
6630 amar.kumar 615
        Parameters:
616
         - invoiceNumber, supplierId
617
        """
618
        try:
6762 amar.kumar 619
            invoice = Invoice.query.filter_by(invoiceNumber=invoiceNumber, supplierId=supplierId).first()
6638 amar.kumar 620
            if invoice is None:
6762 amar.kumar 621
                return None
6638 amar.kumar 622
            else:
623
                return invoice.to_thrift_object()
6630 amar.kumar 624
        finally:
625
            self.close_session()
626
 
5443 mandeep.dh 627
    def createInvoice(self, invoice):
628
        """
629
        Creates an invoice object
630
 
631
        Parameters:
632
         - invoice
633
        """
634
        try:
6762 amar.kumar 635
            if Invoice.query.filter_by(supplierId=invoice.supplierId, date=to_py_date(invoice.date), invoiceNumber=invoice.invoiceNumber).all():
5768 mandeep.dh 636
                raise PurchaseServiceException(ExceptionType.ILLEGAL_ARGUMENTS, "Already received such invoice")
5443 mandeep.dh 637
            invoiceObj = Invoice()
638
            invoiceObj.invoiceNumber = invoice.invoiceNumber
639
            invoiceObj.date = to_py_date(invoice.date)
640
            invoiceObj.receivedFrom = invoice.receivedFrom
641
            invoiceObj.numItems = invoice.numItems
642
            invoiceObj.supplierId = invoice.supplierId
7410 amar.kumar 643
            invoiceObj.warehouseId = invoice.warehouseId
11219 manish.sha 644
            invoiceObj.invoiceDate = to_py_date(invoice.invoiceDate)
5443 mandeep.dh 645
            session.commit()
646
        finally:
647
            self.close_session()        
648
 
5591 mandeep.dh 649
    def addSupplier(self, supplier):
650
        """
651
        Creates a supplier
652
 
653
        Parameters:
654
         - supplier
655
        """
656
        try:
657
            supplierObj = Supplier()
658
            supplierObj.communicationAddress = supplier.communicationAddress
659
            supplierObj.contactEmail = supplier.contactEmail
660
            supplierObj.contactFax = supplier.contactFax
661
            supplierObj.contactName = supplier.contactName
662
            supplierObj.contactPhone = supplier.contactPhone
663
            supplierObj.fax = supplier.fax
664
            supplierObj.headDesignation = supplier.headDesignation
665
            supplierObj.headEmail = supplier.headEmail
666
            supplierObj.headName = supplier.headName
667
            supplierObj.name = supplier.name
668
            supplierObj.pan = supplier.pan
669
            supplierObj.phone = supplier.phone
670
            supplierObj.registeredAddress = supplier.registeredAddress
671
            supplierObj.tin = supplier.tin
10295 amar.kumar 672
            supplierObj.stateId = supplier.stateId
14072 manish.sha 673
            supplierObj.poValidityLimit = supplier.poValidityLimit
5591 mandeep.dh 674
            session.commit()
675
            return self.getSupplier(supplierObj.id)
676
        finally:
677
            self.close_session()
678
 
679
    def updateSupplier(self, supplier):
680
        """
681
        Updates a supplier
682
 
683
        Parameters:
684
         - supplier
685
        """
686
        try:
687
            supplierObj = Supplier.get(supplier.id)
688
            supplierObj.communicationAddress = supplier.communicationAddress
689
            supplierObj.contactEmail = supplier.contactEmail
690
            supplierObj.contactFax = supplier.contactFax
691
            supplierObj.contactName = supplier.contactName
692
            supplierObj.contactPhone = supplier.contactPhone
693
            supplierObj.fax = supplier.fax
694
            supplierObj.headDesignation = supplier.headDesignation
695
            supplierObj.headEmail = supplier.headEmail
696
            supplierObj.headName = supplier.headName
697
            supplierObj.name = supplier.name
698
            supplierObj.pan = supplier.pan
699
            supplierObj.phone = supplier.phone
700
            supplierObj.registeredAddress = supplier.registeredAddress
701
            supplierObj.tin = supplier.tin
13965 manish.sha 702
            supplierObj.stateId = supplierObj.stateId
14072 manish.sha 703
            supplierObj.poValidityLimit = supplier.poValidityLimit
5591 mandeep.dh 704
            session.commit()
705
        finally:
706
            self.close_session()
707
 
6385 amar.kumar 708
    def getInvoicesForPO(self, poNumber):
709
        '''
710
        For getting invoiceNumbers for a Purchase Order
711
        '''
712
        try:
713
 
6762 amar.kumar 714
            purchases = Purchase.query.filter_by(purchaseOrder=poNumber)
6385 amar.kumar 715
            for purchase in purchases:
716
                invoice = purchase.invoiceNumber
717
        except:
718
            return None
719
        finally:
720
            self.close_session()
6467 amar.kumar 721
 
722
    def createPurchaseReturn(self, t_purchaseReturn):
723
        '''
724
        For creating a new Purchase Return
725
        '''
726
        try:
6762 amar.kumar 727
            purchaseReturn = PurchaseReturn(t_purchaseReturn.vendorId, t_purchaseReturn.amount)
6467 amar.kumar 728
            purchaseReturn.vendorId = t_purchaseReturn.vendorId
729
            purchaseReturn.amount = t_purchaseReturn.amount
730
            purchaseReturn.returnTimestamp = to_py_date(t_purchaseReturn.returnTimestamp)
731
            purchaseReturn.isSettled = False
6821 amar.kumar 732
            purchaseReturn.type = t_purchaseReturn.type
10864 manish.sha 733
            purchaseReturn.returnInventoryType = t_purchaseReturn.returnInventoryType
13600 manish.sha 734
            purchaseReturn.unsettledAmount = t_purchaseReturn.amount
6467 amar.kumar 735
            session.commit()
736
            return purchaseReturn.id
737
        except Exception as e:
738
            print e
739
            raise PurchaseServiceException(101, 'Exception while creating  Purchase Return for ' + purchaseReturn.vendorId + ' for Rs' + purchaseReturn.amount)
740
        finally:
741
            self.close_session()
742
 
743
    def getUnsettledPurchaseReturns(self):
744
        '''
745
        For getting all unsettled Purchase Returns
746
        '''
747
        try:
6821 amar.kumar 748
            purchaseReturns = PurchaseReturn.query.filter_by(isSettled=False).filter_by(type=PurchaseReturnType.REAL).all()
6467 amar.kumar 749
            return [purchasereturn.to_thrift_object() for purchasereturn in purchaseReturns]
750
        except Exception as e:
751
            print e
752
            raise PurchaseServiceException(101, 'Exception while fetching all Unsettled Purchase Returns')
753
        finally:
754
            self.close_session()
6385 amar.kumar 755
 
6467 amar.kumar 756
    def settlePurchaseReturn(self, returnId):
757
        '''
758
        For marking a Purchase Return as settled
759
        '''
760
        try:
6762 amar.kumar 761
            purchaseReturn = PurchaseReturn.query.filter_by(id=returnId).one()
6467 amar.kumar 762
            purchaseReturn.isSettled = True
763
            session.commit()
764
        except Exception as e:
765
            print e
766
            raise PurchaseServiceException(101, 'Exception while settling Purchase Return Id : ' + id)
767
        finally:
768
            self.close_session()
6762 amar.kumar 769
 
7672 rajveer 770
    def createPurchaseForOurExtBilling(self, invoiceNumber, unitPrice, nlc, itemId):
6762 amar.kumar 771
        try:
772
            poId = self.getPOforOurExternalBilling()
7672 rajveer 773
            self.updatelineItemforOursExternalBilling(poId, itemId, unitPrice, nlc)
6762 amar.kumar 774
            self.receiveinvoiceforOursExternalBilling(invoiceNumber)
775
            return self.createPurchaseforOursExternalBilling(poId, invoiceNumber)
776
        except Exception as e:
777
            print e
778
            raise PurchaseServiceException(101, '')
779
        finally:
780
            self.close_session()
781
 
782
    def fulfillPOForExtBilling(self, itemId, quantity):
783
        poId = self.getPOforOurExternalBilling()
784
        lineItem = LineItem.get_by(purchaseOrder_id=poId, itemId=itemId)
785
        lineItem.unfulfilledQuantity = lineItem.unfulfilledQuantity - 1
786
        if not lineItem.unfulfilledQuantity:
787
            lineItem.fulfilled = 1
788
        session.commit()
7410 amar.kumar 789
 
790
    def closePO(self, poId):
791
        purchaseOrder = PurchaseOrder.get_by(id=poId)
792
        if not purchaseOrder:
793
                raise PurchaseServiceException(101, "No purchase order can be found with id:" + str(id))
794
        purchaseOrder.status = 4
795
        session.commit()
9925 amar.kumar 796
 
797
    def changePOStatus(self, poId, poStatus):
798
        purchaseOrder = PurchaseOrder.get_by(id=poId)
799
        if not purchaseOrder:
800
                raise PurchaseServiceException(101, "No purchase order can be found with id:" + str(id))
801
        purchaseOrder.status = POStatus.READY
802
        session.commit()
6467 amar.kumar 803
 
7410 amar.kumar 804
    def isInvoiceReceived(self, invoiceNumber, supplierId):
805
        """
806
        Returns whether invoice is already received for given invoiceNumber and supplierId 
807
 
808
        Parameters:
809
         - invoiceNumber, supplierId
810
        """
811
        try:
812
            invoice = Invoice.query.filter_by(invoiceNumber=invoiceNumber, supplierId=supplierId).first()
813
            if invoice is None:
814
                return False
815
            else:
816
                return True
817
        finally:
818
            self.close_session()
9829 amar.kumar 819
 
820
    def changeWarehouseForPO(self, poId, warehouseId):
821
        try:
822
            purchaseOrder = PurchaseOrder.get_by(id = poId)
823
            for lineitem in purchaseOrder.lineitems:
824
                if lineitem.quantity!=lineitem.unfulfilledQuantity:
825
                    raise PurchaseServiceException(101, 'Items have already been received for this PO and hence cant change warehouse')
826
            purchaseOrder.warehouseId = warehouseId
827
            session.commit()
828
        finally:
11751 manish.sha 829
            self.close_session()  
830
 
831
    def getPurchaseReturn(self, id):
832
        """
833
        Returns the purchase return with the given id. Throws an exception if there is no such purchase return.
834
 
835
        Parameters:
836
         - id
837
        """
838
        try:
839
            purchaseReturn = PurchaseReturn.get_by(id=id)
840
            if not purchaseReturn:
841
                raise PurchaseServiceException(101, "No purchase return can be found with id:" + str(id)) 
842
            return purchaseReturn.to_thrift_object()
843
        finally:
844
            self.close_session()
9829 amar.kumar 845
 
13600 manish.sha 846
    def markPurchasereturnSettled(self, id, settlementType, documentNumber, settlementBy, settledAmount):
847
        try:
848
            currentTime = datetime.datetime.now()
849
            purchaseReturn = PurchaseReturn.get_by(id=id)
850
            if not purchaseReturn:
851
                raise PurchaseServiceException(101, "No purchase return can be found with id:" + str(id)) 
852
            if settledAmount > purchaseReturn.unsettledAmount:
853
                raise PurchaseServiceException(101, "Purchase Return Settled Amount Can't be Greater than Unsettled Amount Purchase Return id:" + str(id))
854
            purchaseReturn.currentSettlementType = settlementType
855
            purchaseReturn.latestSettlementDate = currentTime
856
            if purchaseReturn.documentNumber : 
857
                purchaseReturn.documentNumber = purchaseReturn.documentNumber +";"+documentNumber
858
            else:
859
                purchaseReturn.documentNumber = documentNumber
860
            unsettledAmount = purchaseReturn.unsettledAmount - settledAmount
861
            purchaseReturn.unsettledAmount = purchaseReturn.unsettledAmount - settledAmount
862
            if unsettledAmount ==0:
863
                purchaseReturn.isSettled = 1
864
 
865
            purchaseReturnSettlement = PurchaseReturnSettlement()
866
            purchaseReturnSettlement.purchaseReturnId = id
867
            purchaseReturnSettlement.settlementType = settlementType
868
            purchaseReturnSettlement.settlementBy = settlementBy
869
            purchaseReturnSettlement.settlementAmount = settledAmount
870
            purchaseReturnSettlement.settlementDate = currentTime
871
            purchaseReturnSettlement.documentNumber = documentNumber
872
            session.commit()
873
            return True
874
        finally:
875
            self.close_session()
876
 
877
    def getPrSettlementsForPurchaseReturn(self, purchaseReturnId):
878
        try:
879
            settlements = PurchaseReturnSettlement.query.filter_by(purchaseReturnId=purchaseReturnId).all()
880
            prSettlements = []
881
            for settlement in settlements:
882
                prSettlements.append(settlement.to_thrift_object())
883
            return prSettlements
884
        finally:
885
            self.close_session()
886
 
887
    def updatePurchaseReturn(self, t_purchaseReturn):
888
        '''
889
        Updating a Purchase Return
890
        '''
891
        try:
892
            purchaseReturn = PurchaseReturn.get_by(id=t_purchaseReturn.id)
893
            purchaseReturn.purchaseReturnType = t_purchaseReturn.purchaseReturnType
894
            purchaseReturn.reasonText = t_purchaseReturn.reasonText
895
            purchaseReturn.createdBy = t_purchaseReturn.createdBy
896
            session.commit()
897
        finally:
898
            self.close_session()
899
 
6762 amar.kumar 900
    def isAlive(self,):
4503 mandeep.dh 901
        """
902
        For checking weather service is active alive or not. It also checks connectivity with database
903
        """
904
        try:
905
            session.query(Supplier.id).limit(1).all()
906
            return True
907
        except:
908
            return False
909
        finally:
910
            self.close_session()
5944 mandeep.dh 911
 
912
    def __get_item_from_master(self, item_id):
913
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
6762 amar.kumar 914
        return client.getItem(item_id)
13600 manish.sha 915