Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
12363 kshitij.so 1
from elixir import *
2
from sqlalchemy.sql import or_ ,func, asc
3
from shop2020.config.client.ConfigClient import ConfigClient
4
from shop2020.model.v1.catalog.impl import DataService
12364 kshitij.so 5
from shop2020.model.v1.catalog.impl.DataService import Amazonlisted, Item, \
6
Category, SourcePercentageMaster,SourceCategoryPercentage, SourceItemPercentage, AmazonPromotion, AmazonScrapingHistory
12363 kshitij.so 7
from shop2020.thriftpy.model.v1.order.ttypes import OrderSource
12364 kshitij.so 8
from shop2020.thriftpy.model.v1.catalog.ttypes import CompetitionCategory, SalesPotential,\
12363 kshitij.so 9
Decision, RunType, AmazonPromotionType
10
from shop2020.model.v1.catalog.script import SellerCentralInventoryReport, AmazonAsyncScraper
11
from shop2020.clients.CatalogClient import CatalogClient
12
from shop2020.clients.InventoryClient import InventoryClient
13
from shop2020.clients.TransactionClient import TransactionClient
14
import urllib2
15
import time 
16
from datetime import date, datetime, timedelta
17
from shop2020.utils import EmailAttachmentSender
18
from shop2020.utils.EmailAttachmentSender import get_attachment_part
19
import math
20
import simplejson as json
21
import xlwt
22
import optparse
23
import sys
24
import smtplib
25
from email.mime.text import MIMEText
26
import email
27
from email.mime.multipart import MIMEMultipart
28
import email.encoders
29
import mechanize
30
import cookielib
31
 
32
 
33
config_client = ConfigClient()
34
host = config_client.get_property('staging_hostname')
35
syncPrice=config_client.get_property('sync_price_on_marketplace')
36
 
37
amazonAsinPrice={}
38
amazonLongTermActivePromotions = []
39
saleMap = {}
40
DataService.initialize(db_hostname=host)
41
 
42
amScraper = AmazonAsyncScraper.AmazonAsyncScraper()
43
 
44
class __AmazonAsinPrice:
45
    def __init__(self, asin, price):
46
        self.asin = asin
47
        self.price = price
48
 
49
class __AmazonItemInfo:
50
 
51
    def __init__(self, asin, nlc, courierCost, sku, product_group, brand, model_name, model_number, color, weight, parent_category, risky, vatRate, runType, parent_category_name, sourcePercentage, ourInventory, state_id):
52
        self.supc = asin
53
        self.nlc = nlc
54
        self.courierCost = courierCost
55
        self.sku = sku
56
        self.product_group = product_group
57
        self.brand = brand
58
        self.model_name = model_name
59
        self.model_number = model_number
60
        self.color = color
61
        self.weight = weight
62
        self.parent_category = parent_category
63
        self.risky = risky
64
        self.vatRate = vatRate
65
        self.runType = runType
66
        self.parent_category_name = parent_category_name
67
        self.sourcePercentage = sourcePercentage
68
        self.ourInventory = ourInventory
69
        self.state_id = state_id
70
 
71
class __AmazonDetails:
72
    def __init__(self, sku, ourSp, ourRank, lowestSellerName,lowestSellerSp,secondLowestSellerName, secondLowestSellerSp, thirdLowestSellerName, thirdLowestSellerSp, totalSeller, multipleListings):
73
        self.sku =sku
74
        self.ourSp = ourSp
75
        self.ourRank = ourRank
76
        self.lowestSellerName = lowestSellerName
77
        self.lowestSellerSp = lowestSellerSp
78
        self.secondLowestSellerName = secondLowestSellerName
79
        self.secondLowestSellerSp = secondLowestSellerSp
80
        self.thirdLowestSellerName = thirdLowestSellerName
81
        self.thirdLowestSellerSp = thirdLowestSellerSp
82
        self.totalSeller = totalSeller
83
        self.multipleListings = multipleListings 
84
 
85
class __AmazonPricing:
86
 
87
    def __init__(self, ourSp, ourTp, lowestPossibleTp, lowestPossibleSp):
88
        self.ourTp = ourTp
89
        self.lowestPossibleTp = lowestPossibleTp
90
        self.ourSp = ourSp
91
        self.lowestPossibleSp = lowestPossibleSp
92
 
93
 
94
def syncAsin():
95
    notListedOnAmazon = []
96
    diffAsins = []
12365 kshitij.so 97
    login_url = "https://sellercentral.amazon.in/gp/homepage.html"
98
    br = SellerCentralInventoryReport.login(login_url)
99
    report_url = "https://sellercentral.amazon.in/gp/upload-download-utils/requestReport.html?type=OpenListingReport&marketplaceID=44571&Request+Report="
100
    br = SellerCentralInventoryReport.requestReport(br,report_url)
101
    status_url="https://sellercentral.amazon.in/gp/upload-download-utils/reportStatusData.html"
102
    br, page = SellerCentralInventoryReport.checkStatus(br,status_url)
103
    br, batchId = SellerCentralInventoryReport.getReportBatchId(br,page)
104
    print "*********************************"
105
    print "Batch Id for request is ",batchId
106
    print "*********************************"
107
    ready = False
108
    retryCount = 0
109
    while not ready:
110
        if retryCount == 10:
111
            print "File not available for download after multiple retries"
112
            sys.exit(1)
113
        br, download_link = SellerCentralInventoryReport.downloadReport(br,batchId,status_url)
114
        if download_link is not None:
115
            ready= True
116
            continue
117
        print "File not ready for download yet.Will try again after 30 seconds."
118
        retryCount+=1
119
        time.sleep(30)
120
    fPath = SellerCentralInventoryReport.fetchFile(download_link['href'],br,batchId)
12363 kshitij.so 121
    global amazonAsinPrice
122
    for line in open(fPath):
123
        l = line.split('\t')
124
        if (str(l[0]).startswith('FBA') or str(l[0]).startswith('FBB')):
125
            obj = __AmazonAsinPrice(l[1],l[2])
126
            amazonAsinPrice[l[0]] = obj
127
#    systemAsins = session.query(Item,Amazonlisted).join((Amazonlisted,Item.id==Amazonlisted.itemId)).all()
128
#    for systemAsin in systemAsins:
129
#        item = systemAsin[0]
130
#        amListed = systemAsin[1]
131
#        if amazonAsinPrice.get('FBA'+str(item.id)) is None:
132
#            temp=[]
133
#            temp.append(item)
134
#            temp.append(amListed)
135
#            notListedOnAmazon.append(temp)
136
#            continue
137
#        else:
138
#            temp=[]
139
#            temp.append(item)
140
#            temp.append(amListed)
141
#            if item.asin!=((amazonAsinPrice.get('FBA'+str(item.id))).asin).strip():
142
#                diffAsins.append(temp)
143
#                continue
144
#            
145
#    for diffAsin in diffAsins:
146
#        item = diffAsin[0]
147
#        amListed = diffAsin[1]
148
#        item.asin = ((amazonAsinPrice.get('FBA'+str(item.id))).asin).strip()
149
#        amListed.asin = ((amazonAsinPrice.get('FBA'+str(item.id))).asin).strip()
150
#    session.commit()
151
#    session.close()
152
 
153
def fetchFbaSale():
154
    global saleMap
155
    transaction_client = TransactionClient().get_client()
156
    fbaSaleSnapshot = transaction_client.getAmazonFbaSalesSnapshotForDays(4)
157
    for saleSnapshot in fbaSaleSnapshot:
158
        if saleSnapshot.fcLocation == 0:
159
            if saleMap.has_key('FBA'+str(saleSnapshot.item_id)):
160
                temp = []
12367 kshitij.so 161
                val = saleMap.get('FBA'+str(saleSnapshot.item_id))
162
                for l in val:
12363 kshitij.so 163
                    temp.append(l)
164
                temp.append(saleSnapshot)
12366 kshitij.so 165
                saleMap['FBA'+str(saleSnapshot.item_id)]=temp
12363 kshitij.so 166
            else:
167
                saleMap['FBA'+str(saleSnapshot.item_id)] = saleSnapshot
168
        else:
169
            if saleMap.has_key('FBB'+str(saleSnapshot.item_id)):
170
                temp = []
12367 kshitij.so 171
                val = saleMap.get('FBB'+str(saleSnapshot.item_id))
172
                for l in val:
12363 kshitij.so 173
                    temp.append(l)
12366 kshitij.so 174
                saleMap['FBA'+str(saleSnapshot.item_id)]=temp
12363 kshitij.so 175
                temp.append(saleSnapshot)
176
            else:
177
                saleMap['FBB'+str(saleSnapshot.item_id)] = saleSnapshot
178
 
179
def calculateAverageSale(sku):
180
    count,sale = 0,0
181
    oosStatus = saleMap.get(sku)
182
    for obj in oosStatus:
183
        if not obj.is_oos:
184
            count+=1
185
            sale = sale+obj.num_orders
186
    avgSalePerDay=0 if count==0 else (float(sale)/count)
187
    return round(avgSalePerDay,2)
188
 
189
 
190
 
191
 
192
def computeCourierCost(weight):
193
    cCost = 10.0;
194
    slabs = int((weight*1000)/500-.001)
195
    for slab in range(0,slabs):
196
        cCost = cCost + 10.0;
197
    return cCost;
198
 
199
 
200
def populateStuff(time,runType):
201
    global amazonLongTermActivePromotions
202
    itemInfo = []
203
    inventory_client = InventoryClient().get_client()
204
    fbaAvailableInventorySnapshot = inventory_client.getAllAvailableAmazonFbaItemInventory()
205
    for fbaInventoryItem in fbaAvailableInventorySnapshot:
206
        d_amazon_listed = Amazonlisted.get_by(itemId=fbaInventoryItem.item_id)
207
        if d_amazon_listed is None:
208
            continue
209
        if d_amazon_listed.overrrideWanlc:
210
            wanlc = d_amazon_listed.exceptionalWanlc
211
        else:
212
            wanlc = inventory_client.getWanNlcForSource(fbaInventoryItem.item_id,OrderSource.AMAZON)
213
        it = Item.query.filter_by(id=fbaInventoryItem.item_id).one()
214
        category = Category.query.filter_by(id=it.category).one()
215
        parent_category = Category.query.filter_by(id=category.parent_category_id).first()
216
        scp = SourceCategoryPercentage.query.filter(SourceCategoryPercentage.category_id==it.category).filter(SourceCategoryPercentage.source==OrderSource.AMAZON).filter(SourceCategoryPercentage.startDate<=time).filter(SourceCategoryPercentage.expiryDate>=time).first()
217
        if scp is not None:
218
            sourcePercentage = scp
219
        else:
220
            spm = SourcePercentageMaster.get_by(source=OrderSource.AMAZON)
221
            sourcePercentage = spm
222
        if fbaInventoryItem.location==0:
223
            sku = 'FBA'+fbaInventoryItem.item_id
224
            state_id = 1
225
        elif fbaInventoryItem.location==1:
226
            sku = 'FBB'+fbaInventoryItem.item_id
227
            state_id = 2
228
        else:
229
            continue
230
        cc = computeCourierCost(it.weight)
231
        if amazonAsinPrice.get(sku) is None:
232
            asin = None
233
        amazonItemInfo = __AmazonItemInfo(amazonAsinPrice.get(sku).asin, wanlc,cc, sku, it.product_group, it.brand, it.model_name, it.model_number, it.color, it.weight, category.parent_category_id, it.risky, None, runType, parent_category.display_name,sourcePercentage,fbaInventoryItem.availability,state_id)
234
        itemInfo.append(amazonItemInfo)
235
    amPromotions = AmazonPromotion.query.filter(AmazonPromotion.startDate<=time).filter(AmazonPromotion.endDate>=time).filter(AmazonPromotion.promotionType==AmazonPromotionType.LONGTERM).filter(AmazonPromotion.promotionActive==True) \
236
    .group_by(AmazonPromotion.sku).order_by(desc(AmazonPromotion.addedOn)).all()
237
    for amPromotion in amPromotions:
238
        amazonLongTermActivePromotions.append(amPromotion.sku)
239
    session.close()
240
    return itemInfo
241
 
242
def decideCategory(itemInfo):
243
    exceptionList, negativeMargin, cheapest, amongCheapestAndCanCompete, canCompete, almostCompete, cantCompete = [],[],[],[],[],[],[] 
244
    skuUrls = []
245
    #skuAsinMap = {}
246
    for item in itemInfo:
247
        if item.asin is None:
248
            temp = []
249
            temp.append(item)
250
            temp.append("Asin not available")
251
            exceptionList.append(temp)
252
            continue
253
        skuUrls.append('http://www.amazon.in/gp/offer-listing/'+item.asin+'/ref=olp_sort_ps')
254
    aggResponse = amScraper.read(skuUrls, True)
255
#    for asin, scrapInfo in aggResponse:
256
#        skuList = skuAsinMap.get(asin)
257
#        for sku in skuList:
258
#            amDetails = __AmazonDetails(None, None, None, None, None,secondLowestSellerName, secondLowestSellerSp, thirdLowestSellerName, thirdLowestSellerSp)
259
#            for info in scrapInfo:
260
    catalog_client = CatalogClient().get_client()
261
    for val in itemInfo:
262
        if val.asin is None:
263
            continue
264
        scrapInfo = aggResponse.get(val.asin)
265
        if val.sku in amazonLongTermActivePromotions:
266
            print "Sku in promotion, will handle it later.Moving to other..."
267
            continue
268
        if scrapInfo is None or val.nlc==0:
269
            temp = []
270
            temp.append(val)
271
            if val.nlc==0 or val.nlc is None:
272
                temp.append("WANLC is 0")
273
            else:
274
                temp.append("Not able to fetch")
275
            exceptionList.append(temp)
276
            continue
277
        iterator = 0
278
        sku, lowestSellerName,secondLowestSellerName, thirdLowestSellerName = ('',)*4
279
        ourSp, ourRank, lowestSellerSp, secondLowestSellerSp, thirdLowestSellerSp, ourTp, lowestPossibleSp, lowestPossibleTp = (0,)*8
280
        sku = val.sku
281
        scrapedSkuLocation = None
282
        multipleListings = False
283
        for info in scrapInfo:
284
            if (info.sellerName).strip()=='Saholic':
285
                if ourRank>0:
286
                    multipleListings = True
287
                ourSp = info.sellerPrice
288
                ourRank = iterator+1
289
                if val.state_id==1:
290
                    #It means sku starts with FBA
291
                    fbaPrice = (amazonAsinPrice.get(val.sku)).price
292
                    try:
293
                        if ourSp==fbaPrice:
294
                            scrapedSkuLocation = val.state_id
295
                    except:
296
                        scrapedSkuLocation = None
297
                elif val.state_id==2:
298
                    #It means sku starts with FBB
299
                    fbbPrice = (amazonAsinPrice.get(val.sku)).price
300
                    try:
301
                        if ourSp==fbbPrice:
302
                            scrapedSkuLocation = val.state_id
303
                    except:
304
                        scrapedSkuLocation = None
305
                else:
306
                    scrapedSkuLocation = None
307
                if scrapedSkuLocation is None:
308
                    print "fishy...confused for ", val.sku
309
 
310
            if iterator == 0:
311
                lowestSellerName = info.sellerName
312
                lowestSellerSp = info.sellerPrice
313
 
314
            if iterator == 1:
315
                secondLowestSellerName = info.sellerName
316
                secondLowestSellerSp = info.sellerPrice
317
 
318
            if iterator == 2:
319
                thirdLowestSellerName = info.sellerName
320
                thirdLowestSellerSp = info.sellerPrice
321
 
322
            iterator += 1
323
 
324
        #if cheapestSkuLocation!=val.state_id
325
 
326
        if ourSp==0 or scrapedSkuLocation is None:
327
            print "Sku not present in top 3.Getting price from amazonAsinPrice...or multiple listings"
328
            if ourSp==0:
329
                ourRank = 999 #Due to pagination and large no of sellers.Taking it as dummy value, means we are not in top 3
330
                ourSp = (amazonAsinPrice.get(val.sku)).price
331
                if ourSp is None or ourSp==0:
332
                    temp = []
333
                    temp.append(val)
334
                    temp.append("Price not available")
335
                    exceptionList.append(temp)
336
                    continue
337
            else:
338
                #determine rank
339
                if ourSp <= lowestSellerSp or lowestSellerSp==0:
340
                    ourRank = 1
341
                elif ourSp > lowestSellerSp and (ourSp <= secondLowestSellerSp or secondLowestSellerSp==0):
342
                    ourRank = 2
343
                elif ourSp > secondLowestSellerSp and (ourSp<=thirdLowestSellerSp or thirdLowestSellerSp==0):
344
                    ourRank = 3
345
                else:
346
                    ourRank = 999
347
 
348
        if multipleListings:
349
            print "multiple listings..."
350
            ourSp = (amazonAsinPrice.get(val.sku)).price
351
            if ourSp is None or ourSp==0:
352
                temp = []
353
                temp.append(val)
354
                temp.append("Price not available")
355
                exceptionList.append(temp)
356
                continue
357
            if ourSp <= lowestSellerSp:
358
                    ourRank = 1
359
            elif ourSp > lowestSellerSp and (ourSp <= secondLowestSellerSp or secondLowestSellerSp==0):
360
                ourRank = 2
361
            elif ourSp > secondLowestSellerSp and (ourSp<=thirdLowestSellerSp or thirdLowestSellerSp==0):
362
                ourRank = 3
363
            else:
364
                ourRank = 999
365
 
366
 
367
        amDetails = __AmazonDetails(sku, ourSp, ourRank, lowestSellerName,lowestSellerSp,secondLowestSellerName, secondLowestSellerSp, thirdLowestSellerName, thirdLowestSellerSp,len(scrapInfo),multipleListings)
368
        try:
369
            val.vatRate = catalog_client.getVatPercentageForItem(int(val.sku[3:]), val.state_id, amDetails.ourSp)
370
        except:
371
            temp = []
372
            temp.append(val)
373
            temp.append("Vat not available")
374
            exceptionList.append(temp)
375
            continue
376
 
377
        ourTp = getOurTp(amDetails,val,val.sourcePercentage)
378
        lowestPossibleTp = getLowestPossibleTp(amDetails,val,val.sourcePercentage)
379
        lowestPossibleSp = getLowestPossibleSp(amDetails,val,val.sourcePercentage)
380
        amPricing = __AmazonPricing(ourSp,ourTp,lowestPossibleTp,lowestPossibleSp)
381
 
382
        if amPricing.ourTp < amPricing.lowestPossibleTp:
383
            temp = []
384
            temp.append(val)
385
            temp.append(amDetails)
386
            temp.append(amPricing)
387
            negativeMargin.append(temp)
388
            continue
389
 
390
        if amDetails.ourRank==1:
391
            temp = []
392
            temp.append(val)
393
            temp.append(amDetails)
394
            temp.append(amPricing)
395
            cheapest.append(temp)
396
            continue
397
 
398
        if (amDetails.lowestSellerSp > amPricing.lowestPossibleSp) and ((((float(amDetails.ourSp - amDetails.lowestSellerSp))/amDetails.ourSp)<=.01) or ((amDetails.ourSp - amDetails.lowestSellerSp)<=25)):
399
            temp = []
400
            temp.append(val)
401
            temp.append(amDetails)
402
            temp.append(amPricing)
403
            amongCheapestAndCanCompete.append(temp)
404
            continue
405
 
406
        if (amDetails.lowestSellerSp > amPricing.lowestPossibleSp):
407
            temp = []
408
            temp.append(val)
409
            temp.append(amDetails)
410
            temp.append(amPricing)
411
            canCompete.append(temp)
412
            continue
413
 
414
        temp = []
415
        temp.append(val)
416
        temp.append(amDetails)
417
        temp.append(amPricing)
418
        cantCompete.append(temp)
419
 
420
    itemInfo[:]=[]
421
    scrapInfo[:]=[]
422
    return exceptionList, negativeMargin, cheapest, amongCheapestAndCanCompete, canCompete, almostCompete, cantCompete
423
 
424
def getOurTp(amazonDetails,val,spm):
425
    ourTp = amazonDetails.ourSp- amazonDetails.ourSp*(spm.commission/100+spm.emiFee/100)*(1+(spm.serviceTax/100))-(val.courierCost)*(1+(spm.serviceTax/100))*(1+(spm.serviceTax/100));
426
    return round(ourTp,2)
427
 
428
def getLowestPossibleTp(amazonDetails,val,spm):
429
    vat = (amazonDetails.ourSp/(1+(val.vatRate/100))-(val.nlc/(1+(val.vatRate/100))))*(val.vatRate/100)
430
    inHouseCost = 15+vat+(spm.returnProvision/100)*amazonDetails.ourSp
431
    lowest_possible_tp = val.nlc+inHouseCost
432
    return round(lowest_possible_tp,2)
433
 
434
def getLowestPossibleSp(amazonDetails,val,spm):
435
    lowestPossibleSp = (val.nlc+(val.courierCost)*(1+(spm.serviceTax/100))*(1+(val.vatRate/100))+(15)*(1+(val.vatRate)/100))/(1-(spm.commission/100+spm.emiFee/100)*(1+(spm.serviceTax/100))*(1+(val.vatRate)/100)-(spm.returnProvision/100)*(1+(val.vatRate)/100));
436
    return round(lowestPossibleSp,2)
437
 
438
def getTargetTp(targetSp,spm,val):
439
    targetTp = targetSp- targetSp*(spm.commission/100+spm.emiFee/100)*(1+(spm.serviceTax/100))-(val.courierCost)*(1+(val.serviceTax/100))
440
    return round(targetTp,2)
441
 
442
def commitExceptionList(exceptionList,timestamp,runType):
443
    for exceptionItem in exceptionList:
444
        val = exceptionItem[0]
445
        reason = exceptionItem[1]
446
        amazonScrapingHistory = AmazonScrapingHistory()
447
        amazonScrapingHistory.item_id = val.sku[3:]
448
        amazonScrapingHistory.warehouseLocation = val.state_id
449
        amazonScrapingHistory.reason = reason
450
        amazonScrapingHistory.runType = RunType._NAMES_TO_VALUES.get(runType)
451
        amazonScrapingHistory.competitiveCategory = CompetitionCategory.EXCEPTION
452
        amazonScrapingHistory.timestamp = timestamp
453
    session.commit()
454
 
455
def commitNegativeMargin(negativeMargin,timestamp,runType):
456
    for negativeMarginItem in negativeMargin:
457
        val = negativeMarginItem[0]
458
        amDetails = negativeMarginItem[1]
459
        amPricing = negativeMarginItem[2]
460
        spm = val.sourcePercentage
461
        amazonScrapingHistory = AmazonScrapingHistory()
462
        amazonScrapingHistory.item_id = val.sku[3:]
463
        amazonScrapingHistory.warehouseLocation = val.state_id
464
        amazonScrapingHistory.ourSellingPrice = amDetails.ourSp
465
        amazonScrapingHistory.ourTp = amPricing.ourTp
466
        amazonScrapingHistory.lowestPossibleTp = amPricing.lowestPossibleTp
467
        amazonScrapingHistory.lowestPossibleSp = amPricing.lowestPossibleSp
468
        amazonScrapingHistory.ourRank = amDetails.ourRank
469
        amazonScrapingHistory.ourInventory = val.ourInventory
470
        amazonScrapingHistory.lowestSellerName = amDetails.lowestSellerName
471
        amazonScrapingHistory.lowestSellerSp = amDetails.lowestSellerSp
472
        amazonScrapingHistory.secondLowestSellerName = amDetails.secondLowestSellerName
473
        amazonScrapingHistory.secondLowestSellerSp = amDetails.secondLowestSellerSp
474
        amazonScrapingHistory.thirdLowestSellerName = amDetails.thirdLowestSellerName
475
        amazonScrapingHistory.thirdLowestSellerSp = amDetails.thirdLowestSellerSp
476
        amazonScrapingHistory.wanlc = val.nlc
477
        amazonScrapingHistory.commission = spm.commission
478
        amazonScrapingHistory.competitorCommission = spm.competitorCommission
479
        amazonScrapingHistory.returnProvision = spm.returnProvision
480
        amazonScrapingHistory.courierCost = val.courierCost
481
        amazonScrapingHistory.risky = val.risky
482
        amazonScrapingHistory.runType = RunType._NAMES_TO_VALUES.get(runType)
483
        amazonScrapingHistory.totalSeller = amDetails.totalSeller
484
        amazonScrapingHistory.competitiveCategory = CompetitionCategory.NEGATIVE_MARGIN
485
        amazonScrapingHistory.timestamp = timestamp
486
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
487
        amazonScrapingHistory.avgSale = calculateAverageSale(val.sku) #Last five days
488
    session.commit()
489
 
490
 
491
def commitCheapest(cheapest,timestamp,runType):
492
    for cheapestItem in cheapest:
493
        val = cheapestItem[0]
494
        amDetails = cheapestItem[1]
495
        amPricing = cheapestItem[2]
496
        spm = val.sourcePercentage
497
        amazonScrapingHistory = AmazonScrapingHistory()
498
        amazonScrapingHistory.item_id = val.sku[3:]
499
        amazonScrapingHistory.warehouseLocation = val.state_id
500
        amazonScrapingHistory.ourSellingPrice = amDetails.ourSp
501
        amazonScrapingHistory.ourTp = amPricing.ourTp
502
        amazonScrapingHistory.lowestPossibleTp = amPricing.lowestPossibleTp
503
        amazonScrapingHistory.lowestPossibleSp = amPricing.lowestPossibleSp
504
        amazonScrapingHistory.ourRank = amDetails.ourRank
505
        amazonScrapingHistory.ourInventory = val.ourInventory
506
        amazonScrapingHistory.lowestSellerName = amDetails.lowestSellerName
507
        amazonScrapingHistory.lowestSellerSp = amDetails.lowestSellerSp
508
        amazonScrapingHistory.secondLowestSellerName = amDetails.secondLowestSellerName
509
        amazonScrapingHistory.secondLowestSellerSp = amDetails.secondLowestSellerSp
510
        amazonScrapingHistory.thirdLowestSellerName = amDetails.thirdLowestSellerName
511
        amazonScrapingHistory.thirdLowestSellerSp = amDetails.thirdLowestSellerSp
512
        amazonScrapingHistory.wanlc = val.nlc
513
        amazonScrapingHistory.commission = spm.commission
514
        amazonScrapingHistory.competitorCommission = spm.competitorCommission
515
        amazonScrapingHistory.returnProvision = spm.returnProvision
516
        amazonScrapingHistory.courierCost = val.courierCost
517
        amazonScrapingHistory.risky = val.risky
518
        amazonScrapingHistory.runType = RunType._NAMES_TO_VALUES.get(runType)
519
        amazonScrapingHistory.totalSeller = amDetails.totalSeller
520
        amazonScrapingHistory.competitiveCategory = CompetitionCategory.BUY_BOX
521
        amazonScrapingHistory.timestamp = timestamp
522
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
523
        if amDetails.secondLowestSellerName!='Saholic':
524
            competitorSp = amDetails.secondLowestSellerSp
525
        else:
526
            competitorSp = amDetails.thirdLowestSellerSp
527
        proposed_sp = max(competitorSp - max((20, competitorSp*0.002)), amPricing.lowestPossibleSp)
528
        proposed_tp = getTargetTp(proposed_sp,spm,val)
529
        amazonScrapingHistory.proposedSp = proposed_sp
530
        amazonScrapingHistory.proposedTp = proposed_tp
531
        amazonScrapingHistory.marginIncreasedPotential = proposed_tp - amPricing.ourTp
532
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
533
        amazonScrapingHistory.avgSale = calculateAverageSale(val.sku) #Last five days
534
    session.commit()
535
 
536
 
537
 
538
def commitAmongCheapestAndCanCompete(amongCheapestAndCanCompete,timestamp,runType):
539
    for amongCheapestAndCanCompeteItem in amongCheapestAndCanCompete:
540
        val = amongCheapestAndCanCompeteItem[0]
541
        amDetails = amongCheapestAndCanCompeteItem[1]
542
        amPricing = amongCheapestAndCanCompeteItem[2]
543
        spm = val.sourcePercentage
544
        amazonScrapingHistory = AmazonScrapingHistory()
545
        amazonScrapingHistory.item_id = val.sku[3:]
546
        amazonScrapingHistory.warehouseLocation = val.state_id
547
        amazonScrapingHistory.ourSellingPrice = amDetails.ourSp
548
        amazonScrapingHistory.ourTp = amPricing.ourTp
549
        amazonScrapingHistory.lowestPossibleTp = amPricing.lowestPossibleTp
550
        amazonScrapingHistory.lowestPossibleSp = amPricing.lowestPossibleSp
551
        amazonScrapingHistory.ourRank = amDetails.ourRank
552
        amazonScrapingHistory.ourInventory = val.ourInventory
553
        amazonScrapingHistory.lowestSellerName = amDetails.lowestSellerName
554
        amazonScrapingHistory.lowestSellerSp = amDetails.lowestSellerSp
555
        amazonScrapingHistory.secondLowestSellerName = amDetails.secondLowestSellerName
556
        amazonScrapingHistory.secondLowestSellerSp = amDetails.secondLowestSellerSp
557
        amazonScrapingHistory.thirdLowestSellerName = amDetails.thirdLowestSellerName
558
        amazonScrapingHistory.thirdLowestSellerSp = amDetails.thirdLowestSellerSp
559
        amazonScrapingHistory.wanlc = val.nlc
560
        amazonScrapingHistory.commission = spm.commission
561
        amazonScrapingHistory.competitorCommission = spm.competitorCommission
562
        amazonScrapingHistory.returnProvision = spm.returnProvision
563
        amazonScrapingHistory.courierCost = val.courierCost
564
        amazonScrapingHistory.risky = val.risky
565
        amazonScrapingHistory.runType = RunType._NAMES_TO_VALUES.get(runType)
566
        amazonScrapingHistory.totalSeller = amDetails.totalSeller
567
        amazonScrapingHistory.competitiveCategory = CompetitionCategory.AMONG_CHEAPEST_CAN_COMPETE
568
        amazonScrapingHistory.timestamp = timestamp
569
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
570
        proposed_sp = max(amDetails.lowestSellerSp - max((5, amDetails.lowestSellerSp*0.001)), amPricing.lowestPossibleSp)
571
        proposed_tp = getTargetTp(proposed_sp,spm,val)
572
        amazonScrapingHistory.proposedSp = proposed_sp
573
        amazonScrapingHistory.proposedTp = proposed_tp
574
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
575
        amazonScrapingHistory.avgSale = calculateAverageSale(val.sku) #Last five days
576
    session.commit()
577
 
578
 
579
 
580
def commitCanCompete(canCompete,timestamp,runType):
581
    for canCompeteItem in canCompete:
582
        val = canCompeteItem[0]
583
        amDetails = canCompeteItem[1]
584
        amPricing = canCompeteItem[2]
585
        spm = val.sourcePercentage
586
        amazonScrapingHistory = AmazonScrapingHistory()
587
        amazonScrapingHistory.item_id = val.sku[3:]
588
        amazonScrapingHistory.warehouseLocation = val.state_id
589
        amazonScrapingHistory.ourSellingPrice = amDetails.ourSp
590
        amazonScrapingHistory.ourTp = amPricing.ourTp
591
        amazonScrapingHistory.lowestPossibleTp = amPricing.lowestPossibleTp
592
        amazonScrapingHistory.lowestPossibleSp = amPricing.lowestPossibleSp
593
        amazonScrapingHistory.ourRank = amDetails.ourRank
594
        amazonScrapingHistory.ourInventory = val.ourInventory
595
        amazonScrapingHistory.lowestSellerName = amDetails.lowestSellerName
596
        amazonScrapingHistory.lowestSellerSp = amDetails.lowestSellerSp
597
        amazonScrapingHistory.secondLowestSellerName = amDetails.secondLowestSellerName
598
        amazonScrapingHistory.secondLowestSellerSp = amDetails.secondLowestSellerSp
599
        amazonScrapingHistory.thirdLowestSellerName = amDetails.thirdLowestSellerName
600
        amazonScrapingHistory.thirdLowestSellerSp = amDetails.thirdLowestSellerSp
601
        amazonScrapingHistory.wanlc = val.nlc
602
        amazonScrapingHistory.commission = spm.commission
603
        amazonScrapingHistory.competitorCommission = spm.competitorCommission
604
        amazonScrapingHistory.returnProvision = spm.returnProvision
605
        amazonScrapingHistory.courierCost = val.courierCost
606
        amazonScrapingHistory.risky = val.risky
607
        amazonScrapingHistory.runType = RunType._NAMES_TO_VALUES.get(runType)
608
        amazonScrapingHistory.totalSeller = amDetails.totalSeller
609
        amazonScrapingHistory.competitiveCategory = CompetitionCategory.COMPETITIVE
610
        amazonScrapingHistory.timestamp = timestamp
611
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
612
        proposed_sp = max(amDetails.lowestSellerSp - max((5, amDetails.lowestSellerSp*0.001)), amPricing.lowestPossibleSp)
613
        proposed_tp = getTargetTp(proposed_sp,spm,val)
614
        amazonScrapingHistory.proposedSp = proposed_sp
615
        amazonScrapingHistory.proposedTp = proposed_tp
616
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
617
        amazonScrapingHistory.avgSale = calculateAverageSale(val.sku) #Last five days
618
    session.commit()
619
 
620
def commitAlmostCompete(almostCompete,timestamp):
621
    return
622
 
623
def commitCantCompete(cantCompete, timestamp,runType):
624
    for cantCompeteItem in cantCompete:
625
        val = cantCompeteItem[0]
626
        amDetails = cantCompeteItem[1]
627
        amPricing = cantCompeteItem[2]
628
        spm = val.sourcePercentage
629
        amazonScrapingHistory = AmazonScrapingHistory()
630
        amazonScrapingHistory.item_id = val.sku[3:]
631
        amazonScrapingHistory.warehouseLocation = val.state_id
632
        amazonScrapingHistory.ourSellingPrice = amDetails.ourSp
633
        amazonScrapingHistory.ourTp = amPricing.ourTp
634
        amazonScrapingHistory.lowestPossibleTp = amPricing.lowestPossibleTp
635
        amazonScrapingHistory.lowestPossibleSp = amPricing.lowestPossibleSp
636
        amazonScrapingHistory.ourRank = amDetails.ourRank
637
        amazonScrapingHistory.ourInventory = val.ourInventory
638
        amazonScrapingHistory.lowestSellerName = amDetails.lowestSellerName
639
        amazonScrapingHistory.lowestSellerSp = amDetails.lowestSellerSp
640
        amazonScrapingHistory.secondLowestSellerName = amDetails.secondLowestSellerName
641
        amazonScrapingHistory.secondLowestSellerSp = amDetails.secondLowestSellerSp
642
        amazonScrapingHistory.thirdLowestSellerName = amDetails.thirdLowestSellerName
643
        amazonScrapingHistory.thirdLowestSellerSp = amDetails.thirdLowestSellerSp
644
        amazonScrapingHistory.wanlc = val.nlc
645
        amazonScrapingHistory.commission = spm.commission
646
        amazonScrapingHistory.competitorCommission = spm.competitorCommission
647
        amazonScrapingHistory.returnProvision = spm.returnProvision
648
        amazonScrapingHistory.courierCost = val.courierCost
649
        amazonScrapingHistory.risky = val.risky
650
        amazonScrapingHistory.runType = RunType._NAMES_TO_VALUES.get(runType)
651
        amazonScrapingHistory.totalSeller = amDetails.totalSeller
652
        amazonScrapingHistory.competitiveCategory = CompetitionCategory.CANT_COMPETE
653
        amazonScrapingHistory.timestamp = timestamp
654
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
655
        proposed_sp = amDetails.lowestSellerSp - max(5, amDetails.lowestSellerSp*0.001)
656
        proposed_tp = getTargetTp(proposed_sp,spm,val)
657
        target_nlc = proposed_tp - amPricing.lowestPossibleTp + val.nlc
658
        amazonScrapingHistory.proposedSp = proposed_sp
659
        amazonScrapingHistory.proposedTp = proposed_tp
660
        amazonScrapingHistory.targetNlc = target_nlc
661
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
662
        amazonScrapingHistory.avgSale = calculateAverageSale(val.sku) #Last five days
663
    session.commit()
664
 
665
def main():
666
    parser = optparse.OptionParser()
667
    parser.add_option("-t", "--type", dest="runType",
668
                   default="FULL", type="string",
669
                   help="Run type FULL or FAVOURITE")
670
    (options, args) = parser.parse_args()
671
    if options.runType not in ('FULL','FAVOURITE'):
672
        print "Run type argument illegal."
673
        sys.exit(1)
674
    time.sleep(5)
675
    timestamp = datetime.now()
676
    syncAsin()
677
    fetchFbaSale()
678
    itemInfo = populateStuff(timestamp,options.runType)
679
    itemsToPopulate = 0
680
    while (len(itemInfo)>0):
681
        if len(itemInfo) > 50:
682
            itemsToPopulate = 50
683
        else:
684
            itemsToPopulate = len(itemInfo)
685
        exceptionList, negativeMargin, cheapest, amongCheapestAndCanCompete, canCompete, almostCompete, cantCompete = decideCategory(itemInfo[0:itemsToPopulate])
686
        itemInfo[0:itemsToPopulate] = []
687
        commitExceptionList(exceptionList,timestamp,options.runType)
688
        commitNegativeMargin(negativeMargin,timestamp,options.runType)
689
        commitCheapest(cheapest,timestamp,options.runType)
690
        commitAmongCheapestAndCanCompete(amongCheapestAndCanCompete,timestamp,options.runType)
691
        commitCanCompete(canCompete,timestamp,options.runType)
692
        commitAlmostCompete(almostCompete,timestamp,options.runType)
693
        commitCantCompete(cantCompete, timestamp,options.runType)
694
        exceptionList[:], negativeMargin[:], cheapest[:], amongCheapestAndCanCompete[:], canCompete[:], almostCompete[:], cantCompete[:] =[],[],[],[],[],[],[] 
695
 
696
if __name__=='__main__':
697
    main()