Subversion Repositories SmartDukaan

Rev

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