Subversion Repositories SmartDukaan

Rev

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