Subversion Repositories SmartDukaan

Rev

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