Subversion Repositories SmartDukaan

Rev

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