Subversion Repositories SmartDukaan

Rev

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