Subversion Repositories SmartDukaan

Rev

Rev 21619 | Rev 21621 | 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 = ""
21620 amit.gupta 355
                if not oosStatuses:
356
                    continue
6821 amar.kumar 357
                for oosStatus in oosStatuses:
6832 amar.kumar 358
                    if oosStatus.is_oos == False:
6821 amar.kumar 359
                        salesCount = salesCount + oosStatus.num_orders
360
                        numDaysInStock = numDaysInStock + 1
6857 amar.kumar 361
                        lastXdaysSale = lastXdaysSale + str(oosStatus.num_orders) + "-" 
362
                    else:
363
                        lastXdaysSale = lastXdaysSale + "X-"
8182 amar.kumar 364
                lastXdaysSale = lastXdaysSale[:-1]
365
                if oosStatus.rto_orders:
366
                    rtoCount = oosStatus.rto_orders
6832 amar.kumar 367
                if numDaysInStock>0:
6857 amar.kumar 368
                    avgSales = float(salesCount)/float(numDaysInStock)
18588 manish.sha 369
                itemStockPurchaseParam = None
10864 manish.sha 370
                try:
371
                    itemStockPurchaseParam = inventory_client.getItemStockPurchaseParams(key)
372
                except Exception as e:
373
                    inventory_client.updateItemStockPurchaseParams(key, 0, 0)
374
                    itemStockPurchaseParam = inventory_client.getItemStockPurchaseParams(key)
18588 manish.sha 375
 
376
                if itemStockPurchaseParam.numOfDaysStock is None:
377
                    itemStockPurchaseParam.minStockLevel = 0
378
                    itemStockPurchaseParam.numOfDaysStock = 0
379
                    itemStockPurchaseParam.item_id = key
380
 
8182 amar.kumar 381
                advancedPOParameters[key] = [round(avgSales * itemStockPurchaseParam.numOfDaysStock), round(avgSales,2), numDaysInStock, itemStockPurchaseParam.minStockLevel, itemStockPurchaseParam.numOfDaysStock, lastXdaysSale, rtoCount]
6821 amar.kumar 382
 
6857 amar.kumar 383
            cumulativeRequirementsItemIds = list(set(requirements.keys()+SKUListForPO))
4754 mandeep.dh 384
            netRequirements = {}
6857 amar.kumar 385
            for itemId in cumulativeRequirementsItemIds:
12341 manish.sha 386
                print "Item Id for Preferred Vendor", itemId
4754 mandeep.dh 387
                requirementsCount = requirements.get(itemId)
6857 amar.kumar 388
                if requirementsCount is None:
389
                    requirementsCount = 0.0
4754 mandeep.dh 390
                if  availability.has_key(itemId):
391
                    availabilityCount = availability.get(itemId)[0]
7105 amar.kumar 392
                    item = self.__get_item_from_master(itemId)
6857 amar.kumar 393
                    if requirementsCount > availabilityCount or itemId in SKUListForPO:
5238 mandeep.dh 394
                        if item.preferredVendor is None:
395
                            raise PurchaseServiceException(101, 'Preferred Vendor missing for ' + " ".join([str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)]))
4754 mandeep.dh 396
                        if (netRequirements.has_key(item.preferredVendor)):
397
                            netRequirements[item.preferredVendor].append([item, requirementsCount - availabilityCount])
398
                        else:
399
                            netRequirements[item.preferredVendor] = [[item, requirementsCount - availabilityCount]];
400
                else:
5944 mandeep.dh 401
                    item = self.__get_item_from_master(itemId)
4754 mandeep.dh 402
                    if item.preferredVendor is None:
5238 mandeep.dh 403
                        raise PurchaseServiceException(101, 'Preferred Vendor missing for ' + " ".join([str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)]))
4754 mandeep.dh 404
                    if (netRequirements.has_key(item.preferredVendor)):
405
                        netRequirements[item.preferredVendor].append([item, requirementsCount])
406
                    else:
407
                        netRequirements[item.preferredVendor] = [[item, requirementsCount]];
5238 mandeep.dh 408
 
4754 mandeep.dh 409
            if not netRequirements:
410
                return purchaseOrders
411
 
412
            for vendorId in netRequirements.keys():
413
                t_purchase_order = TPurchaseOrder()
414
                t_purchase_order.supplierId = vendorId
415
                t_purchase_order.warehouseId = warehouseId
416
                t_purchase_order.lineitems = []
417
                for key in netRequirements.get(vendorId):
6762 amar.kumar 418
                    item = key[0]
4754 mandeep.dh 419
                    quantity = key[1]
420
                    t_po_lineitem = TLineItem()
421
                    t_po_lineitem.productGroup = item.productGroup
422
                    t_po_lineitem.brand = item.brand
423
                    t_po_lineitem.modelNumber = item.modelNumber
424
                    t_po_lineitem.modelName = item.modelName
425
                    t_po_lineitem.color = item.color
426
                    t_po_lineitem.itemId = item.id
6938 amar.kumar 427
                    if quantity <0: #TODO Check this logic
6882 amar.kumar 428
                        quantity=0
6861 amar.kumar 429
                    t_po_lineitem.quantity = quantity
6832 amar.kumar 430
                    t_po_lineitem.availableQuantity = 0
431
                    if availability.has_key(item.id):
6880 amar.kumar 432
                        if previouslyOrderedQty.has_key(item.id):
433
                            t_po_lineitem.availableQuantity = availability[item.id][0] - previouslyOrderedQty[item.id]
434
                        else:
435
                            t_po_lineitem.availableQuantity = availability[item.id][0]
6857 amar.kumar 436
                    if requirements.has_key(item.id):
437
                        t_po_lineitem.reservedQuantity = requirements[item.id]
8221 amar.kumar 438
                    additionalQty = max(advancedPOParameters[item.id][0], advancedPOParameters[item.id][3])
439
                    additionalQty = max(0,(additionalQty - (advancedPOParameters[item.id][6]/2)))
440
                    suggestedQuantity = additionalQty +key[1]
441
                    t_po_lineitem.suggestedQuantity = max(0,suggestedQuantity)
442
                    #t_po_lineitem.suggestedQuantity = max(advancedPOParameters[item.id][0], advancedPOParameters[item.id][3]) + key[1]
6821 amar.kumar 443
                    t_po_lineitem.avgSales = advancedPOParameters[item.id][1]
444
                    t_po_lineitem.numberOfDaysInStock = advancedPOParameters[item.id][2] 
445
                    t_po_lineitem.minStockLevel = advancedPOParameters[item.id][3]
6857 amar.kumar 446
                    t_po_lineitem.numberOfDaysStock = advancedPOParameters[item.id][4]
6880 amar.kumar 447
                    t_po_lineitem.lastXdaysSale = advancedPOParameters[item.id][5]
8182 amar.kumar 448
                    t_po_lineitem.rtoOrders = advancedPOParameters[item.id][6]
6880 amar.kumar 449
                    if previouslyOrderedQty.has_key(item.id):
450
                        t_po_lineitem.previouslyOrderedQty = previouslyOrderedQty[item.id]
451
                    else:
452
                        t_po_lineitem.previouslyOrderedQty = 0
4754 mandeep.dh 453
                    if codRequirements.has_key(item.id):
454
                        t_po_lineitem.codCount = min(codRequirements[item.id], quantity)
455
                    try:
5944 mandeep.dh 456
                        item_pricing = inventory_client.getItemPricing(item.id, vendorId)
4754 mandeep.dh 457
                    except Exception as e:
458
                        vendor = self.getSupplier(vendorId)
459
                        print 'Could not find transfer price for Item id: ' + str(item.id) + ' and vendor id: ' + str(vendorId)
460
                        print e
461
                        raise PurchaseServiceException(101, 'Transfer price missing for ' + vendor.name + ' and ' + " ".join([item.brand, item.modelName, item.modelNumber, item.color]))
462
                    t_po_lineitem.unitPrice = item_pricing.transferPrice
7672 rajveer 463
                    t_po_lineitem.nlc = item_pricing.nlc
9416 amar.kumar 464
                    t_po_lineitem.mrp = item.mrp
4754 mandeep.dh 465
                    t_purchase_order.lineitems.append(t_po_lineitem)
466
                purchaseOrders.append(t_purchase_order)
467
            return purchaseOrders
7105 amar.kumar 468
        except Exception as e:
469
            print e
8199 amar.kumar 470
            print sys.exc_info()[0]
4754 mandeep.dh 471
        finally:
472
            self.close_session()
473
 
6762 amar.kumar 474
    def getSuppliers(self,):
4754 mandeep.dh 475
        """
476
        Returns all the valid suppliers
477
        """
478
        try:
21619 amit.gupta 479
            return [Supplier.to_thrift_object(supplier) for supplier in Supplier.query.filter(Supplier.id > 220).all()]
4754 mandeep.dh 480
        finally:
481
            self.close_session()
482
 
5185 mandeep.dh 483
    def unFulfillPO(self, purchaseId, itemId, quantity):
484
        """
485
        Unfulfills a given purchase id and an item with its quantity.
486
 
487
        Parameters:
488
         - purchaseId
489
         - itemId
490
         - quantity
491
        """
492
        try:
6762 amar.kumar 493
            purchaseOrderId = Purchase.query.filter_by(id=purchaseId).one().purchaseOrder_id
494
            lineitems = LineItem.query.filter_by(purchaseOrder_id=purchaseOrderId, itemId=itemId).all()
5185 mandeep.dh 495
            if lineitems:
496
                fulfilledQuantity = lineitems[0].quantity - lineitems[0].unfulfilledQuantity
497
                if fulfilledQuantity < quantity:
498
                    raise PurchaseServiceException(101, 'Can UnFulfill only ' + str(fulfilledQuantity) + 'quantity')
499
                else:
5437 mandeep.dh 500
                    lineitems[0].unfulfilledQuantity = lineitems[0].unfulfilledQuantity + quantity
5185 mandeep.dh 501
                    lineitems[0].fulfilled = 0
502
                    purchaseOrder = PurchaseOrder.get_by(id=purchaseOrderId)
503
                    purchaseOrder.status = POStatus.PARTIALLY_FULFILLED
504
                    session.commit()
505
                    return
506
 
507
            raise PurchaseServiceException(101, 'No lineitem found with this itemId: ' + str(itemId) + ' in PO Id: ' + str(purchaseOrderId))
508
        finally:
509
            self.close_session()        
510
 
4754 mandeep.dh 511
    def fulfillPO(self, purchaseOrderId, itemId, quantity):
512
        """
513
        Fulfills a given purchase order with an item.
514
 
515
        Parameters:
516
         - purchaseOrderId
517
         - itemId
518
         - quantity
519
        """
520
        try:
6762 amar.kumar 521
            lineitems = LineItem.query.filter_by(purchaseOrder_id=purchaseOrderId, itemId=itemId).all()
4754 mandeep.dh 522
            if lineitems:
523
                if lineitems[0].unfulfilledQuantity < quantity:
5361 mandeep.dh 524
                    raise PurchaseServiceException(101, 'Can fulfill only ' + str(lineitems[0].unfulfilledQuantity) + ' quantity')
4754 mandeep.dh 525
                else:
5361 mandeep.dh 526
                    lineitems[0].unfulfilledQuantity = lineitems[0].unfulfilledQuantity - quantity
4754 mandeep.dh 527
                    if not lineitems[0].unfulfilledQuantity:
528
                        lineitems[0].fulfilled = 1
5361 mandeep.dh 529
                        session.commit()
6762 amar.kumar 530
                        if not LineItem.query.filter_by(purchaseOrder_id=purchaseOrderId, fulfilled=0).all():
5361 mandeep.dh 531
                            purchaseOrder = PurchaseOrder.get_by(id=purchaseOrderId)
4754 mandeep.dh 532
                            purchaseOrder.status = POStatus.CLOSED
533
                    session.commit()
534
                    return
535
 
6762 amar.kumar 536
            raise PurchaseServiceException(101, 'No lineitem found with this itemId: ' + str(itemId) + ' in PO Id: ' + str(purchaseOrderId))
4754 mandeep.dh 537
        finally:
538
            self.close_session()
539
 
540
    def updatePurchaseOrder(self, purchaseOrder):
541
        """
542
        Amends a PO sa per the new lineitems passed
543
 
544
        Parameters:
545
         - purchaseOrder
546
        """
547
        try:
6762 amar.kumar 548
            existingPurchaseOrder = PurchaseOrder.get_by(id=purchaseOrder.id)
4754 mandeep.dh 549
            maxRevision = 0
6762 amar.kumar 550
            existingRevisions = RevisionedPurchaseOrder.query.filter_by(purchaseOrderId=purchaseOrder.id).all()
4754 mandeep.dh 551
            if existingRevisions:
552
                maxRevision = max([a.revision for a in existingRevisions]) + 1
5147 mandeep.dh 553
 
554
            newPOItems = {}
555
            for t_lineitem in purchaseOrder.lineitems:
556
                newPOItems[t_lineitem.itemId] = t_lineitem
557
 
4754 mandeep.dh 558
            for lineitem in existingPurchaseOrder.lineitems:
5147 mandeep.dh 559
                fulfilledQuantity = lineitem.quantity - lineitem.unfulfilledQuantity
560
                if fulfilledQuantity:
561
                    if not newPOItems.has_key(lineitem.itemId):
562
                        raise PurchaseServiceException(101, 'Cannot remove fulfilled item id: ' + str(lineitem.itemId) + ' from PO')
563
                    else:
564
                        if newPOItems[lineitem.itemId].quantity < fulfilledQuantity:
565
                            raise PurchaseServiceException(101, 'More quantity already fulfilled for item id: ' + str(lineitem.itemId))
566
                        else:
5437 mandeep.dh 567
                            newPOItems[lineitem.itemId].unfulfilledQuantity = newPOItems[lineitem.itemId].unfulfilledQuantity - fulfilledQuantity
4754 mandeep.dh 568
                revisionedPurchaseOrder = RevisionedPurchaseOrder()
569
                revisionedPurchaseOrder.purchaseOrderId = purchaseOrder.id
570
                revisionedPurchaseOrder.revision = maxRevision
571
                revisionedPurchaseOrder.itemId = lineitem.itemId
572
                revisionedPurchaseOrder.unfulfilledQuantity = lineitem.unfulfilledQuantity
573
                revisionedPurchaseOrder.unitPrice = lineitem.unitPrice
7672 rajveer 574
                revisionedPurchaseOrder.nlc = lineitem.nlc
4754 mandeep.dh 575
                revisionedPurchaseOrder.createdAt = lineitem.createdAt
576
                revisionedPurchaseOrder.quantity = lineitem.quantity
577
                lineitem.delete()
578
            existingPurchaseOrder.lineitems = [LineItem(existingPurchaseOrder, t_lineitem) for t_lineitem in purchaseOrder.lineitems]
579
            existingPurchaseOrder.totalCost = sum([t_lineitem.quantity * t_lineitem.unitPrice for t_lineitem in purchaseOrder.lineitems])
580
            session.commit()
581
        finally:
582
            self.close_session()
583
 
4503 mandeep.dh 584
    def close_session(self):
585
        if session.is_active:
586
            print "session is active. closing it."
587
            session.close()
588
 
5443 mandeep.dh 589
    def getInvoices(self, date):
590
        """
591
        Fetches all invoices for a given date
592
 
593
        Parameters:
594
         - date
595
        """
596
        try:
597
            return [i.to_thrift_object() for i in Invoice.query.filter(Invoice.date > to_py_date(date)).all()]
598
        finally:
599
            self.close_session()
6630 amar.kumar 600
 
7410 amar.kumar 601
    def getInvoicesForWarehouse(self, warehouseId, supplierId, date):
602
        """
603
        Fetches all invoices for a given date for specified physical warehouse
604
 
605
        Parameters:
606
         - date
607
        """
608
        try:
609
            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()]
610
        finally:
611
            self.close_session()
612
 
6630 amar.kumar 613
    def getInvoice(self, invoiceNumber, supplierId):
614
        """
615
        Fetches all invoices for  given invoiceNumber and supplierId 
5443 mandeep.dh 616
 
6630 amar.kumar 617
        Parameters:
618
         - invoiceNumber, supplierId
619
        """
620
        try:
6762 amar.kumar 621
            invoice = Invoice.query.filter_by(invoiceNumber=invoiceNumber, supplierId=supplierId).first()
6638 amar.kumar 622
            if invoice is None:
6762 amar.kumar 623
                return None
6638 amar.kumar 624
            else:
625
                return invoice.to_thrift_object()
6630 amar.kumar 626
        finally:
627
            self.close_session()
628
 
5443 mandeep.dh 629
    def createInvoice(self, invoice):
630
        """
631
        Creates an invoice object
632
 
633
        Parameters:
634
         - invoice
635
        """
636
        try:
6762 amar.kumar 637
            if Invoice.query.filter_by(supplierId=invoice.supplierId, date=to_py_date(invoice.date), invoiceNumber=invoice.invoiceNumber).all():
5768 mandeep.dh 638
                raise PurchaseServiceException(ExceptionType.ILLEGAL_ARGUMENTS, "Already received such invoice")
5443 mandeep.dh 639
            invoiceObj = Invoice()
640
            invoiceObj.invoiceNumber = invoice.invoiceNumber
641
            invoiceObj.date = to_py_date(invoice.date)
642
            invoiceObj.receivedFrom = invoice.receivedFrom
643
            invoiceObj.numItems = invoice.numItems
644
            invoiceObj.supplierId = invoice.supplierId
7410 amar.kumar 645
            invoiceObj.warehouseId = invoice.warehouseId
11219 manish.sha 646
            invoiceObj.invoiceDate = to_py_date(invoice.invoiceDate)
5443 mandeep.dh 647
            session.commit()
648
        finally:
649
            self.close_session()        
650
 
5591 mandeep.dh 651
    def addSupplier(self, supplier):
652
        """
653
        Creates a supplier
654
 
655
        Parameters:
656
         - supplier
657
        """
658
        try:
659
            supplierObj = Supplier()
660
            supplierObj.communicationAddress = supplier.communicationAddress
661
            supplierObj.contactEmail = supplier.contactEmail
662
            supplierObj.contactFax = supplier.contactFax
663
            supplierObj.contactName = supplier.contactName
664
            supplierObj.contactPhone = supplier.contactPhone
665
            supplierObj.fax = supplier.fax
666
            supplierObj.headDesignation = supplier.headDesignation
667
            supplierObj.headEmail = supplier.headEmail
668
            supplierObj.headName = supplier.headName
669
            supplierObj.name = supplier.name
670
            supplierObj.pan = supplier.pan
671
            supplierObj.phone = supplier.phone
672
            supplierObj.registeredAddress = supplier.registeredAddress
673
            supplierObj.tin = supplier.tin
10295 amar.kumar 674
            supplierObj.stateId = supplier.stateId
14072 manish.sha 675
            supplierObj.poValidityLimit = supplier.poValidityLimit
5591 mandeep.dh 676
            session.commit()
677
            return self.getSupplier(supplierObj.id)
678
        finally:
679
            self.close_session()
680
 
681
    def updateSupplier(self, supplier):
682
        """
683
        Updates a supplier
684
 
685
        Parameters:
686
         - supplier
687
        """
688
        try:
689
            supplierObj = Supplier.get(supplier.id)
690
            supplierObj.communicationAddress = supplier.communicationAddress
691
            supplierObj.contactEmail = supplier.contactEmail
692
            supplierObj.contactFax = supplier.contactFax
693
            supplierObj.contactName = supplier.contactName
694
            supplierObj.contactPhone = supplier.contactPhone
695
            supplierObj.fax = supplier.fax
696
            supplierObj.headDesignation = supplier.headDesignation
697
            supplierObj.headEmail = supplier.headEmail
698
            supplierObj.headName = supplier.headName
699
            supplierObj.name = supplier.name
700
            supplierObj.pan = supplier.pan
701
            supplierObj.phone = supplier.phone
702
            supplierObj.registeredAddress = supplier.registeredAddress
703
            supplierObj.tin = supplier.tin
13965 manish.sha 704
            supplierObj.stateId = supplierObj.stateId
14072 manish.sha 705
            supplierObj.poValidityLimit = supplier.poValidityLimit
5591 mandeep.dh 706
            session.commit()
707
        finally:
708
            self.close_session()
709
 
6385 amar.kumar 710
    def getInvoicesForPO(self, poNumber):
711
        '''
712
        For getting invoiceNumbers for a Purchase Order
713
        '''
714
        try:
715
 
6762 amar.kumar 716
            purchases = Purchase.query.filter_by(purchaseOrder=poNumber)
6385 amar.kumar 717
            for purchase in purchases:
718
                invoice = purchase.invoiceNumber
719
        except:
720
            return None
721
        finally:
722
            self.close_session()
6467 amar.kumar 723
 
724
    def createPurchaseReturn(self, t_purchaseReturn):
725
        '''
726
        For creating a new Purchase Return
727
        '''
728
        try:
6762 amar.kumar 729
            purchaseReturn = PurchaseReturn(t_purchaseReturn.vendorId, t_purchaseReturn.amount)
6467 amar.kumar 730
            purchaseReturn.vendorId = t_purchaseReturn.vendorId
731
            purchaseReturn.amount = t_purchaseReturn.amount
732
            purchaseReturn.returnTimestamp = to_py_date(t_purchaseReturn.returnTimestamp)
733
            purchaseReturn.isSettled = False
6821 amar.kumar 734
            purchaseReturn.type = t_purchaseReturn.type
10864 manish.sha 735
            purchaseReturn.returnInventoryType = t_purchaseReturn.returnInventoryType
13600 manish.sha 736
            purchaseReturn.unsettledAmount = t_purchaseReturn.amount
6467 amar.kumar 737
            session.commit()
738
            return purchaseReturn.id
739
        except Exception as e:
740
            print e
741
            raise PurchaseServiceException(101, 'Exception while creating  Purchase Return for ' + purchaseReturn.vendorId + ' for Rs' + purchaseReturn.amount)
742
        finally:
743
            self.close_session()
744
 
745
    def getUnsettledPurchaseReturns(self):
746
        '''
747
        For getting all unsettled Purchase Returns
748
        '''
749
        try:
6821 amar.kumar 750
            purchaseReturns = PurchaseReturn.query.filter_by(isSettled=False).filter_by(type=PurchaseReturnType.REAL).all()
6467 amar.kumar 751
            return [purchasereturn.to_thrift_object() for purchasereturn in purchaseReturns]
752
        except Exception as e:
753
            print e
754
            raise PurchaseServiceException(101, 'Exception while fetching all Unsettled Purchase Returns')
755
        finally:
756
            self.close_session()
6385 amar.kumar 757
 
6467 amar.kumar 758
    def settlePurchaseReturn(self, returnId):
759
        '''
760
        For marking a Purchase Return as settled
761
        '''
762
        try:
6762 amar.kumar 763
            purchaseReturn = PurchaseReturn.query.filter_by(id=returnId).one()
6467 amar.kumar 764
            purchaseReturn.isSettled = True
765
            session.commit()
766
        except Exception as e:
767
            print e
768
            raise PurchaseServiceException(101, 'Exception while settling Purchase Return Id : ' + id)
769
        finally:
770
            self.close_session()
6762 amar.kumar 771
 
7672 rajveer 772
    def createPurchaseForOurExtBilling(self, invoiceNumber, unitPrice, nlc, itemId):
6762 amar.kumar 773
        try:
774
            poId = self.getPOforOurExternalBilling()
7672 rajveer 775
            self.updatelineItemforOursExternalBilling(poId, itemId, unitPrice, nlc)
6762 amar.kumar 776
            self.receiveinvoiceforOursExternalBilling(invoiceNumber)
777
            return self.createPurchaseforOursExternalBilling(poId, invoiceNumber)
778
        except Exception as e:
779
            print e
780
            raise PurchaseServiceException(101, '')
781
        finally:
782
            self.close_session()
783
 
784
    def fulfillPOForExtBilling(self, itemId, quantity):
785
        poId = self.getPOforOurExternalBilling()
786
        lineItem = LineItem.get_by(purchaseOrder_id=poId, itemId=itemId)
787
        lineItem.unfulfilledQuantity = lineItem.unfulfilledQuantity - 1
788
        if not lineItem.unfulfilledQuantity:
789
            lineItem.fulfilled = 1
790
        session.commit()
7410 amar.kumar 791
 
792
    def closePO(self, poId):
793
        purchaseOrder = PurchaseOrder.get_by(id=poId)
794
        if not purchaseOrder:
795
                raise PurchaseServiceException(101, "No purchase order can be found with id:" + str(id))
796
        purchaseOrder.status = 4
797
        session.commit()
9925 amar.kumar 798
 
799
    def changePOStatus(self, poId, poStatus):
800
        purchaseOrder = PurchaseOrder.get_by(id=poId)
801
        if not purchaseOrder:
802
                raise PurchaseServiceException(101, "No purchase order can be found with id:" + str(id))
803
        purchaseOrder.status = POStatus.READY
804
        session.commit()
6467 amar.kumar 805
 
7410 amar.kumar 806
    def isInvoiceReceived(self, invoiceNumber, supplierId):
807
        """
808
        Returns whether invoice is already received for given invoiceNumber and supplierId 
809
 
810
        Parameters:
811
         - invoiceNumber, supplierId
812
        """
813
        try:
814
            invoice = Invoice.query.filter_by(invoiceNumber=invoiceNumber, supplierId=supplierId).first()
815
            if invoice is None:
816
                return False
817
            else:
818
                return True
819
        finally:
820
            self.close_session()
9829 amar.kumar 821
 
822
    def changeWarehouseForPO(self, poId, warehouseId):
823
        try:
824
            purchaseOrder = PurchaseOrder.get_by(id = poId)
825
            for lineitem in purchaseOrder.lineitems:
826
                if lineitem.quantity!=lineitem.unfulfilledQuantity:
827
                    raise PurchaseServiceException(101, 'Items have already been received for this PO and hence cant change warehouse')
828
            purchaseOrder.warehouseId = warehouseId
829
            session.commit()
830
        finally:
11751 manish.sha 831
            self.close_session()  
832
 
833
    def getPurchaseReturn(self, id):
834
        """
835
        Returns the purchase return with the given id. Throws an exception if there is no such purchase return.
836
 
837
        Parameters:
838
         - id
839
        """
840
        try:
841
            purchaseReturn = PurchaseReturn.get_by(id=id)
842
            if not purchaseReturn:
843
                raise PurchaseServiceException(101, "No purchase return can be found with id:" + str(id)) 
844
            return purchaseReturn.to_thrift_object()
845
        finally:
846
            self.close_session()
9829 amar.kumar 847
 
13600 manish.sha 848
    def markPurchasereturnSettled(self, id, settlementType, documentNumber, settlementBy, settledAmount):
849
        try:
850
            currentTime = datetime.datetime.now()
851
            purchaseReturn = PurchaseReturn.get_by(id=id)
852
            if not purchaseReturn:
853
                raise PurchaseServiceException(101, "No purchase return can be found with id:" + str(id)) 
854
            if settledAmount > purchaseReturn.unsettledAmount:
855
                raise PurchaseServiceException(101, "Purchase Return Settled Amount Can't be Greater than Unsettled Amount Purchase Return id:" + str(id))
856
            purchaseReturn.currentSettlementType = settlementType
857
            purchaseReturn.latestSettlementDate = currentTime
858
            if purchaseReturn.documentNumber : 
859
                purchaseReturn.documentNumber = purchaseReturn.documentNumber +";"+documentNumber
860
            else:
861
                purchaseReturn.documentNumber = documentNumber
862
            unsettledAmount = purchaseReturn.unsettledAmount - settledAmount
863
            purchaseReturn.unsettledAmount = purchaseReturn.unsettledAmount - settledAmount
864
            if unsettledAmount ==0:
865
                purchaseReturn.isSettled = 1
866
 
867
            purchaseReturnSettlement = PurchaseReturnSettlement()
868
            purchaseReturnSettlement.purchaseReturnId = id
869
            purchaseReturnSettlement.settlementType = settlementType
870
            purchaseReturnSettlement.settlementBy = settlementBy
871
            purchaseReturnSettlement.settlementAmount = settledAmount
872
            purchaseReturnSettlement.settlementDate = currentTime
873
            purchaseReturnSettlement.documentNumber = documentNumber
874
            session.commit()
875
            return True
876
        finally:
877
            self.close_session()
878
 
879
    def getPrSettlementsForPurchaseReturn(self, purchaseReturnId):
880
        try:
881
            settlements = PurchaseReturnSettlement.query.filter_by(purchaseReturnId=purchaseReturnId).all()
882
            prSettlements = []
883
            for settlement in settlements:
884
                prSettlements.append(settlement.to_thrift_object())
885
            return prSettlements
886
        finally:
887
            self.close_session()
888
 
889
    def updatePurchaseReturn(self, t_purchaseReturn):
890
        '''
891
        Updating a Purchase Return
892
        '''
893
        try:
894
            purchaseReturn = PurchaseReturn.get_by(id=t_purchaseReturn.id)
895
            purchaseReturn.purchaseReturnType = t_purchaseReturn.purchaseReturnType
896
            purchaseReturn.reasonText = t_purchaseReturn.reasonText
897
            purchaseReturn.createdBy = t_purchaseReturn.createdBy
898
            session.commit()
899
        finally:
900
            self.close_session()
901
 
6762 amar.kumar 902
    def isAlive(self,):
4503 mandeep.dh 903
        """
904
        For checking weather service is active alive or not. It also checks connectivity with database
905
        """
906
        try:
907
            session.query(Supplier.id).limit(1).all()
908
            return True
909
        except:
910
            return False
911
        finally:
912
            self.close_session()
5944 mandeep.dh 913
 
914
    def __get_item_from_master(self, item_id):
915
        client = CatalogClient("catalog_service_server_host_master", "catalog_service_server_port").get_client()
6762 amar.kumar 916
        return client.getItem(item_id)
13600 manish.sha 917