Subversion Repositories SmartDukaan

Rev

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