Subversion Repositories SmartDukaan

Rev

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

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