Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
6903 anupam.sin 1
# -*- coding: utf-8 -*-
2
 
104 ashish 3
'''
4
Created on 29-Mar-2010
5
 
2536 chandransh 6
@author: Chandranshu
104 ashish 7
'''
2536 chandransh 8
 
4369 rajveer 9
from datetime import date, timedelta
7151 amit.gupta 10
from decimal import Decimal
11
from elixir import *
6424 rajveer 12
from math import ceil
5944 mandeep.dh 13
from random import randrange
7151 amit.gupta 14
from reportlab.lib.enums import TA_CENTER, TA_JUSTIFY
15
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
3499 mandeep.dh 16
from reportlab.lib.units import inch
2536 chandransh 17
from reportlab.pdfgen.canvas import Canvas
6980 anupam.sin 18
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, \
19
    BaseDocTemplate, Frame, PageTemplate
7151 amit.gupta 20
from reportlab.rl_config import defaultPageSize
5944 mandeep.dh 21
from shop2020.clients.AlertClient import AlertClient
3499 mandeep.dh 22
from shop2020.clients.CatalogClient import CatalogClient
23
from shop2020.clients.HelperClient import HelperClient
5944 mandeep.dh 24
from shop2020.clients.InventoryClient import InventoryClient
3499 mandeep.dh 25
from shop2020.clients.LogisticsClient import LogisticsClient
2747 chandransh 26
from shop2020.clients.PaymentClient import PaymentClient
7151 amit.gupta 27
from shop2020.clients.PromotionClient import PromotionClient
3499 mandeep.dh 28
from shop2020.clients.UserClient import UserClient
29
from shop2020.clients.WarehouseClient import WarehouseClient
7151 amit.gupta 30
from shop2020.config.client.ConfigClient import ConfigClient
3499 mandeep.dh 31
from shop2020.model.v1 import order
6048 rajveer 32
from shop2020.model.v1.order.impl import DataService, RechargeService
7198 amar.kumar 33
from shop2020.model.v1.order.impl.Convertors import to_t_emi_scheme, to_t_order
3499 mandeep.dh 34
from shop2020.model.v1.order.impl.DataService import Transaction, LineItem, \
4435 mandeep.dh 35
    Order, BatchNoGenerator, InvoiceIDGenerator, TransactionRequiringExtraProcessing, \
5348 anupam.sin 36
    OrderInventory, Alert, PaymentSettlement, EBSSettlementSummary, \
7151 amit.gupta 37
    CodVerificationAgent, Attribute, RechargeVoucherTracker, EmiScheme, MiscCharges, \
38
    BlockedIpRange, DeniedIpAddress, InsuranceDetailForOrder, DocumentStore, \
39
    RechargeTransaction, HotspotStore, WalletForCompany, WalletHistoryForCompany, \
7311 kshitij.so 40
    FRC, OperatorSeries, SourceDetail, Company, \
41
    AmazonOrder
7151 amit.gupta 42
from shop2020.model.v1.order.impl.model.BaseOrder import BaseOrder
43
from shop2020.model.v1.order.impl.model.DTHRechargeOrder import DTHRechargeOrder
6000 mandeep.dh 44
from shop2020.model.v1.order.impl.model.MobileRechargeOrder import \
45
    MobileRechargeOrder
7151 amit.gupta 46
from shop2020.model.v1.order.impl.model.RechargeDenomination import \
47
    RechargeDenomination
48
from shop2020.model.v1.order.impl.model.RechargeOrder import RechargeOrder
49
from shop2020.model.v1.order.impl.model.RechargePlan import RechargePlan
2687 chandransh 50
from shop2020.model.v1.order.impl.model.ReturnOrder import ReturnOrder
7151 amit.gupta 51
from shop2020.model.v1.order.impl.model.ServiceAvailability import \
52
    ServiceAvailability
53
from shop2020.model.v1.order.impl.model.ServiceProvider import ServiceProvider
54
from shop2020.model.v1.order.impl.model.TelecomCircle import TelecomCircle
55
from shop2020.model.v1.order.impl.model.UserWallet import UserWallet
56
from shop2020.model.v1.order.impl.model.UserWalletHistory import \
57
    UserWalletHistory
5944 mandeep.dh 58
from shop2020.thriftpy.alert.ttypes import MonitoredEntity, EntityType
5527 anupam.sin 59
from shop2020.thriftpy.logistics.ttypes import DeliveryType, PickUpType
6000 mandeep.dh 60
from shop2020.thriftpy.model.v1.catalog.ttypes import ItemType
5944 mandeep.dh 61
from shop2020.thriftpy.model.v1.inventory.ttypes import BillingType, \
62
    InventoryServiceException, WarehouseType, InventoryType
4435 mandeep.dh 63
from shop2020.thriftpy.model.v1.order.ttypes import TransactionServiceException, \
64
    TransactionStatus, OrderStatus, DelayReason, ExtraTransactionProcessingType, \
7151 amit.gupta 65
    HotspotAction, TimeoutSummary, OrderStatusGroups, OrderType, RechargeOrderStatus, \
7293 anupam.sin 66
    RechargeType, RechargeStatistics, DeviceNumberInfo, EmiChargeType, PayMethod, OrderSource
5944 mandeep.dh 67
from shop2020.thriftpy.model.v1.user.ttypes import VoucherType
4421 mandeep.dh 68
from shop2020.thriftpy.payments.ttypes import PaymentException
5110 mandeep.dh 69
from shop2020.thriftpy.warehouse.ttypes import ScanType, \
70
    WarehouseServiceException
6000 mandeep.dh 71
from shop2020.utils.EmailAttachmentSender import mail, get_attachment_part
855 rajveer 72
from shop2020.utils.Utils import to_py_date, to_java_date
4008 mandeep.dh 73
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
3499 mandeep.dh 74
from sqlalchemy.sql import func
7151 amit.gupta 75
from sqlalchemy.sql.expression import and_, or_, desc, not_, distinct, cast, \
76
    between
3499 mandeep.dh 77
from string import Template
78
from textwrap import dedent
79
import datetime
5944 mandeep.dh 80
import httplib
3499 mandeep.dh 81
import logging
82
import os
4421 mandeep.dh 83
import sys
4435 mandeep.dh 84
import time
4421 mandeep.dh 85
import traceback
5806 rajveer 86
import urllib
7308 rajveer 87
import base64
6307 anupam.sin 88
 
5944 mandeep.dh 89
 
3499 mandeep.dh 90
logging.basicConfig(level=logging.DEBUG)
104 ashish 91
 
5966 rajveer 92
sourceId = int(ConfigClient().get_property("sourceid"))
93
mail_user = 'cnc.center@shop2020.in'
94
mail_password = '5h0p2o2o'
95
help_user = 'help@shop2020.in'
96
help_password = '5h0p2o2o'
6029 rajveer 97
source_url = 'www.saholic.com'
98
source_name = 'Saholic'
3499 mandeep.dh 99
 
4763 rajveer 100
PREPAID_SHIPPING_CUTOFF_TIME = 15
4019 chandransh 101
COD_SHIPPING_CUTOFF_TIME = 12
3499 mandeep.dh 102
 
2819 chandransh 103
PAGE_HEIGHT=defaultPageSize[1]
104
PAGE_WIDTH=defaultPageSize[0]
105
 
4763 rajveer 106
billedOrdersColorMap = {}
107
 
3499 mandeep.dh 108
ORDER_STATUS_TO_USER_TRUST_LEVEL_DELTA_DICT = {
4873 mandeep.dh 109
        OrderStatus.RTO_RESHIPPED    :  3,
110
        OrderStatus.RTO_IN_TRANSIT   : -5,
111
        OrderStatus.DELIVERY_SUCCESS :  1,
112
        OrderStatus.DOA_CERT_INVALID : -5
3499 mandeep.dh 113
}
114
 
5783 rajveer 115
delhi_pincodes = ['110001','110002','110003','110004','110005','110006','110007','110008','110009','110010','110011','110012','110013','110014','110015',\
116
                '110016','110017','110018','110019','110020','110021','110022','110023','110024','110025','110026','110027','110028','110029','110030',\
117
                '110031','110032','110033','110034','110035','110037','110038','110041','110042','110044','110045','110046','110047','110048','110049',\
118
                '110051','110052','110053','110054','110055','110056','110057','110058','110059','110060','110061','110062','110063','110064','110065',\
119
                '110066','110067','110068','110070','110071','110074','110075','110076','110078','110081','110082','110083','110084','110085','110086',\
120
                '110087','110088','110089','110091','110092','110093','110094','110095','110096','110101','110103','110104','110105','110106','110107',\
121
                '110108','110109','110110','110112','110113','110114','110115','110116','110117','110118','110119','110120','110122','110124','110125',\
122
                '110301','110302','110501','110502','110503','110504','110505','110510','110511','110512','110601','110602','110603','110604','110605',\
123
                '110606','110607','110608','110609']
124
 
104 ashish 125
def get_new_transaction():
126
    transaction = Transaction()
127
    transaction.createdOn = datetime.datetime.now()
738 chandransh 128
    transaction.status = TransactionStatus.INIT
104 ashish 129
    transaction.status_message = "New transaction"
483 rajveer 130
    return transaction
131
 
132
def create_order(t_order):
133
    order = Order()
134
    if t_order.warehouse_id:
135
        order.warehouse_id = t_order.warehouse_id
509 rajveer 136
    if t_order.logistics_provider_id:    
483 rajveer 137
        order.logistics_provider_id = t_order.logistics_provider_id
138
        order.airwaybill_no = t_order.airwaybill_no
139
        order.tracking_id = t_order.tracking_id
4009 chandransh 140
    if t_order.expected_shipping_time:
4019 chandransh 141
        order.expected_shipping_time = to_py_date(t_order.expected_shipping_time).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4102 chandransh 142
        order.promised_shipping_time = order.expected_shipping_time
4009 chandransh 143
    if t_order.expected_delivery_time:
483 rajveer 144
        order.expected_delivery_time = to_py_date(t_order.expected_delivery_time)
4102 chandransh 145
        order.promised_delivery_time = order.expected_delivery_time
483 rajveer 146
    if t_order.customer_id:    
147
        order.customer_id = t_order.customer_id
148
        order.customer_name = t_order.customer_name
860 rajveer 149
        order.customer_city = t_order.customer_city
150
        order.customer_state = t_order.customer_state
483 rajveer 151
        order.customer_mobilenumber = t_order.customer_mobilenumber
152
        order.customer_pincode = t_order.customer_pincode
738 chandransh 153
        order.customer_address1 = t_order.customer_address1
154
        order.customer_address2 = t_order.customer_address2
483 rajveer 155
        order.customer_email = t_order.customer_email
156
    #new status and status description to be added    
716 rajveer 157
    order.status = t_order.status  
483 rajveer 158
    order.statusDescription = t_order.statusDescription
159
    order.total_amount = t_order.total_amount
6318 rajveer 160
    order.gvAmount = t_order.gvAmount
483 rajveer 161
    order.total_weight = t_order.total_weight
162
    if t_order.created_timestamp:
163
        order.created_timestamp = to_py_date(t_order.created_timestamp)
164
    else:
685 chandransh 165
        order.created_timestamp = datetime.datetime.now()
5555 rajveer 166
    order.pickupStoreId = t_order.pickupStoreId
7033 anupam.sin 167
    if t_order.insurer:
168
        order.insurer = t_order.insurer
169
        order.insuranceAmount = t_order.insuranceAmount
6903 anupam.sin 170
    if order.insurer > 0:
171
        insuranceDetail = InsuranceDetailForOrder()
172
        insuranceDetail.dob = t_order.dob
173
        insuranceDetail.guardianName = t_order.guardianName
174
        insuranceDetail.order = order
7190 amar.kumar 175
    if t_order.freebieItemId:
176
        order.freebieItemId = t_order.freebieItemId
7293 anupam.sin 177
    order.source = t_order.source
178
    order.advanceAmount = t_order.advanceAmount
179
    order.storeId = t_order.storeId
483 rajveer 180
    return order
181
 
182
def create_transaction(t_transaction):
183
    t_orders = t_transaction.orders
184
    if not t_orders:
185
        raise TransactionServiceException(101, "Orders missing from the transaction")
186
    transaction = get_new_transaction()
187
    transaction.customer_id = t_transaction.customer_id 
188
    transaction.shopping_cart_id = t_transaction.shoppingCartid
2219 varun.gupt 189
    transaction.coupon_code = t_transaction.coupon_code
2815 vikas 190
    transaction.session_source = t_transaction.sessionSource
191
    transaction.session_start_time = to_py_date(t_transaction.sessionStartTime)
3858 vikas 192
    transaction.first_source = t_transaction.firstSource
193
    transaction.first_source_start_time = to_py_date(t_transaction.firstSourceTime)
483 rajveer 194
 
6389 rajveer 195
    totalAmount = 0
483 rajveer 196
    for t_order in t_orders:
197
        order = create_order(t_order)
6389 rajveer 198
        totalAmount = totalAmount + order.total_amount
483 rajveer 199
        order.transaction = transaction 
200
        for line_item in t_order.lineitems:
201
            litem = LineItem()
716 rajveer 202
            litem.item_id = line_item.item_id
963 chandransh 203
            litem.productGroup = line_item.productGroup
483 rajveer 204
            litem.brand = line_item.brand
205
            if line_item.model_number:
206
                litem.model_number = line_item.model_number
207
            if line_item.model_name:    
208
                litem.model_name = line_item.model_name
908 chandransh 209
            if line_item.color:
210
                litem.color = line_item.color
483 rajveer 211
            if line_item.extra_info:
212
                litem.extra_info = line_item.extra_info
213
            litem.quantity = line_item.quantity
214
            litem.unit_price = line_item.unit_price
215
            litem.unit_weight = line_item.unit_weight
216
            litem.total_price = line_item.total_price
217
            litem.total_weight = line_item.total_weight
4283 anupam.sin 218
            '''litem.transfer_price = line_item.transfer_price'''
4172 rajveer 219
            litem.dealText = line_item.dealText
4295 varun.gupt 220
            litem.warranty_expiry_timestamp = to_py_date(line_item.warrantry_expiry_timestamp)
1976 varun.gupt 221
 
483 rajveer 222
            """
223
            if line_item.addedOn:
224
                litem.added_on = to_py_date(line_item.addedOn)
225
            else:
226
                litem.added_on = datetime.datetime.now()
227
            """
228
            litem.order = order
229
    session.commit()
6389 rajveer 230
 
231
    generateOtherCharges(transaction, t_transaction.emiSchemeId, totalAmount)
232
 
483 rajveer 233
    return transaction.id
234
 
6389 rajveer 235
def generateOtherCharges(transaction, emiSchemeId, totalAmount):
236
    emiScheme = EmiScheme.get_by(id=emiSchemeId)
237
    if not emiScheme:
238
        return
239
 
240
    if totalAmount < emiScheme.minAmount:
241
        return
242
 
243
    emiCharge = 0
244
    if emiScheme.chargeType == EmiChargeType.FIXED:
6424 rajveer 245
        emiCharge = ceil(emiScheme.chargeValue)
6389 rajveer 246
    if emiScheme.chargeType == EmiChargeType.PERCENTAGE:
6424 rajveer 247
        emiCharge = ceil(totalAmount*(emiScheme.chargeValue)/100)
6736 amit.gupta 248
 
249
    if transaction.coupon_code is not None and transaction.coupon_code != "":    
250
        try:
251
            promotion_client = PromotionClient().get_client()
252
            emis = promotion_client.getEmiDiscount(transaction.shopping_cart_id)
253
            if emis.has_key(emiSchemeId):
254
                discount = emis.get(emiSchemeId)
255
                if emiCharge > discount:
256
                    emiCharge -= discount
257
                else:
258
                    emiCharge = 0
259
        except:
260
            print "Could not get emi discounts from promotion"
261
 
6389 rajveer 262
    miscCharge = MiscCharges()
263
    miscCharge.transaction = transaction
264
    miscCharge.chargeType = 1 ##EMI charges
265
    miscCharge.chargeAmount = emiCharge
266
    session.commit()
267
 
483 rajveer 268
def get_transaction(transaction_id):
269
    transaction = Transaction.get_by(id=transaction_id)
270
    if not transaction:
271
        raise TransactionServiceException(108, "no such transaction")
272
 
273
    return transaction
274
 
275
def get_transactions_for_customer(customer_id, from_date, to_date, status):
276
    if not customer_id:
277
        raise TransactionServiceException(101, "bad customer id")
278
    query = Transaction.query.filter(Transaction.customer_id == customer_id)
1493 vikas 279
    if status is not None:
483 rajveer 280
        query = query.filter(Transaction.status == status)
281
    if from_date:
282
        query = query.filter(Transaction.createdOn >from_date)
283
    if to_date:
284
        query = query.filter(Transaction.createdOn < to_date)
285
    return query.all()
286
 
287
def get_transactions_for_shopping_cart_id(shopping_cart_id):
288
    transactions = Transaction.query.filter_by(shopping_cart_id=shopping_cart_id).all()
289
    return transactions
290
 
291
def get_transaction_status(transaction_id):
292
    if not transaction_id:
293
        raise TransactionServiceException(101, "bad transaction id")
294
 
295
    transaction = get_transaction(transaction_id)
296
 
297
    return transaction.status
298
 
7293 anupam.sin 299
def change_transaction_status(transaction_id, new_status, description, pickUp, orderType, source):
483 rajveer 300
    transaction = get_transaction(transaction_id)
301
    transaction.status = new_status
302
    transaction.status_message = description
5783 rajveer 303
    ## Assign runner in case of delhi pincodes
5784 rajveer 304
    if transaction.orders[0].pickupStoreId:
305
        logistics_client = LogisticsClient().get_client() 
306
        store = logistics_client.getPickupStore(transaction.orders[0].pickupStoreId)
307
        if delhi_pincodes.__contains__(store.pin):
5793 rajveer 308
            pickUp = PickUpType.RUNNER  
5783 rajveer 309
 
690 chandransh 310
    if new_status == TransactionStatus.FAILED:
311
        for order in transaction.orders:
312
            order.status = OrderStatus.PAYMENT_FAILED
2339 chandransh 313
            order.statusDescription = "Payment Failed"
4247 rajveer 314
    elif new_status == TransactionStatus.AUTHORIZED or new_status == TransactionStatus.FLAGGED:
690 chandransh 315
        for order in transaction.orders:
4247 rajveer 316
            if new_status == TransactionStatus.AUTHORIZED:
317
                order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
318
                order.statusDescription = "Submitted to warehouse"
319
            elif new_status == TransactionStatus.FLAGGED:
320
                order.status = OrderStatus.PAYMENT_FLAGGED
321
                order.statusDescription = "Payment flagged by gateway"
3092 chandransh 322
            order.cod = False
5527 anupam.sin 323
            order.orderType = orderType
743 rajveer 324
            #After we got payment success, we will set logistics info also 
325
            logistics_client = LogisticsClient().get_client()
326
            #FIXME line item is only one now. If multiple will come, need to fix.
871 chandransh 327
            item_id = order.lineitems[0].item_id
5767 rajveer 328
            logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp)
743 rajveer 329
 
1730 ankur.sing 330
            current_time = datetime.datetime.now()
331
            logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
4009 chandransh 332
            logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
6726 rajveer 333
            logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
5110 mandeep.dh 334
 
6525 rajveer 335
            order.otg = logistics_info.otgAvailable
743 rajveer 336
            order.warehouse_id = logistics_info.warehouseId
5110 mandeep.dh 337
            order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseId
743 rajveer 338
            order.logistics_provider_id = logistics_info.providerId
339
            order.airwaybill_no = logistics_info.airway_billno
340
            order.tracking_id = order.airwaybill_no
6726 rajveer 341
            order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4019 chandransh 342
            order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4102 chandransh 343
            order.promised_shipping_time = order.expected_shipping_time
5165 rajveer 344
            order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3986 chandransh 345
            order.promised_delivery_time = order.expected_delivery_time 
871 chandransh 346
 
6718 rajveer 347
            if order.pickupStoreId:
348
                order.otg = False
349
 
5944 mandeep.dh 350
            inventory_client = InventoryClient().get_client()
5966 rajveer 351
            inventory_client.reserveItemInWarehouse(item_id, logistics_info.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)
1351 varun.gupt 352
 
4316 anupam.sin 353
            try:
5944 mandeep.dh 354
                item_pricing = inventory_client.getItemPricing(item_id, -1)
4316 anupam.sin 355
                order.lineitems[0].transfer_price = item_pricing.transferPrice
6751 amar.kumar 356
                order.lineitems[0].nlc = item_pricing.nlc
4316 anupam.sin 357
            except:
358
                print "Not able to get transfer price. Skipping"
5944 mandeep.dh 359
 
360
            catalog_client = CatalogClient().get_client() 
5508 rajveer 361
            voucherAmount = catalog_client.getVoucherAmount(item_id, VoucherType.SPICEDECK_MOBILE)
362
            if voucherAmount:
5514 rajveer 363
                __create_recharge_voucher_tracker(order, voucherAmount, VoucherType.SPICEDECK_MOBILE)
5508 rajveer 364
 
3064 chandransh 365
    elif new_status == TransactionStatus.COD_IN_PROCESS:
366
        for order in transaction.orders:
4662 rajveer 367
            order.status = OrderStatus.COD_VERIFICATION_PENDING
3064 chandransh 368
            order.statusDescription = "Verification Pending"
369
            order.cod = True
5527 anupam.sin 370
            order.orderType = orderType
3064 chandransh 371
            #After we got payment success, we will set logistics info also 
372
            logistics_client = LogisticsClient().get_client()
373
            #FIXME line item is only one now. If multiple will come, need to fix.
374
            item_id = order.lineitems[0].item_id
5555 rajveer 375
            if order.pickupStoreId:
5885 mandeep.dh 376
                # Need to send prepaid awb number for store pick up orders
377
                logistics_info = logistics_client.getLogisticsEstimation(item_id, order.customer_pincode, DeliveryType.COD)
378
                prepaid_logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.PREPAID, pickUp)
379
                logistics_info.airway_billno = prepaid_logistics_info.airway_billno
380
                logistics_info.providerId = prepaid_logistics_info.providerId
6525 rajveer 381
                # Will not provide OTG in pickup store
382
                order.otg = False
5555 rajveer 383
            else:
5767 rajveer 384
                logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, item_id, DeliveryType.COD, pickUp)
6525 rajveer 385
                order.otg = logistics_info.otgAvailable
7293 anupam.sin 386
 
3064 chandransh 387
            current_time = datetime.datetime.now()
388
            logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
4009 chandransh 389
            logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
6726 rajveer 390
            logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
391
 
3064 chandransh 392
            order.warehouse_id = logistics_info.warehouseId
5110 mandeep.dh 393
            order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseId
3064 chandransh 394
            order.logistics_provider_id = logistics_info.providerId
395
            order.airwaybill_no = logistics_info.airway_billno
396
            order.tracking_id = order.airwaybill_no
6726 rajveer 397
            order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4019 chandransh 398
            order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4102 chandransh 399
            order.promised_shipping_time = order.expected_shipping_time
5165 rajveer 400
            order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3986 chandransh 401
            order.promised_delivery_time = order.expected_delivery_time
3064 chandransh 402
 
5944 mandeep.dh 403
            inventory_client = InventoryClient().get_client()
5966 rajveer 404
            inventory_client.reserveItemInWarehouse(item_id, logistics_info.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)
3064 chandransh 405
 
4316 anupam.sin 406
            try:
5944 mandeep.dh 407
                item_pricing = inventory_client.getItemPricing(item_id, -1)
6751 amar.kumar 408
                order.lineitems[0].transfer_price = item_pricing.transferPrice
409
                order.lineitems[0].nlc = item_pricing.nlc        
4316 anupam.sin 410
            except:
411
                print "Not able to get transfer price. Skipping"
5508 rajveer 412
 
5944 mandeep.dh 413
            catalog_client = CatalogClient().get_client()
5508 rajveer 414
            voucherAmount = catalog_client.getVoucherAmount(item_id, VoucherType.SPICEDECK_MOBILE)
415
            if voucherAmount:
5514 rajveer 416
                __create_recharge_voucher_tracker(order, voucherAmount, VoucherType.SPICEDECK_MOBILE)
483 rajveer 417
    session.commit()
3499 mandeep.dh 418
 
3530 mandeep.dh 419
    try:
7308 rajveer 420
        if order.source == OrderSource.WEBSITE:    
421
            if new_status == TransactionStatus.COD_IN_PROCESS:
422
                transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
423
                transaction_requiring_extra_processing.category = 'COD_VERIFICATION'
424
                transaction_requiring_extra_processing.transaction_id = transaction_id
425
                session.commit()
426
            elif new_status == TransactionStatus.FLAGGED:
427
                transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
428
                transaction_requiring_extra_processing.category = 'PAYMENT_FLAGGED'
429
                transaction_requiring_extra_processing.transaction_id = transaction_id
430
                session.commit()
7313 rajveer 431
        elif order.source == OrderSource.STORE:
432
                catalog_client = CatalogClient().get_client() 
433
                sourcePricing = catalog_client.getStorePricing(order.lineitems[0].item_id)
434
                if order.total_amount >= sourcePricing.minPrice:
435
                    order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
436
                else: 
437
                    order.status = OrderStatus.COD_VERIFICATION_PENDING
438
                    content = "<html><body>"
439
                    content += "<h2>Order Id:  " + str(order.id) + "</h2>"
440
                    content += "<h2>Product:  " + str(order.lineitems[0]) + "</h2>"
441
                    content += "<h2>Min Price: " +  str(sourcePricing.minPrice) + "</h2>"
442
                    content += "<h2>Max Price: " +  str(sourcePricing.maxPrice) + "</h2>"
443
                    content += "<h2>Recommended Price: " +  str(sourcePricing.recommendedPrice) + "</h2>"
444
                    content += "<h2>Approval Requested for Price: " +  str(order.total_amount) + "</h2>"
445
                    content += "<h3>Please click on link below to approve the order</h3>"
446
                    content += "<a href='http://support.shop2020.in:8080/Support/price-approval?xszbg=" + base64.b64encode(str(order.id))  + "'>Click here for Approval</a>"
447
                    content += "<br><br></body></html>"
448
                    store = get_hotspot_store(order.storeId, "")
449
                    helper_client = HelperClient().get_client()
450
                    helper_client.saveUserEmailForSending(store.approvalEmail.split(';'), "", "Price approval requested for " + str(order.lineitems[0]) + " in store " + store.hotspotId , content, str(transaction_id), "PriceApproval", [], [])
451
                session.commit()
3530 mandeep.dh 452
    except Exception as e:
4065 mandeep.dh 453
        print "Error inserting transaction Id: " + str(transaction_id) + " due to " + str(e)
3499 mandeep.dh 454
 
483 rajveer 455
    return True
456
 
5514 rajveer 457
def __create_recharge_voucher_tracker(order, amount, voucherType):
5508 rajveer 458
    rvt = RechargeVoucherTracker()
459
    rvt.order = order
460
    rvt.amount = amount
461
    rvt.voucherIssued = False
5514 rajveer 462
    rvt.voucherType = voucherType
5508 rajveer 463
 
3994 chandransh 464
def __get_holidays(start_time=0L, to_time=-1L):
465
    '''
466
    Get the list of all public holidays since start time including the
467
    day of start time if it's a holiday
468
    '''
469
    midnightTime = start_time.replace(hour=0, minute=0, second=0, microsecond=0)
1730 ankur.sing 470
    fromDate = to_java_date(midnightTime)
471
    logistics_client = LogisticsClient().get_client()
3994 chandransh 472
    #TODO: This list should be cached after the first call.
473
    #Calling logistics server is also unnecessary.
474
    holidays = logistics_client.getHolidays(fromDate, to_time)
475
    holidays = [to_py_date(holiday).date() for holiday in holidays]
476
    return holidays
477
 
478
def adjust_delivery_time(start_time, delivery_days):
479
    '''
480
    Returns the actual no. of days which will pass while 'delivery_days'
481
    no. of business days will pass since 'order_time'. 
482
    '''
483
    start_date = start_time.date()
484
    end_date = start_date + datetime.timedelta(days = delivery_days)
485
    holidays = __get_holidays(start_time)
1730 ankur.sing 486
 
3994 chandransh 487
    while start_date <= end_date:
488
        if start_date.weekday() == 6 or start_date in holidays:
1730 ankur.sing 489
            delivery_days = delivery_days + 1
3994 chandransh 490
            end_date = end_date + datetime.timedelta(days = 1)
4088 chandransh 491
        start_date = start_date + datetime.timedelta(days = 1)
3994 chandransh 492
 
1730 ankur.sing 493
    return delivery_days
494
 
6561 amit.gupta 495
def get_business_days_count(start_time, end_time):
496
    '''
497
    Returns business dates between two dates
498
    '''
499
    start_date = start_time.date()
500
    end_date  = end_time.date()
6669 amit.gupta 501
    diff = (end_date - start_date).days
6665 amit.gupta 502
    sundays = diff/7 + 1 if (start_date.weekday() + (diff%7) > 6) else diff/7 
6561 amit.gupta 503
    '''holidays = __get_holidays(start_time, end_time)'''
504
    logistics_client = LogisticsClient().get_client()
505
    #TODO: This list should be cached after the first call.
506
    #Calling logistics server is also unnecessary.
507
    holidays = logistics_client.getHolidays(to_java_date(start_time), to_java_date(end_time))
508
    non_business_days = len(holidays)
509
    for holiday in holidays:
6675 rajveer 510
        pyholiday = to_py_date(holiday).date()
511
        if pyholiday.weekday() == 6:
6561 amit.gupta 512
            sundays = sundays - 1
513
    return diff - (non_business_days + sundays)
514
 
515
 
1398 varun.gupt 516
def enqueue_transaction_info_email(transaction_id):
1262 varun.gupt 517
    transaction = get_transaction(transaction_id)
6650 amit.gupta 518
    subject = source_name + " - Order Details"
519
    otgLink = ""
6660 amit.gupta 520
    inOrderOtg = "<div>On Time Guarantee<br><span style=color:red>We pay if we delay</span></div>"
6650 amit.gupta 521
    if len(transaction.orders) == 1:
522
        inOrderOtg = ""
523
        if transaction.orders[0].otg :
524
            subject = "Your Order is confirmed with On Time Guarantee We Pay if we Delay"
525
            otgLink = ' Your Order is covered under the <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee, We pay If we Delay.</a>'
526
 
5793 rajveer 527
    customer_name = "" 
1262 varun.gupt 528
    html_header = """
529
<html>
530
<body>
531
<div>
532
    <p>
5793 rajveer 533
        Hello $customer_name,<br /><br />
6650 amit.gupta 534
        Thanks for placing order with us.$otgLink Following are the details of your order:
1262 varun.gupt 535
    </p>
536
    <div>
537
        Order Date: $order_date
1569 varun.gupt 538
    </div>
1262 varun.gupt 539
    <div>
540
        <table>
5879 rajveer 541
        <tr><td colspan="6"><hr /></td></tr>
542
        <tr><td colspan="6" align="left"><b>Order Details</b></td></tr>
543
        <tr><td colspan="6"><hr /></td></tr>
1262 varun.gupt 544
        <tr>
2050 varun.gupt 545
            <th width="100">Order No.</th>
546
            <th>Product</th>
5879 rajveer 547
            <th width="100">Estimated Delivery Date</th>
2050 varun.gupt 548
            <th width="100">Quantity</th>
549
            <th width="100">Unit Price</th>
550
            <th width="100">Amount</th>
1262 varun.gupt 551
        </tr>
552
    """
1398 varun.gupt 553
    user_email = ""
1262 varun.gupt 554
    total_amount = 0.0
555
    html_table = ""
1569 varun.gupt 556
    order_date = datetime.datetime.now()
5676 rajveer 557
 
558
    orders = transaction.orders
559
    html_pickup_text = ""
560
    random_text = ""
5697 rajveer 561
    if orders[0].pickupStoreId:
5793 rajveer 562
        random_text = str(randrange(100000, 999999)) 
6650 amit.gupta 563
 
6654 amit.gupta 564
    first = True    
5676 rajveer 565
    for order in orders:
5793 rajveer 566
        customer_name = order.customer_name
1262 varun.gupt 567
        order_date = order.created_timestamp
1398 varun.gupt 568
        user_email = order.customer_email
6654 amit.gupta 569
        if first:
570
            first = False
571
            html_tr = "" 
572
        else:
6659 amit.gupta 573
            html_tr =  "<tr><td colspan=6>&nbsp;</td></tr>"
6654 amit.gupta 574
        html_tr += "<tr><td align='center'>" + str(order.id) + "</td>"
5676 rajveer 575
 
5879 rajveer 576
        sdt = datetime.datetime.strptime(str(orders[0].expected_delivery_time), "%Y-%m-%d %H:%M:%S")
577
        store_delivery_date = sdt.strftime("%d %B %Y")
578
 
5676 rajveer 579
        if order.pickupStoreId:
580
            attribute = Attribute()
581
            attribute.orderId = order.id
582
            attribute.name = "SECRET_CODE"
583
            attribute.value = random_text
584
            session.commit()
1262 varun.gupt 585
 
586
        for lineitem in order.lineitems:
2050 varun.gupt 587
            lineitem_total_price = round(lineitem.total_price, 2)
588
 
1276 chandransh 589
            html_tr += "<td>" + str(lineitem) + "</td>"
6561 amit.gupta 590
            if order.otg:
6650 amit.gupta 591
                html_tr += "<td align='center'><div>" + store_delivery_date + "</div>" + inOrderOtg + "</td>"
6561 amit.gupta 592
            else:
593
                html_tr += "<td align='center'>" + store_delivery_date + "</td>"
2050 varun.gupt 594
            html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"
595
            html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"
596
            html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"
597
            total_amount += lineitem_total_price
1262 varun.gupt 598
            html_table += html_tr
7190 amar.kumar 599
        if order.freebieItemId:
600
            catalog_client = CatalogClient().get_client()
601
            item = catalog_client.getItem(order.freebieItemId)
7201 amar.kumar 602
            html_table += "<tr><td align='center'></td><td style='font-style:italic;' colspan='5'> Free Item: "+item.brand + " " + item.modelName + " " + item.modelNumber+"</td></tr>"
6906 rajveer 603
        if order.insurer:
604
            html_table += "<tr><td colspan=6>&nbsp;</td></tr>"
6927 rajveer 605
            html_table += "<tr><td align='center'></td><td style='font-style:italic;'>Insured Against Theft for 1 Year. <a href='http://www.saholic.com/static/insurance-terms'>Know More</a></td><td align='center'></td><td align='center'></td><td align='center'></td>"
6911 rajveer 606
            html_table += "<td align='center'>" + str(order.insuranceAmount) + "</td></tr>"
6927 rajveer 607
            total_amount += order.insuranceAmount
6422 rajveer 608
    emi_amount = 0
609
    miscCharges = get_misc_charges(transaction_id)
610
    if miscCharges.get(1):
611
        emi_amount = miscCharges.get(1)
612
 
1262 varun.gupt 613
    html_footer = """
5879 rajveer 614
        <tr><td colspan=6>&nbsp;</td></tr>
615
        <tr><td colspan=6><hr /></td></tr>
6422 rajveer 616
        """
617
    if emi_amount > 0:
6715 amit.gupta 618
        total_amount += emi_amount
6422 rajveer 619
        html_footer = html_footer + "<tr>\
620
                        <td colspan=5>EMI Processing Charges</td>\
621
                        <td> Rs. $emi_amount</td>\
622
                    </tr>"
623
 
624
    html_footer = html_footer + "<tr>\
625
                <td colspan=5>Total Amount</td>\
626
                <td> Rs. $total_amount</td>\
627
                </tr>\
628
            </table>\
629
        </div>"
5793 rajveer 630
 
6422 rajveer 631
 
5793 rajveer 632
    store_address = ""
633
    if orders[0].pickupStoreId:
634
        store = LogisticsClient().get_client().getPickupStore(orders[0].pickupStoreId)
635
        store_address = __get_store_address_html(store)
636
 
637
        html_pickup_text = html_pickup_text + """
638
        <h3>Steps to Pickup In Store</h3>
5879 rajveer 639
        1) You will receive a confirmation email from us when your product(s) reaches the store. Once you receive the same, please visit the following store selected by you.<br>
5793 rajveer 640
        <br><i>$store_address</i><br>
641
        """
642
 
643
        if orders[0].cod:
644
            html_pickup_text = html_pickup_text + """
6318 rajveer 645
            2) Pay Rs. $net_amount, present a valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>
5793 rajveer 646
            *Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br>
647
            <br>
6029 rajveer 648
            In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a>
5793 rajveer 649
            </br><hr />
650
            """
651
        else:
652
            html_pickup_text = html_pickup_text + """
5879 rajveer 653
            2) Present a valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>
5793 rajveer 654
            *Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br>
655
            <br>
6029 rajveer 656
            In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a>
5793 rajveer 657
            </br><hr />
658
            """
659
 
5676 rajveer 660
    html_footer = html_footer + html_pickup_text + """
1262 varun.gupt 661
    <p>
662
        Best Wishes,<br />
6029 rajveer 663
        $source_name Team
1262 varun.gupt 664
    </p>
665
</div>
666
</body>
667
</html>
668
    """
1398 varun.gupt 669
 
1569 varun.gupt 670
    dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")
1565 varun.gupt 671
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
5793 rajveer 672
 
673
    sdt = datetime.datetime.strptime(str(orders[0].expected_delivery_time), "%Y-%m-%d %H:%M:%S")
674
    store_delivery_date = sdt.strftime("%A, %d %B %Y")
675
 
6650 amit.gupta 676
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, source_url = source_url, otgLink = otgLink))
6422 rajveer 677
    email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, emi_amount = "%.2f" % emi_amount, net_amount = "%.2f" % (total_amount-order.gvAmount), secret_code = random_text, store_address = store_address, store_delivery_date = store_delivery_date, source_url = source_url, source_name = source_name))
1565 varun.gupt 678
 
1351 varun.gupt 679
    try:
680
        helper_client = HelperClient().get_client()
6906 rajveer 681
        helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(transaction_id), "TransactionInfo", [], [])
5866 rajveer 682
 
1351 varun.gupt 683
        return True
684
    except Exception as e:
685
        print e
686
        return False
1262 varun.gupt 687
 
5802 rajveer 688
def enqueue_received_at_store_email(order):
689
    html_header = """
690
    <html>
691
    <body>
692
    <div>
693
        <p>
694
            Hello $customer_name,<br /><br />
695
            Your Product has reached the Store selected by you and is available for pickup. Please pick up your product on or before $order_expiry_date. Following are the details of your order and steps to pickup the same:
696
        </p>
697
        <div>
698
            Order Date: $order_date
699
        </div>
700
        <div>
701
            <table>
702
            <tr><td colspan="5"><hr /></td></tr>
703
            <tr><td colspan="5" align="left"><b>Order Details</b></td></tr>
704
            <tr><td colspan="5"><hr /></td></tr>
705
            <tr>
706
                <th width="100">Order No.</th>
707
                <th>Product</th>
708
                <th width="100">Quantity</th>
709
                <th width="100">Unit Price</th>
710
                <th width="100">Amount</th>
711
            </tr>
712
    """
713
    total_amount = 0.0
714
    html_table = ""
715
 
716
    html_pickup_text = ""
717
    random_text = __get_secret_code(order.id)
718
 
719
    customer_name = order.customer_name
720
    order_date = order.created_timestamp
721
    user_email = order.customer_email
722
    html_tr = "<tr><td align='center'>" + str(order.id) + "</td>"
723
 
724
    for lineitem in order.lineitems:
725
        lineitem_total_price = round(lineitem.total_price, 2)
726
 
727
        html_tr += "<td>" + str(lineitem) + "</td>"
728
        html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"
729
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"
730
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"
731
        total_amount += lineitem_total_price
732
        html_table += html_tr
733
 
734
    html_footer = """
735
        <tr><td colspan=5>&nbsp;</td></tr>
736
        <tr><td colspan=5><hr /></td></tr>
737
        <tr>
738
            <td colspan=4>Total Amount</td>
739
            <td> Rs. $total_amount</td>
740
        </tr>
741
        </table>
742
    </div>
743
    """
744
 
745
    store_address = ""
746
    if order.pickupStoreId:
747
        store = LogisticsClient().get_client().getPickupStore(order.pickupStoreId)
748
        store_address = __get_store_address_html(store)
749
 
750
        html_pickup_text = html_pickup_text + """
751
        <h3>Steps to Pickup In Store</h3>
752
        1) Please visit the following store selected by you on or before $order_expiry_date<br>
753
        <br><i>$store_address</i><br>
754
        """
755
 
756
        if order.cod:
757
            html_pickup_text = html_pickup_text + """
6318 rajveer 758
            2) Pay Rs. $net_amount, present a valid Photo Identity Proof* and quote your Secret Code <b><i>$secret_code</i></b> to claim your Product.<br><br>
5802 rajveer 759
            *Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br>
760
            <br>
6029 rajveer 761
            In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a>
5802 rajveer 762
            </br><hr />
763
            """
764
        else:
765
            html_pickup_text = html_pickup_text + """
766
            2) Present a valid Photo Identity Proof* and use your Secret Code <b><i>$secret_code</i></b> to claim your Product(s).<br><br>
767
            *Valid Photo Identity Proof are Driving License, Passport, PAN Card, Voter ID, Company Issued ID Card, College issued Student ID Card Or any other Government approved Photo Id.<br>
768
            <br>
6029 rajveer 769
            In case you have any questions please visit <a href="$source_url/static/buy-online-and-pickup-in-store">Details on Pickup in Store</a>. If you still have more questions feel free to contact us 24/7 via <a href="$source_url/contact-us">$source_url/contact-us</a>
5802 rajveer 770
            </br><hr />
771
            """
772
 
773
        html_footer = html_footer + html_pickup_text + """
774
        <p>
775
            Best Wishes,<br />
6029 rajveer 776
            $source_name Team
5802 rajveer 777
        </p>
778
        </div>
779
        </body>
780
        </html>
781
        """
782
 
783
    subject = "Your order for " + str(order.lineitems[0]) + " is ready for Pickup in Store"
784
    dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")
785
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
786
 
787
    oetd = datetime.datetime.now() + datetime.timedelta(days=4)
788
    formated_order_expiry_date = oetd.strftime("%A, %d %B %Y")
789
 
790
 
6029 rajveer 791
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, order_expiry_date = formated_order_expiry_date, source_url = source_url, source_name = source_name))
6318 rajveer 792
    email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, net_amount = "%.2f" % (total_amount-order.netAmount), secret_code = random_text, store_address = store_address, order_expiry_date = formated_order_expiry_date, source_url = source_url, source_name = source_name))
5802 rajveer 793
 
794
    try:
5812 rajveer 795
        helper_client = HelperClient(host_key = "helper_service_server_host_prod").get_client()
6280 rajveer 796
        helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(order.id), "ReceivedAtStore", [], [])
5802 rajveer 797
        return True
798
    except Exception as e:
799
        print e
800
        return False
801
 
5966 rajveer 802
def enqueue_delivery_success_mail(order):
5807 rajveer 803
    html_header = """
804
    <html>
805
    <body>
806
    <div>
807
        <p>
808
            Dear $customer_name,<br /><br />
809
    """
6561 amit.gupta 810
 
5807 rajveer 811
    if order.pickupStoreId:
812
        pickup_text = "Pickup Date: " + order.delivery_timestamp.strftime("%A, %d. %B %Y %I:%M%p")
813
        thank_you_html = """
814
        Thank you for shopping with us and picking up your order in Store. Please do join us at our <a href="http://www.facebook.com/mysaholic">Facebook Page</a>, and share your experience with other shoppers.<br><br>
815
 
6029 rajveer 816
        Following are the details of your order for which the pickup has happened. If you have not picked up this product please <a href="$source_url/contact-us" target="_blank">contact us</a> immediately.<br>
5807 rajveer 817
        """
818
    else:
819
        pickup_text = ""
6561 amit.gupta 820
        if order.otg:
821
 
822
            delayed = False
823
            fda = False
824
 
825
            if order.first_dlvyatmp_timestamp.date() < order.delivery_timestamp.date():
826
                fda = True
827
 
828
            fda_datetime = order.first_dlvyatmp_timestamp            
829
            fda_date = fda_datetime.date()
830
 
6711 amit.gupta 831
            if order.promised_delivery_time.date() < fda_date:
6561 amit.gupta 832
                delayed = True
833
 
834
            if not delayed and not fda:
835
                thank_you_html = """As Promised """ + str(order.lineitems[0]) +""" ordered by you has been <b>Delivered On Time.</b>""" 
836
            elif delayed:
837
                max_discount = 500
6711 amit.gupta 838
                delayedDays = get_business_days_count(order.promised_delivery_time, fda_datetime)
6561 amit.gupta 839
                max_discount = min(max_discount, order.lineitems[0].unit_price/10)
6686 anupam.sin 840
                discount = min(round(max_discount),delayedDays*50)  
6561 amit.gupta 841
                promotion_client = PromotionClient().get_client()
842
                endOn =  order.delivery_timestamp + datetime.timedelta(days = 30)
843
                endOn = to_java_date(endOn)
6688 anupam.sin 844
                arguments = "{\"endOn\":" + str(endOn) + ", \"emails\":[\"" + order.customer_email + "\"], \"couponType\":\"both\", \"usage_limit_for_user\":1, \"isCod\":False, \"discount\":" + str(discount) + "}"
6742 anupam.sin 845
                otgCoupon = promotion_client.createCoupon(28, '', arguments, False, "otg")
6691 amit.gupta 846
                thank_you_html = '$prodName ordered by you has been delivered. We apologise for a delay of $delayedDays business days.<br><br> As per our <b>On Time Guarantee</b> Please accept a Gift Voucher worth <b>Rs.$discount</b> as a token of our apology. <br><br>Your unique Gift Voucher Code is <b>$otgCoupon</b>. <br><br>You can use the same to buy any Mobile, Camera, Laptop, Tablet, Accessory or Mobile/DTH Recharge from our website.<br>'
6561 amit.gupta 847
                thank_you_html = Template(thank_you_html).substitute(dict(prodName=order.lineitems[0], delayedDays = delayedDays, discount = discount, otgCoupon = otgCoupon))
848
            elif fda:
849
                fdaFormattedString = order.first_dlvyatmp_timestamp.strftime("%A, %d. %B %Y")
850
                thank_you_html = str(order.lineitems[0]) + """ ordered by you has been delivered.  The First Delivery attempt was made on """+ fdaFormattedString +""" , within our commited estimated time for delivery.""" 
851
 
852
            thank_you_html = thank_you_html + """If you are happy with our services please join us on <a href="http://www.facebook.com/mysaholic">Facebook</a>/<a href="https://twitter.com/saholic">Twitter</a> and help us spread the word."""  
853
 
854
        else :
855
            thank_you_html = str(order.lineitems[0]) + """ ordered by you has been delivered. 
856
            Thank you for shopping with us. Please do join us at our <a href="http://www.facebook.com/mysaholic">Facebook Page</a>, and share your experience with other shoppers. Following are the details of your order.<br>
7198 amar.kumar 857
            """
858
 
859
    freebie_text = "<br/>"
860
    if order.freebieItemId:
861
        catalog_client = CatalogClient().get_client()
862
        item = catalog_client.getItem(order.freebieItemId)
863
        freebie_text = freebie_text = "We have also delivered " + item.brand + " " + item.modelName + "" + item.modelNumber +" as promised"
864
    else:
865
        freebie_orderId = get_order_attribute_value(order.id, "freebieOrderId")
866
        if freebie_orderId != "":
867
            line_items = get_line_items_for_order(int(freebie_orderId))
868
            freebie_order = get_order(int(freebie_orderId))
869
            freebie_text = freebie_text + " We wish to inform you that your freebie item " +line_items[0].brand + " " + line_items[0].model_name + " " + line_items[0].model_number + " will be sent as a separate order with OrderId : " + freebie_orderId + " and is expected to be delivered on " + freebie_order.expected_delivery_time.strftime("%A, %d %B %Y")+ "<br/>You can track the status of this order from My Orders section in saholic.com" 
5807 rajveer 870
 
871
    html_header = html_header + thank_you_html + """        
872
        </p>
873
        <div>
874
            Order Date: $order_date <br>
875
            $pickup_text
876
        </div>
877
        <div>
878
            <table>
879
            <tr><td colspan="5"><hr /></td></tr>
880
            <tr><td colspan="5" align="left"><b>Order Details</b></td></tr>
881
            <tr><td colspan="5"><hr /></td></tr>
882
            <tr>
883
                <th width="100">Order No.</th>
884
                <th>Product</th>
885
                <th width="100">Quantity</th>
886
                <th width="100">Unit Price</th>
887
                <th width="100">Amount</th>
888
            </tr>
889
    """
890
    total_amount = 0.0
891
    html_table = ""
5802 rajveer 892
 
5807 rajveer 893
    customer_name = order.customer_name
894
    order_date = order.created_timestamp
895
    user_email = order.customer_email
896
    html_tr = "<tr><td align='center'>" + str(order.id) + "</td>"
897
 
898
    for lineitem in order.lineitems:
899
        lineitem_total_price = round(lineitem.total_price, 2)
900
 
901
        html_tr += "<td>" + str(lineitem) + "</td>"
902
        html_tr += "<td align='center'>" + ("%.0f" % lineitem.quantity) + "</td>"
903
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem.unit_price) + "</td>"
904
        html_tr += "<td align='center'> Rs. " + ("%.2f" % lineitem_total_price) + "</td></tr>"
905
        total_amount += lineitem_total_price
906
        html_table += html_tr
6906 rajveer 907
    if order.insurer:
6915 anupam.sin 908
        html_table += "<tr><td align='center'></td><td style='font-style:italic;'>Insured Against Theft for 1 Year. <a href='http://www.saholic.com/static/insurance-terms'>Know More</a></td><td align='center'></td><td align='center'></td>"
6911 rajveer 909
        html_table += "<td align='center'>" + str(order.insuranceAmount) + "</td></tr>"
6947 rajveer 910
        html_table += "<tr><td align='center'></td><td style='font-style:italic;'>Please download and read attached policy document.</td><td align='center'></td><td align='center'></td></tr>"
6906 rajveer 911
        total_amount += order.insuranceAmount
912
 
5807 rajveer 913
    html_footer = """
914
        <tr><td colspan=5>&nbsp;</td></tr>
915
        <tr><td colspan=5><hr /></td></tr>
916
        <tr>
917
            <td colspan=4>Total Amount</td>
918
            <td> Rs. $total_amount</td>
919
        </tr>
920
        </table>
7198 amar.kumar 921
        $freebie_text
5807 rajveer 922
    </div>
923
    <p>
924
        Best Wishes,<br />
6029 rajveer 925
        $source_name Team
5807 rajveer 926
    </p>
927
    </div>
928
    </body>
929
    </html>
930
    """
931
 
932
    subject = "Your order for " + str(order.lineitems[0]) + " is now complete"
933
    dt = datetime.datetime.strptime(str(order_date), "%Y-%m-%d %H:%M:%S")
934
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
935
 
936
 
6029 rajveer 937
    email_header = Template(html_header).substitute(dict(order_date = formated_order_date, customer_name = customer_name, pickup_text = pickup_text, source_url = source_url))
7198 amar.kumar 938
    email_footer = Template(html_footer).substitute(dict(total_amount = "%.2f" % total_amount, source_name = source_name, freebie_text = freebie_text))
5807 rajveer 939
 
940
    try:
5812 rajveer 941
        helper_client = HelperClient(host_key = "helper_service_server_host_prod").get_client()
6957 rajveer 942
        if order.insurer:
943
            helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(order.id), "DeliverySuccess", [], ["pramit.singh@shop2020.in ","anupam.singh@shop2020.in","rajveer.singh@shop2020.in"])
944
        else:
945
            helper_client.saveUserEmailForSending([user_email], "", subject, email_header + html_table + email_footer, str(order.id), "DeliverySuccess", [], [])
5807 rajveer 946
        return True
947
    except Exception as e:
948
        print e
949
        return False
950
 
5802 rajveer 951
def __get_secret_code(order_id):
5855 rajveer 952
    return get_order_attribute_value(order_id, 'SECRET_CODE')
5806 rajveer 953
 
5833 rajveer 954
def get_order_attribute_value(order_id, attribute_name):
5808 rajveer 955
    existingAttribute = Attribute.query.filter(Attribute.orderId == order_id).filter(Attribute.name == attribute_name).first()
956
    if existingAttribute:
957
        return existingAttribute.value
5802 rajveer 958
    return ""
5806 rajveer 959
 
6019 rajveer 960
def change_jacket_number(order_id, jacket_number):
961
    order = get_order(order_id)
962
    if order.status == OrderStatus.BILLED:
963
        order.jacket_number = jacket_number
6047 rajveer 964
        session.commit()
6019 rajveer 965
        return True
966
    return False
967
 
968
def mark_order_as_rto_in_transit(order_id):
969
    order = get_order(order_id)
6032 rajveer 970
    if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.DELIVERED_AT_STORE, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERY_SUCCESS]:
6019 rajveer 971
        return False
972
    order.status = OrderStatus.RTO_IN_TRANSIT
973
    order.delivery_timestamp = datetime.datetime.now()
7151 amit.gupta 974
    order.statusDescription = "Order Returned to Origin"
6019 rajveer 975
    update_trust_level(order)
6032 rajveer 976
    session.commit()
6019 rajveer 977
    return True
978
 
483 rajveer 979
def get_order(order_id):
980
    order = Order.get_by(id=order_id)
981
    if not order:
982
        raise TransactionServiceException(108, "no such order")
983
 
984
    return order
985
 
4999 phani.kuma 986
def get_order_list(order_ids):
987
    orders = Order.query.filter(Order.id.in_(tuple(order_ids)))
988
    return orders
989
 
5386 phani.kuma 990
def get_order_list_for_vendor(order_ids, vendor_id):
991
    if vendor_id == -1:
992
        return get_order_list(order_ids)
993
    else:
994
        orders = Order.query.filter_by(vendorId = vendor_id).filter(Order.id.in_(tuple(order_ids)))
995
        return orders
996
 
3014 chandransh 997
def get_orders_for_customer(customer_id, from_date, to_date, statuses):
483 rajveer 998
    if not customer_id:
999
        raise TransactionServiceException(101, "bad customer id")
1000
    query = Order.query.filter(Order.customer_id == customer_id)
3014 chandransh 1001
    if statuses:
1002
        query = query.filter(Order.status.in_(tuple(statuses)))
483 rajveer 1003
    if from_date:
1004
        query = query.filter(Order.created_timestamp >from_date)
1005
    if to_date:
1006
        query = query.filter(Order.created_timestamp < to_date)
1007
    return query.all()
1008
 
1528 ankur.sing 1009
def get_order_for_customer(order_id, customer_id):
1010
    if not customer_id:
1011
        raise TransactionServiceException(101, "bad customer id")
1012
    order = get_order(order_id)
1013
    if order.customer_id != customer_id:
1014
        raise TransactionServiceException(108, "order: " + str(order_id) + " does not belong to customer: " + str(customer_id))
1015
    return order
1016
 
4801 anupam.sin 1017
def get_all_orders(statuses, from_date, to_date, warehouse_id):
1018
    if not len(statuses):
1019
        raise TransactionServiceException(101, "Status list is empty")
1020
    query = Order.query.filter(Order.status.in_(statuses))
1021
    if warehouse_id:
1022
        query = query.filter(Order.warehouse_id == warehouse_id)
1023
        #raise TransactionServiceException(101, "bad warehouse id")
483 rajveer 1024
    if from_date:
1025
        query = query.filter(Order.created_timestamp >from_date)
1026
    if to_date:
1027
        query = query.filter(Order.created_timestamp < to_date)
1028
    return query.all()
1029
 
4133 chandransh 1030
def get_orders_in_batch(statuses=[], offset=0, limit=0, warehouse_id=None):
4296 rajveer 1031
    query = Order.query
1032
    if warehouse_id:
1033
        query = query.filter(Order.warehouse_id == warehouse_id)
4133 chandransh 1034
    if statuses:
1035
        query = query.filter(Order.status.in_(statuses))
1036
    query = query.offset(offset)
1037
    if limit:
1038
        query = query.limit(limit)
1039
    return query.all()
1040
 
1041
def get_order_count(statuses=[], warehouse_id=None):
1042
    if not warehouse_id:
1043
        raise TransactionServiceException(101, "bad warehouse id")
1044
    query = session.query(func.count(Order.id)).filter(Order.warehouse_id == warehouse_id)
1045
    if statuses:
1046
        query = query.filter(Order.status.in_(statuses))
1047
    return query.scalar()
1048
 
1382 varun.gupt 1049
def get_returnable_orders_for_customer(customer_id, limit = None):
1050
    if not customer_id:
1051
        raise TransactionServiceException(101, "bad customer id")
1052
 
1053
    query = Order.query.filter(Order.customer_id == customer_id)
1054
    query = query.filter(Order.status != OrderStatus.PAYMENT_FAILED)
1055
    query = query.filter(Order.status != OrderStatus.REJECTED)
1056
    query = query.filter(Order.status > OrderStatus.SHIPPED_FROM_WH)
1057
    query = query.filter(or_(Order.status < OrderStatus.DELIVERY_SUCCESS, Order.delivery_timestamp < datetime.datetime.now() + datetime.timedelta(hours = 48)))
1058
    orders = query.all()
1059
    order_ids = [order.id for order in orders]
1060
    return order_ids
1061
 
1062
def get_cancellable_orders_for_customer(customer_id, limit = None):
1063
    if not customer_id:
1064
        raise TransactionServiceException(101, "bad customer id")
4815 phani.kuma 1065
    cancellableOrderStatuses = OrderStatusGroups().codCancellable
1382 varun.gupt 1066
    query = Order.query.filter(Order.customer_id == customer_id)
4815 phani.kuma 1067
    query = query.filter(Order.status.in_(cancellableOrderStatuses))
1382 varun.gupt 1068
    orders = query.all()
1069
    return [order.id for order in orders]
1070
 
995 varun.gupt 1071
def get_orders_by_billing_date(status, start_billing_date, end_billing_date, warehouse_id):
1072
    if not warehouse_id:
1073
        raise TransactionServiceException(101, "bad warehouse id")
1074
 
1075
    query = Order.query.filter(Order.warehouse_id == warehouse_id)
1076
 
1077
    if status:
1078
        query = query.filter(Order.status == status)
1079
 
1080
    if start_billing_date:
1081
        query = query.filter(Order.billing_timestamp >= start_billing_date)
1082
 
1083
    if end_billing_date:
1084
        query = query.filter(Order.billing_timestamp <= end_billing_date)
1085
 
1086
    return query.all()
1087
 
3451 chandransh 1088
def get_orders_by_shipping_date(from_shipping_date, to_shipping_date, provider_id, warehouse_id, cod):
1089
    query = Order.query.filter(Order.cod == cod)
3427 chandransh 1090
 
1091
    if warehouse_id and warehouse_id != -1:
1092
        query = query.filter(Order.warehouse_id == warehouse_id)
1093
 
1094
    if provider_id and provider_id != -1:
1095
        query = query.filter(Order.logistics_provider_id == provider_id)
1096
 
1097
    if from_shipping_date:
1098
        query = query.filter(Order.shipping_timestamp >= from_shipping_date)
1099
 
1100
    if to_shipping_date:
1101
        query = query.filter(Order.shipping_timestamp <= to_shipping_date)
1102
 
1103
    query = query.order_by(Order.airwaybill_no)
1104
 
1105
    return query.all()
1106
 
1528 ankur.sing 1107
def get_orders_for_transaction(transaction_id, customer_id):
1108
    orders = Order.query.filter_by(transaction_id=transaction_id, customer_id=customer_id).all()
1109
 
1208 chandransh 1110
    if not orders:
1111
        raise TransactionServiceException(101, "No order for the transaction")
1112
    return orders
1113
 
1405 ankur.sing 1114
def get_undelivered_orders(provider_id, warehouse_id):
1115
    query = Order.query
1116
    if provider_id != -1:
1117
        query = query.filter_by(Order.logistics_provider_id == provider_id)
1118
    if warehouse_id != -1:
1119
        query = query.filter(Order.warehouse_id == warehouse_id)
1120
    query = query.filter(and_(Order.status != OrderStatus.DELIVERY_SUCCESS, Order.status != OrderStatus.FAILED, \
1121
                              Order.status > OrderStatus.SHIPPED_FROM_WH))
1479 ankur.sing 1122
    #Get last midnight time instead of current time as courier company would have sent the 
1123
    #delivery records updated at least till midnight and not by the current time.
1124
    time_format = "%Y-%m-%d %H:%M:%S.%f"
1125
    t = time.strptime(str(datetime.datetime.now()), time_format)
1126
    midnightTime = datetime.datetime(*t[:3])
1127
    query = query.filter(Order.expected_delivery_time < midnightTime)
1405 ankur.sing 1128
    orders = query.all()
1129
    return orders
1130
 
1208 chandransh 1131
def get_line_items_for_order(order_id):
1132
    query = LineItem.query.filter(LineItem.order_id == order_id)
1133
    return query.all()
1134
 
483 rajveer 1135
def change_order_status(self, orderId, status, description):
1136
    order = get_order(orderId)
1137
    order.status = status
1138
    order.statusDescription = description
1139
    session.commit()
3578 mandeep.dh 1140
    update_trust_level(order)
1141
    return True
3499 mandeep.dh 1142
 
3578 mandeep.dh 1143
def update_trust_level(order):
3530 mandeep.dh 1144
    try:
3578 mandeep.dh 1145
        trust_level_delta = 0
1146
        if order.cod == True:
1147
            trust_level_delta = ORDER_STATUS_TO_USER_TRUST_LEVEL_DELTA_DICT.get(order.status, 0)
1148
 
3530 mandeep.dh 1149
        if (trust_level_delta != 0):
1150
            user_client = UserClient().get_client()
1151
            user_client.increaseTrustLevel(order.customer_id, trust_level_delta)
1152
    except Exception as e:
1153
        print e
3499 mandeep.dh 1154
 
483 rajveer 1155
    return True
3064 chandransh 1156
 
1157
def verify_order(self, orderId):
1158
    logging.info("Verifying order no: " + str(orderId))
1159
    order = get_order(orderId)
4662 rajveer 1160
    if order.status == OrderStatus.COD_VERIFICATION_PENDING:
3064 chandransh 1161
        order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
1162
        order.statusDescription = "Submitted for processing"
1163
        order.verification_timestamp = datetime.datetime.now()
1164
        session.commit()
1165
        logging.info("Successfully verified order no: " + str(orderId))
1166
        return True
1167
    else:
1168
        logging.warning("Verify called for order no." + str(orderId) +" which is not in verification pending state");
1169
        return False
1170
 
4285 rajveer 1171
def accept_order(orderId):
3064 chandransh 1172
    logging.info("Accepting order no: " + str(orderId))
921 rajveer 1173
    order = get_order(orderId)
5110 mandeep.dh 1174
    if order.status in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.CAPTURE_IN_PROCESS]:
3064 chandransh 1175
        if not order.cod:
1176
            if order.transaction.status == TransactionStatus.AUTHORIZED:
4421 mandeep.dh 1177
                __capture_txn(order)
3010 chandransh 1178
        order.status = OrderStatus.ACCEPTED
1179
        order.statusDescription = "Order Accepted"
1180
        order.accepted_timestamp = datetime.datetime.now()
5530 mandeep.dh 1181
        __amend_fulfilment_warehouse(order)
6789 rajveer 1182
        __update_transfer_price(order, order.fulfilmentWarehouseId)
3010 chandransh 1183
        session.commit()
3064 chandransh 1184
        logging.info("Successfully accepted the order no.:" + str(orderId))
3010 chandransh 1185
        return True
1186
    else:
3064 chandransh 1187
        logging.warning("Accept called for the unacceptable order: " + str(orderId))
3010 chandransh 1188
        return False
921 rajveer 1189
 
4421 mandeep.dh 1190
def __capture_txn(order):
1191
    txnId = order.transaction_id
3010 chandransh 1192
    logging.info("Capturing payment for merchant txn:" + str(txnId))
4421 mandeep.dh 1193
    try:
1194
        payment_client = PaymentClient().get_client()
1195
        capture_result = payment_client.capturePayment(txnId)
1196
        if capture_result:
1197
            logging.info("Successfully captured payment for merchant txn:" + str(txnId))
7293 anupam.sin 1198
            change_transaction_status(txnId, TransactionStatus.IN_PROCESS, "Payment received", PickUpType.COURIER, order.orderType, order.source)
4421 mandeep.dh 1199
        else:
1200
            raise TransactionServiceException(115, "Payment capture failed.")
1201
    except PaymentException as e:
1202
        if e.error_code == 106:
1203
            order.status = OrderStatus.CAPTURE_IN_PROCESS
1204
            session.commit()
1205
            raise TransactionServiceException(122, "Unable to capture payment due to connection issue.")
1206
        else:
1207
            raise TransactionServiceException(115, "Payment capture failed.")
3010 chandransh 1208
 
5530 mandeep.dh 1209
def __amend_fulfilment_warehouse(order):
1210
    itemId = order.lineitems[0].item_id
5944 mandeep.dh 1211
    inventoryClient = InventoryClient().get_client()
1212
    inventory = inventoryClient.getItemInventoryByItemId(itemId)
5530 mandeep.dh 1213
    if not (inventory.availability.has_key(order.fulfilmentWarehouseId) and inventory.availability[order.fulfilmentWarehouseId]):
5944 mandeep.dh 1214
        for warehouse in inventoryClient.getWarehouses(WarehouseType.OURS, InventoryType.GOOD, 0, order.warehouse_id, 0):
5558 mandeep.dh 1215
            if inventory.availability.has_key(warehouse.id) and inventory.availability[warehouse.id] >= inventory.reserved[warehouse.id] + order.lineitems[0].quantity:
5966 rajveer 1216
                inventoryClient.reduceReservationCount(itemId, order.fulfilmentWarehouseId, sourceId, order.id, order.lineitems[0].quantity)
1217
                inventoryClient.reserveItemInWarehouse(itemId, warehouse.id, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)
5637 mandeep.dh 1218
                order.fulfilmentWarehouseId = warehouse.id
5530 mandeep.dh 1219
                break
1220
 
7190 amar.kumar 1221
def add_billing_details(orderId, invoice_number, serialNumbers, itemNumbers, freebieWarehouseId, billedBy, jacketNumber, billingType, fulfilmentWarehouseId, authorize):
4285 rajveer 1222
    if jacketNumber is None or jacketNumber <= 0:
2783 chandransh 1223
        raise TransactionServiceException(110, "Invalid jacket number")
1224
 
4285 rajveer 1225
    if billedBy is None or billedBy.strip() == "":
2783 chandransh 1226
        raise TransactionServiceException(110, "Invalid Biller")
1227
 
1149 chandransh 1228
    order = Order.get_by(id=orderId)
1229
    if not order:
2783 chandransh 1230
        raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))
5110 mandeep.dh 1231
 
7190 amar.kumar 1232
    '''
1233
    First checking whether freebie can be billed or not otherwise wont proceed.
1234
    '''
7198 amar.kumar 1235
    if order.freebieItemId:
1236
        if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:
1237
            if freebieWarehouseId:
7190 amar.kumar 1238
                try:
7198 amar.kumar 1239
                    inventory_client = InventoryClient().get_client()
1240
                    warehouse = inventory_client.getWarehouse(freebieWarehouseId)
1241
 
7199 amar.kumar 1242
                    if warehouse.warehouseType!= WarehouseType.OURS or warehouse.inventoryType != InventoryType.GOOD:
7198 amar.kumar 1243
                        raise TransactionServiceException(110,'Billing of Freebie is only allowed from OURS_GOOD warehouses ')
1244
 
7190 amar.kumar 1245
                    warehouse_client = WarehouseClient().get_client()
1246
                    inventoryItem = warehouse_client.scanfreebie(orderId, order.freebieItemId, freebieWarehouseId, ScanType.SALE);
1247
 
1248
                    attr = Attribute()
1249
                    attr.orderId = orderId
1250
                    attr.name = "freebie_tp"
1251
                    attr.value = str(inventoryItem.unitPrice)
1252
 
1253
                    attr1 = Attribute()
1254
                    attr1.orderId = orderId
1255
                    attr1.name = "freebie_vendor"
1256
                    attr1.value = str(inventoryItem.supplierId)
5966 rajveer 1257
 
7190 amar.kumar 1258
                    inventory_client = InventoryClient().get_client()
1259
                    item_pricing = inventory_client.getItemPricing(order.freebieItemId, warehouse.vendor.id)
1260
                    attr2 = Attribute()
1261
                    attr2.orderId = orderId
1262
                    attr2.name = "freebie_nlc"
1263
                    attr2.value = str(item_pricing.nlc)
1264
                except Exception as e:
1265
                    print sys.exc_info()[0]
1266
                    print e.message
7198 amar.kumar 1267
                    raise TransactionServiceException(110,'Error in billing freebie for warehouseId ' + str(freebieWarehouseId))
1268
            else:
1269
                raise TransactionServiceException(110,'No warehouseId provided for billing of freebie ')
1270
        else:
1271
            raise TransactionServiceException(110,'Order with freebies associated with it cant be billed from an external warehouse ')
5110 mandeep.dh 1272
    lineitem = order.lineitems[0]
1273
    item_id = lineitem.item_id
5966 rajveer 1274
 
6007 rajveer 1275
#    inventoryClient = InventoryClient().get_client()
1276
#    if not inventoryClient.isOrderBillable(item_id, order.fulfilmentWarehouseId, sourceId, orderId):
1277
#        raise TransactionServiceException(101, "There are other orders to be billed before this order id " + str(orderId))
5966 rajveer 1278
 
5110 mandeep.dh 1279
    catalog_client = CatalogClient().get_client()
1280
    item = catalog_client.getItem(item_id)
4283 anupam.sin 1281
    if order.status == OrderStatus.ACCEPTED:
4285 rajveer 1282
        order.jacket_number = jacketNumber
6751 amar.kumar 1283
 
1284
        if itemNumbers:
1285
            lineitem.item_number = itemNumbers[0]    
7180 rajveer 1286
        if serialNumbers:
1287
            lineitem.serial_number = serialNumbers[0]                
1288
 
6787 rajveer 1289
        '''
6751 amar.kumar 1290
        if billingType == BillingType.EXTERNAL or billingType == BillingType.OURS_EXTERNAL:
4763 rajveer 1291
            if billedOrdersColorMap.has_key(orderId):
1292
                etpColor = billedOrdersColorMap.get(orderId)
1293
                ourColor = order.lineitems[0].color
4781 rajveer 1294
                if ourColor and etpColor != ourColor and not authorize:
4763 rajveer 1295
                    raise TransactionServiceException(777, "ETP color: " + etpColor + " and Order color: " + ourColor)
1296
                else:
1297
                    billedOrdersColorMap.pop(orderId)
6787 rajveer 1298
        '''
6751 amar.kumar 1299
 
1300
        if billingType == BillingType.EXTERNAL:            
1301
            order.invoice_number = invoice_number
1302
 
1303
        if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:
6757 rajveer 1304
            if ItemType.SERIALIZED == item.type and not (serialNumbers and serialNumbers[0]):
1305
                raise TransactionServiceException(110, "No Serial Number supplied")
1306
            if serialNumbers:
1307
                lineitem.serial_number = serialNumbers[0]
6969 amar.kumar 1308
 
4283 anupam.sin 1309
 
2842 chandransh 1310
        order.status = OrderStatus.BILLED
1311
        order.statusDescription = "Order Billed"
1312
        order.billing_timestamp = datetime.datetime.now()
4285 rajveer 1313
        order.billed_by = billedBy
4435 mandeep.dh 1314
 
5436 mandeep.dh 1315
        # Letting the billing process fail in cases where we are unable to 
4435 mandeep.dh 1316
        # fill in transfer price
1317
        try:
5944 mandeep.dh 1318
            inventory_client = InventoryClient().get_client()
1319
            warehouse = inventory_client.getWarehouse(fulfilmentWarehouseId)
1320
            item_pricing = inventory_client.getItemPricing(item_id, warehouse.vendor.id)
5110 mandeep.dh 1321
            lineitem.transfer_price = item_pricing.transferPrice
6751 amar.kumar 1322
            lineitem.nlc = item_pricing.nlc
6075 amit.gupta 1323
            lineitem.vatRate = catalog_client.getVatPercentageForItem(lineitem.item_id, lineitem.unit_price)
5110 mandeep.dh 1324
            order.vendorId = warehouse.vendor.id
4435 mandeep.dh 1325
        except InventoryServiceException as e:
1326
            print sys.exc_info()[0]
1327
            print e.message
5110 mandeep.dh 1328
            raise TransactionServiceException(110, 'Transfer price missing for itemId: ' + str(item_id) + ' and vendor: ' + str(warehouse.vendor.id))
4435 mandeep.dh 1329
 
5110 mandeep.dh 1330
        # For OUR warehouse, we need to scan out items for every billed order
1331
        if billingType == BillingType.OURS:
5530 mandeep.dh 1332
            for index, serialNumber in enumerate(serialNumbers):
5411 rajveer 1333
                try:
1334
                    warehouse_client = WarehouseClient().get_client()
5436 mandeep.dh 1335
                    # Fetching GOOD w/h corresponding to the virtual one here
5835 mandeep.dh 1336
                    if not warehouse.billingWarehouseId:
5950 mandeep.dh 1337
                        warehouse = inventory_client.getWarehouses(None, InventoryType.GOOD, warehouse.vendor.id, order.warehouse_id, 0)[0]
5436 mandeep.dh 1338
 
5411 rajveer 1339
                    if ItemType.SERIALIZED == item.type:
1340
                        inventoryItem = warehouse_client.getInventoryItem(serialNumber)
1341
                    else:
5661 mandeep.dh 1342
                        inventoryItem = warehouse_client.getNonSeralizedInventoryItem(itemNumbers[index], item_id, warehouse.id)
5411 rajveer 1343
 
1344
                    if (inventoryItem.itemId != item_id):
1345
                        catalog_client = CatalogClient().get_client()
1346
                        item = catalog_client.getItem(inventoryItem.itemId)
1347
                        scanItemString = " ".join([str(item.brand), str(item.modelName), str(item.modelNumber), str(item.color)])
1348
                        lineItemString = " ".join([str(lineitem.brand), str(lineitem.model_name), str(lineitem.model_number), str(lineitem.color)])
1349
                        raise TransactionServiceException(110, 'Trying to scan ' + scanItemString + ' instead of ' + lineItemString)
1350
 
1351
                    if ItemType.SERIALIZED == item.type:
5661 mandeep.dh 1352
                        inventoryItem = warehouse_client.scanSerializedItemForOrder(serialNumber, ScanType.SALE, orderId, warehouse.id, 1, order.warehouse_id)
5411 rajveer 1353
                    else:
5661 mandeep.dh 1354
                        inventoryItem = warehouse_client.scanForOrder(inventoryItem, ScanType.SALE, 1, order.id, warehouse.id, order.warehouse_id)
5411 rajveer 1355
 
1356
                    lineitem.transfer_price = inventoryItem.unitPrice
1357
                    order.vendorId = inventoryItem.supplierId
5636 amar.kumar 1358
                    catalog_client = CatalogClient().get_client()
5411 rajveer 1359
                except WarehouseServiceException as e:
1360
                    print sys.exc_info()[0]
1361
                    print 'Could not scan out orders due to: ' + e.message
1362
                    raise TransactionServiceException(110, e.message)
6763 amar.kumar 1363
        elif billingType == BillingType.OURS_EXTERNAL:
1364
            try:
6786 amar.kumar 1365
                if ItemType.SERIALIZED == item.type:
1366
                    serialNumber = serialNumbers[0]
1367
                else:
1368
                    serialNumber = ""
6763 amar.kumar 1369
                warehouse_client = WarehouseClient().get_client()
6768 amar.kumar 1370
                inventoryItem = warehouse_client.scanForOursExternalSale(lineitem.item_id, serialNumber, lineitem.item_number, invoice_number, order.fulfilmentWarehouseId, lineitem.transfer_price, order.id)
6763 amar.kumar 1371
                lineitem.transfer_price = inventoryItem.unitPrice
1372
                order.vendorId = inventoryItem.supplierId
1373
            except WarehouseServiceException as e:
1374
                print sys.exc_info()[0]
1375
                print 'Could not scan out orders due to: ' + e.message
1376
                raise TransactionServiceException(110, e.message)
5123 mandeep.dh 1377
        else:
1378
            if not warehouse.isAvailabilityMonitored:
5944 mandeep.dh 1379
                inventory_client = InventoryClient().get_client()
1380
                inventory_client.addInventory(item.id, warehouse.id, -1 * lineitem.quantity)
4365 mandeep.dh 1381
 
5110 mandeep.dh 1382
        __update_inventory_reservation(order)
5661 mandeep.dh 1383
        order.fulfilmentWarehouseId = warehouse.id
6969 amar.kumar 1384
        if billingType == BillingType.OURS or billingType == BillingType.OURS_EXTERNAL:
1385
            order.invoice_number = get_next_invoice_number(order.orderType)
4541 mandeep.dh 1386
        session.commit()
4283 anupam.sin 1387
        return True
1388
    else:
1389
        return False
1149 chandransh 1390
 
6751 amar.kumar 1391
def add_invoice_number(orderId, invoiceNumber, color, serialNumber, itemNumber):
4579 rajveer 1392
    order = Order.get_by(id=orderId)
1393
    if not order:
1394
        raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))
1395
 
1396
    if order.status == OrderStatus.ACCEPTED:
1397
        order.invoice_number = invoiceNumber
4767 rajveer 1398
        if color:
6764 rajveer 1399
            billedOrdersColorMap[orderId] = color
6751 amar.kumar 1400
        if serialNumber:
6764 rajveer 1401
            order.lineitems[0].serial_number = serialNumber.strip() 
6751 amar.kumar 1402
        if itemNumber:
6764 rajveer 1403
            order.lineitems[0].item_number = itemNumber.strip()
4579 rajveer 1404
    session.commit()
1405
 
1220 chandransh 1406
def batch_orders(warehouseId):
1407
    if not warehouseId:
1408
        raise TransactionServiceException(101, "bad warehouse id")
1225 chandransh 1409
 
1410
    batchno_generator = BatchNoGenerator()
1411
    session.commit()
1220 chandransh 1412
    query = Order.query.filter_by(warehouse_id=warehouseId)
4592 mandeep.dh 1413
    query = query.filter(Order.status == OrderStatus.LOW_INV_PO_RAISED)
1220 chandransh 1414
    query = query.order_by(Order.created_timestamp)
1415
    pending_orders = query.all()
1225 chandransh 1416
 
1220 chandransh 1417
    serial_no = 1
1418
    for order in pending_orders:
1276 chandransh 1419
        order.batchNo = batchno_generator.id
1220 chandransh 1420
        order.serialNo = serial_no
1421
        serial_no += 1
1422
    session.commit() 
1423
    pending_orders = query.all()
1424
    return pending_orders
1425
 
1426
def order_outofstock(orderId):
1911 chandransh 1427
    '''
1428
    Mark order as out of stock
1429
    '''
1220 chandransh 1430
    order = get_order(orderId)
1431
    order.status = OrderStatus.INVENTORY_LOW
1432
    order.statusDescription = "Low Inventory"
1433
    order.outofstock_timestamp = datetime.datetime.now()
1434
    session.commit()
1435
    return True
1436
 
4789 rajveer 1437
def mark_orders_as_shipped_from_warehouse(warehouseId, providerId, cod, orderIds):
4410 rajveer 1438
    try:
1439
        current_timestamp = datetime.datetime.now()
5822 rajveer 1440
        orders = Order.query.filter(Order.id.in_(orderIds)).filter_by(warehouse_id = warehouseId, logistics_provider_id = providerId, status = OrderStatus.BILLED).all()
4410 rajveer 1441
        for order in orders:
5822 rajveer 1442
            order.status = OrderStatus.SHIPPED_FROM_WH
1443
            order.statusDescription = "Order shipped from warehouse"
1444
            order.shipping_timestamp = current_timestamp
1445
            try:
1446
                print "Trying to schedule alert"
1447
                monitoredEntity = MonitoredEntity();
1448
                monitoredEntity.entityType=EntityType.COURIER;
1449
                monitoredEntity.eventType=OrderStatus.SHIPPED_FROM_WH;
1450
                monitoredEntity.entityIdentifier="orderId = " + str(order.id);
1451
                adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);
1452
                sec = datetime.datetime.now()
1453
                #Warn alert time is taken as 16 hrs
1454
                warn_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=16))
1455
                #Critical alert time is taken as 26 hrs                    
1456
                critical_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=26))
1457
                monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1458
                monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
1459
                monitoredEntity.description="warehouseId = " + str(warehouseId) + " providerId = " + str(providerId) + " orderId = "  + str(order.id);
1460
                alert_client = AlertClient().get_client()
1461
                alert_client.scheduleAlert(monitoredEntity)
1462
            except Exception as e:
1463
                print "Exception in scheduling alert in ShippedFromWarehouse method"
1464
                print e
759 chandransh 1465
        session.commit()
5832 rajveer 1466
 
4749 varun.gupt 1467
 
1468
        try:
5832 rajveer 1469
            for order in orders:
1470
                if order.pickupStoreId:
1471
                    send_mails_to_bdms(order)
1472
                else:
1473
                    enqueue_shipping_confirmation_email(order)
4749 varun.gupt 1474
        except Exception as e:
1475
            print e
5832 rajveer 1476
 
759 chandransh 1477
        return True
1478
    except:
1479
        return False
4410 rajveer 1480
 
5832 rajveer 1481
def send_mails_to_bdms(order):
5816 rajveer 1482
    logistics_client = LogisticsClient().get_client()
5832 rajveer 1483
    store = logistics_client.getPickupStore(order.pickupStoreId)
1484
    provider = logistics_client.getProvider(order.logistics_provider_id)
6029 rajveer 1485
    subject = source_name + " order " + str(order.id) +" shipped to store" 
5832 rajveer 1486
    raw_message = '''
1487
    Dear Sir,
5816 rajveer 1488
 
5832 rajveer 1489
    Order mentioned below is being shipped to your store. Customer will pick it from your store. 
1490
 
1491
    Store Id: %(store_id)s
1492
    Order Id: %(order_id)s 
1493
    Product: %(product)s
1494
    Delivery By: %(provider)s
5844 mandeep.dh 1495
    Payment Mode: %(payMode)s
1496
 
1497
    %(note)s
1498
 
5832 rajveer 1499
    Thanks and Regards
1500
    Sandeep Sachdeva
1501
    '''
1502
 
5844 mandeep.dh 1503
    payMode = 'Prepaid'
1504
    note = ''
1505
    if order.cod:
1506
        payMode = 'COD'
6318 rajveer 1507
        note = 'Note: Please collect Rs. ' + str(order.total_amount-order.gvAmount) + ' from customer'
5844 mandeep.dh 1508
 
5832 rajveer 1509
    message = dedent(raw_message) % { 'order_id' : str(order.id),
1510
                                     'store_id' : str(store.hotspotId),
1511
                                  'provider' : provider.name,
5844 mandeep.dh 1512
                                  'product' : str(order.lineitems[0]),
1513
                                  'payMode' : payMode,
1514
                                  'note'    : note
5832 rajveer 1515
                                  }
6643 rajveer 1516
    to_addresses = [store.email, store.bdmEmail, 'sandeep.sachdeva@shop2020.in', 'amit.sirohi@shop2020.in', 'manoj.kumar@shop2020.in']
5894 rajveer 1517
    cc = ['khushal.bhatia@spiceretail.co.in']
1518
    bcc = ['rajneesh.arora@spiceretail.co.in']
5966 rajveer 1519
    mail(mail_user, mail_password, to_addresses, subject, message, [], cc, bcc)
5816 rajveer 1520
 
5713 rajveer 1521
def mark_orders_as_returned_from_store(providerId, orderIds, awbs):
5676 rajveer 1522
    try:
1523
        current_timestamp = datetime.datetime.now()
5824 rajveer 1524
        orders = Order.query.filter(Order.id.in_(orderIds)).filter_by(logistics_provider_id = providerId, status = OrderStatus.RET_PICKUP_REQUEST_RAISED).all()
5676 rajveer 1525
        for order in orders:
6943 amar.kumar 1526
            order.status = OrderStatus.RTO_IN_TRANSIT
5824 rajveer 1527
            order.statusDescription = "Order returned from store"
1528
            order.doa_pickup_timestamp = current_timestamp
1529
            #order.airwaybill_no = awbs[orderIds.index(order.id)]
1530
            order.tracking_id = awbs[orderIds.index(order.id)]
5676 rajveer 1531
        session.commit()
1532
 
1533
        return True
1534
    except:
1535
        return False    
1536
 
1537
def set_order_attributes(orderId, attributes):
5871 rajveer 1538
    for attribute in attributes :
1539
        existingAttribute = Attribute.query.filter(Attribute.orderId == orderId).filter(Attribute.name == attribute.name).first()
1540
        if existingAttribute:
1541
            existingAttribute.value = attribute.value
1542
        else :                
1543
            attr = Attribute()
1544
            attr.orderId = orderId
1545
            attr.name = attribute.name
1546
            attr.value = attribute.value
5791 anupam.sin 1547
    session.commit()
5724 rajveer 1548
 
1113 chandransh 1549
def mark_orders_as_picked_up(provider_id, pickup_details):
1550
    for awb, pickup_timestamp in pickup_details.iteritems():
1135 chandransh 1551
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
2684 chandransh 1552
        if order == None or order.status != OrderStatus.SHIPPED_FROM_WH:
2220 chandransh 1553
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
1554
            continue
1113 chandransh 1555
        order.status = OrderStatus.SHIPPED_TO_LOGST
1556
        order.statusDescription = "Order picked up by Courier Company"
1246 chandransh 1557
        order.pickup_timestamp = pickup_timestamp
5636 amar.kumar 1558
 
1559
        try:
1560
            monitoredEntity = MonitoredEntity();
1561
            monitoredEntity.entityType=EntityType.COURIER;
1562
            monitoredEntity.eventType=OrderStatus.SHIPPED_TO_LOGST
1563
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5744 amar.kumar 1564
            adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);
1565
            sec = datetime.datetime.now()
1566
            #Warn alert time is taken as 16 hrs
5821 amit.gupta 1567
            warn_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=15))
5744 amar.kumar 1568
            #Critical alert time is taken as 26 hrs                    
5821 amit.gupta 1569
            critical_time = (sec + timedelta(days=(adjustedDeliveryDays-1)) + timedelta(hours=20))
5744 amar.kumar 1570
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1571
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5819 amit.gupta 1572
            monitoredEntity.description="providerId = " + str(provider_id)
5636 amar.kumar 1573
            alert_client = AlertClient().get_client()
1574
            alert_client.updateMonitoredObject(monitoredEntity)
1575
        except Exception as e:
5801 amar.kumar 1576
            print "Exception in updating alert in MarkOrdersAsPickedUp method"
5636 amar.kumar 1577
            print e
1113 chandransh 1578
    session.commit()
1217 chandransh 1579
 
4910 phani.kuma 1580
def get_orders_not_picked_up(provider_id):
1132 chandransh 1581
    current_time = datetime.datetime.now()
1582
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4741 phani.kuma 1583
    orders_not_picked_up = Order.query.filter_by(logistics_provider_id = provider_id).filter_by(status=OrderStatus.SHIPPED_FROM_WH).filter(Order.shipping_timestamp <= to_datetime).all()
1113 chandransh 1584
    return orders_not_picked_up
1585
 
1132 chandransh 1586
def mark_orders_as_delivered(provider_id, delivered_orders):
1587
    for awb, detail in delivered_orders.iteritems():
1135 chandransh 1588
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
4910 phani.kuma 1589
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:
1911 chandransh 1590
            continue
6561 amit.gupta 1591
        timestamp, receiver = detail.split('|')
1592
        order.delivery_timestamp = datetime.datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S")
1593
        if order.first_dlvyatmp_timestamp is None:
1594
            order.first_dlvyatmp_timestamp = order.delivery_timestamp
1595
        order.receiver = receiver
5555 rajveer 1596
        if order.pickupStoreId:
1597
            order.status = OrderStatus.DELIVERED_AT_STORE
1598
            order.statusDescription = "Order delivered At Store"
5762 amar.kumar 1599
            try:
1600
                monitoredEntity = MonitoredEntity();
1601
                monitoredEntity.entityType=EntityType.COURIER;
1602
                monitoredEntity.eventType=OrderStatus.RECEIVED_AT_STORE;
1603
                monitoredEntity.entityIdentifier="orderId = " + str(order.id);
1604
                #adjustedDeliveryDays = adjust_delivery_time(datetime.datetime.now(), 1);
1605
                sec = datetime.datetime.now()
1606
                #Critical alert time is taken as 26 hrs                    
1607
                critical_time = (sec + timedelta(hours=4))
1608
                monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
1609
                monitoredEntity.description="deliveryTimeAtStore = " + str(order.delivery_timestamp) + " orderId = "  + str(order.id);
1610
                alert_client = AlertClient().get_client()
1611
                alert_client.updateMonitoredObject(monitoredEntity)
1612
            except Exception as e:
1613
                print e
5555 rajveer 1614
        else:
1615
            order.status = OrderStatus.DELIVERY_SUCCESS
1616
            order.statusDescription = "Order delivered"
5762 amar.kumar 1617
            update_trust_level(order)
6903 anupam.sin 1618
            if order.insuranceDetails:
6906 rajveer 1619
                try:
1620
                    update_insurance_details(order)
1621
                except:
1622
                    print "Error generating insurance file for order " + str(order.id)
1623
                    session.rollback()
1624
                    return
1625
 
6745 anupam.sin 1626
            if enqueue_delivery_success_mail(order) :
1627
                session.commit()
1628
            else :
1629
                session.rollback()
5762 amar.kumar 1630
            try:
1631
                alert_client = AlertClient().get_client()
1632
                alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
1633
            except Exception as e:
5801 amar.kumar 1634
                print "Exception in scheduling alert in ShippedFromWarehouse method"
5762 amar.kumar 1635
                print e
5636 amar.kumar 1636
 
6906 rajveer 1637
def update_insurance_details(order):
1638
    order.insuranceDetails[0].startDate = order.delivery_timestamp
1639
    order.insuranceDetails[0].expiryDate = order.delivery_timestamp + timedelta(days = 365)
6947 rajveer 1640
    filename = "/tmp/" + str(order.id) + "-insurance-policy.pdf"
6906 rajveer 1641
    __generate_policy_doc(order, filename)
1642
    file = open(filename, "rb")
1643
    pdfFile = file.read()
1644
    doc = DocumentStore()
1645
    doc.docType = 1
1646
    doc.docSource = order.id
1647
    doc.document = pdfFile
1132 chandransh 1648
 
4712 rajveer 1649
def mark_order_as_delivered(orderId, deliveryTimestamp, receiver):
1650
    order = Order.get_by(id=orderId)
5555 rajveer 1651
    if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DOA_PICKUP_REQUEST_RAISED, OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.RET_REQUEST_RECEIVED, OrderStatus.RET_PICKUP_CONFIRMED, OrderStatus.RET_REQUEST_AUTHORIZED, OrderStatus.RET_PICKUP_REQUEST_RAISED, OrderStatus.RTO_IN_TRANSIT, OrderStatus.BILLED, OrderStatus.RECEIVED_AT_STORE]:
4712 rajveer 1652
        raise TransactionServiceException(101, "Either wrond order id or invalid state " + str(orderId))
5402 rajveer 1653
 
1654
    # Provider is 4 is for self pickup and hardcoded. We should figure out a way to not to hard code.   
1655
    if order.status == OrderStatus.BILLED and order.logistics_provider_id != 4:
5807 rajveer 1656
        raise TransactionServiceException(101, "Order is not marked for self pickup: " + str(orderId))
5402 rajveer 1657
 
5555 rajveer 1658
    if order.status in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.RTO_IN_TRANSIT, OrderStatus.BILLED, OrderStatus.RECEIVED_AT_STORE]:
6632 amit.gupta 1659
        order.delivery_timestamp = deliveryTimestamp
6631 amit.gupta 1660
        if order.first_dlvyatmp_timestamp is None:
6632 amit.gupta 1661
            order.first_dlvyatmp_timestamp = deliveryTimestamp
4712 rajveer 1662
        order.receiver = receiver
1663
    order.status = OrderStatus.DELIVERY_SUCCESS
1664
    order.statusDescription = "Order delivered"
1665
    update_trust_level(order)
6903 anupam.sin 1666
    if order.insuranceDetails:
6906 rajveer 1667
        try:
1668
            update_insurance_details(order)
1669
        except:
1670
            print "Error generating insurance file for order " + str(order.id)
1671
            session.rollback()
1672
            return
4712 rajveer 1673
    session.commit()
5713 rajveer 1674
 
5812 rajveer 1675
    if order.pickupStoreId and order.cod:
5806 rajveer 1676
        __push_collection_to_hotspot(order, "SALE")
1677
 
5966 rajveer 1678
    enqueue_delivery_success_mail(order)
5713 rajveer 1679
#    if order.pickupStoreId:
1680
#        payment_client = PaymentClient().get_client()
1681
#        payment_client.createRefund(order.id, order.transaction.id, order.total_amount)
1682
#        payment_client = PaymentClient().get_client()
1683
#        payment_client.partiallyCapturePayment(order.transaction.id, order.total_amount, xferBy, xferTxnId, now())
1684
#        order.cod_reconciliation_timestamp = datetime.datetime.now()
1685
#        session.commit()
1686
 
5636 amar.kumar 1687
    try:
1688
        alert_client = AlertClient().get_client()
5744 amar.kumar 1689
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
5636 amar.kumar 1690
    except Exception as e:
5801 amar.kumar 1691
        print "Exception in ending alert in MarkOrderAsDelivered method"
5636 amar.kumar 1692
        print e
1693
 
4712 rajveer 1694
 
5555 rajveer 1695
def mark_order_as_received_at_store(orderId, deliveryTimestamp):
1696
    order = Order.get_by(id=orderId)
1697
    if order != None or order.status in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERED_AT_STORE]:
1698
        order.status = OrderStatus.RECEIVED_AT_STORE
1699
        order.statusDescription = "Order received at store"
1700
        order.delivery_timestamp = deliveryTimestamp
1701
    session.commit()
5713 rajveer 1702
    try:
5762 amar.kumar 1703
        alert_client = AlertClient().get_client()
1704
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
1705
    except Exception as e:
1706
        print e
1707
 
1708
    try:
5713 rajveer 1709
        enqueue_received_at_store_email(order)
1710
    except Exception as e:
1711
        print e
1712
 
1713
 
5555 rajveer 1714
 
4910 phani.kuma 1715
def mark_orders_as_rto(provider_id, returned_orders):
1135 chandransh 1716
    for awb, detail in returned_orders.iteritems():
1717
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
5713 rajveer 1718
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.DELIVERED_AT_STORE, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:
2684 chandransh 1719
            continue
1720
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
4484 rajveer 1721
        order.status = OrderStatus.RTO_IN_TRANSIT
1135 chandransh 1722
        order.delivery_timestamp, reason = detail.split('|')
1723
        order.statusDescription = "Order Returned to Origin:" + reason
3578 mandeep.dh 1724
        update_trust_level(order)
1911 chandransh 1725
    session.commit()
5636 amar.kumar 1726
    try:
1727
        alert_client = AlertClient().get_client()
5801 amar.kumar 1728
        alert_client.endMonitoringEntity(EntityType.COURIER, "orderId = " + str(order.id))
5636 amar.kumar 1729
    except Exception as e:
5801 amar.kumar 1730
        print "Exception in ending alert in MarkOrderAsRTO method"
5636 amar.kumar 1731
        print e
1135 chandransh 1732
 
4910 phani.kuma 1733
def get_rto_orders(provider_id):
1734
    current_time = datetime.datetime.now()
1735
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1736
    rto_orders = Order.query.filter_by(logistics_provider_id = provider_id).filter_by(status=OrderStatus.RTO_IN_TRANSIT).filter(Order.delivery_timestamp <= to_datetime).all()
1737
    return rto_orders
1738
 
5555 rajveer 1739
def get_receive_pending_orders(storeId):
1740
    return Order.query.filter_by(pickupStoreId = storeId).filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE, OrderStatus.DELIVERED_AT_STORE))).all()
1741
 
1742
def get_received_at_store_orders(storeId):
5676 rajveer 1743
    return Order.query.filter_by(pickupStoreId = storeId).filter(Order.status.in_((OrderStatus.RECEIVED_AT_STORE, OrderStatus.RET_PICKUP_REQUEST_RAISED))).all()
5555 rajveer 1744
 
5713 rajveer 1745
def get_orders_collection_at_store(storeId, fromDate, toDate, onlyCod):
1746
    query = Order.query.filter(Order.status == OrderStatus.DELIVERY_SUCCESS)
1747
    if storeId:
1748
        query = query.filter_by(pickupStoreId = storeId)
5720 rajveer 1749
    else:
1750
        query = query.filter(Order.pickupStoreId != 0)
5713 rajveer 1751
    if onlyCod:
1752
        query = query.filter_by(cod = onlyCod)
1753
    if fromDate:
1754
        query = query.filter(Order.delivery_timestamp >= fromDate)
1755
    if toDate:
1756
        query = query.filter(Order.delivery_timestamp <= toDate)
1757
    return query.all()
1758
 
1246 chandransh 1759
def update_non_delivery_reason(provider_id, undelivered_orders):
1760
    for awb, reason in undelivered_orders.iteritems():
1761
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
4920 phani.kuma 1762
        if order == None or order.status == OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE:
2684 chandransh 1763
            continue
1764
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
1246 chandransh 1765
        order.statusDescription = reason
1766
    session.commit()
4910 phani.kuma 1767
 
1768
def get_non_delivered_orders_by_courier(provider_id):
4581 phani.kuma 1769
    current_time = datetime.datetime.now()
1770
    today_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1771
    upto_datetime = today_datetime - datetime.timedelta(4)
4910 phani.kuma 1772
    orders_not_delivered = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE))).filter(or_(Order.shipping_timestamp <= upto_datetime, Order.pickup_timestamp <= upto_datetime)).all()
4581 phani.kuma 1773
    return orders_not_delivered
1246 chandransh 1774
 
4910 phani.kuma 1775
def mark_orders_as_local_connected(provider_id, local_connected_orders):
1776
    for awb, timestamp in local_connected_orders.iteritems():
1777
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1778
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST]:
1779
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
1780
            continue
1781
        order.status = OrderStatus.SHIPPED_TO_DESTINATION_CITY
1782
        order.statusDescription = "Left Out of Origin City"
5636 amar.kumar 1783
        current_time = datetime.datetime.now()
1784
        order.local_connected_timestamp = datetime.datetime(current_time.year, current_time.month, current_time.day)
1785
        try:
1786
            monitoredEntity = MonitoredEntity();
1787
            monitoredEntity.entityType=EntityType.COURIER;
1788
            monitoredEntity.eventType=OrderStatus.SHIPPED_TO_DESTINATION_CITY
1789
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5744 amar.kumar 1790
            #Warn alert time is taken as 23 hrs less than promised delivery time
5821 amit.gupta 1791
            warn_time = (order.expected_delivery_time-timedelta(hours = 15))
5744 amar.kumar 1792
            #Critical alert time is taken as 13 hrs less than promised delivery time                    
5821 amit.gupta 1793
            critical_time = (order.expected_delivery_time-timedelta(hours = 10))
5801 amar.kumar 1794
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1795
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5636 amar.kumar 1796
            monitoredEntity.description="providerId = " + str(provider_id) + " destination city " + order.customer_city 
1797
            alert_client = AlertClient().get_client()
1798
            alert_client.updateMonitoredObject(monitoredEntity)
1799
        except Exception as e:
5801 amar.kumar 1800
            print "Exception in updating alert in MarkOrderAsLocalConnected method"
5636 amar.kumar 1801
            print e
1802
        session.commit()
4910 phani.kuma 1803
 
1804
def get_orders_not_local_connected(provider_id):
1805
    current_time = datetime.datetime.now()
1806
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
1807
    orders_pending_local_connection = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST))).filter(or_(Order.shipping_timestamp <= to_datetime, Order.pickup_timestamp <= to_datetime)).all()
1808
    return orders_pending_local_connection
1809
 
1810
def mark_orders_as_destinationCityReached(provider_id, destination_city_reached_orders):
1811
    for awb, timestamp in destination_city_reached_orders.iteritems():
1812
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1813
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY]:
1814
            continue
1815
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
1816
        order.status = OrderStatus.REACHED_DESTINATION_CITY
1817
        order.statusDescription = "Reached Destination City"
1818
        order.reached_destination_timestamp = timestamp
5636 amar.kumar 1819
        try:
1820
            monitoredEntity = MonitoredEntity();
1821
            monitoredEntity.entityType=EntityType.COURIER;
1822
            monitoredEntity.eventType=OrderStatus.REACHED_DESTINATION_CITY
1823
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5764 amar.kumar 1824
            warn_time = (order.expected_delivery_time)
5801 amar.kumar 1825
            critical_time = (order.expected_delivery_time + timedelta(hours=12))
1826
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1827
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5636 amar.kumar 1828
            monitoredEntity.description="providerId = " + str(provider_id) + " destination city " + order.customer_city 
1829
            alert_client = AlertClient().get_client()
1830
            alert_client.updateMonitoredObject(monitoredEntity)
1831
        except Exception as e:
5801 amar.kumar 1832
            print "Exception in updating alert in MarkOrderAsDestCityReached method"
5636 amar.kumar 1833
            print e
4910 phani.kuma 1834
    session.commit()
1835
 
1836
def mark_orders_as_firstDeliveryAttempted(provider_id, first_atdl_orders):
1837
    for awb, detail in first_atdl_orders.iteritems():
1838
        order = Order.query.filter_by(airwaybill_no=awb, logistics_provider_id = provider_id).first()
1839
        if order == None or order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY]:
1840
            continue
1841
            #raise TransactionServiceException(103, "No order found for the awb:" + awb)
1842
        order.status = OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE
1843
        order.first_dlvyatmp_timestamp, reason = detail.split('|')
1844
        order.statusDescription = reason
5636 amar.kumar 1845
        try:
1846
            monitoredEntity = MonitoredEntity();
1847
            monitoredEntity.entityType=EntityType.COURIER;
1848
            monitoredEntity.eventType=OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE
1849
            monitoredEntity.entityIdentifier="orderId = " + str(order.id);
5744 amar.kumar 1850
            adjustedDeliveryDaysfor1day = adjust_delivery_time(datetime.datetime.now(), 1);
1851
            adjustedDeliveryDaysfor2days = adjust_delivery_time(datetime.datetime.now(), 2);
1852
            sec = datetime.datetime.now()
1853
            #Warn alert time is taken as 16 hrs
1854
            warn_time = (sec + timedelta(days=(adjustedDeliveryDaysfor1day-1)) + timedelta(hours=24))
1855
            #Critical alert time is taken as 26 hrs                    
1856
            critical_time = (sec + timedelta(days=(adjustedDeliveryDaysfor2days-1)) + timedelta(hours=36))
1857
            monitoredEntity.warnExpiryTime = int(warn_time.strftime("%s"))*1000
1858
            monitoredEntity.criticalExpiryTime = int(critical_time.strftime("%s"))*1000
5636 amar.kumar 1859
            monitoredEntity.description="providerId = " + str(provider_id) + " first attempt timestamp" + order.first_dlvyatmp_timestamp
1860
            alert_client = AlertClient().get_client()
1861
            alert_client.updateMonitoredObject(monitoredEntity)
1862
        except Exception as e:
5801 amar.kumar 1863
            print "Exception in updating alert in MarkOrdersAsFirstDeliveryAttempted method"
5636 amar.kumar 1864
            print e
4910 phani.kuma 1865
    session.commit()
1866
 
4783 phani.kuma 1867
def get_orders_not_met_expected_delivery_date():
1868
    current_time = datetime.datetime.now()
1869
    today_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4910 phani.kuma 1870
    orders_not_delivered = Order.query.filter(Order.status.in_((OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY))).filter(Order.expected_delivery_time <= today_datetime).all()
4783 phani.kuma 1871
    return orders_not_delivered
1872
 
4444 rajveer 1873
def get_alerts(type, warehouseId, status, timestamp):
1874
    query = Alert.query.filter(Alert.warehouseId == warehouseId)
1875
    if type != -1 :
1876
        query = query.filter(Alert.type == type)
1877
    if status != -1 :
1878
        query = query.filter(Alert.status == status)
4394 rajveer 1879
    if timestamp:
1880
        query = query.filter(Alert.timestamp >= to_py_date(timestamp))
4412 rajveer 1881
    query = query.order_by(desc(Alert.timestamp))
483 rajveer 1882
    return query.all()
1883
 
4447 rajveer 1884
def add_alert(type, warehouseId, description):
4394 rajveer 1885
    alert = Alert()
1886
    alert.type = type
1887
    alert.status = 1
1888
    alert.description = description
1889
    alert.timestamp = datetime.datetime.now()
4447 rajveer 1890
    alert.warehouseId = warehouseId
4444 rajveer 1891
    session.commit()
766 rajveer 1892
 
4444 rajveer 1893
def mark_alerts_as_seen(warehouseId):
1894
    query = Alert.query.filter(Alert.warehouseId == warehouseId).filter(Alert.status == 1)
1895
    alerts = query.all()
1896
    for alert in alerts:
1897
        alert.status = 0    
1898
    session.commit()
1899
 
1596 ankur.sing 1900
def get_valid_order_count():
2851 chandransh 1901
    '''
1902
    Returns the number of orders which we processed. The reshipped orders are not
1903
    counted since there'll always be a new compensating order present.
1904
    '''
4682 rajveer 1905
    return Order.query.filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).filter(not_(Order.status.in_((OrderStatus.RTO_RESHIPPED, OrderStatus.DOA_INVALID_RESHIPPED, OrderStatus.DOA_VALID_RESHIPPED, OrderStatus.COD_VERIFICATION_FAILED)))).count()
1596 ankur.sing 1906
 
1627 ankur.sing 1907
def get_cust_count_with_successful_txn():
2851 chandransh 1908
    '''
1909
    Returns the number of distinct customers who have done successful transactions.
1910
    It uses the sqlalchemy func module to construct an efficient query.
1911
    '''
1912
    return session.query(func.count(distinct(Order.customer_id))).filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).scalar()
1627 ankur.sing 1913
 
1730 ankur.sing 1914
def get_valid_orders_amount_range():
2851 chandransh 1915
    '''
1916
    Returns a list containing the minimum and maximum amount across all
1917
    orders placed with us. No need to consider reshippped orders for min/max
1918
    amount of orders.
1919
    '''
1920
    return session.query(func.min(Order.total_amount), func.max(Order.total_amount)).filter(Order.status >= OrderStatus.SUBMITTED_FOR_PROCESSING).one()
1627 ankur.sing 1921
 
5874 rajveer 1922
def get_valid_orders(limit, onlyStore):
2851 chandransh 1923
    '''
1924
    Returns the last limit number of valid orders placed with us. Ignored the
1925
    limit if it's passed as 0. Raises an excpetion if the supplied limit is 
1926
    less than 0. 
1927
    '''
1928
    if limit < 0:
1929
        raise TransactionServiceException(101, "Invalid argument limit " + limit)
4662 rajveer 1930
    query = Order.query.filter(Order.status >= OrderStatus.COD_VERIFICATION_PENDING)
5874 rajveer 1931
    if onlyStore:
1932
        query = query.filter(Order.pickupStoreId != 0)
1886 ankur.sing 1933
    query = query.order_by(desc(Order.created_timestamp))
2851 chandransh 1934
    if limit != 0:
1886 ankur.sing 1935
        query = query.limit(limit)
1936
    return query.all()
1937
 
5527 anupam.sin 1938
def get_next_invoice_number(orderType):
1939
    if OrderType.B2Cbulk == orderType:
1940
        orderType = OrderType.B2C
1941
    entity_id = InvoiceIDGenerator.query.filter(InvoiceIDGenerator.orderType == orderType).with_lockmode("update").one()
2783 chandransh 1942
    invoice_number = entity_id.id + 1
1943
    entity_id.id = invoice_number
1944
    return invoice_number
1945
 
2536 chandransh 1946
def toggle_doa_flag(order_id):
1947
    order = get_order(order_id)
1948
    if(order.doaFlag):
1949
        order.doaFlag = False
1950
    else:
1951
        order.doaFlag = True
1952
    session.commit()
1953
    return order.doaFlag
1954
 
4454 rajveer 1955
def mark_order_doa_request_received(orderId):
1956
    order = get_order(orderId)
1957
    if order.status != OrderStatus.DELIVERY_SUCCESS:
1958
        return False
1959
    order.status = OrderStatus.DOA_REQUEST_RECEIVED
4459 rajveer 1960
    order.statusDescription = "DOA Request Received"
4454 rajveer 1961
    session.commit()
1962
    return True
1963
 
1964
def mark_order_doa_request_authorized(orderId, isAuthorized):
1965
    order = get_order(orderId)
1966
    if order.status != OrderStatus.DOA_REQUEST_RECEIVED:
1967
        return False
1968
    if isAuthorized:
1969
        order.status = OrderStatus.DOA_REQUEST_AUTHORIZED
4459 rajveer 1970
        order.statusDescription = "DOA Request Authorized"
4454 rajveer 1971
    else:
1972
        order.status = OrderStatus.DELIVERY_SUCCESS
4459 rajveer 1973
        order.statusDescription = "Order delivered"
4454 rajveer 1974
    session.commit()
1975
    return True
1976
 
4488 rajveer 1977
def mark_order_return_request_received(orderId):
1978
    order = get_order(orderId)
1979
    if order.status != OrderStatus.DELIVERY_SUCCESS:
1980
        return False
1981
    order.status = OrderStatus.RET_REQUEST_RECEIVED
1982
    order.statusDescription = "Return Request Received"
1983
    session.commit()
1984
    return True
1985
 
1986
def mark_order_return_request_authorized(orderId, isAuthorized):
1987
    order = get_order(orderId)
1988
    if order.status != OrderStatus.RET_REQUEST_RECEIVED:
1989
        return False
1990
    if isAuthorized:
1991
        order.status = OrderStatus.RET_REQUEST_AUTHORIZED
1992
        order.statusDescription = "Return Request Authorized"
1993
    else:
1994
        order.status = OrderStatus.DELIVERY_SUCCESS
1995
        order.statusDescription = "Order delivered"
1996
    session.commit()
1997
    return True
1998
 
4579 rajveer 1999
def request_pickup_number(order_id, providerId):
2536 chandransh 2000
    order = get_order(order_id)
4495 rajveer 2001
    if order.status != OrderStatus.DELIVERY_SUCCESS and order.status != OrderStatus.DOA_REQUEST_AUTHORIZED and order.status != OrderStatus.RET_REQUEST_AUTHORIZED:
2536 chandransh 2002
        return False
2003
 
4227 rajveer 2004
    subject = "Pickup request from " + order.customer_city
2536 chandransh 2005
    try:
5944 mandeep.dh 2006
        inventory_client = InventoryClient().get_client()
2007
        warehouse = inventory_client.getWarehouse(order.warehouse_id)
2536 chandransh 2008
 
2009
        logistics_client = LogisticsClient().get_client()
4579 rajveer 2010
        provider = logistics_client.getProvider(providerId)
3051 chandransh 2011
        to_addr = provider.details[DeliveryType.PREPAID].email
2536 chandransh 2012
        raw_message = '''
2013
        Dear Sir/Madam,
2014
 
2559 chandransh 2015
        Kindly arrange a pickup today from %(customer_city)s. Pickup and delivery addresses are mentioned below.
2536 chandransh 2016
 
6663 rajveer 2017
        Order Id: %(order_id)s
2536 chandransh 2018
        Pickup CODE: %(provider_code)s
2019
        Total Weight: %(order_weight)s kg
2020
 
2559 chandransh 2021
        Pickup Address:
2536 chandransh 2022
 
2023
        %(customer_address)s
2024
 
2025
        Delivery Address:
2026
 
2027
        %(warehouse_executive)s
2028
        %(warehouse_address)s
2029
        PIN %(warehouse_pin)s
2030
 
2031
        Thanks and Regards
4227 rajveer 2032
        Sandeep Sachdeva
2536 chandransh 2033
        '''
4579 rajveer 2034
 
2035
        if warehouse.id == 7:
7181 rajveer 2036
            executive = 'Shiv Kumar'
4579 rajveer 2037
        else:
4966 phani.kuma 2038
            executive = 'Dinesh Kumar'
4579 rajveer 2039
 
2559 chandransh 2040
        message = dedent(raw_message) % { 'customer_city' : order.customer_city,
3051 chandransh 2041
                                          'provider_code' : provider.details[DeliveryType.PREPAID].accountNo,
6663 rajveer 2042
                                          'order_id' : str(order_id),
2536 chandransh 2043
                                          'order_weight' : str(order.total_weight),
2044
                                          'customer_address' : __get_order_address(order),
4579 rajveer 2045
                                          'warehouse_executive' : executive,
2536 chandransh 2046
                                          'warehouse_address' : warehouse.location,
4966 phani.kuma 2047
                                          'warehouse_pin' : warehouse.pincode}
6645 anupam.sin 2048
        to_addresses = [to_addr,'amit.sirohi@shop2020.in', 'shrawan.choudhary@shop2020.in', 'ritesh.chauhan@shop2020.in']
4966 phani.kuma 2049
 
5966 rajveer 2050
        mail(mail_user, mail_password, to_addresses, subject, message)
4495 rajveer 2051
        if order.status == OrderStatus.RET_REQUEST_AUTHORIZED:
2052
            order.status = OrderStatus.RET_PICKUP_REQUEST_RAISED
2053
            order.statusDescription = "Pick up requested for RETURN"
2054
        else:
2055
            order.status = OrderStatus.DOA_PICKUP_REQUEST_RAISED
2056
            order.statusDescription = "Pick up requested for DOA"
4815 phani.kuma 2057
        order.doa_logistics_provider_id = providerId
2536 chandransh 2058
        session.commit()
2059
        return True
2060
    except Exception as e:
2061
        print sys.exc_info()[0]
2062
        return False
2063
 
4602 rajveer 2064
def authorize_pickup(order_id, pickup_number, providerId):
2536 chandransh 2065
    order = get_order(order_id)
4495 rajveer 2066
    if order.status not in [OrderStatus.DOA_PICKUP_REQUEST_RAISED, OrderStatus.RET_PICKUP_REQUEST_RAISED]:
2536 chandransh 2067
        return False
4815 phani.kuma 2068
    if order.doa_logistics_provider_id is not None:
2069
        providerId = order.doa_logistics_provider_id    #previously we are not storing this so data is taken from omdashboarduser
2536 chandransh 2070
    subject = 'Pickup details'
2071
    filename = "/tmp/" +  str(order.id) +".pdf" 
2072
    try:
5944 mandeep.dh 2073
        inventory_client = InventoryClient().get_client()
2074
        warehouse = inventory_client.getWarehouse(order.warehouse_id)
2536 chandransh 2075
 
2076
        logistics_client = LogisticsClient().get_client()
4602 rajveer 2077
        provider = logistics_client.getProvider(providerId)
2536 chandransh 2078
        provider_name = provider.name
2079
 
2080
        to_addr = order.customer_email
2081
        today = date.today().strftime("%d-%B-%Y (%A)")
2082
 
2083
        raw_message = '''
2084
        Dear Mr. %(customer_name)s,
2085
 
4815 phani.kuma 2086
        In reference to the return of order ID %(order_id)d, ''' + __generate_mail_body_for_authorize_pickup(order)
2087
        raw_message = raw_message + '''
2536 chandransh 2088
        Take a printout of the attachment in this mail which contains the delivery address and paste it on the packed parcel.
2089
        We have instructed %(provider_name)s to pick up the material from the below mentioned address on %(date)s. %(provider_name)s pickup request number is %(pickup_request_no)s. Kindly keep the parcel ready.
2090
 
2091
        Pickup will happen from the below mentioned address:-
2092
 
2093
        %(customer_address)s
2094
 
2095
        Do let us know in case of any concerns
2096
 
2097
        Thanks & Regards
6029 rajveer 2098
        %(source_name)s Team
2536 chandransh 2099
        '''
2100
        message = dedent(raw_message) % {'customer_name' : order.customer_name,
2101
                                         'order_id' : order_id,
2102
                                         'provider_name' : provider_name,
2103
                                         'date': today,
2104
                                         'pickup_request_no' : pickup_number,
6029 rajveer 2105
                                         'customer_address' : __get_order_address(order),
2106
                                         'source_name' : source_name}
2536 chandransh 2107
        print message
2108
        __generate_return_advice(order, warehouse, provider, filename)
5966 rajveer 2109
        mail(help_user, help_password, [to_addr], subject, message, [get_attachment_part(filename)])
2536 chandransh 2110
        order.pickupRequestNo = pickup_number
4495 rajveer 2111
        if order.status == OrderStatus.RET_PICKUP_REQUEST_RAISED:
2112
            order.status = OrderStatus.RET_PICKUP_CONFIRMED
2113
            order.statusDescription = "RETURN pick up confirmed"
2114
        else:
2115
            order.status = OrderStatus.DOA_PICKUP_CONFIRMED
2116
            order.statusDescription = "DOA pick up confirmed"
2764 chandransh 2117
        order.doa_auth_timestamp = datetime.datetime.now()
2536 chandransh 2118
        session.commit()
2119
        return True
2120
    except Exception as e:
4234 rajveer 2121
        print sys.exc_info()
4506 phani.kuma 2122
        traceback.print_tb(sys.exc_info()[2])
2536 chandransh 2123
        return False
2124
    finally:
2125
        if os.path.exists(filename):
2126
            os.remove(filename)
2127
 
4815 phani.kuma 2128
def __generate_mail_body_for_authorize_pickup(order):
2129
    brand_msgbody_map = {'Nokia' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the all original accessories, original handset and the invoice.',
2130
                         'Micromax' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the all original accessories, original handset and the invoice.',
2131
                         'Karbonn' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the all original accessories, original handset and the invoice.',
2132
                         'Sony Ericsson' : 'we request you to kindly pack the original DOA certificate and the invoice.',
2133
                         'Others Handsets' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the original "DOA" certificate and the invoice. Please paste the original DOA on the sealed box. Kindly ensure that the product is properly sealed. If we receive open sealed products, we will not be able to accept.',
2134
                         'Handsets Return' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the all original accessories, original handset and the invoice.',
2135
                         'Accessories' : 'we request you to kindly pack the box properly with bubble wrap, and send it along with the original product and the invoice.'}
2136
    categories = ["Handsets", "Tablets", "Laptops"]
2137
    lineitem = order.lineitems[0]
2138
    brand = lineitem.brand
2139
    productGroup = lineitem.productGroup
2140
    searchkey = None
2141
    if productGroup not in categories:
2142
        searchkey = 'Accessories'
2143
    elif order.status == OrderStatus.RET_PICKUP_REQUEST_RAISED:
2144
        searchkey = 'Handsets Return'
2145
    elif brand == 'Nokia':
2146
        searchkey = 'Nokia'
2147
    elif brand == 'Micromax':
2148
        searchkey = 'Micromax'
2149
    elif brand == 'Karbonn':
2150
        searchkey = 'Karbonn'
2151
    elif brand == 'Sony Ericsson':
2152
        searchkey = 'Sony Ericsson'
2153
    else:
2154
        searchkey = 'Others Handsets'
2155
    return brand_msgbody_map.get(searchkey)
2156
 
2764 chandransh 2157
def mark_doas_as_picked_up(provider_id, pickup_details):
2158
    for pickupNo, doa_pickup_timestamp in pickup_details.iteritems():
4815 phani.kuma 2159
        order = Order.query.filter_by(pickupRequestNo=pickupNo, doa_logistics_provider_id = provider_id).first()
4452 rajveer 2160
        if order == None or order.status != OrderStatus.DOA_PICKUP_CONFIRMED:
2764 chandransh 2161
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
2162
            continue
2163
        order.status = OrderStatus.DOA_RETURN_IN_TRANSIT
2164
        order.statusDescription = "DOA picked up by Courier Company"
2165
        order.doa_pickup_timestamp = doa_pickup_timestamp
2166
    session.commit()
2167
 
4910 phani.kuma 2168
def get_doas_not_picked_up(provider_id):
2764 chandransh 2169
    current_time = datetime.datetime.now()
2170
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4815 phani.kuma 2171
    orders_not_picked_up = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter_by(status=OrderStatus.DOA_PICKUP_CONFIRMED).filter(Order.doa_auth_timestamp <= to_datetime).all()
2764 chandransh 2172
    return orders_not_picked_up
2173
 
4741 phani.kuma 2174
def mark_return_orders_as_picked_up(provider_id, pickup_details):
2175
    for pickupNo, return_order_pickup_timestamp in pickup_details.iteritems():
4815 phani.kuma 2176
        order = Order.query.filter_by(pickupRequestNo=pickupNo, doa_logistics_provider_id = provider_id).first()
4741 phani.kuma 2177
        if order == None or order.status != OrderStatus.RET_PICKUP_CONFIRMED:
2178
            #raise TransactionServiceException(102, "No order found for the awb: " + awb)
2179
            continue
2180
        order.status = OrderStatus.RET_RETURN_IN_TRANSIT
2181
        order.statusDescription = "Return order picked up by Courier Company"
2182
        order.doa_pickup_timestamp = return_order_pickup_timestamp
2183
    session.commit()
2184
 
4910 phani.kuma 2185
def get_return_orders_not_picked_up(provider_id):
4741 phani.kuma 2186
    current_time = datetime.datetime.now()
2187
    to_datetime = datetime.datetime(current_time.year, current_time.month, current_time.day)
4815 phani.kuma 2188
    orders_not_picked_up = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter_by(status=OrderStatus.RET_PICKUP_CONFIRMED).filter(Order.doa_auth_timestamp <= to_datetime).all()
4741 phani.kuma 2189
    return orders_not_picked_up
2190
 
4479 rajveer 2191
def receive_return(order_id, receiveCondition):
2591 chandransh 2192
    order = get_order(order_id)
7199 amar.kumar 2193
    scanFreebie = False
4365 mandeep.dh 2194
 
4452 rajveer 2195
    if order.status in [OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.DOA_RETURN_IN_TRANSIT]:
4479 rajveer 2196
        if receiveCondition == 0:
2197
            order.status = OrderStatus.DOA_RECEIVED_PRESTINE
2198
            order.statusDescription = "DOA package received"
2199
        elif receiveCondition == 1:
2200
            order.status = OrderStatus.DOA_RECEIVED_DAMAGED
2201
            order.statusDescription = "DOA received damaged"
2202
        elif receiveCondition == 2:
2203
            order.status = OrderStatus.DOA_LOST_IN_TRANSIT
2204
            order.statusDescription = "DOA lost in transit"
2764 chandransh 2205
        order.received_return_timestamp = datetime.datetime.now()
4495 rajveer 2206
    elif order.status in [OrderStatus.RET_PICKUP_CONFIRMED, OrderStatus.RET_RETURN_IN_TRANSIT]:
2207
        if receiveCondition == 0:
2208
            order.status = OrderStatus.RET_RECEIVED_PRESTINE
2209
            order.statusDescription = "RETURN package received"
2210
        elif receiveCondition == 1:
2211
            order.status = OrderStatus.RET_RECEIVED_DAMAGED
2212
            order.statusDescription = "RETURN received damaged"
2213
        elif receiveCondition == 2:
2214
            order.status = OrderStatus.RET_LOST_IN_TRANSIT
2215
            order.statusDescription = "RETURN lost in transit"
2216
        order.received_return_timestamp = datetime.datetime.now()
4484 rajveer 2217
    elif order.status == OrderStatus.RTO_IN_TRANSIT :
4486 rajveer 2218
        if receiveCondition == 0:
2219
            order.status = OrderStatus.RTO_RECEIVED_PRESTINE
4515 mandeep.dh 2220
            order.statusDescription = "Returned to origin"
4486 rajveer 2221
        elif receiveCondition == 1:
2222
            order.status = OrderStatus.RTO_RECEIVED_DAMAGED
2223
            order.statusDescription = "RTO received damaged"
2224
        elif receiveCondition == 2:
2225
            order.status = OrderStatus.RTO_LOST_IN_TRANSIT
2226
            order.statusDescription = "RTO lost in transit"
2764 chandransh 2227
        order.received_return_timestamp = datetime.datetime.now()
7199 amar.kumar 2228
        if order.freebieItemId:
2229
            scanFreebie = True
2616 chandransh 2230
    else:
2591 chandransh 2231
        return False
5110 mandeep.dh 2232
 
2233
    # For OUR warehouses, we need to scan in items for every return
5944 mandeep.dh 2234
    inventoryClient = InventoryClient().get_client()
2235
    warehouse = inventoryClient.getWarehouse(order.warehouse_id)
6763 amar.kumar 2236
    if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
5361 mandeep.dh 2237
        scanMap = {
2238
            OrderStatus.RTO_RECEIVED_PRESTINE : ScanType.SALE_RET,
2239
            OrderStatus.RTO_RECEIVED_DAMAGED  : ScanType.SALE_RET_UNUSABLE,
2240
            OrderStatus.RTO_LOST_IN_TRANSIT   : ScanType.LOST_IN_TRANSIT,
2241
            OrderStatus.DOA_RECEIVED_PRESTINE : ScanType.DOA_IN,
2242
            OrderStatus.DOA_RECEIVED_DAMAGED  : ScanType.DOA_IN,
2243
            OrderStatus.DOA_LOST_IN_TRANSIT   : ScanType.LOST_IN_TRANSIT
2244
        }
5110 mandeep.dh 2245
 
5419 mandeep.dh 2246
        if scanMap.has_key(order.status):
2247
            scanType = scanMap[order.status]
5361 mandeep.dh 2248
            lineitem = order.lineitems[0]
5944 mandeep.dh 2249
            catalogClient = CatalogClient().get_client()
5361 mandeep.dh 2250
            item = catalogClient.getItem(lineitem.item_id)
2251
            warehouseClient = WarehouseClient().get_client()
6763 amar.kumar 2252
            if warehouse.billingType == BillingType.OURS or scanType != ScanType.SALE_RET:
2253
                if item.type == ItemType.SERIALIZED:
2254
                    warehouseClient.scanSerializedItemForOrder(lineitem.serial_number, scanType, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)
2255
                else:
2256
                    warehouseClient.scanForOrder(None, scanType, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2257
            if warehouse.billingType == BillingType.OURS_EXTERNAL and scanType == ScanType.SALE_RET:
2258
                warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)
7199 amar.kumar 2259
            if scanFreebie:
7292 amar.kumar 2260
                warehouseClient.scanfreebie(order.id, order.freebieItemId, 0, scanType)
5558 mandeep.dh 2261
    session.commit()
2591 chandransh 2262
    return True
2263
 
2264
def validate_doa(order_id, is_valid):
2265
    order = get_order(order_id)
4452 rajveer 2266
    if order.status != OrderStatus.DOA_RECEIVED_PRESTINE:
2591 chandransh 2267
        return False
2268
    if is_valid:
2609 chandransh 2269
        order.status = OrderStatus.DOA_CERT_VALID
2270
        order.statusDescription = "DOA Certificate Valid"
2591 chandransh 2271
    else:
2272
        order.status = OrderStatus.DOA_CERT_INVALID
2273
        order.statusDescription = "DOA Certificate Invalid"
3578 mandeep.dh 2274
        update_trust_level(order)
2591 chandransh 2275
    session.commit()
2276
    return True
2277
 
4495 rajveer 2278
def validate_return_product(order_id, is_usable):
2279
    order = get_order(order_id)
2280
    if order.status != OrderStatus.RET_RECEIVED_PRESTINE:
2281
        return False
5110 mandeep.dh 2282
 
2283
    scanType = ScanType.SALE_RET_UNUSABLE
4495 rajveer 2284
    if is_usable:
2285
        order.status = OrderStatus.RET_PRODUCT_USABLE
2286
        order.statusDescription = "Return product usable"
5110 mandeep.dh 2287
        scanType = ScanType.SALE_RET
4495 rajveer 2288
    else:
2289
        order.status = OrderStatus.RET_PRODUCT_UNUSABLE
2290
        order.statusDescription = "Return product unusable"
2291
        update_trust_level(order)
2292
    session.commit()
5110 mandeep.dh 2293
 
2294
    # For OUR warehouses, we need to scan in items for every return
5944 mandeep.dh 2295
    inventoryClient = InventoryClient().get_client()
2296
    warehouse = inventoryClient.getWarehouse(order.warehouse_id)
6786 amar.kumar 2297
    if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
5110 mandeep.dh 2298
        lineitem = order.lineitems[0]
5944 mandeep.dh 2299
        catalogClient = CatalogClient().get_client()
5361 mandeep.dh 2300
        item = catalogClient.getItem(lineitem.item_id)
5110 mandeep.dh 2301
        warehouse_client = WarehouseClient().get_client()
6786 amar.kumar 2302
        if warehouse.billingType == BillingType.OURS or scanType != ScanType.SALE_RET:
2303
            if item.type == ItemType.SERIALIZED:
2304
                warehouse_client.scanSerializedItemForOrder(lineitem.serial_number, scanType, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)
2305
            else:
2306
                warehouse_client.scanForOrder(None, scanType, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2307
        if scanType == ScanType.SALE_RET and warehouse.billingType == BillingType.OURS_EXTERNAL:
2308
            warehouse_client.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)        
4495 rajveer 2309
    return True
2310
 
2628 chandransh 2311
def reship_order(order_id):
2312
    """
4484 rajveer 2313
    If the order is in RTO_RECEIVED_PRESTINE or DOA_CERT_INVALID state, it does the following:
2628 chandransh 2314
        1. Creates a new order for processing in the BILLED state. All billing information is saved.
4484 rajveer 2315
        2. Marks the current order as one of the final states RTO_RESHIPPED and DOA_INVALID_RESHIPPED depending on what state the order started in.
2628 chandransh 2316
 
2317
    If the order is in DOA_CERT_VALID state, it does the following:
2318
        1. Creates a new order for processing in the SUBMITTED_FOR_PROCESSING state.
2319
        2. Creates a return order for the warehouse executive to return the DOA material.
4452 rajveer 2320
        3. Marks the current order as the final DOA_VALID_RESHIPPED state.
2628 chandransh 2321
 
2322
    Returns the id of the newly created order.
2323
 
2324
    Throws an exception if the order with the given id couldn't be found.
2325
 
2326
    Parameters:
2327
     - orderId
2328
    """
2329
    order = get_order(order_id)
4484 rajveer 2330
    if order.status == OrderStatus.RTO_RECEIVED_PRESTINE:
4220 rajveer 2331
        new_order = __clone_order(order, True, order.cod)
4484 rajveer 2332
        order.status = OrderStatus.RTO_RESHIPPED
2628 chandransh 2333
        order.statusDescription = "Order Reshipped"
2334
        session.commit()
3578 mandeep.dh 2335
        update_trust_level(order)
6735 amar.kumar 2336
        __scan_for_reship_order(order_id, new_order)
4486 rajveer 2337
    elif order.status == OrderStatus.RTO_RECEIVED_DAMAGED:
2338
        new_order = __clone_order(order, False, order.cod)
2339
        ret_order = __create_return_order(order)
2340
        order.status = OrderStatus.RTO_DAMAGED_RESHIPPED
2341
        order.statusDescription = "Order Reshipped Received Damaged"
2342
        session.commit()
2343
    elif order.status == OrderStatus.RTO_LOST_IN_TRANSIT:
2344
        new_order = __clone_order(order, False, order.cod)
2345
        order.status = OrderStatus.RTO_LOST_IN_TRANSIT_RESHIPPED
2346
        order.statusDescription = "Order Reshipped Lost In Transit"
2347
        session.commit()
4662 rajveer 2348
    elif order.status == OrderStatus.LOST_IN_TRANSIT:
2349
        new_order = __clone_order(order, False, order.cod)
2350
        order.status = OrderStatus.LOST_IN_TRANSIT_RESHIPPED
2351
        order.statusDescription = "Order Reshipped Lost In Transit"
2352
        session.commit()
2628 chandransh 2353
    elif order.status == OrderStatus.DOA_CERT_INVALID:
4220 rajveer 2354
        new_order = __clone_order(order, True, False)
2628 chandransh 2355
        order.status = OrderStatus.DOA_INVALID_RESHIPPED
2356
        order.statusDescription = "Order Reshipped"
2357
        session.commit()
6735 amar.kumar 2358
        __scan_for_reship_order(order_id, new_order)
2628 chandransh 2359
    elif order.status == OrderStatus.DOA_CERT_VALID:
4220 rajveer 2360
        new_order = __clone_order(order, False, False)
2628 chandransh 2361
        ret_order = __create_return_order(order)
4452 rajveer 2362
        order.status = OrderStatus.DOA_VALID_RESHIPPED
2628 chandransh 2363
        order.statusDescription = "Order Reshipped"
2364
        session.commit()
4479 rajveer 2365
    elif order.status == OrderStatus.DOA_RECEIVED_DAMAGED:
2366
        new_order = __clone_order(order, False, False)
2367
        ret_order = __create_return_order(order)
2368
        order.status = OrderStatus.DOA_RESHIPPED_RCVD_DAMAGED
2369
        order.statusDescription = "Order Reshipped Received Damaged"
2370
        session.commit()
2371
    elif order.status == OrderStatus.DOA_LOST_IN_TRANSIT:
2372
        new_order = __clone_order(order, False, False)
2373
        order.status = OrderStatus.DOA_RESHIPPED_LOST_IN_TRANSIT
2374
        order.statusDescription = "Order Reshipped Lost In Transit"
2375
        session.commit()
4614 rajveer 2376
    elif order.status == OrderStatus.RET_PRODUCT_USABLE:
5620 mandeep.dh 2377
        new_order = __clone_order(order, False, False)
4614 rajveer 2378
        order.status = OrderStatus.RET_PRODUCT_USABLE_RESHIPPED
4495 rajveer 2379
        order.statusDescription = "Order Reshipped"
2380
        session.commit()
4614 rajveer 2381
    elif order.status == OrderStatus.RET_PRODUCT_UNUSABLE:
4495 rajveer 2382
        new_order = __clone_order(order, False, False)
2383
        ret_order = __create_return_order(order)
4614 rajveer 2384
        order.status = OrderStatus.RET_PRODUCT_UNUSABLE_RESHIPPED
4495 rajveer 2385
        order.statusDescription = "Order Reshipped"
2386
        session.commit()
2387
    elif order.status == OrderStatus.RET_RECEIVED_DAMAGED:
2388
        new_order = __clone_order(order, False, False)
2389
        ret_order = __create_return_order(order)
2390
        order.status = OrderStatus.RET_RESHIPPED_RCVD_DAMAGED
2391
        order.statusDescription = "Order Reshipped Received Damaged"
2392
        session.commit()
2393
    elif order.status == OrderStatus.RET_LOST_IN_TRANSIT:
2394
        new_order = __clone_order(order, False, False)
2395
        order.status = OrderStatus.RET_RESHIPPED_LOST_IN_TRANSIT
2396
        order.statusDescription = "Order Reshipped Lost In Transit"
2397
        session.commit()
2628 chandransh 2398
    else:
2399
        raise TransactionServiceException(112, "This order can't be reshipped")
2400
 
2764 chandransh 2401
    order.reship_timestamp = datetime.datetime.now()
2628 chandransh 2402
    order.new_order_id = new_order.id
2403
    session.commit()
2404
 
2405
    return new_order.id
2406
 
6735 amar.kumar 2407
def __scan_for_reship_order(order_id, new_order):
2408
    inventoryClient = InventoryClient().get_client()
2409
    warehouse = inventoryClient.getWarehouse(new_order.warehouse_id)
2410
    if warehouse.billingType == BillingType.OURS:
2411
        warehouseClient = WarehouseClient().get_client()
2412
        inventoryItem = warehouseClient.getInventoryItemFromOrder(order_id)
2413
        warehouseClient.scanForOrder(inventoryItem, ScanType.SALE, new_order.lineitems[0].quantity, new_order.id, new_order.fulfilmentWarehouseId, new_order.warehouse_id)
7199 amar.kumar 2414
    if order.freebieItemId:
2415
        warehouseClient = WarehouseClient().get_client()
2416
        inventoryItem = warehouseClient.reshipfreebie(order_id, new_order.id, new_order.freebieItemId, ScanType.SALE)
6735 amar.kumar 2417
 
3226 chandransh 2418
def refund_order(order_id, refunded_by, reason):
2628 chandransh 2419
    """
4484 rajveer 2420
    If the order is in RTO_RECEIVED_PRESTINE, DOA_CERT_VALID or DOA_CERT_INVALID state, it does the following:
2628 chandransh 2421
        1. Creates a refund request for batch processing.
2422
        2. Creates a return order for the warehouse executive to return the shipped material.
4484 rajveer 2423
        3. Marks the current order as RTO_REFUNDED, DOA_VALID_REFUNDED or DOA_INVALID_REFUNDED final states.
2628 chandransh 2424
 
2425
    If the order is in SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:
2426
        1. Creates a refund request for batch processing.
3226 chandransh 2427
        2. Cancels the reservation of the item in the warehouse.
2428
        3. Marks the current order as the REFUNDED final state.
2628 chandransh 2429
 
3226 chandransh 2430
    For all COD orders, if the order is in INIT, SUBMITTED_FOR_PROCESSING or INVENTORY_LOW state, it does the following:
2431
        1. Cancels the reservation of the item in the warehouse.
2432
        2. Marks the current order as CANCELED.
2433
 
2434
    In all cases, it updates the reason for cancellation or refund and the person who performed the action.
2435
 
2436
    Returns True if it is successful, False otherwise.
2628 chandransh 2437
 
2438
    Throws an exception if the order with the given id couldn't be found.
2439
 
2440
    Parameters:
3226 chandransh 2441
     - order_id
2442
     - refunded_by
2443
     - reason
2628 chandransh 2444
    """
3414 chandransh 2445
    logging.info("Refunding order id: " + str(order_id))
2628 chandransh 2446
    order = get_order(order_id)
3186 chandransh 2447
 
3226 chandransh 2448
    if order.cod:
3414 chandransh 2449
        logging.info("Refunding COD order with status " + str(order.status))
4662 rajveer 2450
        status_transition = { OrderStatus.LOST_IN_TRANSIT : OrderStatus.LOST_IN_TRANSIT_REFUNDED,
2451
                     OrderStatus.RTO_RECEIVED_PRESTINE : OrderStatus.RTO_REFUNDED,
4486 rajveer 2452
                     OrderStatus.RTO_RECEIVED_DAMAGED : OrderStatus.RTO_DAMAGED_REFUNDED,
2453
                     OrderStatus.RTO_LOST_IN_TRANSIT : OrderStatus.RTO_LOST_IN_TRANSIT_REFUNDED,
3366 chandransh 2454
                     OrderStatus.DOA_CERT_INVALID : OrderStatus.DOA_INVALID_REFUNDED,
2455
                     OrderStatus.DOA_CERT_VALID : OrderStatus.DOA_VALID_REFUNDED,
4479 rajveer 2456
                     OrderStatus.DOA_RECEIVED_DAMAGED : OrderStatus.DOA_REFUNDED_RCVD_DAMAGED,
2457
                     OrderStatus.DOA_LOST_IN_TRANSIT : OrderStatus.DOA_REFUNDED_LOST_IN_TRANSIT,
4495 rajveer 2458
                     OrderStatus.RET_PRODUCT_UNUSABLE : OrderStatus.RET_PRODUCT_UNUSABLE_REFUNDED,
2459
                     OrderStatus.RET_PRODUCT_USABLE : OrderStatus.RET_PRODUCT_USABLE_REFUNDED,
2460
                     OrderStatus.RET_RECEIVED_DAMAGED : OrderStatus.RET_REFUNDED_RCVD_DAMAGED,
2461
                     OrderStatus.RET_LOST_IN_TRANSIT : OrderStatus.RET_REFUNDED_LOST_IN_TRANSIT,
4682 rajveer 2462
                     OrderStatus.COD_VERIFICATION_PENDING : OrderStatus.COD_VERIFICATION_FAILED,
2463
                     OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2464
                     OrderStatus.INVENTORY_LOW : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2465
                     OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2466
                     OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2467
                     OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2468
                     OrderStatus.ACCEPTED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2469
                     OrderStatus.BILLED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
4247 rajveer 2470
                     OrderStatus.CANCEL_REQUEST_CONFIRMED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST
3366 chandransh 2471
                     }
2472
        if order.status not in status_transition.keys():
2473
            raise TransactionServiceException(114, "This order can't be refunded")
2474
 
5199 mandeep.dh 2475
        if order.status in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
3226 chandransh 2476
            __update_inventory_reservation(order)
2477
            order.statusDescription = "Order Cancelled"
3415 chandransh 2478
        elif order.status == OrderStatus.BILLED:
3413 chandransh 2479
            __create_return_order(order)
2480
            order.statusDescription = "Order Cancelled"
4486 rajveer 2481
        elif order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT]:
5386 phani.kuma 2482
            if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:
2483
                __create_return_order(order)
4486 rajveer 2484
            order.statusDescription = "RTO Refunded"
4662 rajveer 2485
        elif order.status in [OrderStatus.LOST_IN_TRANSIT]:
5386 phani.kuma 2486
            #__create_return_order(order)
4662 rajveer 2487
            order.statusDescription = "Lost in Transit Refunded"
4479 rajveer 2488
        elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :
5386 phani.kuma 2489
            if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:
2490
                __create_return_order(order)
3226 chandransh 2491
            __create_refund(order)
4495 rajveer 2492
            order.statusDescription = "DOA Refunded"
2493
        elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :
5386 phani.kuma 2494
            if order.status != OrderStatus.RET_LOST_IN_TRANSIT:
2495
                __create_return_order(order)
4495 rajveer 2496
            __create_refund(order)
2497
            order.statusDescription = "Return Refunded"
4247 rajveer 2498
        elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:
5199 mandeep.dh 2499
            if order.previousStatus in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
4247 rajveer 2500
                __update_inventory_reservation(order)
2501
                order.statusDescription = "Order Cancelled on customer request"
2502
            elif order.previousStatus == OrderStatus.BILLED:
2503
                __create_return_order(order)
2504
                order.statusDescription = "Order Cancelled on customer request"
6668 amar.kumar 2505
                order.received_return_timestamp = datetime.datetime.now()
3226 chandransh 2506
    else:
4662 rajveer 2507
        status_transition = {OrderStatus.LOST_IN_TRANSIT : OrderStatus.LOST_IN_TRANSIT_REFUNDED,
2508
                     OrderStatus.RTO_RECEIVED_PRESTINE : OrderStatus.RTO_REFUNDED,
4486 rajveer 2509
                     OrderStatus.RTO_RECEIVED_DAMAGED : OrderStatus.RTO_DAMAGED_REFUNDED,
2510
                     OrderStatus.RTO_LOST_IN_TRANSIT : OrderStatus.RTO_LOST_IN_TRANSIT_REFUNDED,
3366 chandransh 2511
                     OrderStatus.DOA_CERT_INVALID : OrderStatus.DOA_INVALID_REFUNDED,
2512
                     OrderStatus.DOA_CERT_VALID : OrderStatus.DOA_VALID_REFUNDED,
4479 rajveer 2513
                     OrderStatus.DOA_RECEIVED_DAMAGED : OrderStatus.DOA_REFUNDED_RCVD_DAMAGED,
2514
                     OrderStatus.DOA_LOST_IN_TRANSIT : OrderStatus.DOA_REFUNDED_LOST_IN_TRANSIT,
4495 rajveer 2515
                     OrderStatus.RET_PRODUCT_UNUSABLE : OrderStatus.RET_PRODUCT_UNUSABLE_REFUNDED,
2516
                     OrderStatus.RET_PRODUCT_USABLE : OrderStatus.RET_PRODUCT_USABLE_REFUNDED,
2517
                     OrderStatus.RET_RECEIVED_DAMAGED : OrderStatus.RET_REFUNDED_RCVD_DAMAGED,
2518
                     OrderStatus.RET_LOST_IN_TRANSIT : OrderStatus.RET_REFUNDED_LOST_IN_TRANSIT,
4682 rajveer 2519
                     OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2520
                     OrderStatus.INVENTORY_LOW : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2521
                     OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2522
                     OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2523
                     OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2524
                     OrderStatus.ACCEPTED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
2525
                     OrderStatus.BILLED : OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY,
4247 rajveer 2526
                     OrderStatus.CANCEL_REQUEST_CONFIRMED : OrderStatus.CANCELLED_ON_CUSTOMER_REQUEST,
2527
                     OrderStatus.PAYMENT_FLAGGED : OrderStatus.PAYMENT_FLAGGED_DENIED
3366 chandransh 2528
                     }
2529
        if order.status not in status_transition.keys():
2530
            raise TransactionServiceException(114, "This order can't be refunded")
2531
 
4495 rajveer 2532
        if order.status in [OrderStatus.RTO_RECEIVED_PRESTINE, OrderStatus.RTO_RECEIVED_DAMAGED, OrderStatus.RTO_LOST_IN_TRANSIT] :
5386 phani.kuma 2533
            if order.status != OrderStatus.RTO_LOST_IN_TRANSIT:
2534
                __create_return_order(order)
3226 chandransh 2535
            __create_refund(order)
4495 rajveer 2536
            order.statusDescription = "RTO Refunded"
4662 rajveer 2537
        elif order.status in [OrderStatus.LOST_IN_TRANSIT]:
5386 phani.kuma 2538
            #__create_return_order(order)
4662 rajveer 2539
            __create_refund(order)
2540
            order.statusDescription = "Lost in Transit Refunded"
4495 rajveer 2541
        elif order.status in [OrderStatus.DOA_CERT_INVALID, OrderStatus.DOA_CERT_VALID, OrderStatus.DOA_RECEIVED_DAMAGED, OrderStatus.DOA_LOST_IN_TRANSIT] :
5386 phani.kuma 2542
            if order.status != OrderStatus.DOA_LOST_IN_TRANSIT:
2543
                __create_return_order(order)
4495 rajveer 2544
            __create_refund(order)
2545
            order.statusDescription = "DOA Refunded"
2546
        elif order.status in [OrderStatus.RET_PRODUCT_UNUSABLE, OrderStatus.RET_PRODUCT_USABLE, OrderStatus.RET_RECEIVED_DAMAGED, OrderStatus.RET_LOST_IN_TRANSIT] :
5386 phani.kuma 2547
            if order.status != OrderStatus.RET_LOST_IN_TRANSIT:
2548
                __create_return_order(order)
4495 rajveer 2549
            __create_refund(order)
2550
            order.statusDescription = "Return Refunded"
5199 mandeep.dh 2551
        elif order.status in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
3226 chandransh 2552
            __update_inventory_reservation(order)
2553
            order.statusDescription = "Order Refunded"
4247 rajveer 2554
        elif order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED:
5272 mandeep.dh 2555
            if order.previousStatus in [OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.PAYMENT_FLAGGED, OrderStatus.ACCEPTED]:
4672 rajveer 2556
                if order.previousStatus == OrderStatus.ACCEPTED:
2557
                    __create_refund(order)
4247 rajveer 2558
                __update_inventory_reservation(order)
2559
                order.statusDescription = "Order Cancelled on customer request"
2560
            elif order.previousStatus == OrderStatus.BILLED:
2561
                __create_return_order(order)
2562
                __create_refund(order)
2563
                order.statusDescription = "Order Cancelled on customer request"
6668 amar.kumar 2564
                order.received_return_timestamp = datetime.datetime.now()
4247 rajveer 2565
        elif order.status == OrderStatus.PAYMENT_FLAGGED:
2566
            __update_inventory_reservation(order)
2567
            order.statusDescription = "Order Cancelled due to payment flagged"
3195 chandransh 2568
 
4873 mandeep.dh 2569
    # For orders that are cancelled after being billed, we need to scan in the scanned out
2570
    # inventory item and change availability accordingly
5944 mandeep.dh 2571
    inventoryClient = InventoryClient().get_client()
2572
    warehouse = inventoryClient.getWarehouse(order.warehouse_id)
6786 amar.kumar 2573
    if warehouse.billingType == BillingType.OURS or warehouse.billingType == BillingType.OURS_EXTERNAL:
4873 mandeep.dh 2574
        if order.status in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH] or (order.status == OrderStatus.CANCEL_REQUEST_CONFIRMED and order.previousStatus in [OrderStatus.BILLED, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_FROM_WH]):
2575
            lineitem = order.lineitems[0]
5944 mandeep.dh 2576
            catalogClient = CatalogClient().get_client()
5177 mandeep.dh 2577
            item = catalogClient.getItem(lineitem.item_id)
5361 mandeep.dh 2578
            warehouseClient = WarehouseClient().get_client()
6786 amar.kumar 2579
            if warehouse.billingType == BillingType.OURS:
2580
                if ItemType.SERIALIZED == item.type:
2581
                    warehouseClient.scanSerializedItemForOrder(lineitem.serial_number, ScanType.SALE_RET, order.id, order.fulfilmentWarehouseId, lineitem.quantity, order.warehouse_id)
2582
                else:
2583
                    warehouseClient.scanForOrder(None, ScanType.SALE_RET, lineitem.quantity, order.id, order.fulfilmentWarehouseId, order.warehouse_id)
2584
            if warehouse.billingType == BillingType.OURS_EXTERNAL:
2585
                warehouseClient.scanForOursExternalSaleReturn(order.id, lineitem.transfer_price)            
4873 mandeep.dh 2586
 
3195 chandransh 2587
    order.status = status_transition[order.status]
2588
    order.refund_timestamp = datetime.datetime.now()
3226 chandransh 2589
    order.refunded_by = refunded_by
2590
    order.refund_reason = reason
4873 mandeep.dh 2591
 
2628 chandransh 2592
    session.commit()
2593
    return True
2594
 
3186 chandransh 2595
def __update_inventory_reservation(order):
3191 chandransh 2596
    '''
2597
    Reduce the reservation count for all line items of the given order.
2598
    '''
3186 chandransh 2599
    try:
5944 mandeep.dh 2600
        inventoryClient = InventoryClient().get_client()
3186 chandransh 2601
        for lineitem in order.lineitems:
5966 rajveer 2602
            inventoryClient.reduceReservationCount(lineitem.item_id, order.fulfilmentWarehouseId, sourceId, order.id, lineitem.quantity)
3186 chandransh 2603
    except:
2604
        print "Unable to reduce reservation count"
2605
 
4220 rajveer 2606
def __clone_order(order, should_copy_billing_info, is_cod):
2628 chandransh 2607
    current_time = datetime.datetime.now()
2608
    new_order = Order()
2609
    new_order.customer_id = order.customer_id
2610
    new_order.customer_name = order.customer_name
2611
    new_order.customer_city = order.customer_city
2612
    new_order.customer_state = order.customer_state
2613
    new_order.customer_mobilenumber = order.customer_mobilenumber
2614
    new_order.customer_pincode = order.customer_pincode
2615
    new_order.customer_address1 = order.customer_address1
2616
    new_order.customer_address2 = order.customer_address2
2617
    new_order.customer_email = order.customer_email
2618
    new_order.total_amount = order.total_amount
6318 rajveer 2619
    new_order.gvAmount = order.gvAmount
2628 chandransh 2620
    new_order.total_weight = order.total_weight
2621
    new_order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
2622
    new_order.statusDescription = 'Submitted for Processing'
2623
    new_order.created_timestamp = current_time
5062 varun.gupt 2624
    new_order.originalOrderId = order.originalOrderId if order.originalOrderId is not None else order.id 
2628 chandransh 2625
 
2626
    new_order.transaction = order.transaction
4220 rajveer 2627
    new_order.cod = is_cod
5527 anupam.sin 2628
    new_order.orderType = order.orderType
7199 amar.kumar 2629
    new_order.freebieItemId = order.freebieItemId
2628 chandransh 2630
    for line_item in order.lineitems:
2631
        litem = LineItem()
2632
        litem.item_id = line_item.item_id
2633
        litem.productGroup = line_item.productGroup
2634
        litem.brand = line_item.brand
2635
        if line_item.model_number:
2636
            litem.model_number = line_item.model_number
2637
        if line_item.model_name:    
2638
            litem.model_name = line_item.model_name
2639
        if line_item.color:
2640
            litem.color = line_item.color
2641
        if line_item.extra_info:
2642
            litem.extra_info = line_item.extra_info
2643
        litem.quantity = line_item.quantity
2644
        litem.unit_price = line_item.unit_price
2645
        litem.unit_weight = line_item.unit_weight
2646
        litem.total_price = line_item.total_price
2647
        litem.total_weight = line_item.total_weight
2648
        litem.transfer_price = line_item.transfer_price
6751 amar.kumar 2649
        litem.nlc = line_item.nlc
4840 mandeep.dh 2650
        litem.dealText = line_item.dealText
6423 amit.gupta 2651
        litem.vatRate = line_item.vatRate
2628 chandransh 2652
        litem.order = new_order
6912 anupam.sin 2653
 
2654
    if order.insurer > 0:
2655
        new_order.insurer = order.insurer
2656
        new_order.insuranceAmount = order.insuranceAmount
2657
        newDetail = InsuranceDetailForOrder()
2658
        oldDetail = InsuranceDetailForOrder.get_by(order_id = order.id)
2659
        newDetail.dob = oldDetail.dob
2660
        newDetail.guardianName = oldDetail.guardianName
2661
        newDetail.order = new_order
2662
 
2628 chandransh 2663
    logistics_client = LogisticsClient().get_client()
2664
    item_id = new_order.lineitems[0].item_id
5785 mandeep.dh 2665
    logistics_info = logistics_client.getLogisticsInfo(new_order.customer_pincode, item_id, is_cod, PickUpType.COURIER) #TODO: We should be able to pass another flag to suggest ignoring the inventory situation.
6726 rajveer 2666
    logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
2628 chandransh 2667
    logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
6726 rajveer 2668
    logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime + logistics_info.deliveryDelay))
2628 chandransh 2669
    new_order.warehouse_id = logistics_info.warehouseId
5110 mandeep.dh 2670
    new_order.fulfilmentWarehouseId = logistics_info.fulfilmentWarehouseId
2628 chandransh 2671
    new_order.logistics_provider_id = logistics_info.providerId
2672
    new_order.airwaybill_no = logistics_info.airway_billno
2673
    new_order.tracking_id = new_order.airwaybill_no
6726 rajveer 2674
 
2675
    order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
2676
    new_order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3986 chandransh 2677
    new_order.promised_delivery_time = new_order.expected_delivery_time
6629 anupam.sin 2678
    new_order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
2679
    new_order.promised_shipping_time = new_order.expected_shipping_time
2680
 
2628 chandransh 2681
    if should_copy_billing_info:
5388 phani.kuma 2682
        new_order.vendorId = order.vendorId
2628 chandransh 2683
        new_order.invoice_number = order.invoice_number
2684
        new_order.billed_by = order.billed_by
2685
        new_order.warehouse_id = order.warehouse_id
5110 mandeep.dh 2686
        new_order.fulfilmentWarehouseId = order.fulfilmentWarehouseId
5620 mandeep.dh 2687
        new_order.jacket_number = order.jacket_number
2688
        new_order.lineitems[0].serial_number = order.lineitems[0].serial_number
2689
        new_order.lineitems[0].item_number   = order.lineitems[0].item_number
2628 chandransh 2690
        new_order.accepted_timestamp = current_time
2691
        new_order.billing_timestamp = current_time    
2692
        new_order.status = OrderStatus.BILLED
2693
        new_order.statusDescription = 'Order Billed'
5966 rajveer 2694
    else:
2695
        session.commit()       
5944 mandeep.dh 2696
        inventoryClient = InventoryClient().get_client()
5966 rajveer 2697
        inventoryClient.reserveItemInWarehouse(item_id, logistics_info.fulfilmentWarehouseId, sourceId, new_order.id, to_java_date(new_order.created_timestamp), to_java_date(new_order.promised_shipping_time), new_order.lineitems[0].quantity)
2628 chandransh 2698
 
2699
    return new_order
2700
 
2701
def __create_return_order(order):
2687 chandransh 2702
    ret_order = ReturnOrder(order)
2628 chandransh 2703
    return ret_order
2704
 
2705
def __create_refund(order):
4078 chandransh 2706
    payment_client = PaymentClient().get_client()
2707
    payment_client.createRefund(order.id, order.transaction.id, order.total_amount)
2747 chandransh 2708
    return
2628 chandransh 2709
 
2536 chandransh 2710
def __get_order_address(order):
2711
    address = order.customer_name + "\n" + order.customer_address1 + "\n"
2712
    if order.customer_address2:
2713
        address = address + order.customer_address2 + "\n"
2714
    address = address + order.customer_city + "\n"
2715
    address = address + order.customer_state + "\n"
2716
    address = address + "PIN " + order.customer_pincode + "\n"
2717
    address = address + "Phone: " + order.customer_mobilenumber
2718
    return address
2719
 
5767 rajveer 2720
def __get_store_address(store):
2721
    address = store.name + "\n" + store.line1 + "\n"
2722
    if store.line2:
2723
        address = address + store.line2 + "\n"
2724
    address = address + store.city + "\n"
2725
    address = address + store.state + "\n"
5802 rajveer 2726
    address = address + "PIN - " + store.pin + "\n"
5793 rajveer 2727
    if store.phone:
5802 rajveer 2728
        address = address + "Phone - " + store.phone + "\n"
5855 rajveer 2729
    address = address +  "Store timings - 11AM to 8PM (7 days)\n"
5767 rajveer 2730
    return address
2731
 
5793 rajveer 2732
def __get_store_address_html(store):
2733
    address = store.name + "<br>" + store.line1 + "<br>"
2734
    if store.line2:
2735
        address = address + store.line2 + "<br>"
2736
    address = address + store.city + "<br>"
2737
    address = address + store.state + "<br>"
5802 rajveer 2738
    address = address + "PIN - " + store.pin + "<br>"
5793 rajveer 2739
    if store.phone:
5802 rajveer 2740
        address = address + "Phone - " + store.phone + "<br>"
5855 rajveer 2741
    address = address +  "Store timings - 7 days: 11AM to 8PM  (7 days)<br>"
5793 rajveer 2742
    return address
2743
 
4815 phani.kuma 2744
def __generate_return_advice(order, warehouse, provider, filename):
2745
    if warehouse.id == 7:
7181 rajveer 2746
        executive = 'Shiv Kumar'
4815 phani.kuma 2747
    else:
4966 phani.kuma 2748
        executive = 'Dinesh Kumar'
2536 chandransh 2749
    pdf = Canvas(filename)
2750
    pdf.setFont('Times-Bold',16)
2751
    address_text = pdf.beginText(inch, PAGE_HEIGHT - inch)
2752
    address_text.textLine("To")
4815 phani.kuma 2753
    address_text.textLine(executive)
2536 chandransh 2754
    for line in warehouse.location.split("\n"):
2755
        address_text.textLine(line)
2756
    address_text.textLine("PIN " + warehouse.pincode)
2757
    pdf.drawText(address_text)
2758
 
2759
    pdf.setFont('Times-Roman',12)
2760
    order_text = pdf.beginText(inch, PAGE_HEIGHT - 4 * inch)
3051 chandransh 2761
    order_text.textLine("Pickup CODE: " + provider.details[DeliveryType.PREPAID].accountNo)
2536 chandransh 2762
    lineitem = order.lineitems[0] 
4234 rajveer 2763
    order_text.textLine("Content : " + lineitem.brand + " " + str(lineitem.model_number) + " " + str(lineitem.color))
2536 chandransh 2764
    order_text.textLine("Declared Value: Rs. " + str(order.total_amount))
2765
    order_text.textLine("Order ID : " + str(order.id))
2766
    pdf.drawText(order_text)
2767
    pdf.showPage()
2768
    pdf.save()
2769
    return filename
2770
 
5806 rajveer 2771
def __push_collection_to_hotspot(order, type):
2772
    try:
2773
        logistics_client = LogisticsClient().get_client()
2774
        store = logistics_client.getPickupStore(order.pickupStoreId)
2775
        store_string = "<store>" + store.hotspotId + "</store>"
2776
        order_string = "<orderno>" + str(order.id) + "</orderno>"
2777
        collection_type = "<Type>" + type + "</Type>"
5833 rajveer 2778
        payment_mode = get_order_attribute_value(order.id, "PAYMENT_MODE")
5806 rajveer 2779
        if type == "SALE":
6318 rajveer 2780
            amount = int(order.total_amount-order.gvAmount)
5806 rajveer 2781
            ts = order.delivery_timestamp
2782
        if type == "SALE RETURN":
6318 rajveer 2783
            amount = -int(order.total_amount-order.gvAmount)
5806 rajveer 2784
            ts = order.refund_timestamp
2785
        if payment_mode == "Cash":
2786
            cash_string = "<cash>" + str(amount) + "</cash>"
2787
            card_string = "<hdfc>0</hdfc>"
2788
        if payment_mode == "Card":
2789
            cash_string = "<cash>0</cash>"
2790
            card_string = "<hdfc>" + str(amount) + "</hdfc>"
2791
        date_string = "<date>" + ts.strftime("%Y%m%d") + "</date>"
2792
        time_string = "<time>" + ts.strftime("%H%M%S") + "</time>"
2793
 
7254 rajveer 2794
        conn = httplib.HTTPConnection("182.71.104.186")
5806 rajveer 2795
        XML="""
2796
        <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2797
          <soap:Body>
2798
            <SaholicDataTransfer xmlns="http://tempuri.org/">
2799
        """
2800
 
2801
        XML = XML + store_string + order_string + collection_type + cash_string + card_string + date_string + time_string 
2802
 
2803
        footer = """
2804
            </SaholicDataTransfer>
2805
          </soap:Body>
2806
        </soap:Envelope>
2807
        """
2808
        XML = XML + footer
2809
 
2810
        params = urllib.urlencode({'op': 'SaholicDataTransfer'})
2811
        headers = { "Content-type": "text/xml", "Content-Length": "%d" % len(XML)}
2812
        conn.request("POST", "/loaddetect/Service.asmx?"+params, "", headers)
2813
        conn.send(XML)
2814
        response = conn.getresponse()
2815
        print response.status, response.reason
2816
        resp = response.read()
2817
        conn.close()
2818
        print resp
2819
        if "Saved Successfully" in resp:
2820
            return True
2821
        elif "Error in Saving Data" in resp:
2822
            return False
2823
        else: 
2824
            return False
2825
    except Exception as e:
2826
        print e
2827
        return False
2828
 
2697 chandransh 2829
def get_return_orders(warehouse_id, from_date, to_date):
2830
    query = ReturnOrder.query.filter_by(processedStatus = False)
2831
    if warehouse_id != -1:
2832
        query = query.filter_by(warehouseId = warehouse_id)
2833
    if from_date:
4118 chandransh 2834
        query = query.filter(ReturnOrder.createdAt >from_date)
2697 chandransh 2835
    if to_date:
4118 chandransh 2836
        query = query.filter(ReturnOrder.createdAt < to_date)
2697 chandransh 2837
    return [return_order.to_thrift_object() for return_order in query.all()]
2838
 
5481 phani.kuma 2839
def get_all_return_orders(onlyNotProcessed, from_date, to_date):
2840
    query = ReturnOrder.query
2841
    if onlyNotProcessed:
2842
        query = query.filter_by(processedStatus = False)
2843
    if from_date:
2844
        query = query.filter(ReturnOrder.createdAt >= from_date)
2845
    if to_date:
2846
        query = query.filter(ReturnOrder.createdAt <= to_date)
2847
    return [return_order.to_thrift_object() for return_order in query.all()]
2848
 
2700 chandransh 2849
def get_return_order(id):
2850
    ret_order = ReturnOrder.get_by(orderId = id)
2851
    if ret_order is None:
2852
        raise TransactionServiceException(116, "No return order found for the given order id")
2853
    return ret_order.to_thrift_object()
2854
 
2697 chandransh 2855
def process_return(ret_order_id):
2856
    ret_order = ReturnOrder.get_by(orderId = ret_order_id)
2857
    if ret_order is None:
2858
        raise TransactionServiceException(116, "No return order found for the given order id")
2859
    ret_order.processedStatus = True
2701 chandransh 2860
    ret_order.processedAt = datetime.datetime.now()
2697 chandransh 2861
    session.commit()
2862
 
4757 mandeep.dh 2863
def update_orders_as_PORaised(itemIdQuantityMap, purchaseOrderId, warehouseId):
2864
    """
2865
    Updates orders as PO raised. Also updates purchase order id in orders. Pass a map of items mapped to
2866
    the quantities for which the PO is raised.
2867
 
2868
    Parameters:
2869
     - itemIdQuantityMap
2870
     - purchaseOrderId
2871
     - warehouseId
2872
    """
3451 chandransh 2873
    query = Order.query.with_lockmode("update").filter_by(warehouse_id=warehouseId)
4757 mandeep.dh 2874
    query = query.filter(or_(Order.status == OrderStatus.SUBMITTED_FOR_PROCESSING, Order.status == OrderStatus.INVENTORY_LOW))
2819 chandransh 2875
    query = query.filter_by(purchase_order_id=None)
2876
    query = query.order_by(Order.created_timestamp)
2877
    pending_orders = query.all()
4586 mandeep.dh 2878
 
2879
    for order in pending_orders:
4757 mandeep.dh 2880
        lineitem = order.lineitems[0]
2881
        if itemIdQuantityMap.has_key(lineitem.item_id):
2882
            if itemIdQuantityMap[lineitem.item_id] >= lineitem.quantity:
2883
                order.status = OrderStatus.LOW_INV_PO_RAISED
2884
                order.statusDescription = 'In Process'
2885
                order.purchase_order_id = purchaseOrderId
2886
                itemIdQuantityMap[lineitem.item_id] -= lineitem.quantity
4434 mandeep.dh 2887
 
2819 chandransh 2888
    session.commit()
2889
 
3451 chandransh 2890
def update_weight(order_id, weight):
3469 chandransh 2891
    '''
2892
    Update the weight of order
2893
    '''
3451 chandransh 2894
    order = get_order(order_id)
2895
    order.total_weight = weight
3469 chandransh 2896
    lineitem = order.lineitems[0]
2897
    lineitem.total_weight = weight
2898
    lineitem.unit_weight = weight
3451 chandransh 2899
 
3469 chandransh 2900
    session.commit()
2901
    return order
2902
 
2903
def change_product(order_id, item_id):
2904
    '''
2905
    Ship a product of a different color to the customer.
2906
    '''
2907
    order = get_order(order_id)
4662 rajveer 2908
    if order.status not in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT]:
3469 chandransh 2909
        raise TransactionServiceException(120, "This order has already been processed. Please seek help from engineering.")
2910
 
2911
    lineitem = order.lineitems[0]
3451 chandransh 2912
 
3469 chandransh 2913
    catalog_client = CatalogClient().get_client()
2914
 
2915
    old_item = catalog_client.getItem(lineitem.item_id)
2916
    item = catalog_client.getItem(item_id)
2917
    if old_item.catalogItemId != item.catalogItemId:
2918
        raise TransactionServiceException(121, "You can't ship a different item. You can only ship the same item in a different color.")
2919
 
5944 mandeep.dh 2920
    inventoryClient = InventoryClient().get_client()
5966 rajveer 2921
    inventoryClient.reserveItemInWarehouse(item_id, order.fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), order.lineitems[0].quantity)
5110 mandeep.dh 2922
    __update_inventory_reservation(order)
3469 chandransh 2923
    #TODO: Check that this new item has the same price
2924
 
2925
    lineitem.item_id = item_id
2926
    lineitem.color = item.color
2927
 
3451 chandransh 2928
    session.commit()
3469 chandransh 2929
 
2930
    order = get_order(order_id)
3451 chandransh 2931
    return order
3469 chandransh 2932
 
2933
def change_warehouse(order_id, warehouse_id):
2934
    '''
2935
    Update the warehouse which will be used to fulfil this order.
2936
    '''
2937
    order = get_order(order_id)
6019 rajveer 2938
    if order.status not in [OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT, OrderStatus.ACCEPTED]:
3469 chandransh 2939
        raise TransactionServiceException(117, "This order has already been processed. Please seek help from engineering.")
2940
 
2941
    if warehouse_id == order.warehouse_id:
2942
        raise TransactionServiceException(118, "You have selected the current warehouse again. Nothing to do")
2943
 
2944
    lineitem = order.lineitems[0]
2945
    catalog_client = CatalogClient().get_client()
5944 mandeep.dh 2946
    inventoryClient = InventoryClient().get_client()
3469 chandransh 2947
    try:
5944 mandeep.dh 2948
        warehouse = inventoryClient.getWarehouse(warehouse_id)
3469 chandransh 2949
    except:
2950
        raise TransactionServiceException(119, "No warehouse with id" + str(warehouse_id))
5110 mandeep.dh 2951
 
6870 rajveer 2952
    if not warehouse.billingWarehouseId:
5147 mandeep.dh 2953
        raise TransactionServiceException(119, "Shifting of warehouse allowed to warehouse with billing support only")
5110 mandeep.dh 2954
 
5620 mandeep.dh 2955
    # If One gives a billing warehouse for warehouse shift, we should assign order to the GOOD warehouse
2956
    # present within it with maximum availability
2957
    if warehouse.id == warehouse.billingWarehouseId:
5944 mandeep.dh 2958
        warehouses = inventoryClient.getWarehouses(None, InventoryType.GOOD, 0, 0, warehouse.id)
5147 mandeep.dh 2959
        if warehouses:
5944 mandeep.dh 2960
            itemInventory = inventoryClient.getItemInventoryByItemId(lineitem.item_id)
5147 mandeep.dh 2961
            warehouse = warehouses[0]
2962
            maxAvailability = 0
2963
            for goodWarehouse in warehouses:
2964
                if itemInventory.availability.has_key(goodWarehouse.id) and maxAvailability < itemInventory.availability[goodWarehouse.id]:
2965
                    warehouse = goodWarehouse
2966
                    maxAvailability = itemInventory.availability[goodWarehouse.id]
2967
 
2968
            # Use preferred vendor's warehouse if not available anywhere
2969
            if not maxAvailability:
2970
                item = catalog_client.getItem(lineitem.item_id)
2971
                if item.preferredVendor:
2972
                    for goodWarehouse in warehouses:
2973
                        if goodWarehouse.vendor.id == item.preferredVendor:
2974
                            warehouse = goodWarehouse
2975
        else:
2976
            raise TransactionServiceException(119, "Shifting of warehouse allowed to GOOD inventory type warehouse with billing support")
2977
 
6007 rajveer 2978
    inventoryClient.reserveItemInWarehouse(lineitem.item_id, warehouse.id, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), lineitem.quantity)
5110 mandeep.dh 2979
    __update_inventory_reservation(order)
6789 rajveer 2980
    if order.status == OrderStatus.ACCEPTED:
2981
        __update_transfer_price(order, warehouse.id)
5110 mandeep.dh 2982
    order.warehouse_id = warehouse.billingWarehouseId
5147 mandeep.dh 2983
    order.fulfilmentWarehouseId = warehouse.id
3469 chandransh 2984
    session.commit()
2985
    return order
3553 chandransh 2986
 
6789 rajveer 2987
def __update_transfer_price(order, warehouse_id):
2988
    lineitem = order.lineitems[0]
2989
    inventory_client = InventoryClient().get_client()
2990
    warehouse = inventory_client.getWarehouse(warehouse_id)
2991
    item_pricing = inventory_client.getItemPricing(lineitem.item_id, warehouse.vendor.id)
2992
    lineitem.transfer_price = item_pricing.transferPrice
2993
    lineitem.nlc = item_pricing.nlc
2994
 
4647 rajveer 2995
def add_delay_reason(order_id, reason, further_delay, delayReasonText):
3553 chandransh 2996
    '''
3994 chandransh 2997
    Adds a delay reason to the order and updates the expected delivery time.
3553 chandransh 2998
    '''
2999
    order = get_order(order_id)
3000
    try:
3581 chandransh 3001
        order.delay_reason = DelayReason._VALUES_TO_NAMES[reason]
4647 rajveer 3002
        order.delayReasonText = delayReasonText
4009 chandransh 3003
        actual_delivery_delay = adjust_delivery_time(order.expected_delivery_time, further_delay)
3004
        order.expected_delivery_time = order.expected_delivery_time + datetime.timedelta(days=actual_delivery_delay)
4102 chandransh 3005
 
4842 rajveer 3006
        actual_shipping_delay = adjust_delivery_time(order.expected_shipping_time, further_delay)
3007
        order.expected_shipping_time = order.expected_shipping_time + datetime.timedelta(days=actual_shipping_delay)
4102 chandransh 3008
 
6726 rajveer 3009
        order.courier_delivery_time = order.courier_delivery_time + datetime.timedelta(days=adjust_delivery_time(order.courier_delivery_time, further_delay))
3010
 
3553 chandransh 3011
        session.commit()
4008 mandeep.dh 3012
 
3013
        try:
3014
            transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
3015
            transaction_requiring_extra_processing.category = 'DELAYED_DELIVERY'
3016
            transaction_requiring_extra_processing.transaction_id = order.transaction_id
3017
            session.commit()
3018
        except Exception as e:
4065 mandeep.dh 3019
            print 'Could not persist transaction id: ' + str(order.transaction_id) + ' for further processing due to: ' + str(e)
4008 mandeep.dh 3020
 
3553 chandransh 3021
        return True
3022
    except:
3994 chandransh 3023
        print sys.exc_info()[0]
3553 chandransh 3024
        return False
3956 chandransh 3025
 
3026
def reconcile_cod_collection(collected_amount_map, xferBy, xferTxnId, xferDate):
3027
    unprocessed_awbs = {}
3028
    for awb, amount in collected_amount_map.iteritems():
3029
        try:
3030
            order = Order.query.filter_by(airwaybill_no=awb).one()
3031
        except NoResultFound:
3032
            unprocessed_awbs[awb] = "No order was found for the given AWB: " + awb
3033
            continue
3034
        except MultipleResultsFound:
3035
            unprocessed_awbs[awb] = "Multiple orders were found for the given AWB:" + awb
3036
            continue
3037
 
3038
        if order.cod_reconciliation_timestamp:
3039
            #This order has been processed already! This may be a re-run. Let's allow other orders to be processed.
3040
            continue
3041
 
3042
        if order.status < OrderStatus.DELIVERY_SUCCESS:
3043
            #Order has not been delivered yet. No way we can receive the payment.
3044
            unprocessed_awbs[awb] = "Payment has been received for order: " + str(order.id) + " before delivery reconciliation"
3045
            continue
3046
 
4252 rajveer 3047
        ##As per ticket #743 if amount difference less than 0.5 we should reconcile
6318 rajveer 3048
        if abs(amount - (order.total_amount - order.gvAmount)) > 0.5:
3956 chandransh 3049
            #Received amount is less than or more than the order amount. Mustn't let the user proceed.
6318 rajveer 3050
            unprocessed_awbs[awb] = "Payment of Rs. " + str(amount) + " has been received against the total value of Rs. " + str(order.total_amount-order.gvAmount) + " for order: " + str(order.id)
3956 chandransh 3051
            continue
3052
 
3053
        try:
3054
            payment_client = PaymentClient().get_client()
3055
            payment_client.partiallyCapturePayment(order.transaction.id, amount, xferBy, xferTxnId, xferDate)
3056
        except Exception:
3057
            unprocessed_awbs[awb] = "We were unable to partially capture payment for order id " + str(order.id) + ", AWB: " + awb
3058
            continue
3059
 
3060
        #Payment has been recorded now. We can update the order peacefully.
3061
        order.cod_reconciliation_timestamp = datetime.datetime.now()
3062
        session.commit()
3469 chandransh 3063
 
3956 chandransh 3064
    return unprocessed_awbs
4008 mandeep.dh 3065
 
3066
def get_transactions_requiring_extra_processing(category):
4065 mandeep.dh 3067
    """
3068
    Returns the list of transaction ids that require some extra processing and
3069
    which belong to a particular category. This is currently used by CRM
3070
    application. If no such transaction ids are present, it returns an empty list.
3071
    """
3072
    query = TransactionRequiringExtraProcessing.query
4008 mandeep.dh 3073
 
4065 mandeep.dh 3074
    if category is not None:
3075
        query = query.filter_by(category = ExtraTransactionProcessingType._VALUES_TO_NAMES.get(category))
4008 mandeep.dh 3076
 
4065 mandeep.dh 3077
    return [a.transaction_id for a in query.all()]
4008 mandeep.dh 3078
 
3079
def mark_transaction_as_processed(transactionId, category):
4065 mandeep.dh 3080
    """
3081
    Marks a particular transaction as processed for a particular cateogory.
3082
    It essentially deletes the transaction id record for a particular
3083
    processing type category (if present) from DB.
3084
    This is currently used by CRM application.
3085
    """
4008 mandeep.dh 3086
    TransactionRequiringExtraProcessing.query.filter_by(transaction_id = transactionId).filter_by(category = ExtraTransactionProcessingType._VALUES_TO_NAMES.get(category)).delete()
3087
    session.commit()
3088
 
4018 chandransh 3089
def get_item_wise_risky_orders_count():
3090
    """
3091
    Returns a map containing the number of risky orders keyed by item id. A risky order
3092
    is defined as one whose shipping date is about to expire.
3093
    """
3094
    item_wise_risky_orders_count = {}
4019 chandransh 3095
    shipping_cutoff_time = (datetime.datetime.now() + datetime.timedelta(days = 1)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4018 chandransh 3096
    orders = Order.query.filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.ACCEPTED]))).filter(Order.expected_shipping_time <= shipping_cutoff_time).all()
3097
    for order in orders:
3098
        for lineitem in order.lineitems:
3099
            quantity = lineitem.quantity
3100
            if item_wise_risky_orders_count.has_key(lineitem.item_id):
3101
                quantity = quantity + item_wise_risky_orders_count[lineitem.item_id]
3102
 
3103
            item_wise_risky_orders_count[lineitem.item_id] = quantity
3104
    return item_wise_risky_orders_count
3105
 
4324 mandeep.dh 3106
def update_shipment_address(order_id, address_id):
3107
    """
3108
    Updates shipment address of an order. Delivery and shipping date estimates
3109
    etc. are also updated here.
3110
 
3111
    Throws TransactionServiceException in case address change is not
3112
    possible due to certain reasons such as new pincode in address is
3113
    not serviceable etc.
3114
 
3115
    Parameters:
3116
     - orderId
3117
     - addressId
3118
    """
3119
    user_client = UserClient().get_client()
3120
    address     = user_client.getAddressById(address_id)
3121
    order       = get_order(order_id)
3122
 
4630 mandeep.dh 3123
    type = DeliveryType.PREPAID
3124
    if order.cod:
3125
        type = DeliveryType.COD
3126
 
4324 mandeep.dh 3127
    logistics_client = LogisticsClient().get_client()
5886 mandeep.dh 3128
    logistics_info = logistics_client.getLogisticsEstimation(order.lineitems[0].item_id, address.pin, type)
4324 mandeep.dh 3129
 
3130
    # Check for new estimate. Raise exception if new address is not serviceable
3131
    if logistics_info.deliveryTime == -1:
3132
        raise TransactionServiceException(1, 'Location not serviceable')
3133
 
3134
    # COD services are not available everywhere
3135
    if order.cod:
4868 rajveer 3136
        if not logistics_info.codAllowed:
4324 mandeep.dh 3137
            raise TransactionServiceException(2, 'COD service not available')
3138
 
5593 mandeep.dh 3139
    if logistics_info.providerId != order.logistics_provider_id:
5887 mandeep.dh 3140
        logistics_info = logistics_client.getLogisticsInfo(address.pin, order.lineitems[0].item_id, type, PickUpType.COURIER)
5593 mandeep.dh 3141
        order.tracking_id = logistics_info.airway_billno
3142
        order.airwaybill_no = logistics_info.airway_billno
3143
        order.logistics_provider_id = logistics_info.providerId
3144
 
6525 rajveer 3145
    order.otg = logistics_info.otgAvailable
4324 mandeep.dh 3146
    current_time = datetime.datetime.now()
3147
    logistics_info.deliveryTime = adjust_delivery_time(current_time, logistics_info.deliveryTime)
3148
    logistics_info.shippingTime = adjust_delivery_time(current_time, logistics_info.shippingTime)
6726 rajveer 3149
    logistics_info.deliveryDelay = adjust_delivery_time(current_time, (logistics_info.shippingTime+logistics_info.deliveryDelay))
4324 mandeep.dh 3150
 
3151
    order.customer_name         = address.name
3152
    order.customer_pincode      = address.pin
3153
    order.customer_address1     = address.line1
3154
    order.customer_address2     = address.line2
3155
    order.customer_city         = address.city
3156
    order.customer_state        = address.state
3157
    order.customer_mobilenumber = address.phone
3158
 
3159
    if order.cod:
3160
        order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
6726 rajveer 3161
        order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3162
        order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4324 mandeep.dh 3163
    else:
3164
        order.expected_shipping_time = (current_time + datetime.timedelta(days=logistics_info.shippingTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
6726 rajveer 3165
        order.expected_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
3166
        order.courier_delivery_time = (current_time + datetime.timedelta(days=logistics_info.deliveryDelay)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)
4324 mandeep.dh 3167
 
3168
    order.promised_shipping_time = order.expected_shipping_time
3169
    order.promised_delivery_time = order.expected_delivery_time 
3170
 
3171
    session.commit()
3172
 
4247 rajveer 3173
def mark_order_cancellation_request_received(orderId):
3174
    """
3175
    Mark order as cancellation request received. If customer sends request of cancellation of
3176
    a particular order, this method will be called. It will just change status of the order
3177
    depending on its current status. It also records the previous status, so that we can move
3178
    back to that status if cancellation request is denied.
3179
 
3180
    Parameters:
3181
     - orderId
3182
    """
4662 rajveer 3183
    status_transition = {OrderStatus.COD_VERIFICATION_PENDING : OrderStatus.CANCEL_REQUEST_RECEIVED,
4247 rajveer 3184
             OrderStatus.SUBMITTED_FOR_PROCESSING : OrderStatus.CANCEL_REQUEST_RECEIVED,
3185
             OrderStatus.INVENTORY_LOW : OrderStatus.CANCEL_REQUEST_RECEIVED,
4306 rajveer 3186
             OrderStatus.LOW_INV_PO_RAISED : OrderStatus.CANCEL_REQUEST_RECEIVED,
3187
             OrderStatus.LOW_INV_REVERSAL_IN_PROCESS : OrderStatus.CANCEL_REQUEST_RECEIVED,
3188
             OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT : OrderStatus.CANCEL_REQUEST_RECEIVED,
4247 rajveer 3189
             OrderStatus.ACCEPTED : OrderStatus.CANCEL_REQUEST_RECEIVED,
3190
             OrderStatus.BILLED : OrderStatus.CANCEL_REQUEST_RECEIVED,
3191
             OrderStatus.PAYMENT_FLAGGED : OrderStatus.CANCEL_REQUEST_RECEIVED
3192
             }
4662 rajveer 3193
 
3194
    order = get_order(orderId)
4247 rajveer 3195
    if order.status not in status_transition.keys():
3196
        raise TransactionServiceException(114, "This order can't be considered for cancellation")
3197
 
4662 rajveer 3198
 
4247 rajveer 3199
    order.previousStatus = order.status
3200
    order.status = OrderStatus.CANCEL_REQUEST_RECEIVED
3201
    order.statusDescription = "Cancellation request received from user"
3202
    session.commit()
3203
 
4662 rajveer 3204
def mark_order_as_lost_in_transit(orderId):
3205
    """
3206
    Parameters:
3207
     - orderId
3208
    """
3209
    order = get_order(orderId)
4910 phani.kuma 3210
    if order.status not in [OrderStatus.SHIPPED_FROM_WH, OrderStatus.SHIPPED_TO_LOGST, OrderStatus.SHIPPED_TO_DESTINATION_CITY, OrderStatus.REACHED_DESTINATION_CITY, OrderStatus.FIRST_DELIVERY_ATTEMPT_MADE]:
4662 rajveer 3211
        raise TransactionServiceException(115, "This order can't be marked as lost in transit")
3212
    order.status = OrderStatus.LOST_IN_TRANSIT
3213
    order.statusDescription = "Lost in Transit"
3214
    session.commit()
3215
 
4258 rajveer 3216
def mark_transaction_as_payment_flag_removed(transactionId):
4247 rajveer 3217
    """
4258 rajveer 3218
    If we and/or payment gateway has decided to accept the payment, this method needs to be called.
3219
    Changed transaction and all orders status to payment accepted.
4247 rajveer 3220
 
3221
    Parameters:
4258 rajveer 3222
     - transactionId
4247 rajveer 3223
    """
4258 rajveer 3224
    transaction = get_transaction(transactionId)
3225
    transaction.status = TransactionStatus.AUTHORIZED
3226
    for order in transaction.orders:
3227
        order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
3228
        order.statusDescription = "Submitted to warehouse"
4247 rajveer 3229
    session.commit()
3230
 
4259 anupam.sin 3231
def refund_transaction(transactionId, refundedBy, reason):
3232
    """
3233
    This method is called when a flagged payment is deemed unserviceable and the corresponding orders
3234
    need to be cancelled
3235
 
3236
    Parameters:
3237
     - transactionId
3238
    """
3239
    transaction = get_transaction(transactionId)
3240
    transaction.status = TransactionStatus.FAILED
3241
    for order in transaction.orders:
3242
        refund_order(order.id, refundedBy, reason)
3243
    session.commit()
3244
 
4247 rajveer 3245
def mark_order_cancellation_request_denied(orderId):
3246
    """
4283 anupam.sin 3247
    If we decide to not to cancel order, we will move the order to previous status.
4247 rajveer 3248
 
3249
    Parameters:
3250
     - orderId
3251
    """
3252
    order = get_order(orderId)
3253
    order.status = order.previousStatus
3254
    order.previousStatus = None
3255
    order.statusDescription = "Cancellation request denied"
3256
    session.commit()
3257
 
3258
def mark_order_cancellation_request_confirmed(orderId):
3259
    """
3260
    If we decide to to cancel order, CRM will call this method to move the status of order to
3261
    cancellation request confirmed. After this OM will be able to cancel the order.
3262
 
3263
    Parameters:
3264
     - orderId
3265
    """
3266
    order = get_order(orderId)
3267
    order.status = OrderStatus.CANCEL_REQUEST_CONFIRMED
3268
    order.statusDescription = "Cancellation request confirmed"
3269
    session.commit()
3270
 
4285 rajveer 3271
def accept_orders_for_item_id(itemId, inventory):
3272
    """
3273
    Marks the orders as ACCEPTED for the given itemId and inventory. It also updates the accepted timestamp. If the
3274
    given order is not a COD order, it also captures the payment if the same has not been captured.
3275
 
3276
    Parameters:
3277
     - itemId
3278
     - inventory
3279
    """
6782 rajveer 3280
    orders = Order.query.filter(Order.warehouse_id == 9).filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS]))).order_by(Order.expected_shipping_time).all()
4285 rajveer 3281
    for order in orders:
4301 rajveer 3282
        if inventory > 0:
3283
            lineitem = order.lineitems[0]
3284
            if itemId == lineitem.item_id:
3285
                try:
3286
                    accept_order(order.id)
3287
                    inventory = inventory - lineitem.quantity
3288
                except:
3289
                    logging.info("Unable to accept the order")
3290
        else:
3291
            order_outofstock(order.id)
4285 rajveer 3292
    return
3293
 
6864 rajveer 3294
def move_orders_to_correct_warehouse():
3295
    orders = Order.query.filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS]))).order_by(Order.promised_shipping_time).all()
3296
    logistics_client = LogisticsClient().get_client()
3297
    for order in orders:
3298
        lineitem = order.lineitems[0]
6870 rajveer 3299
        logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, lineitem.item_id, order.cod, PickUpType.COURIER)
6864 rajveer 3300
        if order.fulfilmentWarehouseId != logistics_info.fulfilmentWarehouseId:
6870 rajveer 3301
            try:
3302
                print "++++" + str(order.id) + "=" + str(order.fulfilmentWarehouseId) + "->"+ str(logistics_info.fulfilmentWarehouseId)
3303
                change_warehouse(order.id, logistics_info.fulfilmentWarehouseId)
3304
            except:
3305
                print "++++" + str(order.id)
6864 rajveer 3306
 
4607 rajveer 3307
def get_slipped_sipping_date_orders():
4662 rajveer 3308
    return Order.query.filter(Order.status.in_(tuple([OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS, OrderStatus.ACCEPTED, OrderStatus.BILLED]))).filter(Order.promised_shipping_time <= datetime.datetime.now()).order_by(Order.promised_shipping_time).all()
4709 rajveer 3309
 
3310
def get_cancelled_orders(cancelDateFrom, cancelDateTo):
3311
    return Order.query.filter(Order.status == OrderStatus.CANCELLED_DUE_TO_LOW_INVENTORY).filter(Order.refund_timestamp >= cancelDateFrom).filter(Order.refund_timestamp <= cancelDateTo).all()
4607 rajveer 3312
 
4369 rajveer 3313
def mark_orders_as_po_raised(vendorId, itemId, quantity, estimate, isReminder):
3314
    if isReminder:
3315
        statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])
3316
    else:
3317
        statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])
3318
 
3319
    orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()
4303 rajveer 3320
    for order in orders:
3321
        lineitem = order.lineitems[0]
3322
        if quantity >= lineitem.quantity and itemId == lineitem.item_id:
3323
            if estimate > 0:
3324
                add_delay_reason(order.id, DelayReason.OTHERS, estimate)
3325
            order.status = OrderStatus.LOW_INV_PO_RAISED
4362 rajveer 3326
            order.statusDescription = "PO Raised"
4303 rajveer 3327
            quantity = quantity - lineitem.quantity
3328
            store_inventory_action(order, itemId, HotspotAction.PO_RAISED, estimate, lineitem.quantity)
3329
            session.commit()
3330
 
4369 rajveer 3331
def mark_orders_as_reversal_initiated(vendorId, itemId, quantity, estimate, isReminder):
3332
    if isReminder:
3333
        statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])
3334
    else:
3335
        statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])
3336
    orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()
4303 rajveer 3337
    for order in orders:
3338
        lineitem = order.lineitems[0]
3339
        if quantity >= lineitem.quantity and itemId == lineitem.item_id:
3340
            if estimate > 0:
3341
                add_delay_reason(order.id, DelayReason.OTHERS, estimate)
3342
            order.status = OrderStatus.LOW_INV_REVERSAL_IN_PROCESS
4362 rajveer 3343
            order.statusDescription = "Reversal Initiated"
4303 rajveer 3344
            quantity = quantity - lineitem.quantity
3345
            store_inventory_action(order, itemId, HotspotAction.REVERSAL_INITIATED, estimate, lineitem.quantity)
3346
            session.commit()
3347
 
4369 rajveer 3348
def mark_orders_as_not_available(vendorId, itemId, quantity, estimate, isReminder):
3349
    if isReminder:
3350
        statuses = tuple([OrderStatus.LOW_INV_PO_RAISED_TIMEOUT, OrderStatus.LOW_INV_REVERSAL_TIMEOUT])
3351
    else:
3352
        statuses = tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.INVENTORY_LOW])
3353
 
3354
    orders = Order.query.filter(Order.status.in_(statuses)).order_by(Order.expected_shipping_time).all()
4303 rajveer 3355
    for order in orders:
3356
        lineitem = order.lineitems[0]
3357
        if quantity >= lineitem.quantity and itemId == lineitem.item_id:
3358
            order.status = OrderStatus.LOW_INV_NOT_AVAILABLE_AT_HOTSPOT
4362 rajveer 3359
            order.statusDescription = "Not Available"
4303 rajveer 3360
            quantity = quantity - lineitem.quantity
3361
            store_inventory_action(order, itemId, HotspotAction.NOT_AVAILABLE, estimate, lineitem.quantity)
3362
            session.commit()
3363
 
3364
def store_inventory_action(order, itemId, hotspotAction, estimate, quantity):
4369 rajveer 3365
    orderInv = OrderInventory.get_by(order_id=order.id)
3366
    if not orderInv:
3367
        orderInv = OrderInventory()
3368
        orderInv.order = order
4303 rajveer 3369
    orderInv.hotspotAction = hotspotAction  
3370
    orderInv.estimate = estimate
3371
    orderInv.itemId = itemId
3372
    orderInv.timestamp = datetime.datetime.now()
3373
    orderInv.quantity = quantity
3374
 
4556 mandeep.dh 3375
'''    
4369 rajveer 3376
def mark_orders_as_timeout(vendorId):
3377
    ret_timeouts = {}
3378
    orderInvs = OrderInventory.query.all()
3379
    for orderInv in orderInvs:
3380
        if orderInv.timestamp +  timedelta(days=orderInv.estimate) < datetime.datetime.now():
3381
            if not ret_timeouts.has_key(orderInv.itemId):
3382
                timeout = TimeoutSummary()
3383
                ret_timeouts[orderInv.itemId] = timeout
3384
            else:
3385
                timeout = ret_timeouts.get(orderInv.itemId)
3386
            if orderInv.hotspotAction == HotspotAction.PO_RAISED and orderInv.order.status == OrderStatus.LOW_INV_PO_RAISED:
3387
                if timeout.poRaised:
3388
                    timeout.poRaised += 1
3389
                else:
3390
                    timeout.poRaised = 1
3391
 
3392
                if timeout.poEstimate:
3393
                    timeout.poEstimate += orderInv.estimate
3394
                else:
3395
                    timeout.poEstimate = orderInv.estimate
3396
                orderInv.order.status = OrderStatus.LOW_INV_PO_RAISED_TIMEOUT
3397
                orderInv.order.statusDescription = "PO Raised Timeout"
3398
            elif orderInv.hotspotAction == HotspotAction.REVERSAL_INITIATED and orderInv.order.status == OrderStatus.LOW_INV_REVERSAL_IN_PROCESS:
3399
                if timeout.reversalInitiated:
3400
                    timeout.reversalInitiated += 1
3401
                else:
3402
                    timeout.reversalInitiated = 1
3403
 
3404
                if timeout.reversalEstimate:
3405
                    timeout.reversalEstimate += orderInv.estimate
3406
                else:
3407
                    timeout.reversalEstimate = orderInv.estimate
3408
                orderInv.order.status = OrderStatus.LOW_INV_REVERSAL_TIMEOUT
3409
                orderInv.order.statusDescription = "Reversal Initiated Timeout"
3410
            else:
3411
                orderInv.delete()
3412
    session.commit()
3413
    return ret_timeouts
4556 mandeep.dh 3414
'''
3415
 
3416
 
3417
def mark_orders_as_timeout(vendorId):
3418
    ret_timeouts = {}
3419
    orderInvs = OrderInventory.query.all()
3420
    for orderInv in orderInvs:
3421
        if not ret_timeouts.has_key(orderInv.itemId):
3422
            timeout = TimeoutSummary()
3423
            ret_timeouts[orderInv.itemId] = timeout
3424
        else:
3425
            timeout = ret_timeouts.get(orderInv.itemId)
3426
        if orderInv.hotspotAction == HotspotAction.PO_RAISED and orderInv.order.status == OrderStatus.LOW_INV_PO_RAISED:
3427
            if timeout.poRaised:
3428
                timeout.poRaised += 1
3429
            else:
3430
                timeout.poRaised = 1
3431
 
3432
            if timeout.poEstimate:
3433
                timeout.poEstimate = max(orderInv.estimate, timeout.poEstimate)
3434
            else:
3435
                timeout.poEstimate = orderInv.estimate
3436
        elif orderInv.hotspotAction == HotspotAction.REVERSAL_INITIATED and orderInv.order.status == OrderStatus.LOW_INV_REVERSAL_IN_PROCESS:
3437
            if timeout.reversalInitiated:
3438
                timeout.reversalInitiated += 1
3439
            else:
3440
                timeout.reversalInitiated = 1
3441
 
3442
            if timeout.reversalEstimate:
3443
                timeout.reversalEstimate = max(orderInv.estimate, timeout.reversalEstimate)
3444
            else:
3445
                timeout.reversalEstimate = orderInv.estimate
3446
        orderInv.order.status = OrderStatus.INVENTORY_LOW
3447
        orderInv.order.statusDescription = "Low Inventory"
3448
        orderInv.delete()
3449
    session.commit()
3450
    return ret_timeouts
3451
 
4386 anupam.sin 3452
def get_order_for_awb(awb):
3453
    order = Order.get_by(airwaybill_no=awb)
3454
    if not order:
3455
        raise TransactionServiceException(108, "no such order")
3456
 
3457
    return order
4369 rajveer 3458
 
4910 phani.kuma 3459
def get_orders_for_provider_for_status(provider_id, order_status_list):
3460
    if not provider_id or not order_status_list:
4506 phani.kuma 3461
        raise TransactionServiceException(101, "bad provider id or order status")
4910 phani.kuma 3462
    doa_provider = False
3463
    for order_status in order_status_list:
3464
        if order_status in [OrderStatus.DOA_PICKUP_CONFIRMED, OrderStatus.RET_PICKUP_CONFIRMED]:
3465
            doa_provider = True
3466
    if doa_provider:
3467
        query = Order.query.filter_by(doa_logistics_provider_id = provider_id).filter(Order.status.in_(order_status_list))
4815 phani.kuma 3468
    else:
4910 phani.kuma 3469
        query = Order.query.filter_by(logistics_provider_id = provider_id).filter(Order.status.in_(order_status_list))
4506 phani.kuma 3470
    return query.all()
4386 anupam.sin 3471
 
4600 varun.gupt 3472
def get_billed_orders_for_vendor(vendor_id, billing_date_from, billing_date_to):
5368 mandeep.dh 3473
    query = Order.query.filter(Order.status != OrderStatus.PAYMENT_PENDING)
3474
 
3475
    if vendor_id:
3476
        query = query.filter_by(vendorId = vendor_id)
3477
 
4600 varun.gupt 3478
    if billing_date_from:
3479
        query = query.filter(Order.billing_timestamp >= billing_date_from)
5368 mandeep.dh 3480
 
4600 varun.gupt 3481
    if billing_date_to:
3482
        query = query.filter(Order.billing_timestamp <= billing_date_to)
5368 mandeep.dh 3483
 
4600 varun.gupt 3484
    return query.all()
3485
 
5481 phani.kuma 3486
def get_billed_orders(vendor_id, onlyVendorNotPaid, billing_date_from, billing_date_to):
5386 phani.kuma 3487
    query = Order.query.filter(Order.billing_timestamp != None)
5481 phani.kuma 3488
 
3489
    if onlyVendorNotPaid:
5488 phani.kuma 3490
        query = query.filter_by(vendor_paid = False)
5481 phani.kuma 3491
 
5386 phani.kuma 3492
    if vendor_id != -1:
3493
        query = query.filter_by(vendorId = vendor_id)
3494
 
5481 phani.kuma 3495
    if billing_date_from:
3496
        query = query.filter(Order.billing_timestamp >= billing_date_from)
3497
 
3498
    if billing_date_to:
3499
        query = query.filter(Order.billing_timestamp <= billing_date_to)
3500
 
4885 varun.gupt 3501
    return query.all()
4875 varun.gupt 3502
 
4600 varun.gupt 3503
def save_bluedart_settlements(map_awb_and_amount):
3504
    payment_client = PaymentClient().get_client()
3505
 
3506
    for awb, amount in map_awb_and_amount.iteritems():
3507
        order = Order.get_by(airwaybill_no = awb)
3508
 
3509
        payment = payment_client.getSuccessfulPaymentForTxnId(order.transaction_id)
3510
        settlement = PaymentSettlement()
3511
        settlement.paymentId = payment.paymentId
3512
        settlement.paymentGatewayId = payment.gatewayId
3513
        settlement.netCollection = amount
3514
        session.commit()
3515
 
4905 varun.gupt 3516
def save_payment_settlements(settlementDate, paymentGatewayId, referenceId, serviceTax, otherCharges, netCollection):
5386 phani.kuma 3517
    originalOrderId = None
3518
    if paymentGatewayId == 4:
3519
        cod_order = Order.get_by(id = referenceId)
3520
        if cod_order.originalOrderId:
3521
            originalOrderId = cod_order.originalOrderId
3522
        else:
3523
            originalOrderId = referenceId
4600 varun.gupt 3524
    settlement = PaymentSettlement()
3525
    settlement.settlementDate = settlementDate
3526
    settlement.paymentGatewayId = paymentGatewayId
5386 phani.kuma 3527
    if originalOrderId is not None:
3528
        settlement.originalOrderId = originalOrderId
4905 varun.gupt 3529
    settlement.referenceId = referenceId
4600 varun.gupt 3530
    settlement.serviceTax = serviceTax
3531
    settlement.otherCharges = otherCharges
3532
    settlement.netCollection = netCollection
3533
    session.commit()
3534
 
5386 phani.kuma 3535
def get_settlement_for_Prepaid(reference_id, is_refund = False):
3536
    query = PaymentSettlement.query.filter_by(referenceId = reference_id).filter(PaymentSettlement.paymentGatewayId != 4)
4600 varun.gupt 3537
 
5189 varun.gupt 3538
    if is_refund:
3539
        query = query.filter(PaymentSettlement.netCollection < 0)
3540
    else:
3541
        query = query.filter(PaymentSettlement.netCollection > 0)
3542
 
5386 phani.kuma 3543
    return query.first()
3544
 
3545
def get_settlement_for_Cod(orderId, is_refund = False):
3546
    query = PaymentSettlement.query.filter_by(originalOrderId = orderId)
5382 varun.gupt 3547
 
5386 phani.kuma 3548
    if is_refund:
3549
        query = query.filter(PaymentSettlement.netCollection < 0)
3550
    else:
3551
        query = query.filter(PaymentSettlement.netCollection > 0)
3552
 
5189 varun.gupt 3553
    return query.first()
4600 varun.gupt 3554
 
3555
def save_ebs_settlement_summary(settlement_id, settlement_date, transaction_date_from, transaction_date_to, amount):
5551 phani.kuma 3556
    summary = EBSSettlementSummary.query.filter_by(settlementId = settlement_id).first()
5481 phani.kuma 3557
    if summary is None:
3558
        summary = EBSSettlementSummary()
3559
        summary.settlementId = settlement_id
3560
        summary.settlementDate = settlement_date
3561
        summary.transactionDateFrom = transaction_date_from
3562
        summary.transactionDateTo = transaction_date_to
3563
        summary.amount = amount
3564
        summary.detailsUploaded = False
3565
        session.commit()
4600 varun.gupt 3566
 
3567
def get_ebs_settlement_summaries():
3568
    summaries = EBSSettlementSummary.query.filter_by(detailsUploaded = False).order_by(EBSSettlementSummary.transactionDateFrom).all()
3569
    summary_map = {}
3570
 
3571
    for summary in summaries:
3572
        transactionDateFrom = str(summary.transactionDateFrom.year) + '-' + str(summary.transactionDateFrom.month) + '-' + str(summary.transactionDateFrom.day)
3573
        transactionDateTo = str(summary.transactionDateTo.year) + '-' + str(summary.transactionDateTo.month) + '-' + str(summary.transactionDateTo.day)
3574
 
3575
        summary_map[summary.settlementId] = "%s to %s" %(transactionDateFrom, transactionDateTo)
3576
 
3577
    return summary_map
3578
 
3579
def get_ebs_settlement_date(settlement_id):
3580
    summary = EBSSettlementSummary.get_by(settlementId = settlement_id)
3581
 
3582
    if summary:
3583
        return summary.settlementDate
3584
 
3585
def mark_ebs_settlement_uploaded(settlement_id):
3586
    summary = EBSSettlementSummary.get_by(settlementId = settlement_id)
3587
 
3588
    if summary:
3589
        summary.detailsUploaded = True
3590
        session.commit()
4715 varun.gupt 3591
 
3592
def get_settlements_by_date(settlement_date_from, settlement_date_to, is_refund):
3593
    query = PaymentSettlement.query
4600 varun.gupt 3594
 
4715 varun.gupt 3595
    if settlement_date_from:
3596
        query = query.filter(PaymentSettlement.settlementDate >= settlement_date_from)
3597
 
3598
    if settlement_date_to:
3599
        query = query.filter(PaymentSettlement.settlementDate <= settlement_date_to)
3600
 
4749 varun.gupt 3601
    if is_refund is True:
3602
        query = query.filter(PaymentSettlement.netCollection < 0.0)
3603
    else:
3604
        query = query.filter(PaymentSettlement.netCollection > 0.0)
4715 varun.gupt 3605
 
4749 varun.gupt 3606
    return query.all()
4715 varun.gupt 3607
 
3608
def get_reshipped_order_ids(order_ids):
3609
    reshipped_order_ids = []
3610
    return [order.new_order_id for order in Order.query.filter(Order.new_order_id.in_(order_ids)).all()]
3611
 
4749 varun.gupt 3612
def get_shipping_confirmation_email_body(order):
3613
 
3614
    html = """
3615
<html>
3616
<body>
3617
<div>
3618
    <p>Dear Customer,</p>
3619
    <p>
4885 varun.gupt 3620
        We are pleased to inform that we have shipped the order: $order_id for your product $product_name on $shipping_datetime. 
5139 varun.gupt 3621
        The shipment will be delivered to you via $courier_name Courier Service vide AWB# $awb.
7198 amar.kumar 3622
 
4749 varun.gupt 3623
    </p>
3624
    <p>
6655 rajveer 3625
        Expected delivery date for your order is $expected_delivery_date.
6675 rajveer 3626
        <br/>
3627
        $otg_text
7198 amar.kumar 3628
        $freebie_text
6675 rajveer 3629
        <br/> 
6716 rajveer 3630
        The product can be delivered to you between business hours of 10am to 6pm.
3631
        You can Check the current shipment updates for your product online at <a href="www.saholic.com/myaccount">Open Orders</a>.
4749 varun.gupt 3632
    </p>
3633
    <p>
5573 amit.gupta 3634
        For scheduling the delivery of your product at some specific timings, we recommend you to contact the helpline for $courier_name with your complete AWB#.
4749 varun.gupt 3635
    </p>
5139 varun.gupt 3636
    <p>$courier_name: $courier_phone</p>
4749 varun.gupt 3637
    <p>
3638
        Warm Regards,<br />
6029 rajveer 3639
        $source_name Team
4749 varun.gupt 3640
    </p>
4750 varun.gupt 3641
</div>
4749 varun.gupt 3642
</body>
3643
</html>
3644
    """
5573 amit.gupta 3645
    logistics_providers = {1: {'name': 'BlueDart', 'phone': '011-66111234'}, 2: {'name': 'Aramex', 'phone': '0124- 39419900'}, 3: {'name': 'Delhivery', 'phone' : '0124- 4212200'}}
5139 varun.gupt 3646
    provider_name = logistics_providers[order.logistics_provider_id]['name']
3647
    provider_phone = logistics_providers[order.logistics_provider_id]['phone']
3648
 
5868 rajveer 3649
    lclient = LogisticsClient().get_client()
3650
    logistics_info = lclient.getLogisticsEstimation(order.lineitems[0].item_id, order.customer_pincode, DeliveryType.PREPAID)
4749 varun.gupt 3651
    dt = datetime.datetime.strptime(str(order.shipping_timestamp), "%Y-%m-%d %H:%M:%S")
4885 varun.gupt 3652
    shipping_date = dt.strftime("%A, %d %B %Y %I:%M%p")
6712 rajveer 3653
    product = str(order.lineitems[0])
5868 rajveer 3654
    new_expected_delivery_timestamp = datetime.datetime.now() + timedelta(adjust_delivery_time(datetime.datetime.now(), (logistics_info.deliveryTime - logistics_info.shippingTime)))
6728 rajveer 3655
    new_courier_delivery_time = datetime.datetime.now() + timedelta(adjust_delivery_time(datetime.datetime.now(), (logistics_info.deliveryTime - logistics_info.shippingTime - logistics_info.deliveryDelay)))
6666 rajveer 3656
    #update new expected timestamp
3657
    if order.cod:
6705 amar.kumar 3658
        new_expected_delivery_timestamp = new_expected_delivery_timestamp.replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6728 rajveer 3659
        order.courier_delivery_time = new_courier_delivery_time.replace(hour=COD_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6666 rajveer 3660
    else:
6705 amar.kumar 3661
        new_expected_delivery_timestamp = new_expected_delivery_timestamp.replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6728 rajveer 3662
        order.courier_delivery_time = new_courier_delivery_time.replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0, microsecond=0)
6666 rajveer 3663
    order.expected_delivery_time = new_expected_delivery_timestamp
3664
    session.commit()
3665
 
4885 varun.gupt 3666
    new_expected_delivery_date = new_expected_delivery_timestamp.strftime("%A, %d %B %Y")
6655 rajveer 3667
    otg_text = ""
3668
    if order.otg:
6662 rajveer 3669
        promised_delivery_date = order.promised_delivery_time.strftime("%A, %d %B %Y")
6655 rajveer 3670
        if new_expected_delivery_timestamp > order.promised_delivery_time:
6712 rajveer 3671
            otg_text = 'Your order is covered under our <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee; We Pay if we Delay.</a> We apologize in advance for the expected delay from our initial promised delivery date of ' + promised_delivery_date + '. Your will receive a Gift Voucher Code at time of delivery based on the actual delay. You can use the same to buy any Mobile, Camera, Laptop, Tablet, Accessory or Mobile/DTH Recharge from our website.'
6655 rajveer 3672
        elif new_expected_delivery_timestamp < order.promised_delivery_time:
6662 rajveer 3673
            otg_text = 'We are happy to inform you that we expect to deliver your order before time. Your order is covered under our <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee; We Pay if we Delay.</a> Please note, compensation for delay (If Any) will be computed from the initial promised delivery date of ' + promised_delivery_date + '.'
6655 rajveer 3674
        else:            
6662 rajveer 3675
            otg_text = 'Your order is covered under our <a href="http://www.saholic.com/static/on-time-guarantee">On Time Guarantee; We Pay if we Delay.</a> We are committed to deliver your order by our initial promised delivery date of ' + promised_delivery_date + '.'
7190 amar.kumar 3676
 
3677
    freebie_text = "<br/>"
3678
    if order.freebieItemId:
3679
        catalog_client = CatalogClient().get_client()
3680
        item = catalog_client.getItem(order.freebieItemId)
7198 amar.kumar 3681
        freebie_text = freebie_text = "We have also shipped you " + item.brand + " " + item.modelName + "" + item.modelNumber +" as promised<br/>"
7190 amar.kumar 3682
    else:
3683
        freebie_orderId = get_order_attribute_value(order.id, "freebieOrderId")
3684
        if freebie_orderId != "":
3685
            line_items = get_line_items_for_order(int(freebie_orderId))
7198 amar.kumar 3686
            freebie_order = get_order(int(freebie_orderId))
3687
            freebie_text = freebie_text + "We wish to inform you that your freebie item " +line_items[0].brand + " " + line_items[0].model_name + " " + line_items[0].model_number + " will be sent as a separate order with OrderId : " + freebie_orderId + " and is expected to be delivered on " + freebie_order.expected_delivery_time.strftime("%A, %d %B %Y")+ "<br/>"
3688
        else:
3689
            freebie_text = ""
6655 rajveer 3690
 
7190 amar.kumar 3691
    info = dict(order_id = order.id, product_name = product, shipping_datetime = shipping_date, awb = order.airwaybill_no, expected_delivery_date = new_expected_delivery_date, courier_name = provider_name, courier_phone = provider_phone, source_name = source_name, otg_text = otg_text, freebie_text = freebie_text)
4885 varun.gupt 3692
    return Template(html).substitute(info)
4749 varun.gupt 3693
 
5832 rajveer 3694
def enqueue_shipping_confirmation_email(order):
4915 varun.gupt 3695
    # Calling helper service on production
3696
    helperClient = HelperClient(host_key = "helper_service_server_host_prod").get_client()
5832 rajveer 3697
    try:
3698
        emailSubject = 'Shipping Details for Order ID: ' + str(order.id)
3699
        emailBody = get_shipping_confirmation_email_body(order)
6906 rajveer 3700
        helperClient.saveUserEmailForSending([order.customer_email], None, emailSubject, emailBody, str(order.id), 'ShippingConfirmation', [], [])
6687 rajveer 3701
 
5832 rajveer 3702
    except Exception as e:
3703
        print e
5139 varun.gupt 3704
 
4915 varun.gupt 3705
def get_order_distribution_by_status(start_date, end_date):
5067 varun.gupt 3706
    query = session.query(Order.status, func.count(Order.id)).group_by(Order.status)
3707
    query = query.filter(Order.created_timestamp >= start_date)
3708
    query = query.filter(Order.created_timestamp <= end_date)
3709
    return query.all()
4915 varun.gupt 3710
 
5067 varun.gupt 3711
def get_order_ids_for_status(status, start_datetime, end_datetime):
3712
    query = Order.query.filter(Order.status == status)
3713
    query = query.filter(Order.created_timestamp >= start_datetime)
3714
    query = query.filter(Order.created_timestamp <= end_datetime)
3715
    return query.all()
3716
 
5099 varun.gupt 3717
def update_orders_as_paid_to_vendor(order_id):
5139 varun.gupt 3718
    paid_order = Order.get_by(id = order_id)
5099 varun.gupt 3719
 
5139 varun.gupt 3720
    if paid_order.originalOrderId is None:
3721
        paid_order.vendor_paid = True
5099 varun.gupt 3722
        session.commit()
5139 varun.gupt 3723
 
3724
        for order in Order.query.filter(Order.originalOrderId == order_id).all():
3725
            order.vendor_paid = True
3726
            session.commit()
3727
    else:
5208 varun.gupt 3728
        original_order_id = paid_order.originalOrderId
5139 varun.gupt 3729
 
5208 varun.gupt 3730
        for order in Order.query.filter(Order.originalOrderId == original_order_id).all():
5139 varun.gupt 3731
            order.vendor_paid = True
3732
            session.commit()
3733
 
3734
        original_order = Order.get_by(id = original_order_id)
3735
        if original_order:  original_order.vendor_paid = True
3736
        session.commit()
5348 anupam.sin 3737
 
3738
def update_COD_agent(agentEmailId, orderId):
3739
    order = Order.get_by(id=orderId)
3740
    if not order:
3741
        raise TransactionServiceException(101, "No order found for the given order id" + str(orderId))
3742
    agent = CodVerificationAgent()
3743
    agent.orderId = orderId
3744
    agent.verificationAgent = agentEmailId
3745
    session.commit()
3746
 
5099 varun.gupt 3747
 
5386 phani.kuma 3748
def update_order_only_as_paid_to_vendor(order_id):
3749
    paid_order = Order.get_by(id = order_id)
3750
    if paid_order is None:
3751
        raise TransactionServiceException(116, "No order found for the given order id")
3752
    paid_order.vendor_paid = True
3753
    session.commit()
3754
 
5208 varun.gupt 3755
def get_refunded_orders_marked_paid():
3756
    orderStatusGroup = OrderStatusGroups()
3757
    return Order.query.filter(Order.vendor_paid == 1).filter(Order.status.in_(orderStatusGroup.refundedOrders)).all()
3758
 
5447 anupam.sin 3759
def get_all_verification_agents(minOrderId, maxOrderId):
3760
    return CodVerificationAgent.query.filter(CodVerificationAgent.orderId >= minOrderId).filter(CodVerificationAgent.orderId <= maxOrderId).all()
3761
 
5527 anupam.sin 3762
def get_all_attributes_for_order_id(orderId):
3763
    return Attribute.query.filter(Attribute.orderId == orderId).all()
3764
 
3765
def set_order_attribute_for_transaction(transactionId, t_attribute):
3766
    for order in Order.query.filter_by(transaction_id = transactionId).all():
3767
        attribute = Attribute()
3768
        attribute.orderId = order.id
3769
        attribute.name = t_attribute.name
3770
        attribute.value = t_attribute.value
3771
        session.commit()
5593 mandeep.dh 3772
 
5558 mandeep.dh 3773
def accept_order_for_item(itemId, quantity, fulfilmentWarehouseId, billingWarehouseId):
5944 mandeep.dh 3774
    inventoryClient = InventoryClient().get_client()
3775
    inventory = inventoryClient.getItemInventoryByItemId(itemId)
5684 mandeep.dh 3776
    orders = Order.query.filter(Order.fulfilmentWarehouseId != fulfilmentWarehouseId).filter(Order.warehouse_id == billingWarehouseId).filter(Order.status.in_(tuple([OrderStatus.SUBMITTED_FOR_PROCESSING, OrderStatus.COD_VERIFICATION_PENDING, OrderStatus.ACCEPTED, OrderStatus.INVENTORY_LOW, OrderStatus.LOW_INV_PO_RAISED, OrderStatus.LOW_INV_REVERSAL_IN_PROCESS]))).order_by(Order.expected_shipping_time).all()
5558 mandeep.dh 3777
    for order in orders:
5593 mandeep.dh 3778
        lineitem = order.lineitems[0]
5558 mandeep.dh 3779
        if lineitem.item_id == itemId and lineitem.quantity <= quantity:
5944 mandeep.dh 3780
            warehouse = inventoryClient.getWarehouse(order.fulfilmentWarehouseId)
5684 mandeep.dh 3781
            if not warehouse.billingWarehouseId and warehouse.warehouseType == WarehouseType.THIRD_PARTY:
3782
                if (inventory.availability[fulfilmentWarehouseId] >= inventory.reserved[fulfilmentWarehouseId] + lineitem.quantity) and inventory.availability[order.fulfilmentWarehouseId] < inventory.reserved[order.fulfilmentWarehouseId]:
5966 rajveer 3783
                    inventoryClient.reduceReservationCount(itemId, order.fulfilmentWarehouseId, sourceId, order.id, lineitem.quantity)
3784
                    inventoryClient.reserveItemInWarehouse(itemId, fulfilmentWarehouseId, sourceId, order.id, to_java_date(order.created_timestamp), to_java_date(order.promised_shipping_time), lineitem.quantity)
5684 mandeep.dh 3785
                    order.fulfilmentWarehouseId = fulfilmentWarehouseId
5558 mandeep.dh 3786
                    quantity -= lineitem.quantity
5684 mandeep.dh 3787
                    session.commit()
5593 mandeep.dh 3788
                    if not quantity:
3789
                        break
5558 mandeep.dh 3790
 
6031 rajveer 3791
def get_recharge_order(rechargeOrderId):
6048 rajveer 3792
    return RechargeOrder.get_by(id = rechargeOrderId)
6031 rajveer 3793
 
3794
def get_recharge_orders(userId):
3795
    return RechargeOrder.query.filter_by(userId = userId).all()
3796
 
6279 rajveer 3797
def update_recharge_order_status(rechargeOrderId, rechargeOrderStatus, refundDate=None):
6031 rajveer 3798
    recharge_order = get_recharge_order(rechargeOrderId)
3799
    if rechargeOrderStatus == RechargeOrderStatus.PAYMENT_FAILED:
3800
        recharge_order.status = RechargeOrderStatus.PAYMENT_FAILED
3801
        session.commit()
3802
        return True
6214 rajveer 3803
 
3804
    if rechargeOrderStatus == RechargeOrderStatus.RECHARGE_FAILED:
3805
        recharge_order.status = RechargeOrderStatus.RECHARGE_FAILED
3806
        session.commit()
3807
        update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id)
6441 rajveer 3808
        update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6214 rajveer 3809
        enqueue_recharge_info_email(recharge_order)
3810
        return True
3811
 
3812
    if rechargeOrderStatus == RechargeOrderStatus.RECHARGE_SUCCESSFUL:
3813
        recharge_order.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
6553 rajveer 3814
        recharge_order.invoiceNumber = get_next_invoice_number(OrderType.RECHARGE)
6214 rajveer 3815
        session.commit()
6285 rajveer 3816
        gvs = allocate_gift_voucher(recharge_order)
3817
        enqueue_recharge_info_email(recharge_order, gvs)
6214 rajveer 3818
        return True
3819
 
6279 rajveer 3820
    if rechargeOrderStatus == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED:
3821
        recharge_order.status = RechargeOrderStatus.RECHARGE_FAILED_REFUNDED
3822
        order.responseTimestamp = refundDate
3823
        session.commit()
3824
        update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id)
6441 rajveer 3825
        update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6279 rajveer 3826
        enqueue_recharge_info_email(recharge_order)
3827
        return True
3828
 
6031 rajveer 3829
    if rechargeOrderStatus == RechargeOrderStatus.PAYMENT_SUCCESSFUL:
6285 rajveer 3830
        gvs = {}
6206 rajveer 3831
        recharge_order.status = RechargeOrderStatus.PAYMENT_SUCCESSFUL
3832
        session.commit()
6031 rajveer 3833
        if recharge_order.walletAmount > 0:
3834
            wallet = get_user_wallet(recharge_order.userId)
3835
            if wallet and wallet.amount >= recharge_order.walletAmount:
3836
                update_amount_in_wallet(recharge_order.userId, -recharge_order.walletAmount, recharge_order.id)
3837
            else:
6441 rajveer 3838
                update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6031 rajveer 3839
                raise TransactionServiceException(103, 'Wallet amount has already been used')
3840
 
6092 rajveer 3841
        try:
3842
            if activate_recharge_txn(recharge_order):
3843
                recharge_order.invoiceNumber = get_next_invoice_number(OrderType.RECHARGE)
3844
                session.commit()
6285 rajveer 3845
                gvs = allocate_gift_voucher(recharge_order)
6092 rajveer 3846
                return True
3847
            else:
3848
                update_amount_in_wallet(recharge_order.userId, recharge_order.walletAmount, recharge_order.id)
6441 rajveer 3849
                update_amount_in_wallet(recharge_order.userId, recharge_order.totalAmount - recharge_order.walletAmount - recharge_order.couponAmount, recharge_order.id)
6092 rajveer 3850
                session.commit()
3851
                return False
3852
        except:
3853
            transaction_requiring_extra_processing = TransactionRequiringExtraProcessing()
3854
            transaction_requiring_extra_processing.category = 'RECHARGE_UNKNOWN'
3855
            transaction_requiring_extra_processing.transaction_id = recharge_order.transaction_id
6031 rajveer 3856
            session.commit()
3857
            return False
6102 rajveer 3858
        finally:
6285 rajveer 3859
            enqueue_recharge_info_email(recharge_order, gvs)
6102 rajveer 3860
 
6031 rajveer 3861
 
6285 rajveer 3862
def allocate_gift_voucher(recharge_order):            
3863
    totalAmount = recharge_order.totalAmount
3864
    gvs = {}
6438 rajveer 3865
    return gvs
6330 rajveer 3866
    if totalAmount >= 100:
3867
        totalAmount=500 if totalAmount >= 500 else totalAmount
6285 rajveer 3868
        try:
3869
            pc = PromotionClient().get_client()
6330 rajveer 3870
            enddate = datetime.datetime.now() + datetime.timedelta(days=45)
6285 rajveer 3871
            while totalAmount > 0:
6330 rajveer 3872
                gvAmount = totalAmount if totalAmount <= 250 else 250
6285 rajveer 3873
                totalAmount = totalAmount - gvAmount
6561 amit.gupta 3874
                gv = pc.createCoupon(26, to_java_date(enddate), recharge_order.userEmailId, gvAmount, False, 1, None)
6285 rajveer 3875
                gvs[gv] = gvAmount  
3876
        except:
3877
            print "Not able to create gift voucher for user " + recharge_order.userEmailId
3878
    return gvs     
3879
 
6048 rajveer 3880
def activate_recharge_txn(recharge_order):
3881
    if isinstance(recharge_order, MobileRechargeOrder):
3882
        rechargeType = 'MTP'
3883
        deviceNumber = recharge_order.mobileNumber
3884
        strProviderCode = get_provider_code(recharge_order.mobileOperatorId)
6161 rajveer 3885
        plan = recharge_order.rechargePlan
6048 rajveer 3886
    if isinstance(recharge_order, DTHRechargeOrder):
3887
        rechargeType = 'RCH'
3888
        deviceNumber = recharge_order.dthAccountNumber
3889
        strProviderCode = get_provider_code(recharge_order.dthOperatorId)
6161 rajveer 3890
        plan = ''
3891
    retStatus, retCode, spiceTID, description = RechargeService.rechargeDevice(recharge_order.id, rechargeType, strProviderCode, deviceNumber, recharge_order.totalAmount, plan)
6231 rajveer 3892
    recharge_order.spiceTID = spiceTID
3893
    recharge_order.responseTimestamp = datetime.datetime.now()
3894
    recharge_order.description = description
3895
    session.commit()
6092 rajveer 3896
    if retCode == '00' and retStatus == 'S':
3897
        recharge_order.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
3898
        session.commit()
3899
        return True
6259 rajveer 3900
    elif retCode in ('STO', 'US', 'UP') and retStatus == 'S':
6231 rajveer 3901
        raise TransactionServiceException(111, "No response from operator within specified time")
6092 rajveer 3902
    else:
3903
        recharge_order.status = RechargeOrderStatus.RECHARGE_FAILED
6265 rajveer 3904
        if retCode in ('SVAI', 'SVIA', 'AI', 'IA', 'EAI', 'SVEAI'):
3905
            recharge_order.description = "Invalid Amount"
3906
        elif retCode in ('ECL', 'SVECL', 'SCL'):
3907
            recharge_order.description = "Customer Exceeded Daily Limit"
3908
        elif retCode in ('CI', 'ECI', 'ESP', 'SVCI', 'SVECI', 'SVESP', 'SV_ECI', 'SV ECI'):
6399 rajveer 3909
            recharge_order.description = "Invalid Device Number"
6092 rajveer 3910
        session.commit()
6048 rajveer 3911
        return False
6031 rajveer 3912
 
6092 rajveer 3913
 
6031 rajveer 3914
def get_user_wallet(userId):
3915
    wallet = UserWallet.get_by(userId = userId)
3916
    if not wallet:
3917
        wallet = UserWallet()
3918
        wallet.amount = 0
3919
        wallet.userId = userId
3920
    return wallet
3921
 
3922
def get_user_wallet_history(userId):
3923
    wallet = get_user_wallet(userId)
3924
    if wallet.id:
3925
        return UserWalletHistory.query.filter_by(wallet = wallet).all()
3926
    else:
3927
        return []
3928
 
6125 rajveer 3929
def get_provider(providerId):
3930
    return ServiceProvider.query.filter_by(id = providerId).one()
3931
 
6048 rajveer 3932
def get_provider_code(providerId):
3933
    return ServiceProvider.query.filter_by(id = providerId).one().code
6031 rajveer 3934
 
6310 anupam.sin 3935
def get_provider_by_code(providerCode):
3936
    return ServiceProvider.query.filter_by(code = providerCode).one()
6049 rajveer 3937
 
6206 rajveer 3938
def get_service_providers(recharge_type, only_active):
3939
    query = ServiceProvider.query.filter_by(type = recharge_type)
3940
    if only_active:
3941
        query = query.filter_by(status = only_active)
3942
    providers = query.all()
6048 rajveer 3943
    serviceProviders = {}
3944
    for provider in providers:
3945
        serviceProviders[provider.id] = provider.name
3946
    return serviceProviders
3947
 
6049 rajveer 3948
def get_service_provider_for_device(rechargeType, deviceNumber):
3949
    if rechargeType == RechargeType.MOBILE:
3950
        serviceType = 'MTP'
3951
    if rechargeType == RechargeType.DTH:
3952
        serviceType = 'RCH'
6048 rajveer 3953
 
6313 anupam.sin 3954
    provider = None
7120 rajveer 3955
    try:
3956
        series = OperatorSeries.get_by(series = int(deviceNumber))
3957
        if series:
7122 rajveer 3958
            providerId = series.operatorId
7120 rajveer 3959
            tc = TelecomCircle.get_by(id = series.circleId)
3960
            operatorCircle = tc.code
6092 rajveer 3961
        else:
7120 rajveer 3962
            l = len(deviceNumber)
3963
            if l < 10:
3964
                deviceNumber = deviceNumber + "0" * (10-l) 
3965
            providerCode, operatorCircle = RechargeService.checkServiceProviderApi(serviceType, deviceNumber)
3966
            if providerCode == 'SNS' or providerCode == '':
3967
                providerId = 0
3968
            else:
3969
                provider = get_provider_by_code(providerCode)
3970
                providerId = provider.id
6049 rajveer 3971
    except:
6092 rajveer 3972
        providerId = -1
6643 rajveer 3973
        operatorCircle = ""
6092 rajveer 3974
 
6289 anupam.sin 3975
    deviceNumberInfo = DeviceNumberInfo()
6336 anupam.sin 3976
    deviceNumberInfo.circleCode = operatorCircle
6289 anupam.sin 3977
    deviceNumberInfo.operatorId = providerId
6313 anupam.sin 3978
    if provider:
3979
        deviceNumberInfo.operatorName = provider.name
6289 anupam.sin 3980
    return deviceNumberInfo
6269 rajveer 3981
 
6591 anupam.sin 3982
def validate_recharge(rechargeType, deviceNumber, userSelectedProviderId, clientAddress):
3983
 
3984
    addressComponents = clientAddress.split('.')
3985
    n = 3
3986
    addressNumber = 0
3987
    for addressComponent in addressComponents :
3988
        addressNumber = addressNumber + (int(addressComponent) * pow(256, n))
3989
        n = n-1
3990
    matchingRow = BlockedIpRange.query.filter(BlockedIpRange.start <= addressNumber).filter(BlockedIpRange.end >= addressNumber).first()
3991
    #if a match is found then check if date has expired.
3992
    if matchingRow :
3993
        #if expiredOn is None that means this range is permanently blocked.
3994
        if matchingRow.expiredOn is None:
3995
            deniedIpAddress = DeniedIpAddress()
3996
            deniedIpAddress.ip = clientAddress
3997
            deniedIpAddress.deniedOn = datetime.datetime.now()
3998
            deniedIpAddress.deviceNumber = deviceNumber
3999
            deniedIpAddress.rechargeType = rechargeType
4000
            session.commit()
4001
            return "Oops! There seems to be a problem. Please try after some time."
4002
        else :
4003
            #if expired is not None and the blockage is still not expired then block the ip.
4004
            if matchingRow.expiredOn > datetime.datetime.now():
4005
                deniedIpAddress = DeniedIpAddress()
4006
                deniedIpAddress.ip = clientAddress
4007
                deniedIpAddress.deniedOn = datetime.datetime.now()
4008
                deniedIpAddress.deviceNumber = deviceNumber
4009
                deniedIpAddress.rechargeType = rechargeType
4010
                session.commit()
4011
                return "Oops! There seems to be a problem. Please try after some time."
4012
 
4013
 
6307 anupam.sin 4014
    deviceNumberInfo = get_service_provider_for_device(rechargeType, deviceNumber)
4015
    if deviceNumberInfo.operatorId == -1:
4016
        return "Oops! There seems to be a problem. Please try after some time."
6336 anupam.sin 4017
    circle = TelecomCircle.query.filter_by(code = deviceNumberInfo.circleCode).first()
6313 anupam.sin 4018
    if circle:
6734 anupam.sin 4019
        serviceAvailability = ServiceAvailability.query.filter_by(circleId = circle.id).filter_by(operatorId = userSelectedProviderId).first()
4020
        if serviceAvailability.permIsServiceAvailable == False or serviceAvailability.tempIsServiceAvailable == False :
4021
 
6313 anupam.sin 4022
            if deviceNumberInfo.operatorName :
6734 anupam.sin 4023
                if serviceAvailability.permIsServiceAvailable == False:
4024
                    return "We currently do not provide service for " + deviceNumberInfo.operatorName + " in " + circle.name + ". We regret the inconvenience."
6314 anupam.sin 4025
                else :
4026
                    return "We are facing technical issues with " + deviceNumberInfo.operatorName + " in " + circle.name + " currently. Please try later." 
6316 anupam.sin 4027
            else :
6734 anupam.sin 4028
                if serviceAvailability.permIsServiceAvailable == False:
4029
                    return "We currently do not provide service for this operator in " + circle.name + ". We regret the inconvenience."
4030
                else:
4031
                    return "We are facing technical issues with this operator in " + circle.name + " currently. Please try later." 
6719 anupam.sin 4032
    totalSuccessfulRechargeAmount = get_previous_transactions(clientAddress)
4033
    if totalSuccessfulRechargeAmount >= 3000 :
4034
        return "You have exceeded your daily recharge limit. Please try after 24 hours."
6269 rajveer 4035
    return "SUCCESS"
6049 rajveer 4036
 
6719 anupam.sin 4037
def get_previous_transactions(clientAddress):
6271 rajveer 4038
    limittime = datetime.datetime.now() - datetime.timedelta(hours=24)
6719 anupam.sin 4039
    totalSuccessfulRechargeAmount = session.query(func.sum(RechargeOrder.totalAmount)).filter(RechargeOrder.status == 5).filter(RechargeOrder.ipAddress == clientAddress).filter(RechargeOrder.creationTimestamp  > limittime).scalar()
4040
    return totalSuccessfulRechargeAmount    
6269 rajveer 4041
 
6031 rajveer 4042
def update_amount_in_wallet(userId, amount, orderId):
4043
    if amount == 0:
4044
        return
4045
    wallet = get_user_wallet(userId)
4046
    wallet.amount = wallet.amount + amount
4047
 
4048
    history = UserWalletHistory()
4049
    history.amount = amount
4050
    history.orderId = orderId
4051
    history.wallet = wallet
4052
    history.timestamp = datetime.datetime.now()
4053
    session.commit()
6056 amit.gupta 4054
 
6094 rajveer 4055
def get_recharge_orders_for_device(deviceNumber):
4056
    orders = MobileRechargeOrder.query.filter_by(mobileNumber = deviceNumber).all()
4057
    if orders is None:
4058
        orders = DTHRechargeOrder.query.filter_by(dthAccountNumber = deviceNumber).all()
4059
    return orders
4060
 
6154 rajveer 4061
def get_recharge_orders_for_status(status):
4062
    if status == -1:
6161 rajveer 4063
        orders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).all()
6154 rajveer 4064
    else:
6161 rajveer 4065
        orders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = status).all()
6154 rajveer 4066
    return orders
4067
 
6188 rajveer 4068
def get_recharge_statistics():
4069
    rs = RechargeStatistics()
4070
    statusCounts = {}
4071
    operatorCounts = {}
4072
    currentOrders = {}
4073
    amounts = {}
4074
 
4075
    sorders = session.query(RechargeOrder.status, func.count(RechargeOrder.status)).group_by(RechargeOrder.status).all()
4076
    for sorder in sorders:
6190 rajveer 4077
        statusCounts[sorder[0]] = sorder[1]
6188 rajveer 4078
 
4079
    oorders = session.query(MobileRechargeOrder.mobileOperatorId, func.count(MobileRechargeOrder.mobileOperatorId)).group_by(MobileRechargeOrder.mobileOperatorId).all()
4080
    for oorder in oorders:
6190 rajveer 4081
        operatorCounts[oorder[0]] = oorder[1]
6188 rajveer 4082
 
4083
    oorders = session.query(DTHRechargeOrder.dthOperatorId, func.count(DTHRechargeOrder.dthOperatorId)).group_by(DTHRechargeOrder.dthOperatorId).all()
4084
    for oorder in oorders:
6190 rajveer 4085
        operatorCounts[oorder[0]] = oorder[1]
6188 rajveer 4086
 
6219 rajveer 4087
    forders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_FAILED).limit(20).all()
6188 rajveer 4088
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_FAILED)] = [order.to_thrift_object() for order in forders]
4089
    sorders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_SUCCESSFUL).limit(20).all()
6197 rajveer 4090
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_SUCCESSFUL)] = [order.to_thrift_object() for order in sorders]
6216 rajveer 4091
    porders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.PAYMENT_SUCCESSFUL).limit(20).all()
4092
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.PAYMENT_SUCCESSFUL)] = [order.to_thrift_object() for order in porders]
6238 rajveer 4093
    rorders = RechargeOrder.query.order_by(desc(RechargeOrder.id)).filter_by(status = RechargeOrderStatus.RECHARGE_FAILED_REFUNDED).limit(20).all()
4094
    currentOrders[RechargeOrderStatus._VALUES_TO_NAMES.get(RechargeOrderStatus.RECHARGE_FAILED_REFUNDED)] = [order.to_thrift_object() for order in rorders]
6188 rajveer 4095
 
6190 rajveer 4096
    twa = session.query(func.sum(UserWallet.amount)).one()
4097
    tra = session.query(func.sum(RechargeOrder.totalAmount)).filter(RechargeOrder.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL).one()
4098
    gwa = session.query(func.sum(UserWalletHistory.amount)).filter(UserWalletHistory.orderId > 100000).one()
6278 rajveer 4099
    #tpa = session.query(func.sum(UserWalletHistory.amount)).filter(UserWalletHistory.orderId < 100000).one()
6482 rajveer 4100
    tpa = session.query(func.sum(RechargeOrder.totalAmount-RechargeOrder.walletAmount-RechargeOrder.couponAmount)).filter(RechargeOrder.status.in_((RechargeOrderStatus.RECHARGE_SUCCESSFUL, RechargeOrderStatus.RECHARGE_FAILED, RechargeOrderStatus.PAYMENT_SUCCESSFUL, RechargeOrderStatus.RECHARGE_FAILED_REFUNDED))).one()
4101
    tda = session.query(func.sum(RechargeOrder.couponAmount)).filter(RechargeOrder.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL).one()
4102
 
6346 rajveer 4103
    balance = RechargeService.getBalance()
6305 rajveer 4104
    amounts['(a) Total Payment Amount'] = tpa[0]
4105
    amounts['(b) Gift Wallet Amount'] = gwa[0]
4106
    amounts['(c) Total Wallet Amount'] = twa[0]
4107
    amounts['(d) Total Recharge Amount'] = tra[0]
4108
    amounts['(e) Account Balance'] = balance
6482 rajveer 4109
    amounts['(f) Discount Balance'] = tda[0]
6278 rajveer 4110
    #amounts['Total Payment Amount'] = tra[0] + twa[0] - gwa[0]
6524 rajveer 4111
    amounts['Saholic Mismatch = (a+b+f-c-d)'] = tpa[0] + gwa[0] + tda[0] - tra[0] - (twa[0] + 63774)
4112
    amounts['SpiceDeck Mismatch = (d-e)'] = tra[0] + balance - 750000 
6278 rajveer 4113
 
6337 rajveer 4114
    '''
6318 rajveer 4115
    if amounts['SpiceDeck Mismatch = (d-e)'] != -739:
4116
        mail(mail_user, mail_password, ['rajneesh.arora@shop2020.in', 'rajveer.singh@shop2020.in', 'anupam.singh@shop2020.in'], "SpiceDeck Account mismatch of amount " + str(amounts['SpiceDeck Mismatch = (d-e)']), "", [], [], [])
4117
    if amounts['Saholic Mismatch = (a+b-c-d)'] != -1919:
4118
        mail(mail_user, mail_password, ['rajneesh.arora@shop2020.in', 'rajveer.singh@shop2020.in', 'anupam.singh@shop2020.in'], "Saholic Recharge Account mismatch of amount " + str(amounts['Saholic Mismatch = (a+b-c-d)']), "", [], [], [])
6337 rajveer 4119
    '''
6318 rajveer 4120
 
6188 rajveer 4121
    rs.statusCounts = statusCounts
4122
    rs.operatorCounts = operatorCounts    
4123
    rs.currentOrders = currentOrders
4124
    rs.amounts = amounts
4125
 
4126
    return rs
4127
 
4128
 
6159 rajveer 4129
def get_plans_for_operator(operator_id):
4130
    return RechargePlan.query.filter_by(operatorId = operator_id).all()
4131
 
6056 amit.gupta 4132
def get_recharge_orders_for_transaction(txId):
4133
    return RechargeOrder.query.filter_by(transaction_id = txId).first()
6102 rajveer 4134
 
6285 rajveer 4135
def enqueue_recharge_info_email(recharge_order, gvs={}):
6102 rajveer 4136
    status = ""
4137
    message = ""
4138
    html_header = """
4139
 
4140
    <html>
4141
    <body>
4142
    <div>
4143
        <p>
4144
            Hello $email,<br /><br />
6127 rajveer 4145
            Thanks for placing recharge order with us. Following are the details of your recharge order:
6102 rajveer 4146
        </p>
4147
        <div>
6136 rajveer 4148
            Order Id : $order_id <br/>
4149
            Order Date : $order_date <br/>
4150
            Order Amount : Rs. $order_amount <br/>
4151
            Order Status : $order_status <br/>
4152
            Device Number : $device_number <br/>
4153
            Service Provider : $service_provider <br/>
6102 rajveer 4154
        </div>
6348 rajveer 4155
    <br />
6102 rajveer 4156
    """
6288 rajveer 4157
 
4158
    FailureReasonMap = {}
4159
    FailureReasonMap["Invalid Amount"] = "the amount you tried seems to be invalid. Please try another amount."
4160
    FailureReasonMap["Customer Exceeded Daily Limit"] = "you have exceeded daily recharge limit for this number. Please try after 12 hours."
6399 rajveer 4161
    FailureReasonMap["Invalid Device Number"] = "it seems that your device number is not being recognized by selected operator. Please make sure the number you tried is correct."
6288 rajveer 4162
 
4163
    failureReason = FailureReasonMap.get(recharge_order.description)
4164
    if failureReason is None:
4165
        failureReason = "of network failure."
6102 rajveer 4166
    if recharge_order.status == RechargeOrderStatus.RECHARGE_SUCCESSFUL:
4167
        status = "Recharge Successful"
4168
        message = ""
6444 rajveer 4169
        if recharge_order.couponAmount > 0:
4170
            message = message + "<b>You have used coupon " + recharge_order.couponCode + " and got discount of Rs. " + str(recharge_order.couponAmount) + ".</b>" 
4171
 
6102 rajveer 4172
    elif recharge_order.status == RechargeOrderStatus.RECHARGE_FAILED:
4173
        status = "Recharge Failed"
6127 rajveer 4174
        message = """
6288 rajveer 4175
                We could not process your recharge because $failureReason We have credited the amount to your recharge wallet. You can use wallet amount to recharge again. <a href="$source_url/static/recharge-faq">Learn More</a>
6127 rajveer 4176
                """
6206 rajveer 4177
    elif recharge_order.status == RechargeOrderStatus.PAYMENT_SUCCESSFUL:
6102 rajveer 4178
        status = "Recharge Under Process"
6127 rajveer 4179
        message = """
6288 rajveer 4180
                Your Payment was successful but due to some internal error with the operator's system we are not sure if the recharge was successful. In case your recharge is not processed, we will credit amount to your recharge wallet. You can use wallet amount to recharge again. <a href="$source_url/static/recharge-faq">Learn More</a>
6127 rajveer 4181
                """
6279 rajveer 4182
    elif recharge_order.status == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED:
4183
        status = "Recharge Failed, Amount Refunded"
4184
        message = """
4185
                It seems operator could not process your recharge request. We are crediting the refund amount to your recharge wallet. You can use wallet amount to recharge again. <a href="$source_url/static/recharge-faq">Learn More</a>
4186
                """
6285 rajveer 4187
    if len(gvs) > 0:
6340 rajveer 4188
        message = message  + '<br />  You have been awarded with following Gift Voucher(s). You can redeem Gift Voucher(s) to purchase any product for Rs. 5000 and above using credit/debit card and net banking. <a href="$source_url/static/giftvoucher-offer">More details</a>'
6330 rajveer 4189
        message = message + " <br />  <b>Voucher Code &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Amount</b>"
6285 rajveer 4190
        for gv in gvs.keys():
4191
            gvAmount = gvs.get(gv)
6330 rajveer 4192
            message = message + " <br />  <b>" + gv + "&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Rs. "  + str(gvAmount) + "</b>"
6285 rajveer 4193
 
6114 rajveer 4194
    message = message  + '<br />  In case of any problem, please  <a href="$source_url/contact-us">contact us</a>'
6102 rajveer 4195
 
6136 rajveer 4196
    html_header = html_header + message
6102 rajveer 4197
    html_footer = """
4198
    <p>
4199
        Best Wishes,<br />
4200
        $source_name Team
4201
    </p>
4202
    </div>
4203
    </body>
4204
    </html>
4205
    """
4206
 
6125 rajveer 4207
    if isinstance(recharge_order, MobileRechargeOrder):
4208
        deviceNumber = recharge_order.mobileNumber
4209
        providerName = get_provider(recharge_order.mobileOperatorId).name
4210
    if isinstance(recharge_order, DTHRechargeOrder):
4211
        deviceNumber = recharge_order.dthAccountNumber
4212
        providerName = get_provider(recharge_order.dthOperatorId).name
4213
 
6127 rajveer 4214
    display_order_id = recharge_order.idPrefix + str(recharge_order.id)
6102 rajveer 4215
    email = recharge_order.userEmailId
4216
    dt = datetime.datetime.strptime(str(recharge_order.creationTimestamp), "%Y-%m-%d %H:%M:%S")
4217
    formated_order_date = dt.strftime("%A, %d. %B %Y %I:%M%p")
4218
 
6288 rajveer 4219
    email_header = Template(html_header).substitute(dict(order_id = display_order_id, order_date = formated_order_date, email = email, source_url = source_url, order_amount = recharge_order.totalAmount, order_status = status, device_number = deviceNumber, service_provider = providerName, failureReason = failureReason))
6102 rajveer 4220
    email_footer = Template(html_footer).substitute(dict(source_url = source_url, source_name = source_name))
4221
 
4222
    try:
4223
        helper_client = HelperClient().get_client()
6906 rajveer 4224
        helper_client.saveUserEmailForSending([email], "", source_name + " - Recharge Order Details", email_header + email_footer, str(recharge_order.id), "RechargeInfo", [], [])
6102 rajveer 4225
        return True
4226
    except Exception as e:
4227
        print e
4228
        return False
4229
 
6307 anupam.sin 4230
def get_recharge_denominations(operator_id, circleCode, denomination_type):
4231
    circle_id = TelecomCircle.query.filter_by(code = circleCode).first().id
6289 anupam.sin 4232
    return RechargeDenomination.query.filter_by(operatorId = operator_id).filter_by(circleId = circle_id).filter_by(denominationType = denomination_type).all()
6371 rajveer 4233
 
4234
def update_availability_status(operatorId, circleId, isAvailable):
4235
    serviceAvailability = ServiceAvailability.query.filter_by(circleId = circleId).filter_by(operatorId = operatorId).first()
6734 anupam.sin 4236
    serviceAvailability.tempIsServiceAvailable = isAvailable
6371 rajveer 4237
    session.commit()
4238
 
6389 rajveer 4239
def get_misc_charges(transactionId):
4240
    retCharges = {}
4241
    miscCharges = MiscCharges.get_by(transaction_id = transactionId)
4242
    if miscCharges:
6426 rajveer 4243
        retCharges[1] = miscCharges.chargeAmount 
6389 rajveer 4244
    return retCharges
6396 amit.gupta 4245
 
4246
def get_available_emi_schemes():
4247
    t_emi_schemes = []
4248
    emi_schemes = EmiScheme.query.all()
4249
    if emi_schemes:
4250
        t_emi_schemes = [to_t_emi_scheme(emi_scheme) for emi_scheme in emi_schemes]
4251
    return t_emi_schemes
6389 rajveer 4252
 
6507 anupam.sin 4253
def refund_recharge_order(rechargeOrderId):
4254
    try :
4255
        rechargeOrder = RechargeOrder.query.filter_by(id = rechargeOrderId).first()
4256
        wallet = UserWallet.query.filter_by(userId = rechargeOrder.userId).first()
4257
    except:
4258
        return False
4259
 
4260
    paidAmount = rechargeOrder.totalAmount - rechargeOrder.walletAmount - rechargeOrder.couponAmount
4261
    amountToRefund = 0
4262
    status = None
4263
    if (paidAmount <= wallet.amount) :
4264
        amountToRefund = paidAmount
4265
        status = RechargeOrderStatus.REFUNDED
4266
    else :
4267
        amountToRefund = wallet.amount
4268
        status = RechargeOrderStatus.PARTIALLY_REFUNDED
4269
 
4270
    update_amount_in_wallet(rechargeOrder.userId, -amountToRefund, rechargeOrderId)
4271
 
4272
    try:    
4273
        pc = PaymentClient().get_client()
4274
        if pc.refundPayment(rechargeOrder.transaction_id, amountToRefund, True) :
4275
            rechargeOrder.status = status
6515 anupam.sin 4276
            rechargeOrder.refundTimestamp = datetime.datetime.now()
6507 anupam.sin 4277
            session.commit()
4278
            return True
4279
        else :
4280
            update_amount_in_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId)
4281
 
4282
    except:
4283
        update_amount_in_wallet(rechargeOrder.userId, amountToRefund, rechargeOrderId)
4284
 
4285
    return False 
4286
 
6821 amar.kumar 4287
def get_physical_orders(from_date, to_date):
4288
    query = Order.query.filter(Order.created_timestamp >from_date).filter(Order.created_timestamp < to_date).filter(Order.status>=2)
4289
    return query.all()
4290
 
6507 anupam.sin 4291
 
766 rajveer 4292
def close_session():
4293
    if session.is_active:
4294
        print "session is active. closing it."
2783 chandransh 4295
        session.close()
3376 rajveer 4296
 
4297
def is_alive():
4298
    try:
4299
        session.query(Transaction.id).limit(1).one()
4300
        return True
4301
    except:
6000 mandeep.dh 4302
        return False
4303
 
6906 rajveer 4304
def get_document(docType, docSource):
4305
    document = DocumentStore.get_by(docType = docType, docSource = docSource)
4306
    if document:
4307
        return document.document
4308
    else:
7040 amar.kumar 4309
        return bin(0)
6906 rajveer 4310
 
7075 rajveer 4311
def retrieve_invoice(orderId, userId):
4312
    order = get_order(orderId)
4313
    if order.customer_id != userId:
4314
        return bin(0)
6988 rajveer 4315
    strOrderId = '0'*(10-len(str(orderId)))+str(orderId)
7072 rajveer 4316
    filename = "/SaholicInvoices/" + strOrderId[0:2] + "/" + strOrderId[2:4] + "/" + strOrderId[4:6] + "/" + str(orderId) + ".pdf"  
6988 rajveer 4317
    file = open(filename, "rb")
4318
    pdfFile = file.read()
4319
    return pdfFile
4320
 
6906 rajveer 4321
def myFirstPage(canvas, doc):
4322
    canvas.saveState()
6916 anupam.sin 4323
    canvas.setTitle("Theft-Insurance-Policy")
6906 rajveer 4324
    canvas.restoreState()
4325
 
4326
 
4327
def __generate_policy_doc(order, filename):
6903 anupam.sin 4328
    PAGE_HEIGHT=defaultPageSize[1]; PAGE_WIDTH=defaultPageSize[0]
4329
    styles = getSampleStyleSheet()
4330
    styles.add(ParagraphStyle(name='left', leftIndent=12,fontSize=11), alias='li')
4331
    styles.add(ParagraphStyle(name='bullet', bulletIndent=24, leftIndent=24), alias='bull')
6916 anupam.sin 4332
    styles.add(ParagraphStyle(name='insurerName', alignment=TA_CENTER, fontName="Times-Bold", fontSize=16), alias='iN')
4333
    styles.add(ParagraphStyle(name='insurerAdd', alignment=TA_CENTER, fontName="Helvetica",leading=15, fontSize=12), alias='iA')
4334
    styles.add(ParagraphStyle(name='subHeading', alignment=TA_CENTER, fontName="Helvetica", fontSize=13), alias='sH')
6903 anupam.sin 4335
 
6914 rajveer 4336
    invoiceNumber = str(order.invoice_number)
6906 rajveer 4337
    billing_timestamp = str(order.billing_timestamp.date()) 
6903 anupam.sin 4338
 
6906 rajveer 4339
    doc = SimpleDocTemplate(filename)
6916 anupam.sin 4340
    Story = [Spacer(0, 0)]
6903 anupam.sin 4341
    style = styles["Normal"]
6916 anupam.sin 4342
 
4343
 
4344
    file_name = os.path.dirname(os.path.realpath(__file__)) + '/../resources/nia-logo.jpg'
4345
    image = Image(file_name, width=100, height=100)
4346
    Story.append(image)
4347
    Story.append(Spacer(1,0.2*inch))
4348
 
4349
    text = ("""<u>The New India Assurance Company Limited</u>""") 
4350
    p = Paragraph(text, styles['insurerName'])
4351
    Story.append(p)
4352
    Story.append(Spacer(1,0.2*inch))
4353
 
4354
    text = ("""DO-IX, 35/1, Fortune Park, 1st Floor, Park Road, Tasker Town, Shivajinagar, Bangalore  560051""") 
4355
    p = Paragraph(text, styles['insurerAdd'])
4356
    Story.append(p)
4357
    Story.append(Spacer(1,0.3*inch))
4358
 
4359
    text = ("""MOBILE HAND SET INSURANCE – THEFT & BURGLARY RISKS ONLY""")
4360
    p = Paragraph(text, styles['subHeading'])
4361
    Story.append(p)
4362
    Story.append(Spacer(1,1*inch))
4363
 
6903 anupam.sin 4364
    text = ("""<u><b>Subject Matter Of Insurance</b></u> : <i>New Mobile Handsets</i> alone and <i>Tablets with 'Voice Calls'</i> only. 
4365
    Sold 'online' by <b>Spice Online Retail Private Limited, New Delhi</b>, to its customers.""") 
4366
    p = Paragraph(text, style)
4367
    Story.append(p)
4368
    Story.append(Spacer(1,0.2*inch))
4369
    text = ("""Insurer will indemnify the Insured in the event of Theft/Burglary of <i>Mobile Handsets</i> 
6914 rajveer 4370
    alone and <i>Tablets with 'Voice Calls'</i> only sold as per Invoice No. %s
6903 anupam.sin 4371
    dated %s and insured with THE NEW INDIA ASSURANCE COMPANY LIMITED, BANGALORE, as per Policy No. 671700/46/12/2400000008,  
4372
    for a period of 12 months from the date and time of delivery of Mobile Handset to the customer.""" % (invoiceNumber, billing_timestamp)) 
4373
    p = Paragraph(text, style)
4374
    Story.append(p)
4375
    Story.append(Spacer(1,0.2*inch))
4376
    text = ("""<b>WARRANTY</b> -  Warranted that the Mobile Handset sold during the Policy Period of 25/02/2013 to 24/02/2014
4377
             are only covered irrespective of date of delivery to the customer""")
4378
    p = Paragraph(text, style)
4379
    Story.append(p)
4380
    Story.append(Spacer(1,0.2*inch))
6915 anupam.sin 4381
    text = ("<b>INSURER</b> -The New India Assurance company limited.")
6903 anupam.sin 4382
    p = Paragraph(text, style)
4383
    Story.append(p)
4384
    Story.append(Spacer(1,0.2*inch))
4385
    text = ("<b>INSURED</b> - Purchaser of the Mobile Handset OR his/her spouse or children. If the Purchaser is a ‘Company’, user is the duly authorised person.") 
4386
    p = Paragraph(text, style)
4387
    Story.append(p)
4388
    Story.append(Spacer(1,0.2*inch))
4389
    text = ("<b>GEOGRAPHICAL LIMIT</b> – World-wide") 
4390
    p = Paragraph(text, style)
4391
    Story.append(p)
4392
    Story.append(Spacer(1,0.2*inch))
4393
    text = ("<b>RISK COVERAGE</b> – Theft and/or burglary only") 
4394
    p = Paragraph(text, style)
4395
    Story.append(p)
6916 anupam.sin 4396
    Story.append(Spacer(1,0.4*inch))
6915 anupam.sin 4397
    text = ("Terms and Conditions of Insurance:") 
4398
    p = Paragraph(text, styles["h2"])
4399
    Story.append(p)
4400
    Story.append(Spacer(1,0.1*inch))
4401
    text = ("""Insurance Premium paid will not be refunded.""")
4402
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4403
    Story.append(p)
4404
    Story.append(Spacer(1,0.1*inch))
6921 anupam.sin 4405
    text = ("""Claims will be settled by UIB on behalf of The New India Assurance Co. Ltd.<br></br>
4406
            Saholic.com will not be responsible for claim approval and disbursement.""")
4407
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4408
    Story.append(p)
4409
    Story.append(Spacer(1,0.1*inch))
6915 anupam.sin 4410
    text = ("""Insurance will be invalidated for returned products.""")
4411
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4412
    Story.append(p)
6921 anupam.sin 4413
    Story.append(Spacer(1,0.3*inch))
6903 anupam.sin 4414
    text = ("Exclusions:") 
4415
    p = Paragraph(text, styles["h2"])
4416
    Story.append(p)
4417
    Story.append(Spacer(1,0.1*inch))
4418
    text = ("Insurer is not liable") 
4419
    p = Paragraph(text, styles["left"])
4420
    Story.append(p)
4421
    Story.append(Spacer(1,0.1*inch))
4422
    text = ("If the handset is not connected to Mobile Service Provider Network")
4423
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4424
    Story.append(p)
4425
    Story.append(Spacer(1,0.1*inch))
4426
    text = ("Caused by incorrect storage, poor care and maintenance, careless use, negligence.")
4427
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4428
    Story.append(p)
4429
    Story.append(Spacer(1,0.1*inch))
4430
    text = ("Due to mysterious disappearance, forgotten or misplaced or Lost or if handset is left unattended at any point of time.")
4431
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4432
    Story.append(p)
4433
    Story.append(Spacer(1,0.1*inch))
4434
    text = ("Caused by war, war like operation, act of foreign enemy, civil war, rebellion, civil commotion, military usurped power, seizure, capture, confiscation, arrests, restrains and detainment by order of any Government or any other Authority.")
4435
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4436
    Story.append(p)
4437
    Story.append(Spacer(1,0.1*inch))
4438
    text = ("Caused whilst engaging in criminal acts.")
4439
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4440
    Story.append(p)
4441
    Story.append(Spacer(1,0.1*inch))
4442
    text = ("Caused by consequential loss or damage of whatsoever nature or any costs incurred in connection with claim under this policy, including postage, transit costs and reconnection cost.")
4443
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4444
    Story.append(p)
4445
    Story.append(Spacer(1,0.1*inch))
4446
    text = ("Loss of mobile handset due to theft from an unattended vehicle unless the vehicle is of  fully enclosed saloon type having at time all the doors/windows and other opening securely locked and properly fastened.")
4447
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4448
    Story.append(p)
4449
    Story.append(Spacer(1,0.1*inch))
4450
    text = ("Loss of mobile handset due to theft from the building unless there is visible forcible entry/exit into/from the building.")
4451
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4452
    Story.append(p)
4453
    Story.append(Spacer(1,0.1*inch))
4454
    text = ("If the documents are found to be tampered; non-disclosure of material fact, fraud/misrepresentation.")
4455
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4456
    Story.append(p)
4457
    Story.append(Spacer(1,0.1*inch))
4458
    text = ("The policy is not transferable.")
4459
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4460
    Story.append(p)
4461
    Story.append(Spacer(1,0.2*inch))
4462
 
4463
    text = ("Claim Procedure:") 
4464
    p = Paragraph(text, styles["h2"])
4465
    Story.append(p)
4466
    Story.append(Spacer(1,0.1*inch))
4467
    text = ("""For Theft or Burglary of the handset immediate intimation to be given
4468
     to the police within 48 hours of occurrence of incident and proper documents to be obtained 
4469
     and inform the service provider within 48 hours about theft of handset in order to block the SIM services.""")
4470
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4471
    Story.append(p)
4472
    Story.append(Spacer(1,0.1*inch))
4473
    text = ("""To intimate Insurance Company about the loss of Mobile Handset within 48 hours 
6915 anupam.sin 4474
     through Call Centre No.022-49107910 OR through e-mail <u>saholic.claims@universalinsurance.co.in</u> OR through 
6903 anupam.sin 4475
     written communication to <i>Universal Insurance brokers (UIB) No.304, Commerce House, 9/1,Cunningham Road, Bangalore – 560052</i>.""")
4476
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4477
    Story.append(p)
4478
    Story.append(Spacer(1,0.1*inch))
6915 anupam.sin 4479
    text = ("""Claim documents can be downloaded through UIB Website <u>http://www.universalinsurance.co.in/mobileinsurance/claiminfo.html</u>
4480
    <br></br>To know or track your claim please contact Call Centre No. 022-49107910 of Universal Insurance brokers (UIB). """)
6903 anupam.sin 4481
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4482
    Story.append(p)
4483
    Story.append(Spacer(1,0.1*inch))
4484
    text = ("""All the completed claim documents to reach ‘Universal Insurance Brokers (UIB)’ office 
4485
    at <i>No.304, Commerce House, 9/1, Cunningham Road, Bangalore – 560052</i> <b>within 21 days</b>.""")
4486
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4487
    Story.append(p)
4488
    Story.append(Spacer(1,0.2*inch))
4489
 
4490
 
4491
    text = ("Excess(Minimum Deduction):") 
4492
    p = Paragraph(text, styles["h2"])
4493
    Story.append(p)
4494
    Story.append(Spacer(1,0.1*inch))
4495
    text = ("""The excess will be 5% of the value of each claim subject to a minimum of Rs.500/-""")
4496
    p = Paragraph(text, styles["left"])
4497
    Story.append(p)
4498
    Story.append(Spacer(1,0.2*inch))
4499
 
4500
    text = ("Depreciation:") 
4501
    p = Paragraph(text, styles["h2"])
4502
    Story.append(p)
4503
    Story.append(Spacer(1,0.1*inch))
4504
 
4505
    text = ("For 0 – 60 days, 15%")
4506
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4507
    Story.append(p)
4508
    Story.append(Spacer(1,0.1*inch))
4509
 
4510
    text = ("61-150 days, 30%")
4511
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4512
    Story.append(p)
4513
    Story.append(Spacer(1,0.1*inch))
4514
 
4515
    text = ("151 – 365 days, 45%")
4516
    p = Paragraph(text, styles["bullet"], bulletText='\xe2\x80\xa2')
4517
    Story.append(p)
4518
    Story.append(Spacer(1,0.4*inch))
4519
 
4520
    text = ("<i>Insurance is a subject matter of solicitation.</i>")
4521
    p = Paragraph(text, style)
4522
    Story.append(p)
4523
    Story.append(Spacer(1,0.2*inch))
4524
 
6906 rajveer 4525
    doc.build(Story, onFirstPage=myFirstPage)
6980 anupam.sin 4526
 
4527
def drawLine(Story, style):
4528
    Story.append(Paragraph('-'*40, style))
6915 anupam.sin 4529
 
6980 anupam.sin 4530
def generateHotSpotInvoice():
4531
 
4532
    ##########TO BE PASSED TO THIS METHOD####################################
4533
    #########################################################################
4534
    filename = "/home/anupam/test.pdf"                             ##########
4535
    itemCode = "SPICEMI450WHT"                                     ##########
4536
    lotNumber = "12345678901234"                                   ##########
4537
    itemName = "Spice Stellar Craze Mi-450 White"                  ##########
4538
    qty = 1                                                        ##########
4539
    unitPrice = 3099.50                                            ##########
4540
    vat = 310.23                                                   ##########
4541
    billingTime = datetime.datetime.now()                          ##########
4542
    invNum = "885182994"                                           ##########
4543
    counter = 1                                                    ##########
4544
    ourInvoiceNum = "209809"                                       ##########
4545
    customerId = "12345678909"                                     ##########
4546
    customerName = "ANUPAM PRATAP SINGH"                           ##########
4547
    telNum = ""                                                    ##########
4548
    #########################################################################
4549
 
4550
    PAGE_HEIGHT=defaultPageSize[1];
4551
    styles = getSampleStyleSheet()
4552
    styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')
4553
    styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')
4554
    styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')
4555
    styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')
4556
 
4557
    Story = []
4558
    prologueStyle = styles["prologue"]
4559
    lineStyle = styles["line"]
4560
    textStyle = styles["text"]
4561
    epilogueStyle = styles["epilogue"]
4562
 
4563
    doc = BaseDocTemplate(filename,showBoundary=0)
4564
 
4565
    #Two Columns
4566
    frame1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')
4567
 
4568
 
4569
 
4570
    Story.append(Paragraph("""Spice Retail Limited<br></br>
4571
        C/O,PIBCO LIMITED,Basement,Punjsons<br></br>
4572
        2,Kalkaji Industrial Area,New Delhi<br></br>
4573
          .<br></br>
4574
        TIN NO. 07430284979<br></br>
4575
        Service Tax No:AAACM0294PST001<br></br>
4576
        D U P L I C A T E<br></br>
4577
        I N V O I C E<br></br>""", prologueStyle))
4578
    drawLine(Story, lineStyle)
4579
 
4580
    Story.append(Paragraph('{0:7s}{1:>11s}{2:  %d/%m/%Y  %H:%M:%S}'.format("INV NO:", invNum, billingTime).replace(" ", "&nbsp;"), textStyle))
4581
    Story.append(Paragraph("{0:8s}{1:>5d}{2:>11s}{3:>11s}".format('COUNTER:', counter, "CASHIER:", "SUPERADMIN").replace(" ", "&nbsp;"), textStyle))
4582
    Story.append(Paragraph("MN INV NO&amp;DT: {0:<13s}{1:%d/%m/%Y}   ".format(ourInvoiceNum, billingTime).replace(" ", "&nbsp;"), textStyle))
4583
    drawLine(Story, lineStyle)
4584
 
4585
    Story.append(Paragraph("{0:<13s}{1:<27s}".format("CUSTOMER ID:", customerId).replace(" ", "&nbsp;"), textStyle))
4586
    Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName + " " + ourInvoiceNum).replace(" ", "&nbsp;"), textStyle))
4587
    Story.append(Paragraph("{0:<9s}{1:<31s}".format("TEL NO.:", telNum).replace(" ", "&nbsp;"), textStyle))
4588
    drawLine(Story, lineStyle)
4589
 
4590
    Story.append(Paragraph("ITEM" + "&nbsp;"*12 + "LOT NUMBER<br></br>" + \
4591
                            "&nbsp;ITEM NAME<br></br>" + \
4592
                            "&nbsp;"*5 + "QTY" + "&nbsp;"*21 + "AMOUNT(INR)", textStyle))
4593
    drawLine(Story, lineStyle)
4594
 
4595
    Story.append(Paragraph(('{0:<16s}{1:24s}').format(itemCode, lotNumber).replace(' ', '&nbsp;'),textStyle))
4596
    Story.append(Paragraph((' {0:<39s}').format(itemName).replace(' ', '&nbsp;'),textStyle))
4597
    Story.append(Paragraph(('{0:<3d}{1:>10s}{2:13.2f}{3:14.2f}').format(qty, 'PCS', unitPrice, qty*unitPrice).replace(' ', '&nbsp;'),textStyle))
4598
    Story.append(Paragraph(('{0:<3s}{1:37.2f}').format("VAT", vat).replace(' ', '&nbsp;'),textStyle))
4599
    Story.append(Paragraph(('{0:<10s}{1:30.2f}').format("ITEM TOTAL", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4600
 
4601
    drawLine(Story, lineStyle)
4602
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("GROSS TOTAL:","INR", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4603
    drawLine(Story, lineStyle)
4604
 
4605
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("NET TOTAL:","INR", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4606
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("NET VAT:","INR", vat).replace(' ', '&nbsp;'),textStyle))
4607
    drawLine(Story, lineStyle)
4608
 
4609
    Story.append(Paragraph(('{0:13s}{1:>12s}{2:15.2f}').format("SPICE ONLINE:","INR", vat + unitPrice*qty).replace(' ', '&nbsp;'),textStyle))
4610
    drawLine(Story, lineStyle)
4611
 
4612
    Story.append(Paragraph(('{0:16s}{1:>4d}').format("NUMBER OF ITEMS:",qty,).replace(' ', '&nbsp;'),textStyle))
4613
    Story.append(Paragraph(('{0:16s}{1:>9.6f}').format("TOTAL ITEMS    :",qty,).replace(' ', '&nbsp;'),textStyle))
4614
 
4615
    Story.append(Paragraph("Goods once Sold Will not be taken back.<br></br>All Disputes subject to Delhi Jurisdiction",epilogueStyle))
4616
 
4617
 
4618
    doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])
4619
 
4620
    #start the construction of the pdf
4621
    doc.build(Story)
4622
 
6985 anupam.sin 4623
def change_shipping_address(orderId, line1, line2, city, state, pin):
4624
    order = Order.get_by(id = orderId)
4625
    if order:
4626
        order.customer_address1 = line1
4627
        order.customer_address2 = line2
4628
        order.customer_city = city
4629
        order.customer_state = state
4630
        order.customer_pin = pin
4631
        session.commit()
4632
        return True
4633
    return False
4634
 
7084 rajveer 4635
def get_recharge_transactions(storeId):
4636
    query = RechargeTransaction.query.filter(RechargeTransaction.storeId == storeId)
4637
    return query.all()
4638
 
7151 amit.gupta 4639
def get_recharge_trans(storeId, startdate,enddate, status):
4640
    if startdate == -1:
4641
        startdate = None
4642
    if enddate == -1:
4643
        enddate = None
4644
    if storeId== 0:
4645
        storeId = None
4646
    if status == 0:
4647
        status = None    
4648
 
4649
    query = RechargeTransaction.query
4650
    if storeId is not None:
4651
        query = query.filter(RechargeTransaction.storeId == storeId)
4652
    if status is not None:
4653
        query = query.filter(RechargeTransaction.status == status)
7169 anupam.sin 4654
 
4655
    if status == RechargeOrderStatus.RECHARGE_FAILED_REFUNDED :
4656
        query.filter(cast(RechargeTransaction.responseTime, DATE) == enddate)
7151 amit.gupta 4657
 
7169 anupam.sin 4658
    else :
4659
        if startdate is not None and enddate is not None:
4660
            startdate = to_py_date(startdate).date()
4661
            enddate = to_py_date(enddate).date()
4662
            if startdate == enddate:
4663
                query = query.filter(cast(RechargeTransaction.transactionTime, DATE) == enddate)
4664
            elif enddate < startdate:
4665
                query = query.filter(between(cast(RechargeTransaction.transactionTime, DATE), enddate, startdate))
4666
            else:
4667
                query = query.filter(between(cast(RechargeTransaction.transactionTime, DATE), startdate, enddate))
4668
        elif startdate is not None:
4669
            startdate = to_py_date(startdate).date()
4670
            query = query.filter(cast(RechargeTransaction.transactionTime, DATE) >= startdate)
4671
        elif enddate is not None:
4672
            enddate = to_py_date(enddate).date()
4673
            query = query.filter(cast(RechargeTransaction.transactionTime, DATE) <= enddate)
4674
 
7151 amit.gupta 4675
    return query.all()    
4676
 
7243 rajveer 4677
def update_recharge_transaction_status(id, status):
7127 rajveer 4678
    rechargeTransaction = RechargeTransaction.get_by(id=id)
7163 rajveer 4679
    if status in (RechargeOrderStatus.RECHARGE_FAILED_REFUNDED, RechargeOrderStatus.RECHARGE_FAILED):
4680
        rechargeTransaction.status = status
7243 rajveer 4681
        rechargeTransaction.responseTime = datetime.datetime.now() 
7127 rajveer 4682
 
4683
        store = HotspotStore.get_by(id=rechargeTransaction.storeId)
4684
        wallet = WalletForCompany.get_by(companyId=store.companyId)
4685
        wh = WalletHistoryForCompany()
4686
        wh.walletId = wallet.id
4687
        wh.amount = rechargeTransaction.amount
4688
        wh.transactionTime = rechargeTransaction.responseTime
4689
        wh.openingBal = wallet.amount
4690
        wh.closingBal = wallet.amount + wh.amount
4691
        wh.referenceNumber = rechargeTransaction.id 
4692
        wh.description = "Credited amount"
4693
 
4694
        wallet.amount = wallet.amount + rechargeTransaction.amount
4695
        store.availableLimit = store.availableLimit + rechargeTransaction.amount
4696
        store.collectedAmount = store.collectedAmount - rechargeTransaction.amount + rechargeTransaction.discount
4697
        session.commit()
7163 rajveer 4698
 
4699
    if status == RechargeOrderStatus.RECHARGE_SUCCESSFUL:
4700
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
4701
        rechargeTransaction.invoiceNumber = get_next_invoice_number(OrderType.RCH4HOTSPOT)
4702
        session.commit()
4703
 
4704
 
7073 anupam.sin 4705
def create_recharge_transaction(t_recharge):
7163 rajveer 4706
    dt = datetime.datetime.now() - datetime.timedelta(minutes=10)
4707
    txns = RechargeTransaction.query.filter(RechargeTransaction.deviceNum == t_recharge.deviceNum).filter(RechargeTransaction.transactionTime > dt).all()
4708
    if txns:
4709
        raise TransactionServiceException(898, "In last 10 minutes you had already recharged this mobile number. Please try after sometime.")
7073 anupam.sin 4710
    rechargeTransaction = RechargeTransaction()
4711
    rechargeTransaction.amount = t_recharge.amount
7096 anupam.sin 4712
    rechargeTransaction.circleId = t_recharge.circleId
7073 anupam.sin 4713
    rechargeTransaction.deviceNum = t_recharge.deviceNum
4714
    rechargeTransaction.deviceType = t_recharge.deviceType
4715
    rechargeTransaction.discount = t_recharge.discount
4716
    rechargeTransaction.email = t_recharge.email
4717
    rechargeTransaction.name = t_recharge.name
4718
    rechargeTransaction.cafNum = t_recharge.cafNum
4719
    rechargeTransaction.simNum = t_recharge.simNum
4720
    rechargeTransaction.isFrc = t_recharge.isFrc
4721
    rechargeTransaction.status = RechargeOrderStatus.INIT
4722
    rechargeTransaction.storeId = t_recharge.storeId
4723
    rechargeTransaction.transactionTime = datetime.datetime.now()
7075 rajveer 4724
    rechargeTransaction.operatorId = t_recharge.operatorId
4725
    rechargeTransaction.plan = t_recharge.plan
7080 anupam.sin 4726
    rechargeTransaction.ipAddress = t_recharge.ipAddress
7096 anupam.sin 4727
    rechargeTransaction.paymentAmount = t_recharge.paymentAmount
7139 amit.gupta 4728
    rechargeTransaction.payMethod = t_recharge.payMethod
7075 rajveer 4729
 
4730
    store = HotspotStore.get_by(id=rechargeTransaction.storeId)
7304 rajveer 4731
    if not rechargeTransaction.circleId:
4732
        rechargeTransaction.circleId = store.circleId
4733
 
7075 rajveer 4734
    wallet = WalletForCompany.get_by(companyId=store.companyId)
4735
    if store.availableLimit < rechargeTransaction.amount or wallet.amount < rechargeTransaction.amount:
4736
        raise TransactionServiceException(898, "Either wallet amount for company or available limit for store is less than recharge amount.")
7249 rajveer 4737
 
7075 rajveer 4738
    wh = WalletHistoryForCompany()
4739
    wh.walletId = wallet.id
4740
    wh.amount = -rechargeTransaction.amount
4741
    wh.transactionTime = rechargeTransaction.transactionTime
4742
    wh.openingBal = wallet.amount
4743
    wh.closingBal = wallet.amount + wh.amount
4744
    wh.description = "Debited amount"
4745
 
4746
    wallet.amount = wallet.amount - rechargeTransaction.amount
4747
    store.availableLimit = store.availableLimit - rechargeTransaction.amount
7076 rajveer 4748
    store.collectedAmount = store.collectedAmount + rechargeTransaction.amount - rechargeTransaction.discount 
7075 rajveer 4749
    session.commit()
4750
 
7249 rajveer 4751
    wh.referenceNumber = rechargeTransaction.id
4752
    session.commit()
4753
 
4754
 
7101 rajveer 4755
    strProviderCode = get_provider_code(rechargeTransaction.operatorId)
4756
    if rechargeTransaction.deviceType == 1:
4757
        rtype = 'MTP'
4758
    else:
4759
        rtype = 'RCH'
4760
    retStatus, retCode, spiceTID, description = RechargeService.rechargeDevice(rechargeTransaction.id, rtype, strProviderCode, rechargeTransaction.deviceNum, rechargeTransaction.amount, rechargeTransaction.plan)
7075 rajveer 4761
    rechargeTransaction.spiceTID = spiceTID
4762
    rechargeTransaction.responseTime = datetime.datetime.now()
4763
    rechargeTransaction.description = description
4764
    if retCode == '00' and retStatus == 'S':
4765
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_SUCCESSFUL
7096 anupam.sin 4766
        rechargeTransaction.invoiceNumber = get_next_invoice_number(OrderType.RCH4HOTSPOT)
7075 rajveer 4767
 
4768
    elif retCode in ('STO', 'US', 'UP') and retStatus == 'S':
4769
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_UNKNOWN
4770
    else:
4771
        rechargeTransaction.status = RechargeOrderStatus.RECHARGE_FAILED
4772
        if retCode in ('SVAI', 'SVIA', 'AI', 'IA', 'EAI', 'SVEAI'):
4773
            rechargeTransaction.description = "Invalid Amount"
4774
        elif retCode in ('ECL', 'SVECL', 'SCL'):
4775
            rechargeTransaction.description = "Customer Exceeded Daily Limit"
4776
        elif retCode in ('CI', 'ECI', 'ESP', 'SVCI', 'SVECI', 'SVESP', 'SV_ECI', 'SV ECI'):
4777
            rechargeTransaction.description = "Invalid Device Number"
4778
 
4779
        store = HotspotStore.get_by(id=rechargeTransaction.storeId)
4780
        wallet = WalletForCompany.get_by(companyId=store.companyId)
4781
        wh = WalletHistoryForCompany()
4782
        wh.walletId = wallet.id
4783
        wh.amount = rechargeTransaction.amount
4784
        wh.transactionTime = rechargeTransaction.responseTime
4785
        wh.openingBal = wallet.amount
4786
        wh.closingBal = wallet.amount + wh.amount
4787
        wh.referenceNumber = rechargeTransaction.id 
4788
        wh.description = "Credited amount"
4789
 
4790
        wallet.amount = wallet.amount + rechargeTransaction.amount
4791
        store.availableLimit = store.availableLimit + rechargeTransaction.amount
7076 rajveer 4792
        store.collectedAmount = store.collectedAmount - rechargeTransaction.amount + rechargeTransaction.discount
7075 rajveer 4793
 
4794
    session.commit()
4795
 
7073 anupam.sin 4796
    return rechargeTransaction
4797
 
7080 anupam.sin 4798
def get_frcs(circleId, operatorId):
7267 anupam.sin 4799
    query = FRC.query.filter(FRC.circleId == circleId)
4800
    if(operatorId > 0):
4801
        query = query.filter(FRC.operatorId == operatorId)
4802
 
4803
    frcs = query.all()
4804
 
7096 anupam.sin 4805
    if frcs is None:
4806
        return []
4807
    return frcs
7080 anupam.sin 4808
 
4809
def get_recharge_transaction(rechargeId):
4810
    recharge = RechargeTransaction.get_by(id = rechargeId)
4811
    if not recharge:
4812
        raise TransactionServiceException(108, "no such transaction")
4813
    return recharge
4814
 
7096 anupam.sin 4815
def get_hotspot_store(id, hotspotid):
4816
    store = None
4817
    if id > 0:
4818
        store = HotspotStore.query.filter(HotspotStore.id == id).first()
4819
    elif len(hotspotid) > 0:
4820
        store = HotspotStore.query.filter(HotspotStore.hotspotId == hotspotid).first()
4821
    else:
4822
        raise TransactionServiceException(119, 'No such store')
4823
    if store:
4824
        return store
4825
    else:
4826
        raise TransactionServiceException(119, 'No such store')
4827
 
4828
def get_circle(id, code):
4829
    circle = None
4830
    if id > 0:
4831
        circle = TelecomCircle.get_by(id = id)
4832
    elif len(code) > 0:
4833
        circle = TelecomCircle.get_by(code = code)
4834
    else:
4835
        raise TransactionServiceException(119, 'No such circle')
4836
    if circle:
4837
        return circle
4838
    else:
4839
        raise TransactionServiceException(119, 'No such circle')
4840
 
7109 anupam.sin 4841
def retrieve_hotspot_recharge_invoice(id):
4842
    recharge = RechargeTransaction.get_by(id = id)
7139 amit.gupta 4843
    filename = "/tmp/recharge" + str(recharge.invoiceNumber) + ".pdf"
7109 anupam.sin 4844
    operator = ServiceProvider.get_by(id = recharge.operatorId).name
4845
    amount = recharge.amount
4846
    telNum = "+91 " + str(recharge.deviceNum)
4847
    customerName = recharge.name
4848
    invNum = str(recharge.invoiceNumber)
4849
    billingTime = recharge.responseTime
7151 amit.gupta 4850
    payMethod = recharge.payMethod
4851
    return __printRechargeInvoice(filename, operator, amount, telNum, customerName, invNum, billingTime, payMethod)
7109 anupam.sin 4852
 
7190 amar.kumar 4853
def split_freebie_order(order_id, splitReason, shippingDate):
4854
    order = get_order(order_id)
4855
    freebie_order = Order()
4856
 
4857
    freebie_order.transaction = order.transaction
4858
 
4859
    freebie_order.customer_id = order.customer_id
4860
    freebie_order.customer_email = order.customer_email
4861
    freebie_order.customer_name = order.customer_name
4862
    freebie_order.customer_pincode = order.customer_pincode
4863
    freebie_order.customer_address1 = order.customer_address1
4864
    freebie_order.customer_address2 = order.customer_address2
4865
    freebie_order.customer_city = order.customer_city
4866
    freebie_order.customer_state = order.customer_state
4867
    freebie_order.customer_mobilenumber = order.customer_mobilenumber
4868
    freebie_order.total_weight = order.total_weight
4869
    freebie_order.total_amount = 0.01
4870
    freebie_order.status = OrderStatus.SUBMITTED_FOR_PROCESSING
4871
    freebie_order.statusDescription = "In Process";
4872
    freebie_order.created_timestamp = datetime.datetime.now()
4873
    freebie_order.cod = 0
4874
    freebie_order.orderType = OrderType.B2C
4875
    freebie_order.pickupStoreId = 0
4876
    freebie_order.otg = 0
4877
    freebie_order.insurer = 0
4878
    freebie_order.insuranceAmount = 0
4879
 
4880
    logistics_client = LogisticsClient().get_client()
4881
    logistics_info = logistics_client.getLogisticsInfo(order.customer_pincode, 1, DeliveryType.PREPAID, PickUpType.COURIER)
4882
    freebie_order.logistics_provider_id = logistics_info.providerId;
4883
    freebie_order.tracking_id = logistics_info.airway_billno
4884
    freebie_order.airwaybill_no = logistics_info.airway_billno
4885
    freebie_order.expected_delivery_time = (to_py_date(shippingDate)+datetime.timedelta(days=logistics_info.deliveryTime)).replace(hour=PREPAID_SHIPPING_CUTOFF_TIME, minute=0, second=0)  
4886
    freebie_order.promised_delivery_time = order.promised_delivery_time
4887
    freebie_order.expected_shipping_time = to_py_date(shippingDate)
4888
    freebie_order.promised_shipping_time = order.promised_shipping_time
4889
 
4890
    inventory_client = InventoryClient().get_client()
7198 amar.kumar 4891
    item_availability = inventory_client.getItemAvailabilityAtLocation(order.freebieItemId,1)
7190 amar.kumar 4892
    freebie_order.warehouse_id = item_availability[2]
7303 amar.kumar 4893
    freebie_order.fulfilmentWarehouseId = item_availability[0]
7190 amar.kumar 4894
 
4895
    catalog_client = CatalogClient().get_client()
4896
    item = catalog_client.getItem(order.freebieItemId)
4897
    freebie_order.total_weight = item.weight
4898
 
4899
    litem = LineItem()
4900
    litem.item_id = item.id
4901
    litem.productGroup = item.productGroup
4902
    litem.brand = item.brand
4903
    litem.model_number = item.modelNumber
4904
    litem.model_name = item.modelName
4905
    litem.color = item.color
4906
    litem.extra_info = "Freebie Order for Order ID " + str(order.id)
4907
    litem.quantity = 1
4908
    litem.unit_price = 0.01
4909
    litem.unit_weight = item.weight
4910
    litem.total_price = 0.01
4911
    litem.total_weight = item.weight
4912
    litem.vatRate = 5.0
4913
 
4914
    freebie_order.lineitems.append(litem)
7198 amar.kumar 4915
    order.freebieItemId = 0
7190 amar.kumar 4916
    session.commit()
7198 amar.kumar 4917
    order.lineitems[0].extra_info = "Parent Order for Order ID " + str(freebie_order.id)
7190 amar.kumar 4918
 
7198 amar.kumar 4919
    inventory_client = InventoryClient().get_client()   
4920
    inventory_client.reserveItemInWarehouse(freebie_order.lineitems[0].item_id, item_availability[0], sourceId, freebie_order.id, to_java_date(freebie_order.created_timestamp), to_java_date(freebie_order.promised_shipping_time), 1)
7190 amar.kumar 4921
    parentOrderAttribute = Attribute()
4922
    parentOrderAttribute.orderId = freebie_order.id
4923
    parentOrderAttribute.name = "parentOrderIdForFreebie"
4924
    parentOrderAttribute.value = str(order.id)
4925
 
4926
    freebieOrderAttribute = Attribute()
4927
    freebieOrderAttribute.orderId = order.id
4928
    freebieOrderAttribute.name = "freebieOrderId"
4929
    freebieOrderAttribute.value = str(freebie_order.id)
4930
    session.commit()
4931
 
7198 amar.kumar 4932
    return to_t_order(freebie_order)
7190 amar.kumar 4933
 
7151 amit.gupta 4934
def __printRechargeInvoice(filename, operator, amount, telNum, customerName, invNum, billingTime, payMethod): 
7109 anupam.sin 4935
    PAGE_HEIGHT=defaultPageSize[1];
4936
    styles = getSampleStyleSheet()
4937
    styles.add(ParagraphStyle(name='prologue', alignment=TA_CENTER, fontName="Courier", rightIndent = 5, fontSize=10), alias='sH')
4938
    styles.add(ParagraphStyle(name='text', alignment=TA_JUSTIFY, fontName="Courier", fontSize=10), alias='text')
4939
    styles.add(ParagraphStyle(name='line', alignment=TA_CENTER, fontName="Courier", fontSize=10), alias='line')
4940
    styles.add(ParagraphStyle(name='epilogue', alignment=TA_CENTER, fontName="Courier", leftIndent = 30, rightIndent=36, fontSize=10), alias='ep')
7096 anupam.sin 4941
 
7109 anupam.sin 4942
    Story = []
4943
    prologueStyle = styles["prologue"]
4944
    lineStyle = styles["line"]
4945
    textStyle = styles["text"]
4946
    epilogueStyle = styles["epilogue"]
7096 anupam.sin 4947
 
7109 anupam.sin 4948
    doc = BaseDocTemplate(filename,showBoundary=0)
4949
 
4950
    #Two Columns
4951
    frame1 = Frame(58, doc.bottomMargin, doc.width/2 + 25, doc.height + 7, id='col1')
4952
 
4953
 
4954
 
4955
    Story.append(Paragraph("""Spice Retail Limited<br></br>
4956
        C/O,PIBCO LIMITED,Basement,Punjsons<br></br>
4957
        2,Kalkaji Industrial Area,New Delhi<br></br>
4958
          .<br></br>
4959
        TIN NO. 07430284979<br></br>
4960
        Service Tax No:AAACM0294PST001<br></br><br></br><br></br>""", prologueStyle))
4961
    drawLine(Story, lineStyle)
4962
 
4963
    Story.append(Paragraph('{0:7s}{1:>11s}{2:  %d/%m/%Y  %H:%M:%S}'.format("INV NO:", invNum, billingTime).replace(" ", "&nbsp;"), textStyle))
4964
    drawLine(Story, lineStyle)
4965
 
4966
    Story.append(Paragraph("{0:<6s}{1:<34s}".format("NAME:", customerName).replace(" ", "&nbsp;"), textStyle))
4967
    Story.append(Paragraph("{0:<9s}{1:<31s}".format("TEL NO.:", telNum).replace(" ", "&nbsp;"), textStyle))
7151 amit.gupta 4968
    Story.append(Paragraph("{0:<9s}{1:<31s}".format("PAYMENT MODE:", PayMethod._VALUES_TO_NAMES[payMethod]).replace(" ", "&nbsp;"), textStyle))
7109 anupam.sin 4969
    drawLine(Story, lineStyle)
4970
 
4971
    Story.append(Paragraph(('{0:<16s}{1:>13s}{2:11.2f}').format(operator, "RECHARGE", amount).replace(' ', '&nbsp;'),textStyle))
4972
    drawLine(Story, lineStyle)
4973
    doc.addPageTemplates([PageTemplate(id='TwoCol',frames=[frame1]), ])
4974
 
4975
    #start the construction of the pdf
4976
    doc.build(Story)
4977
 
4978
    try:
4979
        fileToSend = open(filename, "rb")
4980
        pdfFile = fileToSend.read()
4981
    except:
4982
        return bin(0)
4983
 
4984
    return pdfFile
4985
 
7172 anupam.sin 4986
def get_recharge_transactions_by_number(number, storeId):
7169 anupam.sin 4987
    query = RechargeTransaction.query.filter(RechargeTransaction.deviceNum == number)
7172 anupam.sin 4988
    query = query.filter(RechargeTransaction.storeId == storeId)
7169 anupam.sin 4989
    return query.all()
4990
 
4991
def update_hotspot_store_password(storeId, password):
4992
    store = None
4993
    if password is None:
4994
        return False
4995
    if storeId:
4996
        store = HotspotStore.query.filter(HotspotStore.id == storeId).first()
4997
    if store:
4998
        store.password = password
4999
        session.commit()
5000
        return True
5001
    return False
5002
 
7263 anupam.sin 5003
def get_source_detail(source):
5004
    detail = SourceDetail.get_by(id=source)
5005
    if not detail:
5006
        raise TransactionServiceException(108, "no such source")
5007
    return detail
5008
 
7267 anupam.sin 5009
def get_all_circles():
5010
    circles = TelecomCircle.query.all();
5011
    if not circles:
5012
        circles = []
5013
    return circles 
5014
 
5015
def delete_frcs(frcIdsToDelete):
5016
    toReturn = False
5017
    if frcIdsToDelete:
5018
        for frcId in frcIdsToDelete:
5019
            frc = FRC.get_by(id = frcId)
5020
            if frc:
5021
                frc.delete()
5022
                toReturn = True
5023
        session.commit()
5024
        return toReturn
5025
    else:
5026
        return toReturn
5027
 
7285 rajveer 5028
def topup_company_wallet(companyId, amount):
5029
    wallet = WalletForCompany.query.filter(WalletForCompany.id == companyId).with_lockmode("update").one()
5030
    company = Company.get_by(id = companyId)
5031
    wh = WalletHistoryForCompany()
5032
    wh.walletId = wallet.id
5033
    wh.openingBal = wallet.amount
5034
    wh.closingBal = wallet.amount +  amount
5035
    wh.amount = amount
5036
    wh.transactionTime = datetime.datetime.now()
5037
    wh.referenceNumber =  get_next_invoice_number(OrderType.WALLETCREDIT)
5038
    wh.description = "Wallet Credited"
5039
 
5040
    wallet.amount += amount
5041
    session.commit()
5042
    mail("cnc.center@shop2020.in", "5h0p2o2o", ["rajveer.singh@shop2020.in", "anupam.singh@shop2020.in", "Ashwani.Kumar@spiceretail.co.in","parveen.mittal@spiceretail.co.in","pardeep.panwar@spiceretail.co.in","gagan.sharma@spiceretail.co.in","j.p.gupta@shop2020.in", "rajneesh.arora@shop2020.in", "amit.tyagi@spiceretail.co.in"] , company.name + " wallet topped up by " +  str(amount) + " rupees.", "", [], [], [])
5043
    return wallet.amount
7267 anupam.sin 5044
 
7285 rajveer 5045
def get_wallet_balance_for_company(companyId):
5046
    return WalletForCompany.get_by(companyId = companyId).amount
5047
 
7311 kshitij.so 5048
def add_amazon_order(amazonOrder):
5049
    amazon_order = AmazonOrder()
5050
    amazon_order.orderId = amazonOrder.orderId
5051
    amazon_order.amazonOrderCode = amazonOrder.amazonOrderCode
5052
    amazon_order.amazonOrderItemCode = amazonOrder.amazonOrderItemCode
5053
    amazon_order.transactionId = amazonOrder.transactionId
5054
    amazon_order.item_id= amazonOrder.item_id
5055
    amazon_order.status= amazonOrder.status
5056
    session.commit()
5057
 
5058
def get_order_for_amazonordercode(order_id,status):
5059
    try:
5060
        row = AmazonOrder.get_by(orderId=order_id)
5061
        row.status=status
5062
        result=True
5063
    except:
5064
        result=False
5065
    finally:
5066
        session.commit()
5067
        return result
5068
 
5069
def get_amazon_orders_marked_sent():
5070
    return AmazonOrder.query.filter(AmazonOrder.status=='Acknowledment_Sent').all()
5071
 
5072
def get_amazon_orders_shipped(interval):
5073
    amazonShippedOrders = []
5074
    toDate = datetime.datetime.now()
5075
    fromDate = toDate-timedelta(days = interval-1, hours=toDate.hour, minutes=toDate.minute, seconds=toDate.second)
5076
    orders = get_amazon_orders_marked_sent()
5077
    for order in orders:
5078
        row = Order.query.filter(Order.shipping_timestamp.between (fromDate,toDate)).filter(Order.id==order.orderId).first()
5079
        amazonShippedOrders.append(to_t_order(row))
5080
    return amazonShippedOrders
5081
 
5082
def get_amazon_orders_cancelled(interval):
5083
    amazonCancelledOrders = []
5084
    toDate = datetime.datetime.now()
5085
    fromDate = toDate-timedelta(days = interval-1, hours=toDate.hour, minutes=toDate.minute, seconds=toDate.second)
5086
    orders = get_amazon_orders_marked_sent()
5087
    for order in orders:
5088
        row = Order.query.filter(Order.refund_timestamp.between (fromDate,toDate)).filter(Order.id==order.orderId).first()
5089
        if ( row.status == 15 or row.status == 18 or row.status == 34 ):
5090
            amazonCancelledOrders.append(to_t_order(row))
5091
    return amazonCancelledOrders        
5092
 
6915 anupam.sin 5093
if __name__ == '__main__':
6980 anupam.sin 5094
    print 'helllo'