Subversion Repositories SmartDukaan

Rev

Rev 12364 | Rev 12366 | 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 = []
161
                for l in saleMap.get('FBA'+str(saleSnapshot.item_id)):
162
                    temp.append(l)
163
                temp.append(saleSnapshot)
164
            else:
165
                saleMap['FBA'+str(saleSnapshot.item_id)] = saleSnapshot
166
        else:
167
            if saleMap.has_key('FBB'+str(saleSnapshot.item_id)):
168
                temp = []
169
                for l in saleMap.get('FBB'+str(saleSnapshot.item_id)):
170
                    temp.append(l)
171
                temp.append(saleSnapshot)
172
            else:
173
                saleMap['FBB'+str(saleSnapshot.item_id)] = saleSnapshot
174
 
175
def calculateAverageSale(sku):
176
    count,sale = 0,0
177
    oosStatus = saleMap.get(sku)
178
    for obj in oosStatus:
179
        if not obj.is_oos:
180
            count+=1
181
            sale = sale+obj.num_orders
182
    avgSalePerDay=0 if count==0 else (float(sale)/count)
183
    return round(avgSalePerDay,2)
184
 
185
 
186
 
187
 
188
def computeCourierCost(weight):
189
    cCost = 10.0;
190
    slabs = int((weight*1000)/500-.001)
191
    for slab in range(0,slabs):
192
        cCost = cCost + 10.0;
193
    return cCost;
194
 
195
 
196
def populateStuff(time,runType):
197
    global amazonLongTermActivePromotions
198
    itemInfo = []
199
    inventory_client = InventoryClient().get_client()
200
    fbaAvailableInventorySnapshot = inventory_client.getAllAvailableAmazonFbaItemInventory()
201
    for fbaInventoryItem in fbaAvailableInventorySnapshot:
202
        d_amazon_listed = Amazonlisted.get_by(itemId=fbaInventoryItem.item_id)
203
        if d_amazon_listed is None:
204
            continue
205
        if d_amazon_listed.overrrideWanlc:
206
            wanlc = d_amazon_listed.exceptionalWanlc
207
        else:
208
            wanlc = inventory_client.getWanNlcForSource(fbaInventoryItem.item_id,OrderSource.AMAZON)
209
        it = Item.query.filter_by(id=fbaInventoryItem.item_id).one()
210
        category = Category.query.filter_by(id=it.category).one()
211
        parent_category = Category.query.filter_by(id=category.parent_category_id).first()
212
        scp = SourceCategoryPercentage.query.filter(SourceCategoryPercentage.category_id==it.category).filter(SourceCategoryPercentage.source==OrderSource.AMAZON).filter(SourceCategoryPercentage.startDate<=time).filter(SourceCategoryPercentage.expiryDate>=time).first()
213
        if scp is not None:
214
            sourcePercentage = scp
215
        else:
216
            spm = SourcePercentageMaster.get_by(source=OrderSource.AMAZON)
217
            sourcePercentage = spm
218
        if fbaInventoryItem.location==0:
219
            sku = 'FBA'+fbaInventoryItem.item_id
220
            state_id = 1
221
        elif fbaInventoryItem.location==1:
222
            sku = 'FBB'+fbaInventoryItem.item_id
223
            state_id = 2
224
        else:
225
            continue
226
        cc = computeCourierCost(it.weight)
227
        if amazonAsinPrice.get(sku) is None:
228
            asin = None
229
        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)
230
        itemInfo.append(amazonItemInfo)
231
    amPromotions = AmazonPromotion.query.filter(AmazonPromotion.startDate<=time).filter(AmazonPromotion.endDate>=time).filter(AmazonPromotion.promotionType==AmazonPromotionType.LONGTERM).filter(AmazonPromotion.promotionActive==True) \
232
    .group_by(AmazonPromotion.sku).order_by(desc(AmazonPromotion.addedOn)).all()
233
    for amPromotion in amPromotions:
234
        amazonLongTermActivePromotions.append(amPromotion.sku)
235
    session.close()
236
    return itemInfo
237
 
238
def decideCategory(itemInfo):
239
    exceptionList, negativeMargin, cheapest, amongCheapestAndCanCompete, canCompete, almostCompete, cantCompete = [],[],[],[],[],[],[] 
240
    skuUrls = []
241
    #skuAsinMap = {}
242
    for item in itemInfo:
243
        if item.asin is None:
244
            temp = []
245
            temp.append(item)
246
            temp.append("Asin not available")
247
            exceptionList.append(temp)
248
            continue
249
        skuUrls.append('http://www.amazon.in/gp/offer-listing/'+item.asin+'/ref=olp_sort_ps')
250
    aggResponse = amScraper.read(skuUrls, True)
251
#    for asin, scrapInfo in aggResponse:
252
#        skuList = skuAsinMap.get(asin)
253
#        for sku in skuList:
254
#            amDetails = __AmazonDetails(None, None, None, None, None,secondLowestSellerName, secondLowestSellerSp, thirdLowestSellerName, thirdLowestSellerSp)
255
#            for info in scrapInfo:
256
    catalog_client = CatalogClient().get_client()
257
    for val in itemInfo:
258
        if val.asin is None:
259
            continue
260
        scrapInfo = aggResponse.get(val.asin)
261
        if val.sku in amazonLongTermActivePromotions:
262
            print "Sku in promotion, will handle it later.Moving to other..."
263
            continue
264
        if scrapInfo is None or val.nlc==0:
265
            temp = []
266
            temp.append(val)
267
            if val.nlc==0 or val.nlc is None:
268
                temp.append("WANLC is 0")
269
            else:
270
                temp.append("Not able to fetch")
271
            exceptionList.append(temp)
272
            continue
273
        iterator = 0
274
        sku, lowestSellerName,secondLowestSellerName, thirdLowestSellerName = ('',)*4
275
        ourSp, ourRank, lowestSellerSp, secondLowestSellerSp, thirdLowestSellerSp, ourTp, lowestPossibleSp, lowestPossibleTp = (0,)*8
276
        sku = val.sku
277
        scrapedSkuLocation = None
278
        multipleListings = False
279
        for info in scrapInfo:
280
            if (info.sellerName).strip()=='Saholic':
281
                if ourRank>0:
282
                    multipleListings = True
283
                ourSp = info.sellerPrice
284
                ourRank = iterator+1
285
                if val.state_id==1:
286
                    #It means sku starts with FBA
287
                    fbaPrice = (amazonAsinPrice.get(val.sku)).price
288
                    try:
289
                        if ourSp==fbaPrice:
290
                            scrapedSkuLocation = val.state_id
291
                    except:
292
                        scrapedSkuLocation = None
293
                elif val.state_id==2:
294
                    #It means sku starts with FBB
295
                    fbbPrice = (amazonAsinPrice.get(val.sku)).price
296
                    try:
297
                        if ourSp==fbbPrice:
298
                            scrapedSkuLocation = val.state_id
299
                    except:
300
                        scrapedSkuLocation = None
301
                else:
302
                    scrapedSkuLocation = None
303
                if scrapedSkuLocation is None:
304
                    print "fishy...confused for ", val.sku
305
 
306
            if iterator == 0:
307
                lowestSellerName = info.sellerName
308
                lowestSellerSp = info.sellerPrice
309
 
310
            if iterator == 1:
311
                secondLowestSellerName = info.sellerName
312
                secondLowestSellerSp = info.sellerPrice
313
 
314
            if iterator == 2:
315
                thirdLowestSellerName = info.sellerName
316
                thirdLowestSellerSp = info.sellerPrice
317
 
318
            iterator += 1
319
 
320
        #if cheapestSkuLocation!=val.state_id
321
 
322
        if ourSp==0 or scrapedSkuLocation is None:
323
            print "Sku not present in top 3.Getting price from amazonAsinPrice...or multiple listings"
324
            if ourSp==0:
325
                ourRank = 999 #Due to pagination and large no of sellers.Taking it as dummy value, means we are not in top 3
326
                ourSp = (amazonAsinPrice.get(val.sku)).price
327
                if ourSp is None or ourSp==0:
328
                    temp = []
329
                    temp.append(val)
330
                    temp.append("Price not available")
331
                    exceptionList.append(temp)
332
                    continue
333
            else:
334
                #determine rank
335
                if ourSp <= lowestSellerSp or lowestSellerSp==0:
336
                    ourRank = 1
337
                elif ourSp > lowestSellerSp and (ourSp <= secondLowestSellerSp or secondLowestSellerSp==0):
338
                    ourRank = 2
339
                elif ourSp > secondLowestSellerSp and (ourSp<=thirdLowestSellerSp or thirdLowestSellerSp==0):
340
                    ourRank = 3
341
                else:
342
                    ourRank = 999
343
 
344
        if multipleListings:
345
            print "multiple listings..."
346
            ourSp = (amazonAsinPrice.get(val.sku)).price
347
            if ourSp is None or ourSp==0:
348
                temp = []
349
                temp.append(val)
350
                temp.append("Price not available")
351
                exceptionList.append(temp)
352
                continue
353
            if ourSp <= lowestSellerSp:
354
                    ourRank = 1
355
            elif ourSp > lowestSellerSp and (ourSp <= secondLowestSellerSp or secondLowestSellerSp==0):
356
                ourRank = 2
357
            elif ourSp > secondLowestSellerSp and (ourSp<=thirdLowestSellerSp or thirdLowestSellerSp==0):
358
                ourRank = 3
359
            else:
360
                ourRank = 999
361
 
362
 
363
        amDetails = __AmazonDetails(sku, ourSp, ourRank, lowestSellerName,lowestSellerSp,secondLowestSellerName, secondLowestSellerSp, thirdLowestSellerName, thirdLowestSellerSp,len(scrapInfo),multipleListings)
364
        try:
365
            val.vatRate = catalog_client.getVatPercentageForItem(int(val.sku[3:]), val.state_id, amDetails.ourSp)
366
        except:
367
            temp = []
368
            temp.append(val)
369
            temp.append("Vat not available")
370
            exceptionList.append(temp)
371
            continue
372
 
373
        ourTp = getOurTp(amDetails,val,val.sourcePercentage)
374
        lowestPossibleTp = getLowestPossibleTp(amDetails,val,val.sourcePercentage)
375
        lowestPossibleSp = getLowestPossibleSp(amDetails,val,val.sourcePercentage)
376
        amPricing = __AmazonPricing(ourSp,ourTp,lowestPossibleTp,lowestPossibleSp)
377
 
378
        if amPricing.ourTp < amPricing.lowestPossibleTp:
379
            temp = []
380
            temp.append(val)
381
            temp.append(amDetails)
382
            temp.append(amPricing)
383
            negativeMargin.append(temp)
384
            continue
385
 
386
        if amDetails.ourRank==1:
387
            temp = []
388
            temp.append(val)
389
            temp.append(amDetails)
390
            temp.append(amPricing)
391
            cheapest.append(temp)
392
            continue
393
 
394
        if (amDetails.lowestSellerSp > amPricing.lowestPossibleSp) and ((((float(amDetails.ourSp - amDetails.lowestSellerSp))/amDetails.ourSp)<=.01) or ((amDetails.ourSp - amDetails.lowestSellerSp)<=25)):
395
            temp = []
396
            temp.append(val)
397
            temp.append(amDetails)
398
            temp.append(amPricing)
399
            amongCheapestAndCanCompete.append(temp)
400
            continue
401
 
402
        if (amDetails.lowestSellerSp > amPricing.lowestPossibleSp):
403
            temp = []
404
            temp.append(val)
405
            temp.append(amDetails)
406
            temp.append(amPricing)
407
            canCompete.append(temp)
408
            continue
409
 
410
        temp = []
411
        temp.append(val)
412
        temp.append(amDetails)
413
        temp.append(amPricing)
414
        cantCompete.append(temp)
415
 
416
    itemInfo[:]=[]
417
    scrapInfo[:]=[]
418
    return exceptionList, negativeMargin, cheapest, amongCheapestAndCanCompete, canCompete, almostCompete, cantCompete
419
 
420
def getOurTp(amazonDetails,val,spm):
421
    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));
422
    return round(ourTp,2)
423
 
424
def getLowestPossibleTp(amazonDetails,val,spm):
425
    vat = (amazonDetails.ourSp/(1+(val.vatRate/100))-(val.nlc/(1+(val.vatRate/100))))*(val.vatRate/100)
426
    inHouseCost = 15+vat+(spm.returnProvision/100)*amazonDetails.ourSp
427
    lowest_possible_tp = val.nlc+inHouseCost
428
    return round(lowest_possible_tp,2)
429
 
430
def getLowestPossibleSp(amazonDetails,val,spm):
431
    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));
432
    return round(lowestPossibleSp,2)
433
 
434
def getTargetTp(targetSp,spm,val):
435
    targetTp = targetSp- targetSp*(spm.commission/100+spm.emiFee/100)*(1+(spm.serviceTax/100))-(val.courierCost)*(1+(val.serviceTax/100))
436
    return round(targetTp,2)
437
 
438
def commitExceptionList(exceptionList,timestamp,runType):
439
    for exceptionItem in exceptionList:
440
        val = exceptionItem[0]
441
        reason = exceptionItem[1]
442
        amazonScrapingHistory = AmazonScrapingHistory()
443
        amazonScrapingHistory.item_id = val.sku[3:]
444
        amazonScrapingHistory.warehouseLocation = val.state_id
445
        amazonScrapingHistory.reason = reason
446
        amazonScrapingHistory.runType = RunType._NAMES_TO_VALUES.get(runType)
447
        amazonScrapingHistory.competitiveCategory = CompetitionCategory.EXCEPTION
448
        amazonScrapingHistory.timestamp = timestamp
449
    session.commit()
450
 
451
def commitNegativeMargin(negativeMargin,timestamp,runType):
452
    for negativeMarginItem in negativeMargin:
453
        val = negativeMarginItem[0]
454
        amDetails = negativeMarginItem[1]
455
        amPricing = negativeMarginItem[2]
456
        spm = val.sourcePercentage
457
        amazonScrapingHistory = AmazonScrapingHistory()
458
        amazonScrapingHistory.item_id = val.sku[3:]
459
        amazonScrapingHistory.warehouseLocation = val.state_id
460
        amazonScrapingHistory.ourSellingPrice = amDetails.ourSp
461
        amazonScrapingHistory.ourTp = amPricing.ourTp
462
        amazonScrapingHistory.lowestPossibleTp = amPricing.lowestPossibleTp
463
        amazonScrapingHistory.lowestPossibleSp = amPricing.lowestPossibleSp
464
        amazonScrapingHistory.ourRank = amDetails.ourRank
465
        amazonScrapingHistory.ourInventory = val.ourInventory
466
        amazonScrapingHistory.lowestSellerName = amDetails.lowestSellerName
467
        amazonScrapingHistory.lowestSellerSp = amDetails.lowestSellerSp
468
        amazonScrapingHistory.secondLowestSellerName = amDetails.secondLowestSellerName
469
        amazonScrapingHistory.secondLowestSellerSp = amDetails.secondLowestSellerSp
470
        amazonScrapingHistory.thirdLowestSellerName = amDetails.thirdLowestSellerName
471
        amazonScrapingHistory.thirdLowestSellerSp = amDetails.thirdLowestSellerSp
472
        amazonScrapingHistory.wanlc = val.nlc
473
        amazonScrapingHistory.commission = spm.commission
474
        amazonScrapingHistory.competitorCommission = spm.competitorCommission
475
        amazonScrapingHistory.returnProvision = spm.returnProvision
476
        amazonScrapingHistory.courierCost = val.courierCost
477
        amazonScrapingHistory.risky = val.risky
478
        amazonScrapingHistory.runType = RunType._NAMES_TO_VALUES.get(runType)
479
        amazonScrapingHistory.totalSeller = amDetails.totalSeller
480
        amazonScrapingHistory.competitiveCategory = CompetitionCategory.NEGATIVE_MARGIN
481
        amazonScrapingHistory.timestamp = timestamp
482
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
483
        amazonScrapingHistory.avgSale = calculateAverageSale(val.sku) #Last five days
484
    session.commit()
485
 
486
 
487
def commitCheapest(cheapest,timestamp,runType):
488
    for cheapestItem in cheapest:
489
        val = cheapestItem[0]
490
        amDetails = cheapestItem[1]
491
        amPricing = cheapestItem[2]
492
        spm = val.sourcePercentage
493
        amazonScrapingHistory = AmazonScrapingHistory()
494
        amazonScrapingHistory.item_id = val.sku[3:]
495
        amazonScrapingHistory.warehouseLocation = val.state_id
496
        amazonScrapingHistory.ourSellingPrice = amDetails.ourSp
497
        amazonScrapingHistory.ourTp = amPricing.ourTp
498
        amazonScrapingHistory.lowestPossibleTp = amPricing.lowestPossibleTp
499
        amazonScrapingHistory.lowestPossibleSp = amPricing.lowestPossibleSp
500
        amazonScrapingHistory.ourRank = amDetails.ourRank
501
        amazonScrapingHistory.ourInventory = val.ourInventory
502
        amazonScrapingHistory.lowestSellerName = amDetails.lowestSellerName
503
        amazonScrapingHistory.lowestSellerSp = amDetails.lowestSellerSp
504
        amazonScrapingHistory.secondLowestSellerName = amDetails.secondLowestSellerName
505
        amazonScrapingHistory.secondLowestSellerSp = amDetails.secondLowestSellerSp
506
        amazonScrapingHistory.thirdLowestSellerName = amDetails.thirdLowestSellerName
507
        amazonScrapingHistory.thirdLowestSellerSp = amDetails.thirdLowestSellerSp
508
        amazonScrapingHistory.wanlc = val.nlc
509
        amazonScrapingHistory.commission = spm.commission
510
        amazonScrapingHistory.competitorCommission = spm.competitorCommission
511
        amazonScrapingHistory.returnProvision = spm.returnProvision
512
        amazonScrapingHistory.courierCost = val.courierCost
513
        amazonScrapingHistory.risky = val.risky
514
        amazonScrapingHistory.runType = RunType._NAMES_TO_VALUES.get(runType)
515
        amazonScrapingHistory.totalSeller = amDetails.totalSeller
516
        amazonScrapingHistory.competitiveCategory = CompetitionCategory.BUY_BOX
517
        amazonScrapingHistory.timestamp = timestamp
518
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
519
        if amDetails.secondLowestSellerName!='Saholic':
520
            competitorSp = amDetails.secondLowestSellerSp
521
        else:
522
            competitorSp = amDetails.thirdLowestSellerSp
523
        proposed_sp = max(competitorSp - max((20, competitorSp*0.002)), amPricing.lowestPossibleSp)
524
        proposed_tp = getTargetTp(proposed_sp,spm,val)
525
        amazonScrapingHistory.proposedSp = proposed_sp
526
        amazonScrapingHistory.proposedTp = proposed_tp
527
        amazonScrapingHistory.marginIncreasedPotential = proposed_tp - amPricing.ourTp
528
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
529
        amazonScrapingHistory.avgSale = calculateAverageSale(val.sku) #Last five days
530
    session.commit()
531
 
532
 
533
 
534
def commitAmongCheapestAndCanCompete(amongCheapestAndCanCompete,timestamp,runType):
535
    for amongCheapestAndCanCompeteItem in amongCheapestAndCanCompete:
536
        val = amongCheapestAndCanCompeteItem[0]
537
        amDetails = amongCheapestAndCanCompeteItem[1]
538
        amPricing = amongCheapestAndCanCompeteItem[2]
539
        spm = val.sourcePercentage
540
        amazonScrapingHistory = AmazonScrapingHistory()
541
        amazonScrapingHistory.item_id = val.sku[3:]
542
        amazonScrapingHistory.warehouseLocation = val.state_id
543
        amazonScrapingHistory.ourSellingPrice = amDetails.ourSp
544
        amazonScrapingHistory.ourTp = amPricing.ourTp
545
        amazonScrapingHistory.lowestPossibleTp = amPricing.lowestPossibleTp
546
        amazonScrapingHistory.lowestPossibleSp = amPricing.lowestPossibleSp
547
        amazonScrapingHistory.ourRank = amDetails.ourRank
548
        amazonScrapingHistory.ourInventory = val.ourInventory
549
        amazonScrapingHistory.lowestSellerName = amDetails.lowestSellerName
550
        amazonScrapingHistory.lowestSellerSp = amDetails.lowestSellerSp
551
        amazonScrapingHistory.secondLowestSellerName = amDetails.secondLowestSellerName
552
        amazonScrapingHistory.secondLowestSellerSp = amDetails.secondLowestSellerSp
553
        amazonScrapingHistory.thirdLowestSellerName = amDetails.thirdLowestSellerName
554
        amazonScrapingHistory.thirdLowestSellerSp = amDetails.thirdLowestSellerSp
555
        amazonScrapingHistory.wanlc = val.nlc
556
        amazonScrapingHistory.commission = spm.commission
557
        amazonScrapingHistory.competitorCommission = spm.competitorCommission
558
        amazonScrapingHistory.returnProvision = spm.returnProvision
559
        amazonScrapingHistory.courierCost = val.courierCost
560
        amazonScrapingHistory.risky = val.risky
561
        amazonScrapingHistory.runType = RunType._NAMES_TO_VALUES.get(runType)
562
        amazonScrapingHistory.totalSeller = amDetails.totalSeller
563
        amazonScrapingHistory.competitiveCategory = CompetitionCategory.AMONG_CHEAPEST_CAN_COMPETE
564
        amazonScrapingHistory.timestamp = timestamp
565
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
566
        proposed_sp = max(amDetails.lowestSellerSp - max((5, amDetails.lowestSellerSp*0.001)), amPricing.lowestPossibleSp)
567
        proposed_tp = getTargetTp(proposed_sp,spm,val)
568
        amazonScrapingHistory.proposedSp = proposed_sp
569
        amazonScrapingHistory.proposedTp = proposed_tp
570
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
571
        amazonScrapingHistory.avgSale = calculateAverageSale(val.sku) #Last five days
572
    session.commit()
573
 
574
 
575
 
576
def commitCanCompete(canCompete,timestamp,runType):
577
    for canCompeteItem in canCompete:
578
        val = canCompeteItem[0]
579
        amDetails = canCompeteItem[1]
580
        amPricing = canCompeteItem[2]
581
        spm = val.sourcePercentage
582
        amazonScrapingHistory = AmazonScrapingHistory()
583
        amazonScrapingHistory.item_id = val.sku[3:]
584
        amazonScrapingHistory.warehouseLocation = val.state_id
585
        amazonScrapingHistory.ourSellingPrice = amDetails.ourSp
586
        amazonScrapingHistory.ourTp = amPricing.ourTp
587
        amazonScrapingHistory.lowestPossibleTp = amPricing.lowestPossibleTp
588
        amazonScrapingHistory.lowestPossibleSp = amPricing.lowestPossibleSp
589
        amazonScrapingHistory.ourRank = amDetails.ourRank
590
        amazonScrapingHistory.ourInventory = val.ourInventory
591
        amazonScrapingHistory.lowestSellerName = amDetails.lowestSellerName
592
        amazonScrapingHistory.lowestSellerSp = amDetails.lowestSellerSp
593
        amazonScrapingHistory.secondLowestSellerName = amDetails.secondLowestSellerName
594
        amazonScrapingHistory.secondLowestSellerSp = amDetails.secondLowestSellerSp
595
        amazonScrapingHistory.thirdLowestSellerName = amDetails.thirdLowestSellerName
596
        amazonScrapingHistory.thirdLowestSellerSp = amDetails.thirdLowestSellerSp
597
        amazonScrapingHistory.wanlc = val.nlc
598
        amazonScrapingHistory.commission = spm.commission
599
        amazonScrapingHistory.competitorCommission = spm.competitorCommission
600
        amazonScrapingHistory.returnProvision = spm.returnProvision
601
        amazonScrapingHistory.courierCost = val.courierCost
602
        amazonScrapingHistory.risky = val.risky
603
        amazonScrapingHistory.runType = RunType._NAMES_TO_VALUES.get(runType)
604
        amazonScrapingHistory.totalSeller = amDetails.totalSeller
605
        amazonScrapingHistory.competitiveCategory = CompetitionCategory.COMPETITIVE
606
        amazonScrapingHistory.timestamp = timestamp
607
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
608
        proposed_sp = max(amDetails.lowestSellerSp - max((5, amDetails.lowestSellerSp*0.001)), amPricing.lowestPossibleSp)
609
        proposed_tp = getTargetTp(proposed_sp,spm,val)
610
        amazonScrapingHistory.proposedSp = proposed_sp
611
        amazonScrapingHistory.proposedTp = proposed_tp
612
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
613
        amazonScrapingHistory.avgSale = calculateAverageSale(val.sku) #Last five days
614
    session.commit()
615
 
616
def commitAlmostCompete(almostCompete,timestamp):
617
    return
618
 
619
def commitCantCompete(cantCompete, timestamp,runType):
620
    for cantCompeteItem in cantCompete:
621
        val = cantCompeteItem[0]
622
        amDetails = cantCompeteItem[1]
623
        amPricing = cantCompeteItem[2]
624
        spm = val.sourcePercentage
625
        amazonScrapingHistory = AmazonScrapingHistory()
626
        amazonScrapingHistory.item_id = val.sku[3:]
627
        amazonScrapingHistory.warehouseLocation = val.state_id
628
        amazonScrapingHistory.ourSellingPrice = amDetails.ourSp
629
        amazonScrapingHistory.ourTp = amPricing.ourTp
630
        amazonScrapingHistory.lowestPossibleTp = amPricing.lowestPossibleTp
631
        amazonScrapingHistory.lowestPossibleSp = amPricing.lowestPossibleSp
632
        amazonScrapingHistory.ourRank = amDetails.ourRank
633
        amazonScrapingHistory.ourInventory = val.ourInventory
634
        amazonScrapingHistory.lowestSellerName = amDetails.lowestSellerName
635
        amazonScrapingHistory.lowestSellerSp = amDetails.lowestSellerSp
636
        amazonScrapingHistory.secondLowestSellerName = amDetails.secondLowestSellerName
637
        amazonScrapingHistory.secondLowestSellerSp = amDetails.secondLowestSellerSp
638
        amazonScrapingHistory.thirdLowestSellerName = amDetails.thirdLowestSellerName
639
        amazonScrapingHistory.thirdLowestSellerSp = amDetails.thirdLowestSellerSp
640
        amazonScrapingHistory.wanlc = val.nlc
641
        amazonScrapingHistory.commission = spm.commission
642
        amazonScrapingHistory.competitorCommission = spm.competitorCommission
643
        amazonScrapingHistory.returnProvision = spm.returnProvision
644
        amazonScrapingHistory.courierCost = val.courierCost
645
        amazonScrapingHistory.risky = val.risky
646
        amazonScrapingHistory.runType = RunType._NAMES_TO_VALUES.get(runType)
647
        amazonScrapingHistory.totalSeller = amDetails.totalSeller
648
        amazonScrapingHistory.competitiveCategory = CompetitionCategory.CANT_COMPETE
649
        amazonScrapingHistory.timestamp = timestamp
650
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
651
        proposed_sp = amDetails.lowestSellerSp - max(5, amDetails.lowestSellerSp*0.001)
652
        proposed_tp = getTargetTp(proposed_sp,spm,val)
653
        target_nlc = proposed_tp - amPricing.lowestPossibleTp + val.nlc
654
        amazonScrapingHistory.proposedSp = proposed_sp
655
        amazonScrapingHistory.proposedTp = proposed_tp
656
        amazonScrapingHistory.targetNlc = target_nlc
657
        amazonScrapingHistory.multipleListings = amDetails.multipleListings
658
        amazonScrapingHistory.avgSale = calculateAverageSale(val.sku) #Last five days
659
    session.commit()
660
 
661
def main():
662
    parser = optparse.OptionParser()
663
    parser.add_option("-t", "--type", dest="runType",
664
                   default="FULL", type="string",
665
                   help="Run type FULL or FAVOURITE")
666
    (options, args) = parser.parse_args()
667
    if options.runType not in ('FULL','FAVOURITE'):
668
        print "Run type argument illegal."
669
        sys.exit(1)
670
    time.sleep(5)
671
    timestamp = datetime.now()
672
    syncAsin()
673
    fetchFbaSale()
674
    itemInfo = populateStuff(timestamp,options.runType)
675
    itemsToPopulate = 0
676
    while (len(itemInfo)>0):
677
        if len(itemInfo) > 50:
678
            itemsToPopulate = 50
679
        else:
680
            itemsToPopulate = len(itemInfo)
681
        exceptionList, negativeMargin, cheapest, amongCheapestAndCanCompete, canCompete, almostCompete, cantCompete = decideCategory(itemInfo[0:itemsToPopulate])
682
        itemInfo[0:itemsToPopulate] = []
683
        commitExceptionList(exceptionList,timestamp,options.runType)
684
        commitNegativeMargin(negativeMargin,timestamp,options.runType)
685
        commitCheapest(cheapest,timestamp,options.runType)
686
        commitAmongCheapestAndCanCompete(amongCheapestAndCanCompete,timestamp,options.runType)
687
        commitCanCompete(canCompete,timestamp,options.runType)
688
        commitAlmostCompete(almostCompete,timestamp,options.runType)
689
        commitCantCompete(cantCompete, timestamp,options.runType)
690
        exceptionList[:], negativeMargin[:], cheapest[:], amongCheapestAndCanCompete[:], canCompete[:], almostCompete[:], cantCompete[:] =[],[],[],[],[],[],[] 
691
 
692
if __name__=='__main__':
693
    main()