Subversion Repositories SmartDukaan

Rev

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